zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
example.c
Go to the documentation of this file.
1 
2 #if 0 /* in case someone actually tries to compile this */
3 
4 /* example.c - an example of using libpng
5  * Last changed in libpng 1.5.7 [December 15, 2011]
6  * Maintained 1998-2011 Glenn Randers-Pehrson
7  * Maintained 1996, 1997 Andreas Dilger
8  * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
9  */
10 
11 /* This is an example of how to use libpng to read and write PNG files.
12  * The file libpng-manual.txt is much more verbose then this. If you have not
13  * read it, do so first. This was designed to be a starting point of an
14  * implementation. This is not officially part of libpng, is hereby placed
15  * in the public domain, and therefore does not require a copyright notice.
16  * To the extent possible under law, the authors have waived all copyright and
17  * related or neighboring rights to this file.
18  *
19  * This file does not currently compile, because it is missing certain
20  * parts, like allocating memory to hold an image. You will have to
21  * supply these parts to get it to compile. For an example of a minimal
22  * working PNG reader/writer, see pngtest.c, included in this distribution;
23  * see also the programs in the contrib directory.
24  */
25 
26 #define _POSIX_SOURCE 1 /* libpng and zlib are POSIX-compliant. You may
27  * change this if your application uses non-POSIX
28  * extensions. */
29 
30 #include "png.h"
31 
32  /* The png_jmpbuf() macro, used in error handling, became available in
33  * libpng version 1.0.6. If you want to be able to run your code with older
34  * versions of libpng, you must define the macro yourself (but only if it
35  * is not already defined by libpng!).
36  */
37 
38 #ifndef png_jmpbuf
39 # define png_jmpbuf(png_ptr) ((png_ptr)->png_jmpbuf)
40 #endif
41 
42 /* Check to see if a file is a PNG file using png_sig_cmp(). png_sig_cmp()
43  * returns zero if the image is a PNG and nonzero if it isn't a PNG.
44  *
45  * The function check_if_png() shown here, but not used, returns nonzero (true)
46  * if the file can be opened and is a PNG, 0 (false) otherwise.
47  *
48  * If this call is successful, and you are going to keep the file open,
49  * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
50  * you have created the png_ptr, so that libpng knows your application
51  * has read that many bytes from the start of the file. Make sure you
52  * don't call png_set_sig_bytes() with more than 8 bytes read or give it
53  * an incorrect number of bytes read, or you will either have read too
54  * many bytes (your fault), or you are telling libpng to read the wrong
55  * number of magic bytes (also your fault).
56  *
57  * Many applications already read the first 2 or 4 bytes from the start
58  * of the image to determine the file type, so it would be easiest just
59  * to pass the bytes to png_sig_cmp() or even skip that if you know
60  * you have a PNG file, and call png_set_sig_bytes().
61  */
62 #define PNG_BYTES_TO_CHECK 4
63 int check_if_png(char *file_name, FILE **fp)
64 {
65  char buf[PNG_BYTES_TO_CHECK];
66 
67  /* Open the prospective PNG file. */
68  if ((*fp = fopen(file_name, "rb")) == NULL)
69  return 0;
70 
71  /* Read in some of the signature bytes */
72  if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
73  return 0;
74 
75  /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
76  Return nonzero (true) if they match */
77 
78  return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
79 }
80 
81 /* Read a PNG file. You may want to return an error code if the read
82  * fails (depending upon the failure). There are two "prototypes" given
83  * here - one where we are given the filename, and we need to open the
84  * file, and the other where we are given an open file (possibly with
85  * some or all of the magic bytes read - see comments above).
86  */
87 #ifdef open_file /* prototype 1 */
88 void read_png(char *file_name) /* We need to open the file */
89 {
90  png_structp png_ptr;
91  png_infop info_ptr;
92  unsigned int sig_read = 0;
94  int bit_depth, color_type, interlace_type;
95  FILE *fp;
96 
97  if ((fp = fopen(file_name, "rb")) == NULL)
98  return (ERROR);
99 
100 #else no_open_file /* prototype 2 */
101 void read_png(FILE *fp, unsigned int sig_read) /* File is already open */
102 {
103  png_structp png_ptr;
104  png_infop info_ptr;
106  int bit_depth, color_type, interlace_type;
107 #endif no_open_file /* Only use one prototype! */
108 
109  /* Create and initialize the png_struct with the desired error handler
110  * functions. If you want to use the default stderr and longjump method,
111  * you can supply NULL for the last three parameters. We also supply the
112  * the compiler header file version, so that we know if the application
113  * was compiled with a compatible version of the library. REQUIRED
114  */
115  png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
116  png_voidp user_error_ptr, user_error_fn, user_warning_fn);
117 
118  if (png_ptr == NULL)
119  {
120  fclose(fp);
121  return (ERROR);
122  }
123 
124  /* Allocate/initialize the memory for image information. REQUIRED. */
125  info_ptr = png_create_info_struct(png_ptr);
126  if (info_ptr == NULL)
127  {
128  fclose(fp);
129  png_destroy_read_struct(&png_ptr, NULL, NULL);
130  return (ERROR);
131  }
132 
133  /* Set error handling if you are using the setjmp/longjmp method (this is
134  * the normal method of doing things with libpng). REQUIRED unless you
135  * set up your own error handlers in the png_create_read_struct() earlier.
136  */
137 
138  if (setjmp(png_jmpbuf(png_ptr)))
139  {
140  /* Free all of the memory associated with the png_ptr and info_ptr */
141  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
142  fclose(fp);
143  /* If we get here, we had a problem reading the file */
144  return (ERROR);
145  }
146 
147  /* One of the following I/O initialization methods is REQUIRED */
148 #ifdef streams /* PNG file I/O method 1 */
149  /* Set up the input control if you are using standard C streams */
150  png_init_io(png_ptr, fp);
151 
152 #else no_streams /* PNG file I/O method 2 */
153  /* If you are using replacement read functions, instead of calling
154  * png_init_io() here you would call:
155  */
156  png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
157  /* where user_io_ptr is a structure you want available to the callbacks */
158 #endif no_streams /* Use only one I/O method! */
159 
160  /* If we have already read some of the signature */
161  png_set_sig_bytes(png_ptr, sig_read);
162 
163 #ifdef hilevel
164  /*
165  * If you have enough memory to read in the entire image at once,
166  * and you need to specify only transforms that can be controlled
167  * with one of the PNG_TRANSFORM_* bits (this presently excludes
168  * quantizing, filling, setting background, and doing gamma
169  * adjustment), then you can read the entire image (including
170  * pixels) into the info structure with this call:
171  */
172  png_read_png(png_ptr, info_ptr, png_transforms, NULL);
173 
174 #else
175  /* OK, you're doing it the hard way, with the lower-level functions */
176 
177  /* The call to png_read_info() gives us all of the information from the
178  * PNG file before the first IDAT (image data chunk). REQUIRED
179  */
180  png_read_info(png_ptr, info_ptr);
181 
182  png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
183  &interlace_type, NULL, NULL);
184 
185  /* Set up the data transformations you want. Note that these are all
186  * optional. Only call them if you want/need them. Many of the
187  * transformations only work on specific types of images, and many
188  * are mutually exclusive.
189  */
190 
191  /* Tell libpng to strip 16 bit/color files down to 8 bits/color.
192  * Use accurate scaling if it's available, otherwise just chop off the
193  * low byte.
194  */
195 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
196  png_set_scale_16(png_ptr);
197 #else
198  png_set_strip_16(png_ptr);
199 #endif
200 
201  /* Strip alpha bytes from the input data without combining with the
202  * background (not recommended).
203  */
204  png_set_strip_alpha(png_ptr);
205 
206  /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
207  * byte into separate bytes (useful for paletted and grayscale images).
208  */
209  png_set_packing(png_ptr);
210 
211  /* Change the order of packed pixels to least significant bit first
212  * (not useful if you are using png_set_packing). */
213  png_set_packswap(png_ptr);
214 
215  /* Expand paletted colors into true RGB triplets */
216  if (color_type == PNG_COLOR_TYPE_PALETTE)
217  png_set_palette_to_rgb(png_ptr);
218 
219  /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
220  if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
222 
223  /* Expand paletted or RGB images with transparency to full alpha channels
224  * so the data will be available as RGBA quartets.
225  */
226  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
227  png_set_tRNS_to_alpha(png_ptr);
228 
229  /* Set the background color to draw transparent and alpha images over.
230  * It is possible to set the red, green, and blue components directly
231  * for paletted images instead of supplying a palette index. Note that
232  * even if the PNG file supplies a background, you are not required to
233  * use it - you should use the (solid) application background if it has one.
234  */
235 
236  png_color_16 my_background, *image_background;
237 
238  if (png_get_bKGD(png_ptr, info_ptr, &image_background))
239  png_set_background(png_ptr, image_background,
240  PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
241  else
242  png_set_background(png_ptr, &my_background,
244 
245  /* Some suggestions as to how to get a screen gamma value
246  *
247  * Note that screen gamma is the display_exponent, which includes
248  * the CRT_exponent and any correction for viewing conditions
249  */
250  if (/* We have a user-defined screen gamma value */)
251  {
252  screen_gamma = user-defined screen_gamma;
253  }
254  /* This is one way that applications share the same screen gamma value */
255  else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
256  {
257  screen_gamma = atof(gamma_str);
258  }
259  /* If we don't have another value */
260  else
261  {
262  screen_gamma = 2.2; /* A good guess for a PC monitor in a dimly
263  lit room */
264  screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
265  }
266 
267  /* Tell libpng to handle the gamma conversion for you. The final call
268  * is a good guess for PC generated images, but it should be configurable
269  * by the user at run time by the user. It is strongly suggested that
270  * your application support gamma correction.
271  */
272 
273  int intent;
274 
275  if (png_get_sRGB(png_ptr, info_ptr, &intent))
276  png_set_gamma(png_ptr, screen_gamma, 0.45455);
277  else
278  {
279  double image_gamma;
280  if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
281  png_set_gamma(png_ptr, screen_gamma, image_gamma);
282  else
283  png_set_gamma(png_ptr, screen_gamma, 0.45455);
284  }
285 
286 #ifdef PNG_READ_QUANTIZE_SUPPORTED
287  /* Quantize RGB files down to 8 bit palette or reduce palettes
288  * to the number of colors available on your screen.
289  */
290  if (color_type & PNG_COLOR_MASK_COLOR)
291  {
292  int num_palette;
293  png_colorp palette;
294 
295  /* This reduces the image to the application supplied palette */
296  if (/* We have our own palette */)
297  {
298  /* An array of colors to which the image should be quantized */
299  png_color std_color_cube[MAX_SCREEN_COLORS];
300 
301  png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
302  MAX_SCREEN_COLORS, NULL, 0);
303  }
304  /* This reduces the image to the palette supplied in the file */
305  else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
306  {
308 
309  png_get_hIST(png_ptr, info_ptr, &histogram);
310 
311  png_set_quantize(png_ptr, palette, num_palette,
312  max_screen_colors, histogram, 0);
313  }
314  }
315 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
316 
317  /* Invert monochrome files to have 0 as white and 1 as black */
318  png_set_invert_mono(png_ptr);
319 
320  /* If you want to shift the pixel values from the range [0,255] or
321  * [0,65535] to the original [0,7] or [0,31], or whatever range the
322  * colors were originally in:
323  */
324  if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
325  {
326  png_color_8p sig_bit_p;
327 
328  png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
329  png_set_shift(png_ptr, sig_bit_p);
330  }
331 
332  /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
333  if (color_type & PNG_COLOR_MASK_COLOR)
334  png_set_bgr(png_ptr);
335 
336  /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
337  png_set_swap_alpha(png_ptr);
338 
339  /* Swap bytes of 16 bit files to least significant byte first */
340  png_set_swap(png_ptr);
341 
342  /* Add filler (or alpha) byte (before/after each RGB triplet) */
343  png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
344 
345 #ifdef PNG_READ_INTERLACING_SUPPORTED
346  /* Turn on interlace handling. REQUIRED if you are not using
347  * png_read_image(). To see how to handle interlacing passes,
348  * see the png_read_row() method below:
349  */
350  number_passes = png_set_interlace_handling(png_ptr);
351 #else
352  number_passes = 1;
353 #endif /* PNG_READ_INTERLACING_SUPPORTED */
354 
355 
356  /* Optional call to gamma correct and add the background to the palette
357  * and update info structure. REQUIRED if you are expecting libpng to
358  * update the palette for you (ie you selected such a transform above).
359  */
360  png_read_update_info(png_ptr, info_ptr);
361 
362  /* Allocate the memory to hold the image using the fields of info_ptr. */
363 
364  /* The easiest way to read the image: */
365  png_bytep row_pointers[height];
366 
367  /* Clear the pointer array */
368  for (row = 0; row < height; row++)
369  row_pointers[row] = NULL;
370 
371  for (row = 0; row < height; row++)
372  row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
373  info_ptr));
374 
375  /* Now it's time to read the image. One of these methods is REQUIRED */
376 #ifdef entire /* Read the entire image in one go */
377  png_read_image(png_ptr, row_pointers);
378 
379 #else no_entire /* Read the image one or more scanlines at a time */
380  /* The other way to read images - deal with interlacing: */
381 
382  for (pass = 0; pass < number_passes; pass++)
383  {
384 #ifdef single /* Read the image a single row at a time */
385  for (y = 0; y < height; y++)
386  {
387  png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
388  }
389 
390 #else no_single /* Read the image several rows at a time */
391  for (y = 0; y < height; y += number_of_rows)
392  {
393 #ifdef sparkle /* Read the image using the "sparkle" effect. */
394  png_read_rows(png_ptr, &row_pointers[y], NULL,
395  number_of_rows);
396 #else no_sparkle /* Read the image using the "rectangle" effect */
397  png_read_rows(png_ptr, NULL, &row_pointers[y],
398  number_of_rows);
399 #endif no_sparkle /* Use only one of these two methods */
400  }
401 
402  /* If you want to display the image after every pass, do so here */
403 #endif no_single /* Use only one of these two methods */
404  }
405 #endif no_entire /* Use only one of these two methods */
406 
407  /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
408  png_read_end(png_ptr, info_ptr);
409 #endif hilevel
410 
411  /* At this point you have read the entire image */
412 
413  /* Clean up after the read, and free any memory allocated - REQUIRED */
414  png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
415 
416  /* Close the file */
417  fclose(fp);
418 
419  /* That's it */
420  return (OK);
421 }
422 
423 /* Progressively read a file */
424 
425 int
426 initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
427 {
428  /* Create and initialize the png_struct with the desired error handler
429  * functions. If you want to use the default stderr and longjump method,
430  * you can supply NULL for the last three parameters. We also check that
431  * the library version is compatible in case we are using dynamically
432  * linked libraries.
433  */
434  *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
435  png_voidp user_error_ptr, user_error_fn, user_warning_fn);
436 
437  if (*png_ptr == NULL)
438  {
439  *info_ptr = NULL;
440  return (ERROR);
441  }
442 
443  *info_ptr = png_create_info_struct(png_ptr);
444 
445  if (*info_ptr == NULL)
446  {
447  png_destroy_read_struct(png_ptr, info_ptr, NULL);
448  return (ERROR);
449  }
450 
451  if (setjmp(png_jmpbuf((*png_ptr))))
452  {
453  png_destroy_read_struct(png_ptr, info_ptr, NULL);
454  return (ERROR);
455  }
456 
457  /* This one's new. You will need to provide all three
458  * function callbacks, even if you aren't using them all.
459  * If you aren't using all functions, you can specify NULL
460  * parameters. Even when all three functions are NULL,
461  * you need to call png_set_progressive_read_fn().
462  * These functions shouldn't be dependent on global or
463  * static variables if you are decoding several images
464  * simultaneously. You should store stream specific data
465  * in a separate struct, given as the second parameter,
466  * and retrieve the pointer from inside the callbacks using
467  * the function png_get_progressive_ptr(png_ptr).
468  */
469  png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
470  info_callback, row_callback, end_callback);
471 
472  return (OK);
473 }
474 
475 int
476 process_data(png_structp *png_ptr, png_infop *info_ptr,
478 {
479  if (setjmp(png_jmpbuf((*png_ptr))))
480  {
481  /* Free the png_ptr and info_ptr memory on error */
482  png_destroy_read_struct(png_ptr, info_ptr, NULL);
483  return (ERROR);
484  }
485 
486  /* This one's new also. Simply give it chunks of data as
487  * they arrive from the data stream (in order, of course).
488  * On segmented machines, don't give it any more than 64K.
489  * The library seems to run fine with sizes of 4K, although
490  * you can give it much less if necessary (I assume you can
491  * give it chunks of 1 byte, but I haven't tried with less
492  * than 256 bytes yet). When this function returns, you may
493  * want to display any rows that were generated in the row
494  * callback, if you aren't already displaying them there.
495  */
496  png_process_data(*png_ptr, *info_ptr, buffer, length);
497  return (OK);
498 }
499 
500 info_callback(png_structp png_ptr, png_infop info)
501 {
502  /* Do any setup here, including setting any of the transformations
503  * mentioned in the Reading PNG files section. For now, you _must_
504  * call either png_start_read_image() or png_read_update_info()
505  * after all the transformations are set (even if you don't set
506  * any). You may start getting rows before png_process_data()
507  * returns, so this is your last chance to prepare for that.
508  */
509 }
510 
511 row_callback(png_structp png_ptr, png_bytep new_row,
512  png_uint_32 row_num, int pass)
513 {
514  /*
515  * This function is called for every row in the image. If the
516  * image is interlaced, and you turned on the interlace handler,
517  * this function will be called for every row in every pass.
518  *
519  * In this function you will receive a pointer to new row data from
520  * libpng called new_row that is to replace a corresponding row (of
521  * the same data format) in a buffer allocated by your application.
522  *
523  * The new row data pointer "new_row" may be NULL, indicating there is
524  * no new data to be replaced (in cases of interlace loading).
525  *
526  * If new_row is not NULL then you need to call
527  * png_progressive_combine_row() to replace the corresponding row as
528  * shown below:
529  */
530 
531  /* Get pointer to corresponding row in our
532  * PNG read buffer.
533  */
534  png_bytep old_row = ((png_bytep *)our_data)[row_num];
535 
536 #ifdef PNG_READ_INTERLACING_SUPPORTED
537  /* If both rows are allocated then copy the new row
538  * data to the corresponding row data.
539  */
540  if ((old_row != NULL) && (new_row != NULL))
541  png_progressive_combine_row(png_ptr, old_row, new_row);
542 
543  /*
544  * The rows and passes are called in order, so you don't really
545  * need the row_num and pass, but I'm supplying them because it
546  * may make your life easier.
547  *
548  * For the non-NULL rows of interlaced images, you must call
549  * png_progressive_combine_row() passing in the new row and the
550  * old row, as demonstrated above. You can call this function for
551  * NULL rows (it will just return) and for non-interlaced images
552  * (it just does the png_memcpy for you) if it will make the code
553  * easier. Thus, you can just do this for all cases:
554  */
555 
556  png_progressive_combine_row(png_ptr, old_row, new_row);
557 
558  /* where old_row is what was displayed for previous rows. Note
559  * that the first pass (pass == 0 really) will completely cover
560  * the old row, so the rows do not have to be initialized. After
561  * the first pass (and only for interlaced images), you will have
562  * to pass the current row as new_row, and the function will combine
563  * the old row and the new row.
564  */
565 #endif /* PNG_READ_INTERLACING_SUPPORTED */
566 }
567 
568 end_callback(png_structp png_ptr, png_infop info)
569 {
570  /* This function is called when the whole image has been read,
571  * including any chunks after the image (up to and including
572  * the IEND). You will usually have the same info chunk as you
573  * had in the header, although some data may have been added
574  * to the comments and time fields.
575  *
576  * Most people won't do much here, perhaps setting a flag that
577  * marks the image as finished.
578  */
579 }
580 
581 /* Write a png file */
582 void write_png(char *file_name /* , ... other image information ... */)
583 {
584  FILE *fp;
585  png_structp png_ptr;
586  png_infop info_ptr;
587  png_colorp palette;
588 
589  /* Open the file */
590  fp = fopen(file_name, "wb");
591  if (fp == NULL)
592  return (ERROR);
593 
594  /* Create and initialize the png_struct with the desired error handler
595  * functions. If you want to use the default stderr and longjump method,
596  * you can supply NULL for the last three parameters. We also check that
597  * the library version is compatible with the one used at compile time,
598  * in case we are using dynamically linked libraries. REQUIRED.
599  */
600  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
601  png_voidp user_error_ptr, user_error_fn, user_warning_fn);
602 
603  if (png_ptr == NULL)
604  {
605  fclose(fp);
606  return (ERROR);
607  }
608 
609  /* Allocate/initialize the image information data. REQUIRED */
610  info_ptr = png_create_info_struct(png_ptr);
611  if (info_ptr == NULL)
612  {
613  fclose(fp);
614  png_destroy_write_struct(&png_ptr, NULL);
615  return (ERROR);
616  }
617 
618  /* Set error handling. REQUIRED if you aren't supplying your own
619  * error handling functions in the png_create_write_struct() call.
620  */
621  if (setjmp(png_jmpbuf(png_ptr)))
622  {
623  /* If we get here, we had a problem writing the file */
624  fclose(fp);
625  png_destroy_write_struct(&png_ptr, &info_ptr);
626  return (ERROR);
627  }
628 
629  /* One of the following I/O initialization functions is REQUIRED */
630 
631 #ifdef streams /* I/O initialization method 1 */
632  /* Set up the output control if you are using standard C streams */
633  png_init_io(png_ptr, fp);
634 
635 #else no_streams /* I/O initialization method 2 */
636  /* If you are using replacement write functions, instead of calling
637  * png_init_io() here you would call
638  */
639  png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
640  user_IO_flush_function);
641  /* where user_io_ptr is a structure you want available to the callbacks */
642 #endif no_streams /* Only use one initialization method */
643 
644 #ifdef hilevel
645  /* This is the easy way. Use it if you already have all the
646  * image info living in the structure. You could "|" many
647  * PNG_TRANSFORM flags into the png_transforms integer here.
648  */
649  png_write_png(png_ptr, info_ptr, png_transforms, NULL);
650 
651 #else
652  /* This is the hard way */
653 
654  /* Set the image information here. Width and height are up to 2^31,
655  * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
656  * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
657  * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
658  * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
659  * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
660  * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
661  */
662  png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
663  PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
664 
665  /* Set the palette if there is one. REQUIRED for indexed-color images */
666  palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
667  * png_sizeof(png_color));
668  /* ... Set palette colors ... */
669  png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
670  /* You must not free palette here, because png_set_PLTE only makes a link to
671  * the palette that you malloced. Wait until you are about to destroy
672  * the png structure.
673  */
674 
675  /* Optional significant bit (sBIT) chunk */
676  png_color_8 sig_bit;
677 
678  /* If we are dealing with a grayscale image then */
679  sig_bit.gray = true_bit_depth;
680 
681  /* Otherwise, if we are dealing with a color image then */
682  sig_bit.red = true_red_bit_depth;
683  sig_bit.green = true_green_bit_depth;
684  sig_bit.blue = true_blue_bit_depth;
685 
686  /* If the image has an alpha channel then */
687  sig_bit.alpha = true_alpha_bit_depth;
688 
689  png_set_sBIT(png_ptr, info_ptr, &sig_bit);
690 
691 
692  /* Optional gamma chunk is strongly suggested if you have any guess
693  * as to the correct gamma of the image.
694  */
695  png_set_gAMA(png_ptr, info_ptr, gamma);
696 
697  /* Optionally write comments into the image */
698  text_ptr[0].key = "Title";
699  text_ptr[0].text = "Mona Lisa";
700  text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
701  text_ptr[0].itxt_length = 0;
702  text_ptr[0].lang = NULL;
703  text_ptr[0].lang_key = NULL;
704  text_ptr[1].key = "Author";
705  text_ptr[1].text = "Leonardo DaVinci";
706  text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
707  text_ptr[1].itxt_length = 0;
708  text_ptr[1].lang = NULL;
709  text_ptr[1].lang_key = NULL;
710  text_ptr[2].key = "Description";
711  text_ptr[2].text = "<long text>";
712  text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
713  text_ptr[2].itxt_length = 0;
714  text_ptr[2].lang = NULL;
715  text_ptr[2].lang_key = NULL;
716  png_set_text(png_ptr, info_ptr, text_ptr, 3);
717 
718  /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
719 
720  /* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
721  * on read and, if your application chooses to write them, they must
722  * be written in accordance with the sRGB profile
723  */
724 
725  /* Write the file header information. REQUIRED */
726  png_write_info(png_ptr, info_ptr);
727 
728  /* If you want, you can write the info in two steps, in case you need to
729  * write your private chunk ahead of PLTE:
730  *
731  * png_write_info_before_PLTE(write_ptr, write_info_ptr);
732  * write_my_chunk();
733  * png_write_info(png_ptr, info_ptr);
734  *
735  * However, given the level of known- and unknown-chunk support in 1.2.0
736  * and up, this should no longer be necessary.
737  */
738 
739  /* Once we write out the header, the compression type on the text
740  * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
741  * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
742  * at the end.
743  */
744 
745  /* Set up the transformations you want. Note that these are
746  * all optional. Only call them if you want them.
747  */
748 
749  /* Invert monochrome pixels */
750  png_set_invert_mono(png_ptr);
751 
752  /* Shift the pixels up to a legal bit depth and fill in
753  * as appropriate to correctly scale the image.
754  */
755  png_set_shift(png_ptr, &sig_bit);
756 
757  /* Pack pixels into bytes */
758  png_set_packing(png_ptr);
759 
760  /* Swap location of alpha bytes from ARGB to RGBA */
761  png_set_swap_alpha(png_ptr);
762 
763  /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
764  * RGB (4 channels -> 3 channels). The second parameter is not used.
765  */
766  png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
767 
768  /* Flip BGR pixels to RGB */
769  png_set_bgr(png_ptr);
770 
771  /* Swap bytes of 16-bit files to most significant byte first */
772  png_set_swap(png_ptr);
773 
774  /* Swap bits of 1, 2, 4 bit packed pixel formats */
775  png_set_packswap(png_ptr);
776 
777  /* Turn on interlace handling if you are not using png_write_image() */
778  if (interlacing)
779  number_passes = png_set_interlace_handling(png_ptr);
780 
781  else
782  number_passes = 1;
783 
784  /* The easiest way to write the image (you may have a different memory
785  * layout, however, so choose what fits your needs best). You need to
786  * use the first method if you aren't handling interlacing yourself.
787  */
789  png_byte image[height][width*bytes_per_pixel];
790  png_bytep row_pointers[height];
791 
792  if (height > PNG_UINT_32_MAX/png_sizeof(png_bytep))
793  png_error (png_ptr, "Image is too tall to process in memory");
794 
795  for (k = 0; k < height; k++)
796  row_pointers[k] = image + k*width*bytes_per_pixel;
797 
798  /* One of the following output methods is REQUIRED */
799 
800 #ifdef entire /* Write out the entire image data in one call */
801  png_write_image(png_ptr, row_pointers);
802 
803  /* The other way to write the image - deal with interlacing */
804 
805 #else no_entire /* Write out the image data by one or more scanlines */
806 
807  /* The number of passes is either 1 for non-interlaced images,
808  * or 7 for interlaced images.
809  */
810  for (pass = 0; pass < number_passes; pass++)
811  {
812  /* Write a few rows at a time. */
813  png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
814 
815  /* If you are only writing one row at a time, this works */
816  for (y = 0; y < height; y++)
817  png_write_rows(png_ptr, &row_pointers[y], 1);
818  }
819 #endif no_entire /* Use only one output method */
820 
821  /* You can write optional chunks like tEXt, zTXt, and tIME at the end
822  * as well. Shouldn't be necessary in 1.2.0 and up as all the public
823  * chunks are supported and you can use png_set_unknown_chunks() to
824  * register unknown chunks into the info structure to be written out.
825  */
826 
827  /* It is REQUIRED to call this to finish writing the rest of the file */
828  png_write_end(png_ptr, info_ptr);
829 #endif hilevel
830 
831  /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
832  * as recommended in versions 1.0.5m and earlier of this example; if
833  * libpng mallocs info_ptr->palette, libpng will free it). If you
834  * allocated it with malloc() instead of png_malloc(), use free() instead
835  * of png_free().
836  */
837  png_free(png_ptr, palette);
838  palette = NULL;
839 
840  /* Similarly, if you png_malloced any data that you passed in with
841  * png_set_something(), such as a hist or trans array, free it here,
842  * when you can be sure that libpng is through with it.
843  */
844  png_free(png_ptr, trans);
845  trans = NULL;
846  /* Whenever you use png_free() it is a good idea to set the pointer to
847  * NULL in case your application inadvertently tries to png_free() it
848  * again. When png_free() sees a NULL it returns without action, thus
849  * avoiding the double-free security problem.
850  */
851 
852  /* Clean up after the write, and free any memory allocated */
853  png_destroy_write_struct(&png_ptr, &info_ptr);
854 
855  /* Close the file */
856  fclose(fp);
857 
858  /* That's it */
859  return (OK);
860 }
861 
862 #endif /* if 0 */
void PNGAPI png_set_packing(png_structp png_ptr)
Definition: pngtrans.c:50
void PNGAPI png_set_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: pngset.c:219
png_byte blue
Definition: png.h:577
png_size_t PNGAPI png_get_rowbytes(png_const_structp png_ptr, png_const_infop info_ptr)
Definition: pngget.c:30
void PNGAPI png_write_image(png_structp png_ptr, png_bytepp image)
Definition: pngwrite.c:578
void PNGAPI png_write_png(png_structp png_ptr, png_infop info_ptr, int transforms, voidp params)
Definition: pngwrite.c:1571
void PNGAPI png_set_expand_gray_1_2_4_to_8(png_structp png_ptr)
Definition: pngrtran.c:867
#define PNG_FILLER_BEFORE
Definition: png.h:1395
png_uint_32 PNGAPI png_get_PLTE(png_const_structp png_ptr, png_const_infop info_ptr, png_colorp *palette, int *num_palette)
Definition: pngget.c:912
void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, png_bytep buffer, png_size_t buffer_size)
Definition: pngpread.c:30
void PNGAPI png_progressive_combine_row(png_structp png_ptr, png_bytep old_row, png_const_bytep new_row)
Definition: pngpread.c:1805
png_byte red
Definition: png.h:575
png_uint_32 PNGAPI png_get_sRGB(png_const_structp png_ptr, png_const_infop info_ptr, int *file_srgb_intent)
Definition: pngget.c:660
#define NULL
Definition: ftobjs.h:61
#define PNG_BACKGROUND_GAMMA_SCREEN
Definition: png.h:1456
#define PNG_MAX_PALETTE_LENGTH
Definition: png.h:802
void PNGAPI png_set_background(png_structp png_ptr, png_const_color_16p background_color, int background_gamma_code, int need_expand, double background_gamma)
Definition: pngrtran.c:125
void PNGAPI png_set_palette_to_rgb(png_structp png_ptr)
Definition: pngrtran.c:854
int32_t k
Definition: e_log.c:102
void PNGAPI png_write_rows(png_structp png_ptr, png_bytepp row, png_uint_32 num_rows)
Definition: pngwrite.c:556
#define PNG_COLOR_TYPE_PALETTE
Definition: png.h:746
void PNGAPI png_read_rows(png_structp png_ptr, png_bytepp row, png_bytepp display_row, png_uint_32 num_rows)
Definition: pngread.c:679
#define PNG_LIBPNG_VER_STRING
Definition: png.h:382
png_error(png_ptr,"Missing IHDR before iCCP")
void PNGAPI png_set_quantize(png_structp png_ptr, png_colorp palette, int num_palette, int maximum_colors, png_const_uint_16p histogram, int full_quantize)
Definition: pngrtran.c:381
png_byte green
Definition: png.h:576
void PNGAPI png_set_sig_bytes(png_structp png_ptr, int num_bytes)
Definition: png.c:27
EGLSurface EGLint EGLint EGLint EGLint height
Definition: eglext.h:293
unsigned int png_uint_32
Definition: pngconf.h:441
png_uint_32 PNGAPI png_get_hIST(png_const_structp png_ptr, png_const_infop info_ptr, png_uint_16p *hist)
Definition: pngget.c:719
png_uint_32 PNGAPI png_get_gAMA(png_const_structp png_ptr, png_const_infop info_ptr, double *file_gamma)
Definition: pngget.c:643
void PNGAPI png_set_strip_16(png_structp png_ptr)
Definition: pngrtran.c:155
void PNGAPI png_set_write_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr write_data_fn, png_flush_ptr output_flush_fn)
Definition: pngwio.c:180
#define PNG_BACKGROUND_GAMMA_FILE
Definition: png.h:1457
#define png_jmpbuf(png_ptr)
Definition: png.h:1035
void PNGAPI png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
Definition: pngset.c:167
EGLImageKHR image
Definition: eglext.h:88
void PNGAPI png_set_bgr(png_structp png_ptr)
Definition: pngtrans.c:21
png_uint_32 PNGAPI png_get_sBIT(png_const_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
Definition: pngget.c:931
#define PNG_TEXT_COMPRESSION_zTXt
Definition: png.h:662
EGLContext EGLenum EGLClientBuffer buffer
Definition: eglext.h:87
#define PNG_TEXT_COMPRESSION_NONE
Definition: png.h:661
GLenum GLenum GLvoid * row
Definition: glew.h:4447
void PNGAPI png_set_sBIT(png_structp png_ptr, png_infop info_ptr, png_const_color_8p sig_bit)
Definition: pngset.c:561
png_struct FAR * png_structp
Definition: png.h:849
void PNGAPI png_write_info(png_structp png_ptr, png_infop info_ptr)
Definition: pngwrite.c:122
void PNGAPI png_read_end(png_structp png_ptr, png_infop info_ptr)
Definition: pngread.c:799
void PNGAPI png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
Definition: pngtrans.c:118
void PNGAPI png_set_PLTE(png_structp png_ptr, png_infop info_ptr, png_const_colorp palette, int num_palette)
Definition: pngset.c:516
#define PNG_COLOR_MASK_COLOR
Definition: png.h:741
void PNGAPI png_set_packswap(png_structp png_ptr)
Definition: pngtrans.c:68
png_info FAR * png_infop
Definition: png.h:721
GLsizei GLsizei * length
Definition: gl2ext.h:792
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:736
void PNGAPI png_set_swap(png_structp png_ptr)
Definition: pngtrans.c:35
EGLSurface EGLint EGLint EGLint width
Definition: eglext.h:293
unsigned char png_byte
Definition: pngconf.h:449
void PNGAPI png_set_text(png_structp png_ptr, png_infop info_ptr, png_const_textp text_ptr, int num_text)
Definition: pngset.c:668
#define PNG_COLOR_TYPE_GRAY
Definition: png.h:745
void PNGAPI png_set_scale_16(png_structp png_ptr)
Definition: pngrtran.c:141
png_uint_16 FAR * png_uint_16p
Definition: pngconf.h:532
#define PNG_UINT_32_MAX
Definition: png.h:727
void PNGAPI png_write_end(png_structp png_ptr, png_infop info_ptr)
Definition: pngwrite.c:298
void PNGAPI png_set_shift(png_structp png_ptr, png_const_color_8p true_bits)
Definition: pngtrans.c:82
void PNGAPI png_set_gamma(png_structp png_ptr, double scrn_gamma, double file_gamma)
Definition: pngrtran.c:809
png_uint_32 PNGAPI png_get_valid(png_const_structp png_ptr, png_const_infop info_ptr, png_uint_32 flag)
Definition: pngget.c:20
#define PNG_INFO_sBIT
Definition: png.h:810
void PNGAPI png_set_strip_alpha(png_structp png_ptr)
Definition: pngrtran.c:168
void PNGAPI png_read_info(png_structp png_ptr, png_infop info_ptr)
Definition: pngread.c:182
void PNGAPI png_set_read_fn(png_structp png_ptr, png_voidp io_ptr, png_rw_ptr read_data_fn)
Definition: pngrio.c:145
void PNGAPI png_set_invert_mono(png_structp png_ptr)
Definition: pngtrans.c:198
EGLSurface EGLint EGLint y
Definition: eglext.h:293
png_byte FAR * png_bytep
Definition: pngconf.h:526
#define PNG_FILTER_TYPE_BASE
Definition: png.h:759
#define PNG_COMPRESSION_TYPE_BASE
Definition: png.h:755
GLenum GLuint GLsizei const GLchar * buf
Definition: glew.h:2539
#define PNG_INFO_tRNS
Definition: png.h:813
void PNGAPI png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
Definition: pngwrite.c:876
png_color_8 FAR * png_color_8p
Definition: png.h:581
int PNGAPI png_set_interlace_handling(png_structp png_ptr)
Definition: pngtrans.c:97
void FAR * png_voidp
Definition: pngconf.h:524
void PNGAPI png_set_tRNS_to_alpha(png_structp png_ptr)
Definition: pngrtran.c:882
void PNGAPI png_read_png(png_structp png_ptr, png_infop info_ptr, int transforms, voidp params)
Definition: pngread.c:1125
void PNGAPI png_read_image(png_structp png_ptr, png_bytepp image)
Definition: pngread.c:734
#define PNG_FILLER_AFTER
Definition: png.h:1396
size_t png_size_t
Definition: pngconf.h:454
png_byte alpha
Definition: png.h:579
void PNGAPI png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, png_progressive_end_ptr end_fn)
Definition: pngpread.c:1821
png_uint_32 PNGAPI png_get_bKGD(png_const_structp png_ptr, png_infop info_ptr, png_color_16p *background)
Definition: pngget.c:445
float ** histogram
Definition: metrics.c:44
void PNGAPI png_free(png_structp png_ptr, png_voidp ptr)
Definition: pngmem.c:578
void PNGAPI png_set_swap_alpha(png_structp png_ptr)
Definition: pngtrans.c:171
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:940
png_byte gray
Definition: png.h:578
void PNGAPI png_read_update_info(png_structp png_ptr, png_infop info_ptr)
Definition: pngread.c:345
void PNGAPI png_init_io(png_structp png_ptr, png_FILE_p fp)
Definition: png.c:577
int PNGAPI png_sig_cmp(png_const_bytep sig, png_size_t start, png_size_t num_to_check)
Definition: png.c:49
#define png_sizeof(x)
Definition: pngconf.h:456
png_color FAR * png_colorp
Definition: png.h:557