Visualization Library 2.0.0-b5

A lightweight C++ OpenGL middleware for 2D/3D graphics

VL     Star     Watch     Fork     Issue

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