Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

430 lines
11 KiB

  1. /*
  2. * png2pnm.c --- conversion from PNG-file to PGM/PPM-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. #include <stdio.h>
  15. #include <stdlib.h>
  16. #ifdef __TURBOC__
  17. #include <mem.h>
  18. #include <fcntl.h>
  19. #endif
  20. #ifndef BOOL
  21. #define BOOL unsigned char
  22. #endif
  23. #ifndef TRUE
  24. #define TRUE (BOOL) 1
  25. #endif
  26. #ifndef FALSE
  27. #define FALSE (BOOL) 0
  28. #endif
  29. #ifdef __TURBOC__
  30. #define STDIN 0
  31. #define STDOUT 1
  32. #define STDERR 2
  33. #endif
  34. /* to make png2pnm verbose so we can find problems (needs to be before png.h) */
  35. #ifndef PNG_DEBUG
  36. #define PNG_DEBUG 0
  37. #endif
  38. #include "png.h"
  39. /* Define png_jmpbuf() in case we are using a pre-1.0.6 version of libpng */
  40. #ifndef png_jmpbuf
  41. # define png_jmpbuf(png_ptr) ((png_ptr)->jmpbuf)
  42. #endif
  43. /* function prototypes */
  44. int main (int argc, char *argv[]);
  45. void usage ();
  46. BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha);
  47. /*
  48. * main
  49. */
  50. int main(int argc, char *argv[])
  51. {
  52. FILE *fp_rd = stdin;
  53. FILE *fp_wr = stdout;
  54. FILE *fp_al = NULL;
  55. BOOL raw = TRUE;
  56. BOOL alpha = FALSE;
  57. int argi;
  58. for (argi = 1; argi < argc; argi++)
  59. {
  60. if (argv[argi][0] == '-')
  61. {
  62. switch (argv[argi][1])
  63. {
  64. case 'n':
  65. raw = FALSE;
  66. break;
  67. case 'r':
  68. raw = TRUE;
  69. break;
  70. case 'a':
  71. alpha = TRUE;
  72. argi++;
  73. if ((fp_al = fopen (argv[argi], "wb")) == NULL)
  74. {
  75. fprintf (stderr, "PNM2PNG\n");
  76. fprintf (stderr, "Error: can not create alpha-channel file %s\n", argv[argi]);
  77. exit (1);
  78. }
  79. break;
  80. case 'h':
  81. case '?':
  82. usage();
  83. exit(0);
  84. break;
  85. default:
  86. fprintf (stderr, "PNG2PNM\n");
  87. fprintf (stderr, "Error: unknown option %s\n", argv[argi]);
  88. usage();
  89. exit(1);
  90. break;
  91. } /* end switch */
  92. }
  93. else if (fp_rd == stdin)
  94. {
  95. if ((fp_rd = fopen (argv[argi], "rb")) == NULL)
  96. {
  97. fprintf (stderr, "PNG2PNM\n");
  98. fprintf (stderr, "Error: file %s does not exist\n", argv[argi]);
  99. exit (1);
  100. }
  101. }
  102. else if (fp_wr == stdout)
  103. {
  104. if ((fp_wr = fopen (argv[argi], "wb")) == NULL)
  105. {
  106. fprintf (stderr, "PNG2PNM\n");
  107. fprintf (stderr, "Error: can not create file %s\n", argv[argi]);
  108. exit (1);
  109. }
  110. }
  111. else
  112. {
  113. fprintf (stderr, "PNG2PNM\n");
  114. fprintf (stderr, "Error: too many parameters\n");
  115. usage();
  116. exit(1);
  117. }
  118. } /* end for */
  119. #ifdef __TURBOC__
  120. /* set stdin/stdout if required to binary */
  121. if (fp_rd == stdin)
  122. {
  123. setmode (STDIN, O_BINARY);
  124. }
  125. if ((raw) && (fp_wr == stdout))
  126. {
  127. setmode (STDOUT, O_BINARY);
  128. }
  129. #endif
  130. /* call the conversion program itself */
  131. if (png2pnm (fp_rd, fp_wr, fp_al, raw, alpha) == FALSE)
  132. {
  133. fprintf (stderr, "PNG2PNM\n");
  134. fprintf (stderr, "Error: unsuccessful convertion of PNG-image\n");
  135. exit(1);
  136. }
  137. /* close input file */
  138. fclose (fp_rd);
  139. /* close output file */
  140. fclose (fp_wr);
  141. /* close alpha file */
  142. if (alpha)
  143. fclose (fp_al);
  144. return 0;
  145. }
  146. /*
  147. * usage
  148. */
  149. void usage()
  150. {
  151. fprintf (stderr, "PNG2PNM\n");
  152. fprintf (stderr, " by Willem van Schaik, 1999\n");
  153. #ifdef __TURBOC__
  154. fprintf (stderr, " for Turbo-C and Borland-C compilers\n");
  155. #else
  156. fprintf (stderr, " for Linux (and Unix) compilers\n");
  157. #endif
  158. fprintf (stderr, "Usage: png2pnm [options] <file>.png [<file>.pnm]\n");
  159. fprintf (stderr, " or: ... | png2pnm [options]\n");
  160. fprintf (stderr, "Options:\n");
  161. fprintf (stderr, " -r[aw] write pnm-file in binary format (P4/P5/P6) (default)\n");
  162. fprintf (stderr, " -n[oraw] write pnm-file in ascii format (P1/P2/P3)\n");
  163. fprintf (stderr, " -a[lpha] <file>.pgm write PNG alpha channel as pgm-file\n");
  164. fprintf (stderr, " -h | -? print this help-information\n");
  165. }
  166. /*
  167. * png2pnm
  168. */
  169. BOOL png2pnm (FILE *png_file, FILE *pnm_file, FILE *alpha_file, BOOL raw, BOOL alpha)
  170. {
  171. png_struct *png_ptr = NULL;
  172. png_info *info_ptr = NULL;
  173. png_byte buf[8];
  174. png_byte *png_pixels = NULL;
  175. png_byte **row_pointers = NULL;
  176. png_byte *pix_ptr = NULL;
  177. png_uint_32 row_bytes;
  178. png_uint_32 width;
  179. png_uint_32 height;
  180. int bit_depth;
  181. int channels;
  182. int color_type;
  183. int alpha_present;
  184. int row, col;
  185. int ret;
  186. int i;
  187. long dep_16;
  188. /* read and check signature in PNG file */
  189. ret = fread (buf, 1, 8, png_file);
  190. if (ret != 8)
  191. return FALSE;
  192. ret = png_sig_cmp (buf, 0, 8);
  193. if (ret)
  194. return FALSE;
  195. /* create png and info structures */
  196. png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING,
  197. NULL, NULL, NULL);
  198. if (!png_ptr)
  199. return FALSE; /* out of memory */
  200. info_ptr = png_create_info_struct (png_ptr);
  201. if (!info_ptr)
  202. {
  203. png_destroy_read_struct (&png_ptr, NULL, NULL);
  204. return FALSE; /* out of memory */
  205. }
  206. if (setjmp (png_jmpbuf(png_ptr)))
  207. {
  208. png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  209. return FALSE;
  210. }
  211. /* set up the input control for C streams */
  212. png_init_io (png_ptr, png_file);
  213. png_set_sig_bytes (png_ptr, 8); /* we already read the 8 signature bytes */
  214. /* read the file information */
  215. png_read_info (png_ptr, info_ptr);
  216. /* get size and bit-depth of the PNG-image */
  217. png_get_IHDR (png_ptr, info_ptr,
  218. &width, &height, &bit_depth, &color_type,
  219. NULL, NULL, NULL);
  220. /* set-up the transformations */
  221. /* transform paletted images into full-color rgb */
  222. if (color_type == PNG_COLOR_TYPE_PALETTE)
  223. png_set_expand (png_ptr);
  224. /* expand images to bit-depth 8 (only applicable for grayscale images) */
  225. if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
  226. png_set_expand (png_ptr);
  227. /* transform transparency maps into full alpha-channel */
  228. if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
  229. png_set_expand (png_ptr);
  230. #ifdef NJET
  231. /* downgrade 16-bit images to 8 bit */
  232. if (bit_depth == 16)
  233. png_set_strip_16 (png_ptr);
  234. /* transform grayscale images into full-color */
  235. if (color_type == PNG_COLOR_TYPE_GRAY ||
  236. color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  237. png_set_gray_to_rgb (png_ptr);
  238. /* only if file has a file gamma, we do a correction */
  239. if (png_get_gAMA (png_ptr, info_ptr, &file_gamma))
  240. png_set_gamma (png_ptr, (double) 2.2, file_gamma);
  241. #endif
  242. /* all transformations have been registered; now update info_ptr data,
  243. * get rowbytes and channels, and allocate image memory */
  244. png_read_update_info (png_ptr, info_ptr);
  245. /* get the new color-type and bit-depth (after expansion/stripping) */
  246. png_get_IHDR (png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
  247. NULL, NULL, NULL);
  248. /* check for 16-bit files */
  249. if (bit_depth == 16)
  250. {
  251. raw = FALSE;
  252. #ifdef __TURBOC__
  253. pnm_file->flags &= ~((unsigned) _F_BIN);
  254. #endif
  255. }
  256. /* calculate new number of channels and store alpha-presence */
  257. if (color_type == PNG_COLOR_TYPE_GRAY)
  258. channels = 1;
  259. else if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
  260. channels = 2;
  261. else if (color_type == PNG_COLOR_TYPE_RGB)
  262. channels = 3;
  263. else if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
  264. channels = 4;
  265. else
  266. channels = 0; /* should never happen */
  267. alpha_present = (channels - 1) % 2;
  268. /* check if alpha is expected to be present in file */
  269. if (alpha && !alpha_present)
  270. {
  271. fprintf (stderr, "PNG2PNM\n");
  272. fprintf (stderr, "Error: PNG-file doesn't contain alpha channel\n");
  273. exit (1);
  274. }
  275. /* row_bytes is the width x number of channels x (bit-depth / 8) */
  276. row_bytes = png_get_rowbytes (png_ptr, info_ptr);
  277. if ((png_pixels = (png_byte *) malloc (row_bytes * height * sizeof (png_byte))) == NULL) {
  278. png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  279. return FALSE;
  280. }
  281. if ((row_pointers = (png_byte **) malloc (height * sizeof (png_bytep))) == NULL)
  282. {
  283. png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
  284. free (png_pixels);
  285. png_pixels = NULL;
  286. return FALSE;
  287. }
  288. /* set the individual row_pointers to point at the correct offsets */
  289. for (i = 0; i < (height); i++)
  290. row_pointers[i] = png_pixels + i * row_bytes;
  291. /* now we can go ahead and just read the whole image */
  292. png_read_image (png_ptr, row_pointers);
  293. /* read rest of file, and get additional chunks in info_ptr - REQUIRED */
  294. png_read_end (png_ptr, info_ptr);
  295. /* clean up after the read, and free any memory allocated - REQUIRED */
  296. png_destroy_read_struct (&png_ptr, &info_ptr, (png_infopp) NULL);
  297. /* write header of PNM file */
  298. if ((color_type == PNG_COLOR_TYPE_GRAY) ||
  299. (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
  300. {
  301. fprintf (pnm_file, "%s\n", (raw) ? "P5" : "P2");
  302. fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
  303. fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
  304. }
  305. else if ((color_type == PNG_COLOR_TYPE_RGB) ||
  306. (color_type == PNG_COLOR_TYPE_RGB_ALPHA))
  307. {
  308. fprintf (pnm_file, "%s\n", (raw) ? "P6" : "P3");
  309. fprintf (pnm_file, "%d %d\n", (int) width, (int) height);
  310. fprintf (pnm_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
  311. }
  312. /* write header of PGM file with alpha channel */
  313. if ((alpha) &&
  314. ((color_type == PNG_COLOR_TYPE_GRAY_ALPHA) ||
  315. (color_type == PNG_COLOR_TYPE_RGB_ALPHA)))
  316. {
  317. fprintf (alpha_file, "%s\n", (raw) ? "P5" : "P2");
  318. fprintf (alpha_file, "%d %d\n", (int) width, (int) height);
  319. fprintf (alpha_file, "%ld\n", ((1L << (int) bit_depth) - 1L));
  320. }
  321. /* write data to PNM file */
  322. pix_ptr = png_pixels;
  323. for (row = 0; row < height; row++)
  324. {
  325. for (col = 0; col < width; col++)
  326. {
  327. for (i = 0; i < (channels - alpha_present); i++)
  328. {
  329. if (raw)
  330. fputc ((int) *pix_ptr++ , pnm_file);
  331. else
  332. if (bit_depth == 16){
  333. dep_16 = (long) *pix_ptr++;
  334. fprintf (pnm_file, "%ld ", (dep_16 << 8) + ((long) *pix_ptr++));
  335. }
  336. else
  337. fprintf (pnm_file, "%ld ", (long) *pix_ptr++);
  338. }
  339. if (alpha_present)
  340. {
  341. if (!alpha)
  342. {
  343. pix_ptr++; /* alpha */
  344. if (bit_depth == 16)
  345. pix_ptr++;
  346. }
  347. else /* output alpha-channel as pgm file */
  348. {
  349. if (raw)
  350. fputc ((int) *pix_ptr++ , alpha_file);
  351. else
  352. if (bit_depth == 16){
  353. dep_16 = (long) *pix_ptr++;
  354. fprintf (alpha_file, "%ld ", (dep_16 << 8) + (long) *pix_ptr++);
  355. }
  356. else
  357. fprintf (alpha_file, "%ld ", (long) *pix_ptr++);
  358. }
  359. } /* if alpha_present */
  360. if (!raw)
  361. if (col % 4 == 3)
  362. fprintf (pnm_file, "\n");
  363. } /* end for col */
  364. if (!raw)
  365. if (col % 4 != 0)
  366. fprintf (pnm_file, "\n");
  367. } /* end for row */
  368. if (row_pointers != (unsigned char**) NULL)
  369. free (row_pointers);
  370. if (png_pixels != (unsigned char*) NULL)
  371. free (png_pixels);
  372. return TRUE;
  373. } /* end of source */