root/trunk/lodepng/Recode.d

Revision 217, 4.9 kB (checked in by Lutger, 4 years ago)

bugfixes and DMD compatibility

Line 
1 /***************************************************************************************************
2     Decode and encode a png image.
3
4     This can be useful to:
5     - test lodepng
6     - convert png images to RGB(A) format
7     - remove redundant information that is not parsed by lodepng
8     - possibly reduce png image size
9
10     Usage: recode pngfile1 pngfile2 [options]
11    -f=<filter>         filter can be one of: adaptive, none, sub, up, average, paeth
12    -c=<compression>    zlib strategy, one of: none, rle, default, filtered
13
14
15 ***************************************************************************************************/
16 module Recode;
17
18 version(Tango)
19 {
20     import tango.io.File;
21     import tango.io.Stdout;
22 }
23 else
24 {
25     import std.stdio;
26     import std.file;
27     import std.path;
28     import std.stdio;
29 }
30
31 import lodepng.Decode;
32 import lodepng.Encode;
33
34 version( Tango )
35 {
36     void println(char[] str)
37     {
38         Stdout(str).newline;
39     }
40 }
41 else
42 {
43     alias writefln println;
44 }
45 /+
46 None      (ubyte c, ubyte b, ubyte a, ubyte x) { return x; }
47     ubyte Sub       (ubyte c, ubyte b, ubyte a, ubyte x) { return x - a; }
48     ubyte Up        (ubyte c, ubyte b, ubyte a, ubyte x) { return x - b; }
49     ubyte Average   (ubyte c, ubyte b, ubyte a, ubyte x) { return x - (a + b) / 2; }
50     ubyte Paeth     (
51 +/
52 void showHelp(char[] errorMessage = "")
53 {
54     if (errorMessage.length)
55         println("error: " ~ errorMessage);
56     println("  usage: recode pngfile1 pngfile2 [options]");
57     println("   -f=<filter>         filter can be one of: adaptive, none, sub, up, average, paeth");
58     println("   -c=<compression>    zlib strategy, one of: none, rle, default, filtered");
59 }
60
61 CompressionStrategy cs = CompressionStrategy.RLE;
62 FilterStrategy fs = FilterStrategy.Dynamic;
63
64 void main(char[][] args)
65 {
66     println("Recode. Decode and encode a png image, will discard unsupported chunks.\n");
67
68     if (args.length < 3)
69     {
70         showHelp("wrong number of arguments provided");
71         return 0;
72     }
73
74     char[] pngFile1;
75     char[] pngFile2;
76
77     foreach(arg; args[1..$])
78     {
79         if (arg[0] == '-')
80         {
81             if (arg.length < 4)
82             {
83                 showHelp("option not recognized");
84                 return 1;
85             }
86             if (arg[1..3] == "f=")
87             {
88                 switch(arg[3..$])
89                 {
90                     case "adaptive": fs = FilterStrategy.Dynamic; break;
91                     case "none":  fs = FilterStrategy.None; break;
92                     case "sub":  fs = FilterStrategy.Sub; break;
93                     case "up":  fs = FilterStrategy.Up; break;
94                     case "average":  fs = FilterStrategy.Average; break;
95                     case "paeth":  fs = FilterStrategy.Paeth; break;
96                     default: showHelp("wrong filter type"); return 1; break;
97                 }
98             }
99             else if (arg[1..3] == "c=")
100             {
101                 switch (arg[3..$])
102                 {
103                     case "rle": case "RLE": cs = CompressionStrategy.RLE; break;
104                     case "default": cs = CompressionStrategy.Default; break;
105                     case "filtered": cs = CompressionStrategy.Filtered; break;
106                     case "none": cs = CompressionStrategy.None; break;
107                     default: showHelp("wrong compression type"); return 1; break;
108                 }
109             }
110             else
111             {
112                 showHelp("unrecognized option");
113                 return 1;
114             }
115         }
116         else
117         {
118             if (pngFile1.length)
119             {
120                 if (pngFile2.length)
121                 {
122                     showHelp("too files specified");
123                     return 1;
124                 }
125                 pngFile2 = arg;
126             }
127             else
128                 pngFile1 = arg;
129         }
130     }
131
132     ubyte[] source;
133
134     version (Tango)
135     {
136         source = cast(ubyte[])((new File(pngFile1)).read());
137     }
138     else
139     {
140         source = cast(ubyte[])read(pngFile1);
141     }
142
143     ubyte[] data;
144     data.length = source.length * 2;
145
146     PngInfo inf;
147     inf.image = readHeader(source);
148
149     assert(source.length > 0);
150     data = decode(source, inf, data);
151     assert(data.length > 0);
152
153     ubyte[] dataOut = encode(data, Settings(inf, false));
154     version(Tango)
155     {
156         (new File(pngFile2)).write(dataOut);
157         Stdout("Original file: ")(pngFile1)(" (")(source.length / 1024)(" Kb)").newline;
158         Stdout("Recoded as: ")(pngFile2)(" (")(dataOut.length / 1024)(" Kb)").newline;
159         Stdout("Difference: ")( (cast(int)dataOut.length - cast(int)source.length) / 1024)(" Kb)").newline;
160     }
161     else
162     {
163         std.file.write(pngFile2, dataOut);
164         writefln("Original file: ", pngFile1, " (", source.length / 1024, " Kb)");
165         writefln("Recoded as: ", pngFile2, " (", dataOut.length / 1024, " Kb)");
166         writefln("Difference: ", (cast(int)dataOut.length - cast(int)source.length) / 1024, " Kb");
167     }
168 }
Note: See TracBrowser for help on using the browser.