fixed 8bit writes to vmem, unaligned data buffers, and started on
[gba_blender] / tools / pngdump / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include "image.h"
6
7 void print_usage(const char *argv0);
8
9 int main(int argc, char **argv)
10 {
11         int i, mode = 0;
12         int text = 0;
13         char *fname = 0, *outfname = 0;
14         struct image img;
15         FILE *out = stdout;
16
17         for(i=1; i<argc; i++) {
18                 if(argv[i][0] == '-') {
19                         if(argv[i][2] == 0) {
20                                 switch(argv[i][1]) {
21                                 case 'p':
22                                         mode = 0;
23                                         break;
24
25                                 case 'c':
26                                         mode = 1;
27                                         break;
28
29                                 case 'i':
30                                         mode = 2;
31                                         break;
32
33                                 case 't':
34                                         text = 1;
35                                         break;
36
37                                 case 'o':
38                                         if(!argv[++i]) {
39                                                 fprintf(stderr, "%s must be followed by a filename\n", argv[i - 1]);
40                                                 return 1;
41                                         }
42                                         outfname = argv[i];
43                                         break;
44
45                                 case 'h':
46                                         print_usage(argv[0]);
47                                         return 0;
48
49                                 default:
50                                         fprintf(stderr, "invalid option: %s\n", argv[i]);
51                                         print_usage(argv[0]);
52                                         return 1;
53                                 }
54                         } else {
55                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
56                                 print_usage(argv[0]);
57                                 return 1;
58                         }
59                 } else {
60                         if(fname) {
61                                 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
62                                 print_usage(argv[0]);
63                                 return 1;
64                         }
65                         fname = argv[i];
66                 }
67         }
68
69         if(!fname) {
70                 fprintf(stderr, "pass the filename of a PNG file\n");
71                 return 1;
72         }
73         if(load_image(&img, fname) == -1) {
74                 fprintf(stderr, "failed to load PNG file: %s\n", fname);
75                 return 1;
76         }
77
78         if(outfname) {
79                 if(!(out = fopen(outfname, "wb"))) {
80                         fprintf(stderr, "failed to open output file: %s: %s\n", outfname, strerror(errno));
81                         return 1;
82                 }
83         }
84
85         switch(mode) {
86         case 0:
87                 if(img.bpp > 8 || img.cmap_ncolors == 0 || img.cmap_ncolors > 16) {
88                         fwrite(img.pixels, 1, img.scansz * img.height, out);
89                 } else {
90                         /* pack into nibbles */
91                         unsigned char *ptr = img.pixels;
92                         for(i=0; i<img.width * img.height / 2; i++) {
93                                 unsigned char pair = (ptr[0] << 4) | ptr[1];
94                                 fputc(pair, out);
95                                 ptr += 2;
96                         }
97                 }
98                 break;
99
100         case 1:
101                 if(text) {
102                         for(i=0; i<img.cmap_ncolors; i++) {
103                                 printf("%d %d %d\n", img.cmap[i].r, img.cmap[i].g, img.cmap[i].b);
104                         }
105                 } else {
106                         fwrite(img.cmap, sizeof img.cmap[0], img.cmap_ncolors, out);
107                 }
108                 break;
109
110         case 2:
111                 printf("size: %dx%d\n", img.width, img.height);
112                 printf("bit depth: %d\n", img.bpp);
113                 printf("scanline size: %d bytes\n", img.scansz);
114                 if(img.cmap_ncolors > 0) {
115                         printf("colormap entries: %d\n", img.cmap_ncolors);
116                 } else {
117                         printf("color channels: %d\n", img.nchan);
118                 }
119                 break;
120         }
121
122         fclose(out);
123         return 0;
124 }
125
126 void print_usage(const char *argv0)
127 {
128         printf("Usage: %s [options] <input file>\n", argv0);
129         printf("Options:\n");
130         printf(" -p: dump pixels (default)\n");
131         printf(" -c: dump colormap (palette) entries\n");
132         printf(" -i: print image information\n");
133         printf(" -t: dump as text\n");
134         printf(" -h: print usage and exit\n");
135 }