Home | History | Annotate | Download | only in libpng
      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.6.3 [July 18, 2013]
      6  * Maintained 1998-2013 Glenn Randers-Pehrson
      7  * Maintained 1996, 1997 Andreas Dilger)
      8  * Written 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
      9  * To the extent possible under law, the authors have waived
     10  * all copyright and related or neighboring rights to this file.
     11  * This work is published from: United States.
     12  */
     13 
     14 /* This is an example of how to use libpng to read and write PNG files.
     15  * The file libpng-manual.txt is much more verbose then this.  If you have not
     16  * read it, do so first.  This was designed to be a starting point of an
     17  * implementation.  This is not officially part of libpng, is hereby placed
     18  * in the public domain, and therefore does not require a copyright notice.
     19  *
     20  * This file does not currently compile, because it is missing certain
     21  * parts, like allocating memory to hold an image.  You will have to
     22  * supply these parts to get it to compile.  For an example of a minimal
     23  * working PNG reader/writer, see pngtest.c, included in this distribution;
     24  * see also the programs in the contrib directory.
     25  */
     26 
     27 /* The simple, but restricted, approach to reading a PNG file or data stream
     28  * just requires two function calls, as in the following complete program.
     29  * Writing a file just needs one function call, so long as the data has an
     30  * appropriate layout.
     31  *
     32  * The following code reads PNG image data from a file and writes it, in a
     33  * potentially new format, to a new file.  While this code will compile there is
     34  * minimal (insufficient) error checking; for a more realistic version look at
     35  * contrib/examples/pngtopng.c
     36  */
     37 #include <stddef.h>
     38 #include <stdlib.h>
     39 #include <string.h>
     40 #include <stdio.h>
     41 #include <png.h>
     42 #include <zlib.h>
     43 
     44 int main(int argc, const char **argv)
     45 {
     46    if (argc == 3)
     47    {
     48       png_image image; /* The control structure used by libpng */
     49 
     50       /* Initialize the 'png_image' structure. */
     51       memset(&image, 0, (sizeof image));
     52       image.version = PNG_IMAGE_VERSION;
     53 
     54       /* The first argument is the file to read: */
     55       if (png_image_begin_read_from_file(&image, argv[1]))
     56       {
     57          png_bytep buffer;
     58 
     59          /* Set the format in which to read the PNG file; this code chooses a
     60           * simple sRGB format with a non-associated alpha channel, adequate to
     61           * store most images.
     62           */
     63          image.format = PNG_FORMAT_RGBA;
     64 
     65          /* Now allocate enough memory to hold the image in this format; the
     66           * PNG_IMAGE_SIZE macro uses the information about the image (width,
     67           * height and format) stored in 'image'.
     68           */
     69          buffer = malloc(PNG_IMAGE_SIZE(image));
     70 
     71          /* If enough memory was available read the image in the desired format
     72           * then write the result out to the new file.  'background' is not
     73           * necessary when reading the image because the alpha channel is
     74           * preserved; if it were to be removed, for example if we requested
     75           * PNG_FORMAT_RGB, then either a solid background color would have to
     76           * be supplied or the output buffer would have to be initialized to the
     77           * actual background of the image.
     78           *
     79           * The fourth argument to png_image_finish_read is the 'row_stride' -
     80           * this is the number of components allocated for the image in each
     81           * row.  It has to be at least as big as the value returned by
     82           * PNG_IMAGE_ROW_STRIDE, but if you just allocate space for the
     83           * default, minimum, size using PNG_IMAGE_SIZE as above you can pass
     84           * zero.
     85           *
     86           * The final argument is a pointer to a buffer for the colormap;
     87           * colormaps have exactly the same format as a row of image pixels (so
     88           * you choose what format to make the colormap by setting
     89           * image.format).  A colormap is only returned if
     90           * PNG_FORMAT_FLAG_COLORMAP is also set in image.format, so in this
     91           * case NULL is passed as the final argument.  If you do want to force
     92           * all images into an index/color-mapped format then you can use:
     93           *
     94           *    PNG_IMAGE_COLORMAP_SIZE(image)
     95           *
     96           * to find the maximum size of the colormap in bytes.
     97           */
     98          if (buffer != NULL &&
     99             png_image_finish_read(&image, NULL/*background*/, buffer,
    100                0/*row_stride*/, NULL/*colormap*/))
    101          {
    102             /* Now write the image out to the second argument.  In the write
    103              * call 'convert_to_8bit' allows 16-bit data to be squashed down to
    104              * 8 bits; this isn't necessary here because the original read was
    105              * to the 8-bit format.
    106              */
    107             if (png_image_write_to_file(&image, argv[2], 0/*convert_to_8bit*/,
    108                buffer, 0/*row_stride*/, NULL/*colormap*/))
    109             {
    110                /* The image has been written successfully. */
    111                exit(0);
    112             }
    113          }
    114 
    115          else
    116          {
    117             /* Calling png_free_image is optional unless the simplified API was
    118              * not run to completion.  In this case if there wasn't enough
    119              * memory for 'buffer' we didn't complete the read, so we must free
    120              * the image:
    121              */
    122             if (buffer == NULL)
    123                png_free_image(&image);
    124 
    125             else
    126                free(buffer);
    127       }
    128 
    129       /* Something went wrong reading or writing the image.  libpng stores a
    130        * textual message in the 'png_image' structure:
    131        */
    132       fprintf(stderr, "pngtopng: error: %s\n", image.message);
    133       exit (1);
    134    }
    135 
    136    fprintf(stderr, "pngtopng: usage: pngtopng input-file output-file\n");
    137    exit(1);
    138 }
    139 
    140 /* That's it ;-)  Of course you probably want to do more with PNG files than
    141  * just converting them all to 32-bit RGBA PNG files; you can do that between
    142  * the call to png_image_finish_read and png_image_write_to_file.  You can also
    143  * ask for the image data to be presented in a number of different formats.  You
    144  * do this by simply changing the 'format' parameter set before allocating the
    145  * buffer.
    146  *
    147  * The format parameter consists of five flags that define various aspects of
    148  * the image, you can simply add these together to get the format or you can use
    149  * one of the predefined macros from png.h (as above):
    150  *
    151  * PNG_FORMAT_FLAG_COLOR: if set the image will have three color components per
    152  *    pixel (red, green and blue), if not set the image will just have one
    153  *    luminance (grayscale) component.
    154  *
    155  * PNG_FORMAT_FLAG_ALPHA: if set each pixel in the image will have an additional
    156  *    alpha value; a linear value that describes the degree the image pixel
    157  *    covers (overwrites) the contents of the existing pixel on the display.
    158  *
    159  * PNG_FORMAT_FLAG_LINEAR: if set the components of each pixel will be returned
    160  *    as a series of 16-bit linear values, if not set the components will be
    161  *    returned as a series of 8-bit values encoded according to the 'sRGB'
    162  *    standard.  The 8-bit format is the normal format for images intended for
    163  *    direct display, because almost all display devices do the inverse of the
    164  *    sRGB transformation to the data they receive.  The 16-bit format is more
    165  *    common for scientific data and image data that must be further processed;
    166  *    because it is linear simple math can be done on the component values.
    167  *    Regardless of the setting of this flag the alpha channel is always linear,
    168  *    although it will be 8 bits or 16 bits wide as specified by the flag.
    169  *
    170  * PNG_FORMAT_FLAG_BGR: if set the components of a color pixel will be returned
    171  *    in the order blue, then green, then red.  If not set the pixel components
    172  *    are in the order red, then green, then blue.
    173  *
    174  * PNG_FORMAT_FLAG_AFIRST: if set the alpha channel (if present) precedes the
    175  *    color or grayscale components.  If not set the alpha channel follows the
    176  *    components.
    177  *
    178  * You do not have to read directly from a file.  You can read from memory or,
    179  * on systems that support it, from a <stdio.h> FILE*.  This is controlled by
    180  * the particular png_image_read_from_ function you call at the start.  Likewise
    181  * on write you can write to a FILE* if your system supports it.  Check the
    182  * macro PNG_STDIO_SUPPORTED to see if stdio support has been included in your
    183  * libpng build.
    184  *
    185  * If you read 16-bit (PNG_FORMAT_FLAG_LINEAR) data you may need to write it in
    186  * the 8-bit format for display.  You do this by setting the convert_to_8bit
    187  * flag to 'true'.
    188  *
    189  * Don't repeatedly convert between the 8-bit and 16-bit forms.  There is
    190  * significant data loss when 16-bit data is converted to the 8-bit encoding and
    191  * the current libpng implementation of convertion to 16-bit is also
    192  * significantly lossy.  The latter will be fixed in the future, but the former
    193  * is unavoidable - the 8-bit format just doesn't have enough resolution.
    194  */
    195 
    196 /* If your program needs more information from the PNG data it reads, or if you
    197  * need to do more complex transformations, or minimise transformations, on the
    198  * data you read, then you must use one of the several lower level libpng
    199  * interfaces.
    200  *
    201  * All these interfaces require that you do your own error handling - your
    202  * program must be able to arrange for control to return to your own code any
    203  * time libpng encounters a problem.  There are several ways to do this, but the
    204  * standard way is to use the ANSI-C (C90) <setjmp.h> interface to establish a
    205  * return point within your own code.  You must do this if you do not use the
    206  * simplified interface (above).
    207  *
    208  * The first step is to include the header files you need, including the libpng
    209  * header file.  Include any standard headers and feature test macros your
    210  * program requires before including png.h:
    211  */
    212 #include <png.h>
    213 
    214  /* The png_jmpbuf() macro, used in error handling, became available in
    215   * libpng version 1.0.6.  If you want to be able to run your code with older
    216   * versions of libpng, you must define the macro yourself (but only if it
    217   * is not already defined by libpng!).
    218   */
    219 
    220 #ifndef png_jmpbuf
    221 #  define png_jmpbuf(png_ptr) ((png_ptr)->png_jmpbuf)
    222 #endif
    223 
    224 /* Check to see if a file is a PNG file using png_sig_cmp().  png_sig_cmp()
    225  * returns zero if the image is a PNG and nonzero if it isn't a PNG.
    226  *
    227  * The function check_if_png() shown here, but not used, returns nonzero (true)
    228  * if the file can be opened and is a PNG, 0 (false) otherwise.
    229  *
    230  * If this call is successful, and you are going to keep the file open,
    231  * you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
    232  * you have created the png_ptr, so that libpng knows your application
    233  * has read that many bytes from the start of the file.  Make sure you
    234  * don't call png_set_sig_bytes() with more than 8 bytes read or give it
    235  * an incorrect number of bytes read, or you will either have read too
    236  * many bytes (your fault), or you are telling libpng to read the wrong
    237  * number of magic bytes (also your fault).
    238  *
    239  * Many applications already read the first 2 or 4 bytes from the start
    240  * of the image to determine the file type, so it would be easiest just
    241  * to pass the bytes to png_sig_cmp() or even skip that if you know
    242  * you have a PNG file, and call png_set_sig_bytes().
    243  */
    244 #define PNG_BYTES_TO_CHECK 4
    245 int check_if_png(char *file_name, FILE **fp)
    246 {
    247    char buf[PNG_BYTES_TO_CHECK];
    248 
    249    /* Open the prospective PNG file. */
    250    if ((*fp = fopen(file_name, "rb")) == NULL)
    251       return 0;
    252 
    253    /* Read in some of the signature bytes */
    254    if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
    255       return 0;
    256 
    257    /* Compare the first PNG_BYTES_TO_CHECK bytes of the signature.
    258       Return nonzero (true) if they match */
    259 
    260    return(!png_sig_cmp(buf, (png_size_t)0, PNG_BYTES_TO_CHECK));
    261 }
    262 
    263 /* Read a PNG file.  You may want to return an error code if the read
    264  * fails (depending upon the failure).  There are two "prototypes" given
    265  * here - one where we are given the filename, and we need to open the
    266  * file, and the other where we are given an open file (possibly with
    267  * some or all of the magic bytes read - see comments above).
    268  */
    269 #ifdef open_file /* prototype 1 */
    270 void read_png(char *file_name)  /* We need to open the file */
    271 {
    272    png_structp png_ptr;
    273    png_infop info_ptr;
    274    unsigned int sig_read = 0;
    275    png_uint_32 width, height;
    276    int bit_depth, color_type, interlace_type;
    277    FILE *fp;
    278 
    279    if ((fp = fopen(file_name, "rb")) == NULL)
    280       return (ERROR);
    281 
    282 #else no_open_file /* prototype 2 */
    283 void read_png(FILE *fp, unsigned int sig_read)  /* File is already open */
    284 {
    285    png_structp png_ptr;
    286    png_infop info_ptr;
    287    png_uint_32 width, height;
    288    int bit_depth, color_type, interlace_type;
    289 #endif no_open_file /* Only use one prototype! */
    290 
    291    /* Create and initialize the png_struct with the desired error handler
    292     * functions.  If you want to use the default stderr and longjump method,
    293     * you can supply NULL for the last three parameters.  We also supply the
    294     * the compiler header file version, so that we know if the application
    295     * was compiled with a compatible version of the library.  REQUIRED
    296     */
    297    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
    298       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    299 
    300    if (png_ptr == NULL)
    301    {
    302       fclose(fp);
    303       return (ERROR);
    304    }
    305 
    306    /* Allocate/initialize the memory for image information.  REQUIRED. */
    307    info_ptr = png_create_info_struct(png_ptr);
    308    if (info_ptr == NULL)
    309    {
    310       fclose(fp);
    311       png_destroy_read_struct(&png_ptr, NULL, NULL);
    312       return (ERROR);
    313    }
    314 
    315    /* Set error handling if you are using the setjmp/longjmp method (this is
    316     * the normal method of doing things with libpng).  REQUIRED unless you
    317     * set up your own error handlers in the png_create_read_struct() earlier.
    318     */
    319 
    320    if (setjmp(png_jmpbuf(png_ptr)))
    321    {
    322       /* Free all of the memory associated with the png_ptr and info_ptr */
    323       png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    324       fclose(fp);
    325       /* If we get here, we had a problem reading the file */
    326       return (ERROR);
    327    }
    328 
    329    /* One of the following I/O initialization methods is REQUIRED */
    330 #ifdef streams /* PNG file I/O method 1 */
    331    /* Set up the input control if you are using standard C streams */
    332    png_init_io(png_ptr, fp);
    333 
    334 #else no_streams /* PNG file I/O method 2 */
    335    /* If you are using replacement read functions, instead of calling
    336     * png_init_io() here you would call:
    337     */
    338    png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
    339    /* where user_io_ptr is a structure you want available to the callbacks */
    340 #endif no_streams /* Use only one I/O method! */
    341 
    342    /* If we have already read some of the signature */
    343    png_set_sig_bytes(png_ptr, sig_read);
    344 
    345 #ifdef hilevel
    346    /*
    347     * If you have enough memory to read in the entire image at once,
    348     * and you need to specify only transforms that can be controlled
    349     * with one of the PNG_TRANSFORM_* bits (this presently excludes
    350     * quantizing, filling, setting background, and doing gamma
    351     * adjustment), then you can read the entire image (including
    352     * pixels) into the info structure with this call:
    353     */
    354    png_read_png(png_ptr, info_ptr, png_transforms, NULL);
    355 
    356 #else
    357    /* OK, you're doing it the hard way, with the lower-level functions */
    358 
    359    /* The call to png_read_info() gives us all of the information from the
    360     * PNG file before the first IDAT (image data chunk).  REQUIRED
    361     */
    362    png_read_info(png_ptr, info_ptr);
    363 
    364    png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
    365        &interlace_type, NULL, NULL);
    366 
    367    /* Set up the data transformations you want.  Note that these are all
    368     * optional.  Only call them if you want/need them.  Many of the
    369     * transformations only work on specific types of images, and many
    370     * are mutually exclusive.
    371     */
    372 
    373    /* Tell libpng to strip 16 bit/color files down to 8 bits/color.
    374     * Use accurate scaling if it's available, otherwise just chop off the
    375     * low byte.
    376     */
    377 #ifdef PNG_READ_SCALE_16_TO_8_SUPPORTED
    378     png_set_scale_16(png_ptr);
    379 #else
    380    png_set_strip_16(png_ptr);
    381 #endif
    382 
    383    /* Strip alpha bytes from the input data without combining with the
    384     * background (not recommended).
    385     */
    386    png_set_strip_alpha(png_ptr);
    387 
    388    /* Extract multiple pixels with bit depths of 1, 2, and 4 from a single
    389     * byte into separate bytes (useful for paletted and grayscale images).
    390     */
    391    png_set_packing(png_ptr);
    392 
    393    /* Change the order of packed pixels to least significant bit first
    394     * (not useful if you are using png_set_packing). */
    395    png_set_packswap(png_ptr);
    396 
    397    /* Expand paletted colors into true RGB triplets */
    398    if (color_type == PNG_COLOR_TYPE_PALETTE)
    399       png_set_palette_to_rgb(png_ptr);
    400 
    401    /* Expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
    402    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    403       png_set_expand_gray_1_2_4_to_8(png_ptr);
    404 
    405    /* Expand paletted or RGB images with transparency to full alpha channels
    406     * so the data will be available as RGBA quartets.
    407     */
    408    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
    409       png_set_tRNS_to_alpha(png_ptr);
    410 
    411    /* Set the background color to draw transparent and alpha images over.
    412     * It is possible to set the red, green, and blue components directly
    413     * for paletted images instead of supplying a palette index.  Note that
    414     * even if the PNG file supplies a background, you are not required to
    415     * use it - you should use the (solid) application background if it has one.
    416     */
    417 
    418    png_color_16 my_background, *image_background;
    419 
    420    if (png_get_bKGD(png_ptr, info_ptr, &image_background))
    421       png_set_background(png_ptr, image_background,
    422                          PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
    423    else
    424       png_set_background(png_ptr, &my_background,
    425                          PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
    426 
    427    /* Some suggestions as to how to get a screen gamma value
    428     *
    429     * Note that screen gamma is the display_exponent, which includes
    430     * the CRT_exponent and any correction for viewing conditions
    431     */
    432    if (/* We have a user-defined screen gamma value */)
    433    {
    434       screen_gamma = user-defined screen_gamma;
    435    }
    436    /* This is one way that applications share the same screen gamma value */
    437    else if ((gamma_str = getenv("SCREEN_GAMMA")) != NULL)
    438    {
    439       screen_gamma = atof(gamma_str);
    440    }
    441    /* If we don't have another value */
    442    else
    443    {
    444       screen_gamma = PNG_DEFAULT_sRGB;  /* A good guess for a PC monitor
    445                                            in a dimly lit room */
    446       screen_gamma = PNG_GAMMA_MAC_18 or 1.0; /* Good guesses for Mac systems */
    447    }
    448 
    449    /* Tell libpng to handle the gamma conversion for you.  The final call
    450     * is a good guess for PC generated images, but it should be configurable
    451     * by the user at run time by the user.  It is strongly suggested that
    452     * your application support gamma correction.
    453     */
    454 
    455    int intent;
    456 
    457    if (png_get_sRGB(png_ptr, info_ptr, &intent))
    458       png_set_gamma(png_ptr, screen_gamma, PNG_DEFAULT_sRGB);
    459    else
    460    {
    461       double image_gamma;
    462       if (png_get_gAMA(png_ptr, info_ptr, &image_gamma))
    463          png_set_gamma(png_ptr, screen_gamma, image_gamma);
    464       else
    465          png_set_gamma(png_ptr, screen_gamma, 0.45455);
    466    }
    467 
    468 #ifdef PNG_READ_QUANTIZE_SUPPORTED
    469    /* Quantize RGB files down to 8 bit palette or reduce palettes
    470     * to the number of colors available on your screen.
    471     */
    472    if (color_type & PNG_COLOR_MASK_COLOR)
    473    {
    474       int num_palette;
    475       png_colorp palette;
    476 
    477       /* This reduces the image to the application supplied palette */
    478       if (/* We have our own palette */)
    479       {
    480          /* An array of colors to which the image should be quantized */
    481          png_color std_color_cube[MAX_SCREEN_COLORS];
    482 
    483          png_set_quantize(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
    484             MAX_SCREEN_COLORS, NULL, 0);
    485       }
    486       /* This reduces the image to the palette supplied in the file */
    487       else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette))
    488       {
    489          png_uint_16p histogram = NULL;
    490 
    491          png_get_hIST(png_ptr, info_ptr, &histogram);
    492 
    493          png_set_quantize(png_ptr, palette, num_palette,
    494                         max_screen_colors, histogram, 0);
    495       }
    496    }
    497 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
    498 
    499    /* Invert monochrome files to have 0 as white and 1 as black */
    500    png_set_invert_mono(png_ptr);
    501 
    502    /* If you want to shift the pixel values from the range [0,255] or
    503     * [0,65535] to the original [0,7] or [0,31], or whatever range the
    504     * colors were originally in:
    505     */
    506    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
    507    {
    508       png_color_8p sig_bit_p;
    509 
    510       png_get_sBIT(png_ptr, info_ptr, &sig_bit_p);
    511       png_set_shift(png_ptr, sig_bit_p);
    512    }
    513 
    514    /* Flip the RGB pixels to BGR (or RGBA to BGRA) */
    515    if (color_type & PNG_COLOR_MASK_COLOR)
    516       png_set_bgr(png_ptr);
    517 
    518    /* Swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
    519    png_set_swap_alpha(png_ptr);
    520 
    521    /* Swap bytes of 16 bit files to least significant byte first */
    522    png_set_swap(png_ptr);
    523 
    524    /* Add filler (or alpha) byte (before/after each RGB triplet) */
    525    png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
    526 
    527 #ifdef PNG_READ_INTERLACING_SUPPORTED
    528    /* Turn on interlace handling.  REQUIRED if you are not using
    529     * png_read_image().  To see how to handle interlacing passes,
    530     * see the png_read_row() method below:
    531     */
    532    number_passes = png_set_interlace_handling(png_ptr);
    533 #else
    534    number_passes = 1;
    535 #endif /* PNG_READ_INTERLACING_SUPPORTED */
    536 
    537 
    538    /* Optional call to gamma correct and add the background to the palette
    539     * and update info structure.  REQUIRED if you are expecting libpng to
    540     * update the palette for you (ie you selected such a transform above).
    541     */
    542    png_read_update_info(png_ptr, info_ptr);
    543 
    544    /* Allocate the memory to hold the image using the fields of info_ptr. */
    545 
    546    /* The easiest way to read the image: */
    547    png_bytep row_pointers[height];
    548 
    549    /* Clear the pointer array */
    550    for (row = 0; row < height; row++)
    551       row_pointers[row] = NULL;
    552 
    553    for (row = 0; row < height; row++)
    554       row_pointers[row] = png_malloc(png_ptr, png_get_rowbytes(png_ptr,
    555          info_ptr));
    556 
    557    /* Now it's time to read the image.  One of these methods is REQUIRED */
    558 #ifdef entire /* Read the entire image in one go */
    559    png_read_image(png_ptr, row_pointers);
    560 
    561 #else no_entire /* Read the image one or more scanlines at a time */
    562    /* The other way to read images - deal with interlacing: */
    563 
    564    for (pass = 0; pass < number_passes; pass++)
    565    {
    566 #ifdef single /* Read the image a single row at a time */
    567       for (y = 0; y < height; y++)
    568       {
    569          png_read_rows(png_ptr, &row_pointers[y], NULL, 1);
    570       }
    571 
    572 #else no_single /* Read the image several rows at a time */
    573       for (y = 0; y < height; y += number_of_rows)
    574       {
    575 #ifdef sparkle /* Read the image using the "sparkle" effect. */
    576          png_read_rows(png_ptr, &row_pointers[y], NULL,
    577             number_of_rows);
    578 #else no_sparkle /* Read the image using the "rectangle" effect */
    579          png_read_rows(png_ptr, NULL, &row_pointers[y],
    580             number_of_rows);
    581 #endif no_sparkle /* Use only one of these two methods */
    582       }
    583 
    584       /* If you want to display the image after every pass, do so here */
    585 #endif no_single /* Use only one of these two methods */
    586    }
    587 #endif no_entire /* Use only one of these two methods */
    588 
    589    /* Read rest of file, and get additional chunks in info_ptr - REQUIRED */
    590    png_read_end(png_ptr, info_ptr);
    591 #endif hilevel
    592 
    593    /* At this point you have read the entire image */
    594 
    595    /* Clean up after the read, and free any memory allocated - REQUIRED */
    596    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    597 
    598    /* Close the file */
    599    fclose(fp);
    600 
    601    /* That's it */
    602    return (OK);
    603 }
    604 
    605 /* Progressively read a file */
    606 
    607 int
    608 initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
    609 {
    610    /* Create and initialize the png_struct with the desired error handler
    611     * functions.  If you want to use the default stderr and longjump method,
    612     * you can supply NULL for the last three parameters.  We also check that
    613     * the library version is compatible in case we are using dynamically
    614     * linked libraries.
    615     */
    616    *png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
    617        png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    618 
    619    if (*png_ptr == NULL)
    620    {
    621       *info_ptr = NULL;
    622       return (ERROR);
    623    }
    624 
    625    *info_ptr = png_create_info_struct(png_ptr);
    626 
    627    if (*info_ptr == NULL)
    628    {
    629       png_destroy_read_struct(png_ptr, info_ptr, NULL);
    630       return (ERROR);
    631    }
    632 
    633    if (setjmp(png_jmpbuf((*png_ptr))))
    634    {
    635       png_destroy_read_struct(png_ptr, info_ptr, NULL);
    636       return (ERROR);
    637    }
    638 
    639    /* This one's new.  You will need to provide all three
    640     * function callbacks, even if you aren't using them all.
    641     * If you aren't using all functions, you can specify NULL
    642     * parameters.  Even when all three functions are NULL,
    643     * you need to call png_set_progressive_read_fn().
    644     * These functions shouldn't be dependent on global or
    645     * static variables if you are decoding several images
    646     * simultaneously.  You should store stream specific data
    647     * in a separate struct, given as the second parameter,
    648     * and retrieve the pointer from inside the callbacks using
    649     * the function png_get_progressive_ptr(png_ptr).
    650     */
    651    png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
    652       info_callback, row_callback, end_callback);
    653 
    654    return (OK);
    655 }
    656 
    657 int
    658 process_data(png_structp *png_ptr, png_infop *info_ptr,
    659    png_bytep buffer, png_uint_32 length)
    660 {
    661    if (setjmp(png_jmpbuf((*png_ptr))))
    662    {
    663       /* Free the png_ptr and info_ptr memory on error */
    664       png_destroy_read_struct(png_ptr, info_ptr, NULL);
    665       return (ERROR);
    666    }
    667 
    668    /* This one's new also.  Simply give it chunks of data as
    669     * they arrive from the data stream (in order, of course).
    670     * On segmented machines, don't give it any more than 64K.
    671     * The library seems to run fine with sizes of 4K, although
    672     * you can give it much less if necessary (I assume you can
    673     * give it chunks of 1 byte, but I haven't tried with less
    674     * than 256 bytes yet).  When this function returns, you may
    675     * want to display any rows that were generated in the row
    676     * callback, if you aren't already displaying them there.
    677     */
    678    png_process_data(*png_ptr, *info_ptr, buffer, length);
    679    return (OK);
    680 }
    681 
    682 info_callback(png_structp png_ptr, png_infop info)
    683 {
    684    /* Do any setup here, including setting any of the transformations
    685     * mentioned in the Reading PNG files section.  For now, you _must_
    686     * call either png_start_read_image() or png_read_update_info()
    687     * after all the transformations are set (even if you don't set
    688     * any).  You may start getting rows before png_process_data()
    689     * returns, so this is your last chance to prepare for that.
    690     */
    691 }
    692 
    693 row_callback(png_structp png_ptr, png_bytep new_row,
    694    png_uint_32 row_num, int pass)
    695 {
    696    /*
    697     * This function is called for every row in the image.  If the
    698     * image is interlaced, and you turned on the interlace handler,
    699     * this function will be called for every row in every pass.
    700     *
    701     * In this function you will receive a pointer to new row data from
    702     * libpng called new_row that is to replace a corresponding row (of
    703     * the same data format) in a buffer allocated by your application.
    704     *
    705     * The new row data pointer "new_row" may be NULL, indicating there is
    706     * no new data to be replaced (in cases of interlace loading).
    707     *
    708     * If new_row is not NULL then you need to call
    709     * png_progressive_combine_row() to replace the corresponding row as
    710     * shown below:
    711     */
    712 
    713    /* Get pointer to corresponding row in our
    714     * PNG read buffer.
    715     */
    716    png_bytep old_row = ((png_bytep *)our_data)[row_num];
    717 
    718 #ifdef PNG_READ_INTERLACING_SUPPORTED
    719    /* If both rows are allocated then copy the new row
    720     * data to the corresponding row data.
    721     */
    722    if ((old_row != NULL) && (new_row != NULL))
    723    png_progressive_combine_row(png_ptr, old_row, new_row);
    724 
    725    /*
    726     * The rows and passes are called in order, so you don't really
    727     * need the row_num and pass, but I'm supplying them because it
    728     * may make your life easier.
    729     *
    730     * For the non-NULL rows of interlaced images, you must call
    731     * png_progressive_combine_row() passing in the new row and the
    732     * old row, as demonstrated above.  You can call this function for
    733     * NULL rows (it will just return) and for non-interlaced images
    734     * (it just does the memcpy for you) if it will make the code
    735     * easier.  Thus, you can just do this for all cases:
    736     */
    737 
    738    png_progressive_combine_row(png_ptr, old_row, new_row);
    739 
    740    /* where old_row is what was displayed for previous rows.  Note
    741     * that the first pass (pass == 0 really) will completely cover
    742     * the old row, so the rows do not have to be initialized.  After
    743     * the first pass (and only for interlaced images), you will have
    744     * to pass the current row as new_row, and the function will combine
    745     * the old row and the new row.
    746     */
    747 #endif /* PNG_READ_INTERLACING_SUPPORTED */
    748 }
    749 
    750 end_callback(png_structp png_ptr, png_infop info)
    751 {
    752    /* This function is called when the whole image has been read,
    753     * including any chunks after the image (up to and including
    754     * the IEND).  You will usually have the same info chunk as you
    755     * had in the header, although some data may have been added
    756     * to the comments and time fields.
    757     *
    758     * Most people won't do much here, perhaps setting a flag that
    759     * marks the image as finished.
    760     */
    761 }
    762 
    763 /* Write a png file */
    764 void write_png(char *file_name /* , ... other image information ... */)
    765 {
    766    FILE *fp;
    767    png_structp png_ptr;
    768    png_infop info_ptr;
    769    png_colorp palette;
    770 
    771    /* Open the file */
    772    fp = fopen(file_name, "wb");
    773    if (fp == NULL)
    774       return (ERROR);
    775 
    776    /* Create and initialize the png_struct with the desired error handler
    777     * functions.  If you want to use the default stderr and longjump method,
    778     * you can supply NULL for the last three parameters.  We also check that
    779     * the library version is compatible with the one used at compile time,
    780     * in case we are using dynamically linked libraries.  REQUIRED.
    781     */
    782    png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
    783       png_voidp user_error_ptr, user_error_fn, user_warning_fn);
    784 
    785    if (png_ptr == NULL)
    786    {
    787       fclose(fp);
    788       return (ERROR);
    789    }
    790 
    791    /* Allocate/initialize the image information data.  REQUIRED */
    792    info_ptr = png_create_info_struct(png_ptr);
    793    if (info_ptr == NULL)
    794    {
    795       fclose(fp);
    796       png_destroy_write_struct(&png_ptr,  NULL);
    797       return (ERROR);
    798    }
    799 
    800    /* Set error handling.  REQUIRED if you aren't supplying your own
    801     * error handling functions in the png_create_write_struct() call.
    802     */
    803    if (setjmp(png_jmpbuf(png_ptr)))
    804    {
    805       /* If we get here, we had a problem writing the file */
    806       fclose(fp);
    807       png_destroy_write_struct(&png_ptr, &info_ptr);
    808       return (ERROR);
    809    }
    810 
    811    /* One of the following I/O initialization functions is REQUIRED */
    812 
    813 #ifdef streams /* I/O initialization method 1 */
    814    /* Set up the output control if you are using standard C streams */
    815    png_init_io(png_ptr, fp);
    816 
    817 #else no_streams /* I/O initialization method 2 */
    818    /* If you are using replacement write functions, instead of calling
    819     * png_init_io() here you would call
    820     */
    821    png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
    822       user_IO_flush_function);
    823    /* where user_io_ptr is a structure you want available to the callbacks */
    824 #endif no_streams /* Only use one initialization method */
    825 
    826 #ifdef hilevel
    827    /* This is the easy way.  Use it if you already have all the
    828     * image info living in the structure.  You could "|" many
    829     * PNG_TRANSFORM flags into the png_transforms integer here.
    830     */
    831    png_write_png(png_ptr, info_ptr, png_transforms, NULL);
    832 
    833 #else
    834    /* This is the hard way */
    835 
    836    /* Set the image information here.  Width and height are up to 2^31,
    837     * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
    838     * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
    839     * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
    840     * or PNG_COLOR_TYPE_RGB_ALPHA.  interlace is either PNG_INTERLACE_NONE or
    841     * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
    842     * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
    843     */
    844    png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
    845       PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
    846 
    847    /* Set the palette if there is one.  REQUIRED for indexed-color images */
    848    palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH
    849              * (sizeof (png_color)));
    850    /* ... Set palette colors ... */
    851    png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH);
    852    /* You must not free palette here, because png_set_PLTE only makes a link to
    853     * the palette that you malloced.  Wait until you are about to destroy
    854     * the png structure.
    855     */
    856 
    857    /* Optional significant bit (sBIT) chunk */
    858    png_color_8 sig_bit;
    859 
    860    /* If we are dealing with a grayscale image then */
    861    sig_bit.gray = true_bit_depth;
    862 
    863    /* Otherwise, if we are dealing with a color image then */
    864    sig_bit.red = true_red_bit_depth;
    865    sig_bit.green = true_green_bit_depth;
    866    sig_bit.blue = true_blue_bit_depth;
    867 
    868    /* If the image has an alpha channel then */
    869    sig_bit.alpha = true_alpha_bit_depth;
    870 
    871    png_set_sBIT(png_ptr, info_ptr, &sig_bit);
    872 
    873 
    874    /* Optional gamma chunk is strongly suggested if you have any guess
    875     * as to the correct gamma of the image.
    876     */
    877    png_set_gAMA(png_ptr, info_ptr, gamma);
    878 
    879    /* Optionally write comments into the image */
    880    {
    881       png_text text_ptr[3];
    882 
    883       char key0[]="Title";
    884       char text0[]="Mona Lisa";
    885       text_ptr[0].key = key0;
    886       text_ptr[0].text = text0;
    887       text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
    888       text_ptr[0].itxt_length = 0;
    889       text_ptr[0].lang = NULL;
    890       text_ptr[0].lang_key = NULL;
    891 
    892       char key1[]="Author";
    893       char text1[]="Leonardo DaVinci";
    894       text_ptr[1].key = key1;
    895       text_ptr[1].text = text1;
    896       text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
    897       text_ptr[1].itxt_length = 0;
    898       text_ptr[1].lang = NULL;
    899       text_ptr[1].lang_key = NULL;
    900 
    901       char key2[]="Description";
    902       char text2[]="<long text>";
    903       text_ptr[2].key = key2;
    904       text_ptr[2].text = text2;
    905       text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
    906       text_ptr[2].itxt_length = 0;
    907       text_ptr[2].lang = NULL;
    908       text_ptr[2].lang_key = NULL;
    909 
    910       png_set_text(write_ptr, write_info_ptr, text_ptr, 3);
    911    }
    912 
    913    /* Other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs */
    914 
    915    /* Note that if sRGB is present the gAMA and cHRM chunks must be ignored
    916     * on read and, if your application chooses to write them, they must
    917     * be written in accordance with the sRGB profile
    918     */
    919 
    920    /* Write the file header information.  REQUIRED */
    921    png_write_info(png_ptr, info_ptr);
    922 
    923    /* If you want, you can write the info in two steps, in case you need to
    924     * write your private chunk ahead of PLTE:
    925     *
    926     *   png_write_info_before_PLTE(write_ptr, write_info_ptr);
    927     *   write_my_chunk();
    928     *   png_write_info(png_ptr, info_ptr);
    929     *
    930     * However, given the level of known- and unknown-chunk support in 1.2.0
    931     * and up, this should no longer be necessary.
    932     */
    933 
    934    /* Once we write out the header, the compression type on the text
    935     * chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
    936     * PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
    937     * at the end.
    938     */
    939 
    940    /* Set up the transformations you want.  Note that these are
    941     * all optional.  Only call them if you want them.
    942     */
    943 
    944    /* Invert monochrome pixels */
    945    png_set_invert_mono(png_ptr);
    946 
    947    /* Shift the pixels up to a legal bit depth and fill in
    948     * as appropriate to correctly scale the image.
    949     */
    950    png_set_shift(png_ptr, &sig_bit);
    951 
    952    /* Pack pixels into bytes */
    953    png_set_packing(png_ptr);
    954 
    955    /* Swap location of alpha bytes from ARGB to RGBA */
    956    png_set_swap_alpha(png_ptr);
    957 
    958    /* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
    959     * RGB (4 channels -> 3 channels). The second parameter is not used.
    960     */
    961    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
    962 
    963    /* Flip BGR pixels to RGB */
    964    png_set_bgr(png_ptr);
    965 
    966    /* Swap bytes of 16-bit files to most significant byte first */
    967    png_set_swap(png_ptr);
    968 
    969    /* Swap bits of 1, 2, 4 bit packed pixel formats */
    970    png_set_packswap(png_ptr);
    971 
    972    /* Turn on interlace handling if you are not using png_write_image() */
    973    if (interlacing)
    974       number_passes = png_set_interlace_handling(png_ptr);
    975 
    976    else
    977       number_passes = 1;
    978 
    979    /* The easiest way to write the image (you may have a different memory
    980     * layout, however, so choose what fits your needs best).  You need to
    981     * use the first method if you aren't handling interlacing yourself.
    982     */
    983    png_uint_32 k, height, width;
    984 
    985    /* In this example, "image" is a one-dimensional array of bytes */
    986    png_byte image[height*width*bytes_per_pixel];
    987 
    988    png_bytep row_pointers[height];
    989 
    990    if (height > PNG_UINT_32_MAX/(sizeof (png_bytep)))
    991      png_error (png_ptr, "Image is too tall to process in memory");
    992 
    993    /* Set up pointers into your "image" byte array */
    994    for (k = 0; k < height; k++)
    995      row_pointers[k] = image + k*width*bytes_per_pixel;
    996 
    997    /* One of the following output methods is REQUIRED */
    998 
    999 #ifdef entire /* Write out the entire image data in one call */
   1000    png_write_image(png_ptr, row_pointers);
   1001 
   1002    /* The other way to write the image - deal with interlacing */
   1003 
   1004 #else no_entire /* Write out the image data by one or more scanlines */
   1005 
   1006    /* The number of passes is either 1 for non-interlaced images,
   1007     * or 7 for interlaced images.
   1008     */
   1009    for (pass = 0; pass < number_passes; pass++)
   1010    {
   1011       /* Write a few rows at a time. */
   1012       png_write_rows(png_ptr, &row_pointers[first_row], number_of_rows);
   1013 
   1014       /* If you are only writing one row at a time, this works */
   1015       for (y = 0; y < height; y++)
   1016          png_write_rows(png_ptr, &row_pointers[y], 1);
   1017    }
   1018 #endif no_entire /* Use only one output method */
   1019 
   1020    /* You can write optional chunks like tEXt, zTXt, and tIME at the end
   1021     * as well.  Shouldn't be necessary in 1.2.0 and up as all the public
   1022     * chunks are supported and you can use png_set_unknown_chunks() to
   1023     * register unknown chunks into the info structure to be written out.
   1024     */
   1025 
   1026    /* It is REQUIRED to call this to finish writing the rest of the file */
   1027    png_write_end(png_ptr, info_ptr);
   1028 #endif hilevel
   1029 
   1030    /* If you png_malloced a palette, free it here (don't free info_ptr->palette,
   1031     * as recommended in versions 1.0.5m and earlier of this example; if
   1032     * libpng mallocs info_ptr->palette, libpng will free it).  If you
   1033     * allocated it with malloc() instead of png_malloc(), use free() instead
   1034     * of png_free().
   1035     */
   1036    png_free(png_ptr, palette);
   1037    palette = NULL;
   1038 
   1039    /* Similarly, if you png_malloced any data that you passed in with
   1040     * png_set_something(), such as a hist or trans array, free it here,
   1041     * when you can be sure that libpng is through with it.
   1042     */
   1043    png_free(png_ptr, trans);
   1044    trans = NULL;
   1045    /* Whenever you use png_free() it is a good idea to set the pointer to
   1046     * NULL in case your application inadvertently tries to png_free() it
   1047     * again.  When png_free() sees a NULL it returns without action, thus
   1048     * avoiding the double-free security problem.
   1049     */
   1050 
   1051    /* Clean up after the write, and free any memory allocated */
   1052    png_destroy_write_struct(&png_ptr, &info_ptr);
   1053 
   1054    /* Close the file */
   1055    fclose(fp);
   1056 
   1057    /* That's it */
   1058    return (OK);
   1059 }
   1060 
   1061 #endif /* if 0 */
   1062