root/trunk/lodepng/lodepng/examples/recoder.d

Revision 256, 4.8 kB (checked in by Lutger, 4 months ago)

bugfixes, added png2bin.d example

Line 
1 /**
2  *
3  */
4 module recoder;
5
6 version(Windows)
7 {
8     pragma(lib, "zlib");
9 }
10
11 import lodepng.Decode,
12        lodepng.Encode;
13
14 import tango.util.Arguments,
15        tango.io.Stdout,
16        tango.io.File,
17        tango.stdc.stdio,
18        tango.text.Ascii,
19        tango.io.FilePath,
20        tango.io.FileSystem,
21        tango.util.PathUtil;
22
23 /+
24 TODO
25     verbose output
26     ask for overwriting / renaming
27     option aliasing
28 +/
29
30 char[] description = "Recoder: utility to re-encode png files. Test program for the lodepng library. usage: recode pngfile1 [pngfile2] [options]\n";
31 char[][] options =
32 [
33     "h", "help",       "\tdisplay this help message",
34     "r", "reencode",     "keep only known information, this will lose unknown chunks",
35     "s", "shrink",       "\tdiscard as much data as possible while still keeping original pixels",
36     "t", "test",       "\ttest run, do not save final image"      ,
37     "d", "dump",       "\tonly reads and saves chunks, doesn't decode.",
38     "f", "force",      "\tdo not ask for confirmation when overwriting files",
39 ];
40 //"c=x", "color=x",  "\tconvert source to color format x:\n\t\t 2 - 24-bit RGB color format\n\t\t 6 - 32-bit RGBA color format\n\t\t 0 - chooses format 2 if this is a lossless operation, otherwise 6\n"
41 enum : int
42 {
43     shrink = 1, recode, dump
44 }
45
46 int main(char[][] args)
47 {
48     auto arguments = new Arguments(args, ["source", "target"],
49     [
50     ["h", "help"],
51     ["r", "reencode"],
52     ["s", "shrink"],
53     ["t", "test"],
54     ["d", "dump"],
55     ["f", "force"]
56     ]
57     );
58     char[] sourceFile = arguments["source"].length ? arguments["source"][0] : null;
59     char[] targetFile = arguments["target"].length ? arguments["target"][0] : null;
60
61     addValidations(arguments);
62     arguments.validate();
63
64     if ("h" in arguments || sourceFile.length == 0)
65     {
66         printHelp();
67         return 0;
68     }
69
70     if (targetFile.length == 0)
71         targetFile = sourceFile.dup;
72
73     bool verbose = "v" in arguments;
74     bool test = "t" in arguments;
75     bool force = "f" in arguments;
76     int  method = chooseMethod(arguments);
77
78     if ((new FilePath(targetFile)).exists() && !force)
79     {
80         char response;
81         while (true)
82         {
83             Stdout.format("Are you sure you want to overwrite {} (y/n)?", targetFile).newline;
84             response = getchar();
85             if (response == 'n' || response == 'N')
86                 return 0;
87             else if (response == 'y' || response == 'Y')
88                 break;
89         }
90     }
91
92     ubyte[] pngBytes = cast(ubyte[]) (new File(sourceFile)).read();
93     PngInfo info;
94     ubyte[] result;
95
96     void recodeImage()
97     {
98         auto imgBytes = pngBytes.decode(info);
99         result = imgBytes.encode(Settings(info, false));
100     }
101
102     void shrinkImage()
103     {
104         auto imgBytes = pngBytes.decode(info);
105         info.parseText = false;
106         auto settings = Settings(info, true);
107         settings.compressionLevel = 9;
108         result = imgBytes.encode(settings);
109
110     }
111
112     void dumpImage()
113     {
114         Chunk[] chunks;
115         info.image = pngBytes.readHeader();
116         pngBytes.iterateChunks(info.image, (ref Chunk chunk)
117             {
118                 if (parseChunk(chunk, info) == false)
119                     chunks ~= chunk.dup;
120                 return 0;
121             });
122
123         result = encode(null, Settings(info, false), chunks);
124     }
125
126     if (method == dump)
127         dumpImage();
128     else if (method == shrink)
129         shrinkImage();
130     else if (method == recode)
131         recodeImage();
132     else
133         Stdout("?").newline;
134
135     if (!test)
136         (new File(targetFile)).write(result);
137
138
139     return 0;
140 }
141
142
143 void printHelp()
144 {
145     Stdout(description).newline;
146     for (int i = 0; i < options.length - 3; i+=3)
147         Stdout.format("  -{}\t--{}\t{}", options[i], options[i+1], options[i+2]).newline;
148 }
149
150
151 void addValidations(ref Arguments arguments)
152 {
153     for (int i = 0; i < options.length - 3; i+=3)
154     {
155         arguments.addValidation(options[i], false, false);
156         arguments.addValidation(options[i + 1], false, false);
157     }
158     //arguments.addValidation("c", false, true);
159     //arguments.addValidation("color", false, true);
160 }
161
162
163 int chooseMethod(Arguments arguments)
164 {
165     int method = 0;
166
167     if ("s" in arguments)
168         method = shrink;
169     if ("r" in arguments)
170     {
171         if (method != 0)
172             throw new Exception("options r and s are mutually exclusive");
173         method = recode;
174     }
175     if ("d" in arguments)
176     {
177         if (method != 0)
178             throw new Exception("options mutually exclusive");
179         method = dump;
180     }
181     if (method == 0)
182         method = dump;
183     return method;
184 }
185
186
187 void printHeader(PngImage image)
188 {
189     Stdout("Source image properties:").newline;
190     Stdout.format("    width: {}", image.width).newline;
191     Stdout.format("    height: {}", image.height).newline;
192     Stdout.format("    color format: {}", image.colorType).newline;
193 }
Note: See TracBrowser for help on using the browser.