diff options
Diffstat (limited to '')
-rw-r--r-- | libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c | 533 |
1 files changed, 533 insertions, 0 deletions
diff --git a/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c new file mode 100644 index 0000000..2f321cc --- /dev/null +++ b/libraries/irrlicht-1.8/source/Irrlicht/libpng/contrib/pngminus/pnm2png.c | |||
@@ -0,0 +1,533 @@ | |||
1 | /* | ||
2 | * pnm2png.c --- conversion from PBM/PGM/PPM-file to PNG-file | ||
3 | * copyright (C) 1999 by Willem van Schaik <willem@schaik.com> | ||
4 | * | ||
5 | * version 1.0 - 1999.10.15 - First version. | ||
6 | * | ||
7 | * Permission to use, copy, modify, and distribute this software and | ||
8 | * its documentation for any purpose and without fee is hereby granted, | ||
9 | * provided that the above copyright notice appear in all copies and | ||
10 | * that both that copyright notice and this permission notice appear in | ||
11 | * supporting documentation. This software is provided "as is" without | ||
12 | * express or implied warranty. | ||
13 | */ | ||
14 | |||
15 | #include <stdio.h> | ||
16 | #include <stdlib.h> | ||
17 | #ifdef __TURBOC__ | ||
18 | #include <mem.h> | ||
19 | #include <fcntl.h> | ||
20 | #endif | ||
21 | |||
22 | #ifndef BOOL | ||
23 | #define BOOL unsigned char | ||
24 | #endif | ||
25 | #ifndef TRUE | ||
26 | #define TRUE (BOOL) 1 | ||
27 | #endif | ||
28 | #ifndef FALSE | ||
29 | #define FALSE (BOOL) 0 | ||
30 | #endif | ||
31 | |||
32 | #define STDIN 0 | ||
33 | #define STDOUT 1 | ||
34 | #define STDERR 2 | ||
35 | |||
36 | /* to make pnm2png verbose so we can find problems (needs to be before png.h) */ | ||
37 | #ifndef PNG_DEBUG | ||
38 | #define PNG_DEBUG 0 | ||
39 | #endif | ||
40 | |||
41 | #include "png.h" | ||
42 | |||
43 | /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */ | ||
44 | #ifndef png_jmpbuf | ||
45 | # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf) | ||
46 | #endif | ||
47 | |||
48 | /* function prototypes */ | ||
49 | |||
50 | int main (int argc, char *argv[]); | ||
51 | void usage (); | ||
52 | BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha); | ||
53 | void get_token(FILE *pnm_file, char *token); | ||
54 | png_uint_32 get_data (FILE *pnm_file, int depth); | ||
55 | png_uint_32 get_value (FILE *pnm_file, int depth); | ||
56 | |||
57 | /* | ||
58 | * main | ||
59 | */ | ||
60 | |||
61 | int main(int argc, char *argv[]) | ||
62 | { | ||
63 | FILE *fp_rd = stdin; | ||
64 | FILE *fp_al = NULL; | ||
65 | FILE *fp_wr = stdout; | ||
66 | BOOL interlace = FALSE; | ||
67 | BOOL alpha = FALSE; | ||
68 | int argi; | ||
69 | |||
70 | for (argi = 1; argi < argc; argi++) | ||
71 | { | ||
72 | if (argv[argi][0] == '-') | ||
73 | { | ||
74 | switch (argv[argi][1]) | ||
75 | { | ||
76 | case 'i': | ||
77 | interlace = TRUE; | ||
78 | break; | ||
79 | case 'a': | ||
80 | alpha = TRUE; | ||
81 | argi++; | ||
82 | if ((fp_al = fopen (argv[argi], "rb")) == NULL) | ||
83 | { | ||
84 | fprintf (stderr, "PNM2PNG\n"); | ||
85 | fprintf (stderr, "Error: alpha-channel file %s does not exist\n", | ||
86 | argv[argi]); | ||
87 | exit (1); | ||
88 | } | ||
89 | break; | ||
90 | case 'h': | ||
91 | case '?': | ||
92 | usage(); | ||
93 | exit(0); | ||
94 | break; | ||
95 | default: | ||
96 | fprintf (stderr, "PNM2PNG\n"); | ||
97 | fprintf (stderr, "Error: unknown option %s\n", argv[argi]); | ||
98 | usage(); | ||
99 | exit(1); | ||
100 | break; | ||
101 | } /* end switch */ | ||
102 | } | ||
103 | else if (fp_rd == stdin) | ||
104 | { | ||
105 | if ((fp_rd = fopen (argv[argi], "rb")) == NULL) | ||
106 | { | ||
107 | fprintf (stderr, "PNM2PNG\n"); | ||
108 | fprintf (stderr, "Error: file %s does not exist\n", argv[argi]); | ||
109 | exit (1); | ||
110 | } | ||
111 | } | ||
112 | else if (fp_wr == stdout) | ||
113 | { | ||
114 | if ((fp_wr = fopen (argv[argi], "wb")) == NULL) | ||
115 | { | ||
116 | fprintf (stderr, "PNM2PNG\n"); | ||
117 | fprintf (stderr, "Error: can not create PNG-file %s\n", argv[argi]); | ||
118 | exit (1); | ||
119 | } | ||
120 | } | ||
121 | else | ||
122 | { | ||
123 | fprintf (stderr, "PNM2PNG\n"); | ||
124 | fprintf (stderr, "Error: too many parameters\n"); | ||
125 | usage(); | ||
126 | exit (1); | ||
127 | } | ||
128 | } /* end for */ | ||
129 | |||
130 | #ifdef __TURBOC__ | ||
131 | /* set stdin/stdout to binary, we're reading the PNM always! in binary format */ | ||
132 | if (fp_rd == stdin) | ||
133 | { | ||
134 | setmode (STDIN, O_BINARY); | ||
135 | } | ||
136 | if (fp_wr == stdout) | ||
137 | { | ||
138 | setmode (STDOUT, O_BINARY); | ||
139 | } | ||
140 | #endif | ||
141 | |||
142 | /* call the conversion program itself */ | ||
143 | if (pnm2png (fp_rd, fp_wr, fp_al, interlace, alpha) == FALSE) | ||
144 | { | ||
145 | fprintf (stderr, "PNM2PNG\n"); | ||
146 | fprintf (stderr, "Error: unsuccessful converting to PNG-image\n"); | ||
147 | exit (1); | ||
148 | } | ||
149 | |||
150 | /* close input file */ | ||
151 | fclose (fp_rd); | ||
152 | /* close output file */ | ||
153 | fclose (fp_wr); | ||
154 | /* close alpha file */ | ||
155 | if (alpha) | ||
156 | fclose (fp_al); | ||
157 | |||
158 | return 0; | ||
159 | } | ||
160 | |||
161 | /* | ||
162 | * usage | ||
163 | */ | ||
164 | |||
165 | void usage() | ||
166 | { | ||
167 | fprintf (stderr, "PNM2PNG\n"); | ||
168 | fprintf (stderr, " by Willem van Schaik, 1999\n"); | ||
169 | #ifdef __TURBOC__ | ||
170 | fprintf (stderr, " for Turbo-C and Borland-C compilers\n"); | ||
171 | #else | ||
172 | fprintf (stderr, " for Linux (and Unix) compilers\n"); | ||
173 | #endif | ||
174 | fprintf (stderr, "Usage: pnm2png [options] <file>.<pnm> [<file>.png]\n"); | ||
175 | fprintf (stderr, " or: ... | pnm2png [options]\n"); | ||
176 | fprintf (stderr, "Options:\n"); | ||
177 | fprintf (stderr, " -i[nterlace] write png-file with interlacing on\n"); | ||
178 | fprintf (stderr, " -a[lpha] <file>.pgm read PNG alpha channel as pgm-file\n"); | ||
179 | fprintf (stderr, " -h | -? print this help-information\n"); | ||
180 | } | ||
181 | |||
182 | /* | ||
183 | * pnm2png | ||
184 | */ | ||
185 | |||
186 | BOOL pnm2png (FILE *pnm_file, FILE *png_file, FILE *alpha_file, BOOL interlace, BOOL alpha) | ||
187 | { | ||
188 | png_struct *png_ptr = NULL; | ||
189 | png_info *info_ptr = NULL; | ||
190 | png_byte *png_pixels = NULL; | ||
191 | png_byte **row_pointers = NULL; | ||
192 | png_byte *pix_ptr = NULL; | ||
193 | png_uint_32 row_bytes; | ||
194 | |||
195 | char type_token[16]; | ||
196 | char width_token[16]; | ||
197 | char height_token[16]; | ||
198 | char maxval_token[16]; | ||
199 | int color_type; | ||
200 | png_uint_32 width, alpha_width; | ||
201 | png_uint_32 height, alpha_height; | ||
202 | png_uint_32 maxval; | ||
203 | int bit_depth = 0; | ||
204 | int channels; | ||
205 | int alpha_depth = 0; | ||
206 | int alpha_present; | ||
207 | int row, col; | ||
208 | BOOL raw, alpha_raw = FALSE; | ||
209 | png_uint_32 tmp16; | ||
210 | int i; | ||
211 | |||
212 | /* read header of PNM file */ | ||
213 | |||
214 | get_token(pnm_file, type_token); | ||
215 | if (type_token[0] != 'P') | ||
216 | { | ||
217 | return FALSE; | ||
218 | } | ||
219 | else if ((type_token[1] == '1') || (type_token[1] == '4')) | ||
220 | { | ||
221 | raw = (type_token[1] == '4'); | ||
222 | color_type = PNG_COLOR_TYPE_GRAY; | ||
223 | bit_depth = 1; | ||
224 | } | ||
225 | else if ((type_token[1] == '2') || (type_token[1] == '5')) | ||
226 | { | ||
227 | raw = (type_token[1] == '5'); | ||
228 | color_type = PNG_COLOR_TYPE_GRAY; | ||
229 | get_token(pnm_file, width_token); | ||
230 | sscanf (width_token, "%lu", &width); | ||
231 | get_token(pnm_file, height_token); | ||
232 | sscanf (height_token, "%lu", &height); | ||
233 | get_token(pnm_file, maxval_token); | ||
234 | sscanf (maxval_token, "%lu", &maxval); | ||
235 | if (maxval <= 1) | ||
236 | bit_depth = 1; | ||
237 | else if (maxval <= 3) | ||
238 | bit_depth = 2; | ||
239 | else if (maxval <= 15) | ||
240 | bit_depth = 4; | ||
241 | else if (maxval <= 255) | ||
242 | bit_depth = 8; | ||
243 | else /* if (maxval <= 65535) */ | ||
244 | bit_depth = 16; | ||
245 | } | ||
246 | else if ((type_token[1] == '3') || (type_token[1] == '6')) | ||
247 | { | ||
248 | raw = (type_token[1] == '6'); | ||
249 | color_type = PNG_COLOR_TYPE_RGB; | ||
250 | get_token(pnm_file, width_token); | ||
251 | sscanf (width_token, "%lu", &width); | ||
252 | get_token(pnm_file, height_token); | ||
253 | sscanf (height_token, "%lu", &height); | ||
254 | get_token(pnm_file, maxval_token); | ||
255 | sscanf (maxval_token, "%lu", &maxval); | ||
256 | if (maxval <= 1) | ||
257 | bit_depth = 1; | ||
258 | else if (maxval <= 3) | ||
259 | bit_depth = 2; | ||
260 | else if (maxval <= 15) | ||
261 | bit_depth = 4; | ||
262 | else if (maxval <= 255) | ||
263 | bit_depth = 8; | ||
264 | else /* if (maxval <= 65535) */ | ||
265 | bit_depth = 16; | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | return FALSE; | ||
270 | } | ||
271 | |||
272 | /* read header of PGM file with alpha channel */ | ||
273 | |||
274 | if (alpha) | ||
275 | { | ||
276 | if (color_type == PNG_COLOR_TYPE_GRAY) | ||
277 | color_type = PNG_COLOR_TYPE_GRAY_ALPHA; | ||
278 | if (color_type == PNG_COLOR_TYPE_RGB) | ||
279 | color_type = PNG_COLOR_TYPE_RGB_ALPHA; | ||
280 | |||
281 | get_token(alpha_file, type_token); | ||
282 | if (type_token[0] != 'P') | ||
283 | { | ||
284 | return FALSE; | ||
285 | } | ||
286 | else if ((type_token[1] == '2') || (type_token[1] == '5')) | ||
287 | { | ||
288 | alpha_raw = (type_token[1] == '5'); | ||
289 | get_token(alpha_file, width_token); | ||
290 | sscanf (width_token, "%lu", &alpha_width); | ||
291 | if (alpha_width != width) | ||
292 | return FALSE; | ||
293 | get_token(alpha_file, height_token); | ||
294 | sscanf (height_token, "%lu", &alpha_height); | ||
295 | if (alpha_height != height) | ||
296 | return FALSE; | ||
297 | get_token(alpha_file, maxval_token); | ||
298 | sscanf (maxval_token, "%lu", &maxval); | ||
299 | if (maxval <= 1) | ||
300 | alpha_depth = 1; | ||
301 | else if (maxval <= 3) | ||
302 | alpha_depth = 2; | ||
303 | else if (maxval <= 15) | ||
304 | alpha_depth = 4; | ||
305 | else if (maxval <= 255) | ||
306 | alpha_depth = 8; | ||
307 | else /* if (maxval <= 65535) */ | ||
308 | alpha_depth = 16; | ||
309 | if (alpha_depth != bit_depth) | ||
310 | return FALSE; | ||
311 | } | ||
312 | else | ||
313 | { | ||
314 | return FALSE; | ||
315 | } | ||
316 | } /* end if alpha */ | ||
317 | |||
318 | /* calculate the number of channels and store alpha-presence */ | ||
319 | if (color_type == PNG_COLOR_TYPE_GRAY) | ||
320 | channels = 1; | ||
321 | else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) | ||
322 | channels = 2; | ||
323 | else if (color_type == PNG_COLOR_TYPE_RGB) | ||
324 | channels = 3; | ||
325 | else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) | ||
326 | channels = 4; | ||
327 | else | ||
328 | channels = 0; /* should not happen */ | ||
329 | |||
330 | alpha_present = (channels - 1) % 2; | ||
331 | |||
332 | /* row_bytes is the width x number of channels x (bit-depth / 8) */ | ||
333 | row_bytes = width * channels * ((bit_depth <= 8) ? 1 : 2); | ||
334 | |||
335 | if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) | ||
336 | return FALSE; | ||
337 | |||
338 | /* read data from PNM file */ | ||
339 | pix_ptr = png_pixels; | ||
340 | |||
341 | for (row = 0; row < height; row++) | ||
342 | { | ||
343 | for (col = 0; col < width; col++) | ||
344 | { | ||
345 | for (i = 0; i < (channels - alpha_present); i++) | ||
346 | { | ||
347 | if (raw) | ||
348 | *pix_ptr++ = get_data (pnm_file, bit_depth); | ||
349 | else | ||
350 | if (bit_depth <= 8) | ||
351 | *pix_ptr++ = get_value (pnm_file, bit_depth); | ||
352 | else | ||
353 | { | ||
354 | tmp16 = get_value (pnm_file, bit_depth); | ||
355 | *pix_ptr = (png_byte) ((tmp16 >> 8) & 0xFF); | ||
356 | pix_ptr++; | ||
357 | *pix_ptr = (png_byte) (tmp16 & 0xFF); | ||
358 | pix_ptr++; | ||
359 | } | ||
360 | } | ||
361 | |||
362 | if (alpha) /* read alpha-channel from pgm file */ | ||
363 | { | ||
364 | if (alpha_raw) | ||
365 | *pix_ptr++ = get_data (alpha_file, alpha_depth); | ||
366 | else | ||
367 | if (alpha_depth <= 8) | ||
368 | *pix_ptr++ = get_value (alpha_file, bit_depth); | ||
369 | else | ||
370 | { | ||
371 | tmp16 = get_value (alpha_file, bit_depth); | ||
372 | *pix_ptr++ = (png_byte) ((tmp16 >> 8) & 0xFF); | ||
373 | *pix_ptr++ = (png_byte) (tmp16 & 0xFF); | ||
374 | } | ||
375 | } /* if alpha */ | ||
376 | |||
377 | } /* end for col */ | ||
378 | } /* end for row */ | ||
379 | |||
380 | /* prepare the standard PNG structures */ | ||
381 | png_ptr = png_create_write_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); | ||
382 | if (!png_ptr) | ||
383 | { | ||
384 | return FALSE; | ||
385 | } | ||
386 | info_ptr = png_create_info_struct (png_ptr); | ||
387 | if (!info_ptr) | ||
388 | { | ||
389 | png_destroy_write_struct (&png_ptr, (png_infopp) NULL); | ||
390 | return FALSE; | ||
391 | } | ||
392 | |||
393 | /* setjmp() must be called in every function that calls a PNG-reading libpng function */ | ||
394 | if (setjmp (png_jmpbuf(png_ptr))) | ||
395 | { | ||
396 | png_destroy_write_struct (&png_ptr, (png_infopp) NULL); | ||
397 | return FALSE; | ||
398 | } | ||
399 | |||
400 | /* initialize the png structure */ | ||
401 | png_init_io (png_ptr, png_file); | ||
402 | |||
403 | /* we're going to write more or less the same PNG as the input file */ | ||
404 | png_set_IHDR (png_ptr, info_ptr, width, height, bit_depth, color_type, | ||
405 | (!interlace) ? PNG_INTERLACE_NONE : PNG_INTERLACE_ADAM7, | ||
406 | PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); | ||
407 | |||
408 | /* write the file header information */ | ||
409 | png_write_info (png_ptr, info_ptr); | ||
410 | |||
411 | /* if needed we will allocate memory for an new array of row-pointers */ | ||
412 | if (row_pointers == (unsigned char**) NULL) | ||
413 | { | ||
414 | if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL) | ||
415 | { | ||
416 | png_destroy_write_struct (&png_ptr, (png_infopp) NULL); | ||
417 | return FALSE; | ||
418 | } | ||
419 | } | ||
420 | |||
421 | /* set the individual row_pointers to point at the correct offsets */ | ||
422 | for (i = 0; i < (height); i++) | ||
423 | row_pointers[i] = png_pixels + i * row_bytes; | ||
424 | |||
425 | /* write out the entire image data in one call */ | ||
426 | png_write_image (png_ptr, row_pointers); | ||
427 | |||
428 | /* write the additional chuncks to the PNG file (not really needed) */ | ||
429 | png_write_end (png_ptr, info_ptr); | ||
430 | |||
431 | /* clean up after the write, and free any memory allocated */ | ||
432 | png_destroy_write_struct (&png_ptr, (png_infopp) NULL); | ||
433 | |||
434 | if (row_pointers != (unsigned char**) NULL) | ||
435 | free (row_pointers); | ||
436 | if (png_pixels != (unsigned char*) NULL) | ||
437 | free (png_pixels); | ||
438 | |||
439 | return TRUE; | ||
440 | } /* end of pnm2png */ | ||
441 | |||
442 | /* | ||
443 | * get_token() - gets the first string after whitespace | ||
444 | */ | ||
445 | |||
446 | void get_token(FILE *pnm_file, char *token) | ||
447 | { | ||
448 | int i = 0; | ||
449 | |||
450 | /* remove white-space */ | ||
451 | do | ||
452 | { | ||
453 | token[i] = (unsigned char) fgetc (pnm_file); | ||
454 | } | ||
455 | while ((token[i] == '\n') || (token[i] == '\r') || (token[i] == ' ')); | ||
456 | |||
457 | /* read string */ | ||
458 | do | ||
459 | { | ||
460 | i++; | ||
461 | token[i] = (unsigned char) fgetc (pnm_file); | ||
462 | } | ||
463 | while ((token[i] != '\n') && (token[i] != '\r') && (token[i] != ' ')); | ||
464 | |||
465 | token[i] = '\0'; | ||
466 | |||
467 | return; | ||
468 | } | ||
469 | |||
470 | /* | ||
471 | * get_data() - takes first byte and converts into next pixel value, | ||
472 | * taking as much bits as defined by bit-depth and | ||
473 | * using the bit-depth to fill up a byte (0Ah -> AAh) | ||
474 | */ | ||
475 | |||
476 | png_uint_32 get_data (FILE *pnm_file, int depth) | ||
477 | { | ||
478 | static int bits_left = 0; | ||
479 | static int old_value = 0; | ||
480 | static int mask = 0; | ||
481 | int i; | ||
482 | png_uint_32 ret_value; | ||
483 | |||
484 | if (mask == 0) | ||
485 | for (i = 0; i < depth; i++) | ||
486 | mask = (mask >> 1) | 0x80; | ||
487 | |||
488 | if (bits_left <= 0) | ||
489 | { | ||
490 | old_value = fgetc (pnm_file); | ||
491 | bits_left = 8; | ||
492 | } | ||
493 | |||
494 | ret_value = old_value & mask; | ||
495 | for (i = 1; i < (8 / depth); i++) | ||
496 | ret_value = ret_value || (ret_value >> depth); | ||
497 | |||
498 | old_value = (old_value << depth) & 0xFF; | ||
499 | bits_left -= depth; | ||
500 | |||
501 | return ret_value; | ||
502 | } | ||
503 | |||
504 | /* | ||
505 | * get_value() - takes first (numeric) string and converts into number, | ||
506 | * using the bit-depth to fill up a byte (0Ah -> AAh) | ||
507 | */ | ||
508 | |||
509 | png_uint_32 get_value (FILE *pnm_file, int depth) | ||
510 | { | ||
511 | static png_uint_32 mask = 0; | ||
512 | png_byte token[16]; | ||
513 | png_uint_32 ret_value; | ||
514 | int i = 0; | ||
515 | |||
516 | if (mask == 0) | ||
517 | for (i = 0; i < depth; i++) | ||
518 | mask = (mask << 1) | 0x01; | ||
519 | |||
520 | get_token (pnm_file, (char *) token); | ||
521 | sscanf ((const char *) token, "%lu", &ret_value); | ||
522 | |||
523 | ret_value &= mask; | ||
524 | |||
525 | if (depth < 8) | ||
526 | for (i = 0; i < (8 / depth); i++) | ||
527 | ret_value = (ret_value << depth) || ret_value; | ||
528 | |||
529 | return ret_value; | ||
530 | } | ||
531 | |||
532 | /* end of source */ | ||
533 | |||