1 #include <stdlib.h>
2 #include <stdio.h>
3 #include <stdarg.h>
4 #include <string.h>
5 #include <unistd.h>
6 #include <sys/socket.h>
7 
8 #include <ming_config.h>
9 
10 #include <png.h>
11 
12 #include <zlib.h>
13 
14 int verbose = 0;
15 typedef unsigned char byte;
16 
error(char * s,...)17 void error(char *s, ...)
18 {
19   va_list ap;
20   va_start(ap, s);
21   vprintf(s, ap);
22   va_end(ap);
23   putchar('\n');
24   exit(1);
25 }
26 
usage()27 void usage()
28 {
29   printf("dbl2png - convert a dbl file to an png file\n");
30   printf("\nUsage: dbl2png [--verbose] <file.dbl>\n");
31   printf("where file.dbl is your dbl file.  Writes to file.png.\n");
32   exit(1);
33 }
34 
35 struct pngdata
36 {
37   png_uint_32 width;
38   png_uint_32 height;
39   int bit_depth;
40   int color_type;
41   int num_palette;
42   int channels;
43   png_colorp palette;
44   unsigned char *data;
45 };
46 
47 
readDBL(FILE * fp)48 struct pngdata readDBL(FILE *fp)
49 {
50   struct pngdata png;
51   byte header[13],*data;
52   unsigned long outsize,readsize=0,datsize;
53   int i, ret;
54 
55   if(!fp)
56     error("Couldn't open file!\n");
57 
58   ret = fread(header, 1, 13, fp);
59   if(ret != 13)
60     error("Couldn't read header\n");
61 
62   if (header[3]==2)
63   {
64    if(verbose)
65     printf("image data RGBA\n");
66    png.color_type=PNG_COLOR_TYPE_RGB_ALPHA;
67   }
68   else
69   {
70    if (header[3]==1)
71    {
72     if(verbose)
73      printf("image data RGB\n");
74     png.color_type=PNG_COLOR_TYPE_RGB;
75    }
76    else
77     error("unexpected 3rd byte in header");
78   }
79   outsize=(header[4]<<24)+(header[5]<<16)+(header[6]<<8)+header[7];
80   if(verbose)
81     printf("outsize=%ld \n",outsize);
82 
83   png.bit_depth=8; 					// Can't deal with bit depth !=8
84   png.width= header[9] +(header[10]<<8);
85   png.height=header[11]+(header[12]<<8);
86 
87   if (header[8]==3)
88   {
89     png.color_type=PNG_COLOR_TYPE_PALETTE;
90     readsize=outsize-6 ;
91     png.num_palette=0;
92     i=  fread(&png.num_palette,  1,  1 ,fp);
93     if (verbose)
94     {
95       printf("image has PALETTE\npalette size=%d\n",png.num_palette+1);
96       printf("size %d x %d\n", (int)png.width, (int)png.height);
97     }
98   }
99   else
100   {
101    if (header[8]!=5)
102     error("unexpected 8th byte in header");
103    else
104    {
105     readsize=outsize-5 ;
106     if(verbose)
107     {
108      printf("size %d x %d\n", (int)png.width, (int)png.height);
109     }
110    }
111   }
112   if (!readsize)
113    error("internal error");
114   //
115   // ------ now we go --------
116   //
117   data=malloc( readsize );
118   if (!data)
119   {
120    error("memory allocation");
121   }
122   datsize=fread(data, 1, readsize, fp);
123   fclose(fp);
124   if (datsize != readsize)
125   {
126     free(data);
127     error("Didn't read all of the file! %d  vs %d",datsize , readsize);
128   }
129   if (png.color_type==PNG_COLOR_TYPE_PALETTE)			// for palette bit_depth==8
130    datsize = (png.num_palette+1) * 3 + png.width * png.height;	// palette of RGB style
131   else
132    datsize = png.width *  png.height * 4;			// RGBA
133   png.data=malloc(datsize);
134   if (!png.data)
135   {
136    free(data);
137    error("memory allocation");
138   }
139 
140   /* uncompress the data */
141   i=uncompress (png.data, &datsize, data, readsize );
142   if (i)
143   {
144    printf("uncompress call result = %d\n",i);
145    free(data);
146    error("uncompress error");
147   }
148   if(verbose)
149   {
150     printf("unpacked data size t=%ld byte\n",datsize);
151   }
152   free(data);
153   return png;
154 }
155 
156 // callback function:
157 // reverse apply alpha, bytes shifting (see png2dbl.c for details)
158 // expecting pixel_depth==32, bit_depth==8, color_type==PNG_COLOR_TYPE_RGB_ALPHA
alpha_apply(png_structp png_ptr,png_row_infop row_info,png_bytep p)159 void alpha_apply(png_structp png_ptr, png_row_infop row_info, png_bytep p)
160 {
161   int i;
162   byte a, r, g, b;
163   for(i=0;i<row_info->width;i++)
164   {
165    a = p[0];
166    r = p[1];
167    g = p[2];
168    b = p[3];
169    *p++ = (r<<8)/(a+1);
170    *p++ = (g<<8)/(a+1);
171    *p++ = (b<<8)/(a+1);
172    *p++ = a;
173   }
174 }
175 
176 
writePNG(FILE * fp,struct pngdata png)177 void writePNG(FILE *fp, struct pngdata png)
178 {
179   png_structp png_ptr;
180   png_infop info_ptr;
181   int i,chan;
182   byte *ptr=png.data;
183 
184   if(!fp)
185     error("Couldn't open file!\n");
186 
187   png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
188   if(!png_ptr)
189     error("Couldn't create png_ptr\n");
190 
191   info_ptr = png_create_info_struct(png_ptr);
192   if(!info_ptr)
193   {
194     png_destroy_write_struct(&png_ptr,(png_infopp)NULL);
195     error("Couldn't create info_ptr\n");
196   }
197 
198   if (setjmp(png_jmpbuf(png_ptr)))
199   {
200     png_destroy_write_struct(&png_ptr, &info_ptr);
201     fclose(fp);
202     error("Mystery error (longjmp called)\n");
203   }
204 
205   png_init_io(png_ptr, fp);
206   png_set_IHDR(png_ptr, info_ptr, png.width, png.height,
207   		png.bit_depth, png.color_type, PNG_INTERLACE_NONE,
208   		PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
209   if (png.color_type==PNG_COLOR_TYPE_PALETTE)
210     png_set_PLTE(png_ptr, info_ptr,(png_colorp)png.data, png.num_palette+1);
211   png_write_info(png_ptr, info_ptr);
212 
213   //
214   // ------ now we go --------
215   //
216   chan=png_get_channels(png_ptr, info_ptr);
217   if (verbose)
218     printf("channel count=%d\n",chan);
219 
220   if(png.color_type == PNG_COLOR_TYPE_RGB_ALPHA )
221   {
222    png_set_write_user_transform_fn(png_ptr, alpha_apply);
223    for (i=0;i<png.height;i++)
224    {
225       png_write_row(png_ptr,ptr);
226       ptr+=png.width * chan;				// 4
227    }
228   }
229   if(png.color_type == PNG_COLOR_TYPE_RGB)
230   {
231    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
232    for (i=0;i<png.height;i++)
233    {
234       png_write_row(png_ptr,ptr);
235       ptr+=png.width * 4;
236    }
237   }
238   if(png.color_type == PNG_COLOR_TYPE_PALETTE)
239   {
240     ptr+=(png.num_palette+1) * 3; 			// for palette bit_depth==8 of RGB style
241     for (i=0;i<png.height;i++)
242     {
243       png_write_row(png_ptr,ptr);
244       ptr+=png.width * chan;				// 1
245     }
246   }
247 
248   png_write_end(png_ptr,NULL);
249   png_destroy_write_struct(&png_ptr, &info_ptr);
250   free(png.data);
251   fclose(fp);
252 }
253 
254 
main(int argc,char * argv[])255 int main(int argc, char *argv[])
256 {
257   int len;
258   char *outfile;
259   struct pngdata png;
260 
261   if (argc > 2 && strcmp(argv[1], "--verbose")==0) {
262 	verbose = 1;
263 	argc--;
264 	argv++;
265   }
266 
267   if(argc < 2)
268     usage();
269 
270   len = strlen(argv[1]);
271 
272   if(strcmp(argv[1]+len-4, ".dbl") != 0)
273     usage();
274 
275   if(argc < 3)
276   {
277     outfile = strdup(argv[1]);
278     outfile[len-3] = 'p';
279     outfile[len-2] = 'n';
280     outfile[len-1] = 'g';
281   }
282   else
283     outfile = argv[2];
284 
285   png = readDBL(fopen(argv[1], "rb"));
286   writePNG(fopen(outfile, "wb"), png);
287   exit(0);
288 }
289