libpng.txt - A description on how to use and modify libpng

 libpng version 1.2.8 - December 3, 2004
 Updated and distributed by Glenn Randers-Pehrson
 <glennrp at users.sourceforge.net>
 Copyright (c) 1998-2004 Glenn Randers-Pehrson
 For conditions of distribution and use, see copyright
 notice in png.h.

 based on:

 libpng 1.0 beta 6  version 0.96 May 28, 1997
 Updated and distributed by Andreas Dilger
 Copyright (c) 1996, 1997 Andreas Dilger

 libpng 1.0 beta 2 - version 0.88  January 26, 1996
 For conditions of distribution and use, see copyright
 notice in png.h. Copyright (c) 1995, 1996 Guy Eric
 Schalnat, Group 42, Inc.

 Updated/rewritten per request in the libpng FAQ
 Copyright (c) 1995, 1996 Frank J. T. Wojcik
 December 18, 1995 & January 20, 1996

I. Introduction

This file describes how to use and modify the PNG reference library
(known as libpng) for your own use.  There are five sections to this
file: introduction, structures, reading, writing, and modification and
configuration notes for various special platforms.  In addition to this
file, example.c is a good starting point for using the library, as
it is heavily commented and should include everything most people
will need.  We assume that libpng is already installed; see the
INSTALL file for instructions on how to install libpng.

Libpng was written as a companion to the PNG specification, as a way
of reducing the amount of time and effort it takes to support the PNG
file format in application programs.

The PNG specification (second edition), November 2003, is available as
a W3C Recommendation and as an ISO Standard (ISO/IEC 15948:2003 (E)) at
<http://www.w3.org/TR/2003/REC-PNG-20031110/
The W3C and ISO documents have identical technical content.

The PNG-1.2 specification is available at
<http://www.libpng.org/pub/png/documents/>

The PNG-1.0 specification is available
as RFC 2083 <http://www.libpng.org/pub/png/documents/> and as a
W3C Recommendation <http://www.w3.org/TR/REC.png.html>. Some
additional chunks are described in the special-purpose public chunks
documents at <http://www.libpng.org/pub/png/documents/>.

Other information
about PNG, and the latest version of libpng, can be found at the PNG home
page, <http://www.libpng.org/pub/png/>.

Most users will not have to modify the library significantly; advanced
users may want to modify it more.  All attempts were made to make it as
complete as possible, while keeping the code easy to understand.
Currently, this library only supports C.  Support for other languages
is being considered.

Libpng has been designed to handle multiple sessions at one time,
to be easily modifiable, to be portable to the vast majority of
machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
to use.  The ultimate goal of libpng is to promote the acceptance of
the PNG file format in whatever way possible.  While there is still
work to be done (see the TODO file), libpng should cover the
majority of the needs of its users.

Libpng uses zlib for its compression and decompression of PNG files.
Further information about zlib, and the latest version of zlib, can
be found at the zlib home page, <http://www.info-zip.org/pub/infozip/zlib/>.
The zlib compression utility is a general purpose utility that is
useful for more than PNG files, and can be used without libpng.
See the documentation delivered with zlib for more details.
You can usually find the source files for the zlib utility wherever you
find the libpng source files.

Libpng is thread safe, provided the threads are using different
instances of the structures.  Each thread should have its own
png_struct and png_info instances, and thus its own image.
Libpng does not protect itself against two threads using the
same instance of a structure.  Note: thread safety may be defeated
by use of some of the MMX assembler code in pnggccrd.c, which is only
compiled when the user defines PNG_THREAD_UNSAFE_OK.

II. Structures

There are two main structures that are important to libpng, png_struct
and png_info.  The first, png_struct, is an internal structure that
will not, for the most part, be used by a user except as the first
variable passed to every libpng function call.

The png_info structure is designed to provide information about the
PNG file.  At one time, the fields of png_info were intended to be
directly accessible to the user.  However, this tended to cause problems
with applications using dynamically loaded libraries, and as a result
a set of interface functions for png_info (the png_get_*() and png_set_*()
functions) was developed.  The fields of png_info are still available for
older applications, but it is suggested that applications use the new
interfaces if at all possible.

Applications that do make direct access to the members of png_struct (except
for png_ptr->jmpbuf) must be recompiled whenever the library is updated,
and applications that make direct access to the members of png_info must
be recompiled if they were compiled or loaded with libpng version 1.0.6,
in which the members were in a different order.  In version 1.0.7, the
members of the png_info structure reverted to the old order, as they were
in versions 0.97c through 1.0.5.  Starting with version 2.0.0, both
structures are going to be hidden, and the contents of the structures will
only be accessible through the png_get/png_set functions.

The png.h header file is an invaluable reference for programming with libpng.
And while I'm on the topic, make sure you include the libpng header file:

#include <png.h>

III. Reading

We'll now walk you through the possible functions to call when reading
in a PNG file sequentially, briefly explaining the syntax and purpose
of each one.  See example.c and png.h for more detail.  While
progressive reading is covered in the next section, you will still
need some of the functions discussed in this section to read a PNG
file.

Setup

You will want to do the I/O initialization(*) before you get into libpng,
so if it doesn't work, you don't have much to undo.  Of course, you
will also want to insure that you are, in fact, dealing with a PNG
file.  Libpng provides a simple check to see if a file is a PNG file.
To use it, pass in the first 1 to 8 bytes of the file to the function
png_sig_cmp(), and it will return 0 if the bytes match the corresponding
bytes of the PNG signature, or nonzero otherwise.  Of course, the more bytes
you pass in, the greater the accuracy of the prediction.

If you are intending to keep the file pointer open for use in libpng,
you must ensure you don't read more than 8 bytes from the beginning
of the file, and you also have to make a call to png_set_sig_bytes_read()
with the number of bytes you read from the beginning.  Libpng will
then only check the bytes (if any) that your program didn't read.

(*): If you are not using the standard I/O functions, you will need
to replace them with custom functions.  See the discussion under
Customizing libpng.


    FILE *fp = fopen(file_name, "rb");
    if (!fp)
    {
        return (ERROR);
    }
    fread(header, 1, number, fp);
    is_png = !png_sig_cmp(header, 0, number);
    if (!is_png)
    {
        return (NOT_PNG);
    }


Next, png_struct and png_info need to be allocated and initialized.  In
order to ensure that the size of these structures is correct even with a
dynamically linked libpng, there are functions to initialize and
allocate the structures.  We also pass the library version, optional
pointers to error handling functions, and a pointer to a data struct for
use by the error functions, if necessary (the pointer and functions can
be NULL if the default error handlers are to be used).  See the section
on Changes to Libpng below regarding the old initialization functions.
The structure allocation functions quietly return NULL if they fail to
create the structure, so your application should check for that.

    png_structp png_ptr = png_create_read_struct
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn);
    if (!png_ptr)
        return (ERROR);

    png_infop info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr)
    {
        png_destroy_read_struct(&png_ptr,
           (png_infopp)NULL, (png_infopp)NULL);
        return (ERROR);
    }

    png_infop end_info = png_create_info_struct(png_ptr);
    if (!end_info)
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
          (png_infopp)NULL);
        return (ERROR);
    }

If you want to use your own memory allocation routines,
define PNG_USER_MEM_SUPPORTED and use
png_create_read_struct_2() instead of png_create_read_struct():

    png_structp png_ptr = png_create_read_struct_2
       (PNG_LIBPNG_VER_STRING, (png_voidp)user_error_ptr,
        user_error_fn, user_warning_fn, (png_voidp)
        user_mem_ptr, user_malloc_fn, user_free_fn);

The error handling routines passed to png_create_read_struct()
and the memory alloc/free routines passed to png_create_struct_2()
are only necessary if you are not using the libpng supplied error
handling and memory alloc/free functions.

When libpng encounters an error, it expects to longjmp back
to your routine.  Therefore, you will need to call setjmp and pass
your png_jmpbuf(png_ptr).  If you read the file from different
routines, you will need to update the jmpbuf field every time you enter
a new routine that will call a png_*() function.

See your documentation of setjmp/longjmp for your compiler for more
information on setjmp/longjmp.  See the discussion on libpng error
handling in the Customizing Libpng section below for more information
on the libpng error handling.  If an error occurs, and libpng longjmp's
back to your setjmp, you will want to call png_destroy_read_struct() to
free any memory.

    if (setjmp(png_jmpbuf(png_ptr)))
    {
        png_destroy_read_struct(&png_ptr, &info_ptr,
           &end_info);
        fclose(fp);
        return (ERROR);
    }

If you would rather avoid the complexity of setjmp/longjmp issues,
you can compile libpng with PNG_SETJMP_NOT_SUPPORTED, in which case
errors will result in a call to PNG_ABORT() which defaults to abort().

Now you need to set up the input code.  The default for libpng is to
use the C function fread().  If you use this, you will need to pass a
valid FILE * in the function png_init_io().  Be sure that the file is
opened in binary mode.  If you wish to handle reading data in another
way, you need not call the png_init_io() function, but you must then
implement the libpng I/O methods discussed in the Customizing Libpng
section below.

    png_init_io(png_ptr, fp);

If you had previously opened the file and read any of the signature from
the beginning in order to see if this was a PNG file, you need to let
libpng know that there are some bytes missing from the start of the file.

    png_set_sig_bytes(png_ptr, number);

Setting up callback code

You can set up a callback function to handle any unknown chunks in the
input stream. You must supply the function

    read_chunk_callback(png_ptr ptr,
         png_unknown_chunkp chunk);
    {
       /* The unknown chunk structure contains your
          chunk data: */
           png_byte name[5];
           png_byte *data;
           png_size_t size;
       /* Note that libpng has already taken care of
          the CRC handling */

       /* put your code here.  Return one of the
          following: */

       return (-n); /* chunk had an error */
       return (0); /* did not recognize */
       return (n); /* success */
    }

(You can give your function another name that you like instead of
"read_chunk_callback")

To inform libpng about your function, use

    png_set_read_user_chunk_fn(png_ptr, user_chunk_ptr,
        read_chunk_callback);

This names not only the callback function, but also a user pointer that
you can retrieve with

    png_get_user_chunk_ptr(png_ptr);

At this point, you can set up a callback function that will be
called after each row has been read, which you can use to control
a progress meter or the like.  It's demonstrated in pngtest.c.
You must supply a function

    void read_row_callback(png_ptr ptr, png_uint_32 row,
       int pass);
    {
      /* put your code here */
    }

(You can give it another name that you like instead of "read_row_callback")

To inform libpng about your function, use

    png_set_read_status_fn(png_ptr, read_row_callback);

Width and height limits

The PNG specification allows the width and height of an image to be as
large as 2^31-1 (0x7fffffff), or about 2.147 billion rows and columns.
Since very few applications really need to process such large images,
we have imposed an arbitrary 1-million limit on rows and columns.
Larger images will be rejected immediately with a png_error() call. If
you wish to override this limit, you can use

   png_set_user_limits(png_ptr, width_max, height_max);

to set your own limits, or use width_max = height_max = 0x7fffffffL
to allow all valid dimensions (libpng may reject some very large images
anyway because of potential buffer overflow conditions).

You should put this statement after you create the PNG structure and
before calling png_read_info(), png_read_png(), or png_process_data().
If you need to retrieve the limits that are being applied, use

   width_max = png_get_user_width_max(png_ptr);
   height_max = png_get_user_height_max(png_ptr);

Unknown-chunk handling

Now you get to set the way the library processes unknown chunks in the
input PNG stream. Both known and unknown chunks will be read.  Normal
behavior is that known chunks will be parsed into information in
various info_ptr members; unknown chunks will be discarded. To change
this, you can call:

    png_set_keep_unknown_chunks(png_ptr, keep,
        chunk_list, num_chunks);
    keep       - 0: do not handle as unknown
                 1: do not keep
                 2: keep only if safe-to-copy
                 3: keep even if unsafe-to-copy
               You can use these definitions:
                 PNG_HANDLE_CHUNK_AS_DEFAULT   0
                 PNG_HANDLE_CHUNK_NEVER        1
                 PNG_HANDLE_CHUNK_IF_SAFE      2
                 PNG_HANDLE_CHUNK_ALWAYS       3
    chunk_list - list of chunks affected (a byte string,
                 five bytes per chunk, NULL or '\0' if
                 num_chunks is 0)
    num_chunks - number of chunks affected; if 0, all
                 unknown chunks are affected.  If nonzero,
                 only the chunks in the list are affected

Unknown chunks declared in this way will be saved as raw data onto a
list of png_unknown_chunk structures.  If a chunk that is normally
known to libpng is named in the list, it will be handled as unknown,
according to the "keep" directive.  If a chunk is named in successive
instances of png_set_keep_unknown_chunks(), the final instance will
take precedence.  The IHDR and IEND chunks should not be named in
chunk_list; if they are, libpng will process them normally anyway.

The high-level read interface

At this point there are two ways to proceed; through the high-level
read interface, or through a sequence of low-level read operations.
You can use the high-level interface if (a) you are willing to read
the entire image into memory, and (b) the input transformations
you want to do are limited to the following set:

    PNG_TRANSFORM_IDENTITY      No transformation
    PNG_TRANSFORM_STRIP_16      Strip 16-bit samples to
                                8 bits
    PNG_TRANSFORM_STRIP_ALPHA   Discard the alpha channel
    PNG_TRANSFORM_PACKING       Expand 1, 2 and 4-bit
                                samples to bytes
    PNG_TRANSFORM_PACKSWAP      Change order of packed
                                pixels to LSB first
    PNG_TRANSFORM_EXPAND        Perform set_expand()
    PNG_TRANSFORM_INVERT_MONO   Invert monochrome images
    PNG_TRANSFORM_SHIFT         Normalize pixels to the
                                sBIT depth
    PNG_TRANSFORM_BGR           Flip RGB to BGR, RGBA
                                to BGRA
    PNG_TRANSFORM_SWAP_ALPHA    Flip RGBA to ARGB or GA
                                to AG
    PNG_TRANSFORM_INVERT_ALPHA  Change alpha from opacity
                                to transparency
    PNG_TRANSFORM_SWAP_ENDIAN   Byte-swap 16-bit samples

(This excludes setting a background color, doing gamma transformation,
dithering, and setting filler.)  If this is the case, simply do this:

    png_read_png(png_ptr, info_ptr, png_transforms, NULL)

where png_transforms is an integer containing the logical OR of
some set of transformation flags.  This call is equivalent to png_read_info(),
followed the set of transformations indicated by the transform mask,
then png_read_image(), and finally png_read_end().

(The final parameter of this call is not yet used.  Someday it might point
to transformation parameters required by some future input transform.)

You must use png_transforms and not call any png_set_transform() functions
when you use png_read_png().

After you have called png_read_png(), you can retrieve the image data
with

   row_pointers = png_get_rows(png_ptr, info_ptr);

where row_pointers is an array of pointers to the pixel data for each row:

   png_bytep row_pointers[height];

If you know your image size and pixel size ahead of time, you can allocate
row_pointers prior to calling png_read_png() with

   if (height > PNG_UINT_32_MAX/png_sizeof(png_byte))
      png_error (png_ptr,
         "Image is too tall to process in memory");
   if (width > PNG_UINT_32_MAX/pixel_size)
      png_error (png_ptr,
         "Image is too wide to process in memory");
   row_pointers = png_malloc(png_ptr,
      height*png_sizeof(png_bytep));
   for (int i=0; i<height, i++)
      row_pointers[i]=png_malloc(png_ptr,
         width*pixel_size);
   png_set_rows(png_ptr, info_ptr, &row_pointers);

Alternatively you could allocate your image in one big block and define
row_pointers[i] to point into the proper places in your block.

If you use png_set_rows(), the application is responsible for freeing
row_pointers (and row_pointers[i], if they were separately allocated).

If you don't allocate row_pointers ahead of time, png_read_png() will
do it, and it'll be free'ed when you call png_destroy_*().

The low-level read interface

If you are going the low-level route, you are now ready to read all
the file information up to the actual image data.  You do this with a
call to png_read_info().

    png_read_info(png_ptr, info_ptr);

This will process all chunks up to but not including the image data.

Querying the info structure

Functions are used to get the information from the info_ptr once it
has been read.  Note that these fields may not be completely filled
in until png_read_end() has read the chunk data following the image.

    png_get_IHDR(png_ptr, info_ptr, &width, &height,
       &bit_depth, &color_type, &interlace_type,
       &compression_type, &filter_method);

    width          - holds the width of the image
                     in pixels (up to 2^31).
    height         - holds the height of the image
                     in pixels (up to 2^31).
    bit_depth      - holds the bit depth of one of the
                     image channels.  (valid values are
                     1, 2, 4, 8, 16 and depend also on
                     the color_type.  See also
                     significant bits (sBIT) below).
    color_type     - describes which color/alpha channels
                         are present.
                     PNG_COLOR_TYPE_GRAY
                        (bit depths 1, 2, 4, 8, 16)
                     PNG_COLOR_TYPE_GRAY_ALPHA
                        (bit depths 8, 16)
                     PNG_COLOR_TYPE_PALETTE
                        (bit depths 1, 2, 4, 8)
                     PNG_COLOR_TYPE_RGB
                        (bit_depths 8, 16)
                     PNG_COLOR_TYPE_RGB_ALPHA
                        (bit_depths 8, 16)

                     PNG_COLOR_MASK_PALETTE
                     PNG_COLOR_MASK_COLOR
                     PNG_COLOR_MASK_ALPHA

    filter_method  - (must be PNG_FILTER_TYPE_BASE
                     for PNG 1.0, and can also be
                     PNG_INTRAPIXEL_DIFFERENCING if
                     the PNG datastream is embedded in
                     a MNG-1.0 datastream)
    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
                     for PNG 1.0)
    interlace_type - (PNG_INTERLACE_NONE or
                     PNG_INTERLACE_ADAM7)
    Any or all of interlace_type, compression_type, of
    filter_method can be NULL if you are
    not interested in their values.

    channels = png_get_channels(png_ptr, info_ptr);
    channels       - number of channels of info for the
                     color type (valid values are 1 (GRAY,
                     PALETTE), 2 (GRAY_ALPHA), 3 (RGB),
                     4 (RGB_ALPHA or RGB + filler byte))
    rowbytes = png_get_rowbytes(png_ptr, info_ptr);
    rowbytes       - number of bytes needed to hold a row

    signature = png_get_signature(png_ptr, info_ptr);
    signature      - holds the signature read from the
                     file (if any).  The data is kept in
                     the same offset it would be if the
                     whole signature were read (i.e. if an
                     application had already read in 4
                     bytes of signature before starting
                     libpng, the remaining 4 bytes would
                     be in signature[4] through signature[7]
                     (see png_set_sig_bytes())).


    width            = png_get_image_width(png_ptr,
                         info_ptr);
    height           = png_get_image_height(png_ptr,
                         info_ptr);
    bit_depth        = png_get_bit_depth(png_ptr,
                         info_ptr);
    color_type       = png_get_color_type(png_ptr,
                         info_ptr);
    filter_method    = png_get_filter_type(png_ptr,
                         info_ptr);
    compression_type = png_get_compression_type(png_ptr,
                         info_ptr);
    interlace_type   = png_get_interlace_type(png_ptr,
                         info_ptr);


These are also important, but their validity depends on whether the chunk
has been read.  The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
data has been read, or zero if it is missing.  The parameters to the
png_get_<chunk> are set directly if they are simple data types, or a pointer
into the info_ptr is returned for any complex types.

    png_get_PLTE(png_ptr, info_ptr, &palette,
                     &num_palette);
    palette        - the palette for the file
                     (array of png_color)
    num_palette    - number of entries in the palette

    png_get_gAMA(png_ptr, info_ptr, &gamma);
    gamma          - the gamma the file is written
                     at (PNG_INFO_gAMA)

    png_get_sRGB(png_ptr, info_ptr, &srgb_intent);
    srgb_intent    - the rendering intent (PNG_INFO_sRGB)
                     The presence of the sRGB chunk
                     means that the pixel data is in the
                     sRGB color space.  This chunk also
                     implies specific values of gAMA and
                     cHRM.

    png_get_iCCP(png_ptr, info_ptr, &name,
       &compression_type, &profile, &proflen);
    name            - The profile name.
    compression     - The compression type; always
                      PNG_COMPRESSION_TYPE_BASE for PNG 1.0.
                      You may give NULL to this argument to
                      ignore it.
    profile         - International Color Consortium color
                      profile data. May contain NULs.
    proflen         - length of profile data in bytes.

    png_get_sBIT(png_ptr, info_ptr, &sig_bit);
    sig_bit        - the number of significant bits for
                     (PNG_INFO_sBIT) each of the gray,
                     red, green, and blue channels,
                     whichever are appropriate for the
                     given color type (png_color_16)

    png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans,
                     &trans_values);
    trans          - array of transparent entries for
                     palette (PNG_INFO_tRNS)
    trans_values   - graylevel or color sample values of
                     the single transparent color for
                     non-paletted images (PNG_INFO_tRNS)
    num_trans      - number of transparent entries
                     (PNG_INFO_tRNS)

    png_get_hIST(png_ptr, info_ptr, &hist);
                     (PNG_INFO_hIST)
    hist           - histogram of palette (array of
                     png_uint_16)

    png_get_tIME(png_ptr, info_ptr, &mod_time);
    mod_time       - time image was last modified
                    (PNG_VALID_tIME)

    png_get_bKGD(png_ptr, info_ptr, &background);
    background     - background color (PNG_VALID_bKGD)
                     valid 16-bit red, green and blue
                     values, regardless of color_type

    num_comments   = png_get_text(png_ptr, info_ptr,
                     &text_ptr, &num_text);
    num_comments   - number of comments
    text_ptr       - array of png_text holding image
                     comments
    text_ptr[i].compression - type of compression used
                 on "text" PNG_TEXT_COMPRESSION_NONE
                           PNG_TEXT_COMPRESSION_zTXt
                           PNG_ITXT_COMPRESSION_NONE
                           PNG_ITXT_COMPRESSION_zTXt
    text_ptr[i].key   - keyword for comment.  Must contain
                         1-79 characters.
    text_ptr[i].text  - text comments for current
                         keyword.  Can be empty.
    text_ptr[i].text_length - length of text string,
                 after decompression, 0 for iTXt
    text_ptr[i].itxt_length - length of itxt string,
                 after decompression, 0 for tEXt/zTXt
    text_ptr[i].lang  - language of comment (empty
                         string for unknown).
    text_ptr[i].lang_key  - keyword in UTF-8
                         (empty string for unknown).
    num_text       - number of comments (same as
                     num_comments; you can put NULL here
                     to avoid the duplication)
    Note while png_set_text() will accept text, language,
    and translated keywords that can be NULL pointers, the
    structure returned by png_get_text will always contain
    regular zero-terminated C strings.  They might be
    empty strings but they will never be NULL pointers.

    num_spalettes = png_get_sPLT(png_ptr, info_ptr,
       &palette_ptr);
    palette_ptr    - array of palette structures holding
                     contents of one or more sPLT chunks
                     read.
    num_spalettes  - number of sPLT chunks read.

    png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y,
       &unit_type);
    offset_x       - positive offset from the left edge
                     of the screen
    offset_y       - positive offset from the top edge
                     of the screen
    unit_type      - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER

    png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y,
       &unit_type);
    res_x          - pixels/unit physical resolution in
                     x direction
    res_y          - pixels/unit physical resolution in
                     x direction
    unit_type      - PNG_RESOLUTION_UNKNOWN,
                     PNG_RESOLUTION_METER

    png_get_sCAL(png_ptr, info_ptr, &unit, &width,
       &height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                 (width and height are doubles)

    png_get_sCAL_s(png_ptr, info_ptr, &unit, &width,
       &height)
    unit        - physical scale units (an integer)
    width       - width of a pixel in physical scale units
    height      - height of a pixel in physical scale units
                 (width and height are strings like "2.54")

    num_unknown_chunks = png_get_unknown_chunks(png_ptr,
       info_ptr, &unknowns)
    unknowns          - array of png_unknown_chunk
                        structures holding unknown chunks
    unknowns[i].name  - name of unknown chunk
    unknowns[i].data  - data of unknown chunk
    unknowns[i].size  - size of unknown chunk's data
    unknowns[i].location - position of chunk in file

    The value of "i" corresponds to the order in which the
    chunks were read from the PNG file or inserted with the
    png_set_unknown_chunks() function.

The data from the pHYs chunk can be retrieved in several convenient
forms:

    res_x = png_get_x_pixels_per_meter(png_ptr,
       info_ptr)
    res_y = png_get_y_pixels_per_meter(png_ptr,
       info_ptr)
    res_x_and_y = png_get_pixels_per_meter(png_ptr,
       info_ptr)
    res_x = png_get_x_pixels_per_inch(png_ptr,
       info_ptr)
    res_y = png_get_y_pixels_per_inch(png_ptr,
       info_ptr)
    res_x_and_y = png_get_pixels_per_inch(png_ptr,
       info_ptr)
    aspect_ratio = png_get_pixel_aspect_ratio(png_ptr,
       info_ptr)

   (Each of these returns 0 [signifying "unknown"] if
       the data is not present or if res_x is 0;
       res_x_and_y is 0 if res_x != res_y)

The data from the oFFs chunk can be retrieved in several convenient
forms:

    x_offset = png_get_x_offset_microns(png_ptr, info_ptr);
    y_offset = png_get_y_offset_microns(png_ptr, info_ptr);
    x_offset = png_get_x_offset_inches(png_ptr, info_ptr);
    y_offset = png_get_y_offset_inches(png_ptr, info_ptr);

   (Each of these returns 0 [signifying "unknown" if both
       x and y are 0] if the data is not present or if the
       chunk is present but the unit is the pixel)

For more information, see the png_info definition in png.h and the
PNG specification for chunk contents.  Be careful with trusting
rowbytes, as some of the transformations could increase the space
needed to hold a row (expand, filler, gray_to_rgb, etc.).
See png_read_update_info(), below.

A quick word about text_ptr and num_text.  PNG stores comments in
keyword/text pairs, one pair per chunk, with no limit on the number
of text chunks, and a 2^31 byte limit on their size.  While there are
suggested keywords, there is no requirement to restrict the use to these
strings.  It is strongly suggested that keywords and text be sensible
to humans (that's the point), so don't use abbreviations.  Non-printing
symbols are not allowed.  See the PNG specification for more details.
There is also no requirement to have text after the keyword.

Keywords should be limited to 79 Latin-1 characters without leading or
trailing spaces, but non-consecutive spaces are allowed within the
keyword.  It is possible to have the same keyword any number of times.
The text_ptr is an array of png_text structures, each holding a
pointer to a language string, a pointer to a keyword and a pointer to
a text string.  The text string, language code, and translated
keyword may be empty or NULL pointers.  The keyword/text
pairs are put into the array in the order that they are received.
However, some or all of the text chunks may be after the image, so, to
make sure you have read all the text chunks, don't mess with these
until after you read the stuff after the image.  This will be
mentioned again below in the discussion that goes with png_read_end().

Input transformations

After you've read the header information, you can set up the library
to handle any special transformations of the image data.  The various
ways to transform the data will be described in the order that they
should occur.  This is important, as some of these change the color
type and/or bit depth of the data, and some others only work on
certain color types and bit depths.  Even though each transformation
checks to see if it has data that it can do something with, you should
make sure to only enable a transformation if it will be valid for the
data.  For example, don't swap red and blue on grayscale data.

The colors used for the background and transparency values should be
supplied in the same format/depth as the current image data.  They
are stored in the same format/depth as the image data in a bKGD or tRNS
chunk, so this is what libpng expects for this data.  The colors are
transformed to keep in sync with the image data when an application
calls the png_read_update_info() routine (see below).

Data will be decoded into the supplied row buffers packed into bytes
unless the library has been told to transform it into another format.
For example, 4 bit/pixel paletted or grayscale data will be returned
2 pixels/byte with the leftmost pixel in the high-order bits of the
byte, unless png_set_packing() is called.  8-bit RGB data will be stored
in RGB RGB RGB format unless png_set_filler() or png_set_add_alpha()
is called to insert filler bytes, either before or after each RGB triplet.
16-bit RGB data will be returned RRGGBB RRGGBB, with the most significant
byte of the color value first, unless png_set_strip_16() is called to
transform it to regular RGB RGB triplets, or png_set_filler() or
png_set_add alpha() is called to insert filler bytes, either before or
after each RRGGBB triplet.  Similarly, 8-bit or 16-bit grayscale data can
be modified with
png_set_filler(), png_set_add_alpha(), or png_set_strip_16().

The following code transforms grayscale images of less than 8 to 8 bits,
changes paletted images to RGB, and adds a full alpha channel if there is
transparency information in a tRNS chunk.  This is most useful on
grayscale images with bit depths of 2 or 4 or if there is a multiple-image
viewing application that wishes to treat all images in the same way.

    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb(png_ptr);

    if (color_type == PNG_COLOR_TYPE_GRAY &&
        bit_depth < 8) png_set_gray_1_2_4_to_8(png_ptr);

    if (png_get_valid(png_ptr, info_ptr,
        PNG_INFO_tRNS)) png_set_tRNS_to_alpha(png_ptr);

These three functions are actually aliases for png_set_expand(), added
in libpng version 1.0.4, with the function names expanded to improve code
readability.  In some future version they may actually do different
things.

PNG can have files with 16 bits per channel.  If you only can handle
8 bits per channel, this will strip the pixels down to 8 bit.

    if (bit_depth == 16)
        png_set_strip_16(png_ptr);

If, for some reason, you don't need the alpha channel on an image,
and you want to remove it rather than combining it with the background
(but the image author certainly had in mind that you *would* combine
it with the background, so that's what you should probably do):

    if (color_type & PNG_COLOR_MASK_ALPHA)
        png_set_strip_alpha(png_ptr);

In PNG files, the alpha channel in an image
is the level of opacity.  If you need the alpha channel in an image to
be the level of transparency instead of opacity, you can invert the
alpha channel (or the tRNS chunk data) after it's read, so that 0 is
fully opaque and 255 (in 8-bit or paletted images) or 65535 (in 16-bit
images) is fully transparent, with

    png_set_invert_alpha(png_ptr);

PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
they can, resulting in, for example, 8 pixels per byte for 1 bit
files.  This code expands to 1 pixel per byte without changing the
values of the pixels:

    if (bit_depth < 8)
        png_set_packing(png_ptr);

PNG files have possible bit depths of 1, 2, 4, 8, and 16.  All pixels
stored in a PNG image have been "scaled" or "shifted" up to the next
higher possible bit depth (e.g. from 5 bits/sample in the range [0,31] to
8 bits/sample in the range [0, 255]).  However, it is also possible to
convert the PNG pixel data back to the original bit depth of the image.
This call reduces the pixels back down to the original bit depth:

    png_color_8p sig_bit;

    if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
        png_set_shift(png_ptr, sig_bit);

PNG files store 3-color pixels in red, green, blue order.  This code
changes the storage of the pixels to blue, green, red:

    if (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
        png_set_bgr(png_ptr);

PNG files store RGB pixels packed into 3 or 6 bytes. This code expands them
into 4 or 8 bytes for windowing systems that need them in this format:

    if (color_type == PNG_COLOR_TYPE_RGB)
        png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);

where "filler" is the 8 or 16-bit number to fill with, and the location is
either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
you want the filler before the RGB or after.  This transformation
does not affect images that already have full alpha channels.  To add an
opaque alpha channel, use filler=0xff or 0xffff and PNG_FILLER_AFTER which
will generate RGBA pixels.

Note that png_set_filler() does not change the color type.  If you want
to do that, you can add a true alpha channel with

    if (color_type == PNG_COLOR_TYPE_RGB ||
           color_type == PNG_COLOR_TYPE_GRAY)
    png_set_add_alpha(png_ptr, filler, PNG_FILLER_AFTER);

where "filler" contains the alpha value to assign to each pixel.
This function was added in libpng-1.2.7.

If you are reading an image with an alpha channel, and you need the
data as ARGB instead of the normal PNG format RGBA:

    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
        png_set_swap_alpha(png_ptr);

For some uses, you may want a grayscale image to be represented as
RGB.  This code will do that conversion:

    if (color_type == PNG_COLOR_TYPE_GRAY ||
        color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
          png_set_gray_to_rgb(png_ptr);

Conversely, you can convert an RGB or RGBA image to grayscale or grayscale
with alpha.

    if (color_type == PNG_COLOR_TYPE_RGB ||
        color_type == PNG_COLOR_TYPE_RGB_ALPHA)
          png_set_rgb_to_gray_fixed(png_ptr, error_action,
             int red_weight, int green_weight);

    error_action = 1: silently do the conversion
    error_action = 2: issue a warning if the original
                      image has any pixel where
                      red != green or red != blue
    error_action = 3: issue an error and abort the
                      conversion if the original
                      image has any pixel where
                      red != green or red != blue

    red_weight:       weight of red component times 100000
    green_weight:     weight of green component times 100000
                      If either weight is negative, default
                      weights (21268, 71514) are used.

If you have set error_action = 1 or 2, you can
later check whether the s el wheretext  you haCOLOtor_typ texttivew*ou have set_expand(), addedall        le ding the scolor_ty5g_ptr, irt thetr, &medall_r for21268, rsionyyou nor graght is negativthe
vE
, addency instead of opK     the RGB = 1: sileng_create_infoes, png_een_weight:8, 715vthpng_een_weight:8,uonyyou nor gCq_ptr);

    ifou want
to do a
list of pnote that png_set_fillemedaley
  can set up or 6553 = 1 or ller byte
 if t modifiissueoon th(ca   yte without changing to assiy
  can alloces);

PNG files _set_filler  png_set_r
cation is
either PNG_FILLER_BEFORE or PNG_FILLER_AFTER,,
     (er PNG_FILL
un to each pW  srgb_inte
set up or 65rt an RG rsionyyou norg_create_infoes, the s     ithersdo a
list of pnote1colng_get_cha    in ptr);

Conversely, you fysicaat it care == Pou mapng_ptr, info_pttls packed into 3 oinfo_pttls packed lFORM_SWAP_ENDIAN   B) modifii)
e 65rt ans to 1     thee 65
illemfault
    H== PNG_COLOR_TYPE_RGB_ALPHA)
        png_set_swap_alph   weight eiIckedoOR_TY+ up totheo_ptl-color p;e
      ;kedoOR_TY+ 9
      pessionD||
   0F=LL
un togs.  ThiinfoesU=Mt of p
 packed into 3 oinfo_pdefine PNG
aa togs.  (Usion if_Arpng_ee+ 9
      pess_o3 oinfo_alph   weighannel  norr    pghts (212olor_typed translte
stion =eP_ptr, &unit, &   let_fof the
by= 1: sithe su mapng_ptrCnorr ams packed65
illem  pngstoreped trages in the safened the_ptrCnt  you haC          (212olors    &heightor_reped the        PrCnt  yF "filler" isb.r
you want
                  and 1k daoes, pngs importRGB_ALPHA)
 (you want
   r_inch(png_pt(212olorsn = 1 or 2, 8ured != blue
      (212olors    &heightoEsform it to regulae_SWA12olox)
  very fe &width,
    -terminated C strin)x)
  very fe &width,
    -termion
calls the pne su mapusnks  r_inch(png,
    -teraa, &   eight of r: silenon
calls the pne saoes,  negado   rea212olors    &ontainlTscale im a PNG image hysicaatir 2, 8uer a(png_ptr);
of pnlors  ivthe
vE
, dle im a trin)x)"uc           (png_ptr,
     16mse(fp);
 a widto (212olor_typed t,before o_    (arrm"uc  NG_COLOR_TYPE_Gee'ed whesform    calls them
yl

ller before the RGeight of rednversely   PNG_C
    -teraa, &   eight of r
s.

No
   eight ler     to 1 pixel perhe complon was 4a from the oFFt it to regulae_SWA12olox)   pessiowant
 comr PNG_Fht ler   etr,r you re png_LOR
 r);

Fo);
of Eo), pn    png_se  -teraa, &   ebort the
    etr,ro the way olox)
 Or widt
ilter8ueran al9r before the RGeight o
PNG fMNG_SETJ=ve tex let_fofYPE_Rof chunkore th to the or#h(png,

I 

ter8al9r before tho);
of = 3:SETJ=ve tex aaif_R);

For or if q (height > PNG_the range  ul9r before te of alpha ch2 (arrm
e  graession, or thw wil
    - importRGB_ALaiht > P1you use pngng_geo    - iy    ss */
     aiht rs   r t7he       tr pC

I 

ter8al9aque ed in tng_LOR
 r);

Fo); res_ou need to retrieve s   rD or tRNSanowns)
  ro the wayg from t__TYPE_RGB_ALi

PNG can h5 bits   res    to 1 pixe
PNG fMNGtr);
ij bits      png_sbyte, png,
    -te] image to grayscale or gVset_sw     pe the pne suimage hled rhpng_te_to_rgb(png_prmat RGBA:

    if (ru liaj retriorder that tK_<chat tKiU*_text       - nsbyer" te_to_rgb(p num_spalor thw,i.!fL of gAMA aetrans
 chunk_l orry fe      (width ed the lT); /* succ

Fo);
opng_sethe lru lio_rgb(p re b(p reAF4tr,
       in(width ed th3rcale image  (yol image

No
fo_ptr, &braesswill always coP_ptr, Vset_sw     pe_lly transparen  pn;ata in by_ptr, Vset_sw )o pess.          hem
into 4 lid FILcOR_TYPE_       - tin by_ptrt ofCpng== PNG8pne suLnto 4or#6
all a in .[ 4f sync wthe ra(in nip   "Imagis code w
erau wande w
erarht poforfh     )o pess.      ent ti_
    ifou want
to do a
list of pno the   rs   ixpands to 1 pixel
alor  one a
lita.  T widto (rieve s   rD, infiFny ot
pairs MNGtr);:rmion
calls the pne su mapusnks  r_ins the pne No
  d      psted in th
trangelOoint)E MNGtr);:rmionpne su mapusnks ON_zTX_COLOcan set uUsionu mapusnks  r_insur: sipixel in p    if
beforeVN_NONE
   .ex aaif_R);..pne s sh    added in lo tho    iholds the &medersxel innnnnnnnitypelibrary
to handle any speciallo tho    ihols res_y =       ng_een_ 

ter8al9r orgbxel in p    o the next
higher po te o/alpha    =       ng_ee     ig_ee     ichunkore th tof, keep is to b   ichunkoro
  d oesU=of time, youo/alpha lita.  T widt isb.dth_max = of ti          (PNG_INFO_sBP, &baof ti       l9r  next
hiy_to_rgbidt isb.dtidt iNONE
 mment
d as
RGB.  This code wilvT ared images) o_rows(png_ptr,.lors    &hei small as
theye,_n 8 to 8 bits,
changes paletted images to RG      - width ogstoreped t 2^31 bt
hiy_to- the ga          o h2t up e  ul9r sange  ul9r bpfecutive nsparency valueUsparency valSa limitsore inforE5Irga    ller betidis formation had already g_ptr,.lors  iVu cander thatSIrga    llalueUsparendAS_DEf chunkore tLd to itsoolds theucc

Fo)mX_COLor 1  dnt bitser of sPLT  reowing co-tra T ayscale or g]sparre th tof    i_ptr, V

ter8alaysc (se_rows(pShold(Cy
are bto itsF4tr,ixel
alor  onea
list of pno th31 byte tuSgb(png_prmt or n_BEFORE or PpessionD|, youo/at ti_
    ifou YPE_RGels = pnlls the pne )tsF4tr,ixel
could incug;Ppe  you haCOLOtor_ow).
    color_type     - describes which color/alpha channels
                         are prealphia_prmt or n_n is
eit pneow).
   cct of pR..    s them
y     e,_n 8 to 8 sl be
mentiosame formas
o8 to 8 ble any ned again below in thet_fixch eo_rgbw).

p   res_xha ch if
befol whery_ptr ones(png_ptr,.land 16.mage  ca (riemay be after t
u want
     w).
 ned  imar: smage  ca.ex aaif_R);..pn.max = of ofile         - International Color Conon up to theist of pnor=0xff or pne )tsF4tr, or Consorti  tr pC

I  theist of pnor=0xff or pne )tsF4tr,        )d row_poin       PNGin lo
PNG fM  ccters o  png_se _valuen't ne o  png_sepe ==ing t_text   num_cpixelLOcanfeywordt_IHD pne ) code
reada for ()
or red != bl            PNG
     as      pFORederithe nextarenrnkspe AFTER); closes array oavag_L  ured != gand 16. 4 bifaisyncweRGBA:


op  mn =eP  - widt_error aisyncbadl be par hysicaatir pnlb        , & type dt
ilter8u by_ptr,lormal
pixelmaximoffsew   o
fo_ptr, p to 2NGin lo              _sw    hunkore th to tntentlLOcanfeywwher
maximoffsew   ,ixel
couthe alphCOMPRESSIscard the NG8pif (pnckin
rd.

Keth eig - arhoicream      in ot
pairs th to ,ixel
couthe alno
COMPRESSIscardofYPE_Ro    s     aa job.max = of a PNG image have been "scalebeen y_to- the ga ng_set_strip_alpha(png_ptr);

In PNG files, tthe alpha namenon up to{
 PNG_ITXT_COMPRESSIOp_COMPRESSIO bt
hi;

 PNG_ITXT_COMNONE
                      lng_get_cha  &COMPRESSING_TEXT_COMPode
reada for (          - The cthis argumen lng_get_cha  maxRGB.  Thsew   o
COMPRESSIsc1NG_TEXT_C}_TEXT_C  tr pC

I {
 PNG_ITXT_COMxt);
  tdaaif_R)nlb [MAX th3rcaebeen S] =lng_get_cha  {     _sw        };

 PNG_ITXT_COMreada for (          tdaaif_R)nlb  lng_get_cha  MAX th3rcaebeen S, MAX th3rcaebeen S,lng_get_cha  t
hi,0NG_TEXT_C}_TEX}G_COLOR_TYPEow).

Da transformat().
lB or1
    + up whery_pixe1
       .y may actually do diwap_alpher wPNG
  (cking
lB or1
     - ery_pixe1

+ ups
storet depths 1, 2, and &&          png_set_rgb_to_gray_fixed(png_t_shift(png_ptr, tranevel of opacitrror_action of bytes necolor/alpginal btrin)x)"uc    trin-;
ij brmt or:max = of a PNG imageof red component times 100000
    green_weight:     weight of green component timshift(png_ptr, tranevel of opacCOLOR_TYPE_GRAY)5 (in 
will genernet 4 biOLOR_Tmatioeptg-pha(an,
i ,ilor_type == PNG_uint_16 bit)red != green _filler() does not c       ncy vaescr(tertle-pha(an, ce_tytho _type == PNG_uint_16 bit
    rescr isE_GRAY)ta. ): of bit depths 1, 2, and 4 into bytes as smawaphey can, resul        (png_ptr_add_-
transp        4 or ou do"filler thel where
      (widGBA image te decode the colo
make_set_add_alpha()    color_oloset_bgr(png_ptr);

PNG files stor RGB pixels awaphey can, resF(png_p    color_ata.tely fiafterMAX/png_sizeof(_action insforb(p   PNG_xire al     t_eetsely fifh   = 16)
      PNG byere row_poi thei.!f
  png_set_shift(pnripletmmenrMAX/png__fnuld increase the riplerMAX/png__fn res    row_p    etr,ro (_actiong_set_    uriplerMAX/png__fnuld incr      he i        ase the re i    ,le for freeces t
 structua()t.cn thet. 4 bi tripr" isry fe ror_action =oesU=Mtlpha(plly ali For exampl the neor n_BEFORE or this format ans t careY don't alsoors are
d some others o of p           fromsG byely f
 thei.!for_actionl where
   origi
    s   res , 4, 8, neor n_BEF
r_action =oesUGBA image t                (seetransform itg_get_x_o(_actiong_set_t_micronsmmenrMAX/png__
             smmenncrease the  mment
em
yl mmen      (she wayg  mme'snes(png_ptr,,PE_Roer the cepth, &color_type, idth of      epeinterlagis nfo().e s sh    s, eithe of p         areY don't e your image some othviar,ro (_actiongr_inch(pnmmenrMAX/png__ncr()less png_set_f:g_set_    p ripletmmenrMAX/png__ncr =
NG_ITXT_COMNONEnmmenrMAX/png__ncr(vel of opacity     1byte, to keep inpng_sNFO_gAte,;PNG
     cNONE      ussion-bit g,
nto 

ller becthe backh31 byte tuthe  grayscalets   res   keep inh(pngtivthon whethINFO_gAMdYPE_GRAY_ALPH      _of_typee      - sPNG_INFO_gAMAkeep packed into 3 ois is re row_prd.  It is possible      Perlor_o.  Si, 8, nmited to
            PNGflwillgis eor n_BEFORE or what libpquage, sg_get_xis
 the= 16)
        png_set_s  Po.  Si,color_type     - d bacwed wit
OR_TYtnte  color_olopif (pn completely filled
info().= 16)
  (_actiongr  one so_o.  Si, 8, nmth to tmfault
  if_R);.parre th tof    epi.!fL of gAi)o pess.this forma);
   mfault
  ieach abNONd depend also ont.  Similarlmans (that's the poinow_pointerheight ofes, each holding a
pu don't allocatelgis
nfo().epoin       P of tth as the curr 65
iecificatif you 
rawiOLOR_plicationeighnt
thing
      windschannels.  (idth of ongpusn yF tra,
and you wans orgbg_set_f =oesU=Mt);
        , & .  The v of    PNG lormauage codraysc           PbuilR_TYP you use png_set_rows is respnto bored
in RGBany numng in, fhon whet need the ointer tREo), pnin one big his is what lidth      info().ld allocate adnt bits (sBIT) beTh, info_p pnges) o
        png_sePNG r_action ofls) is fullyset_he v of    enrned
nfo().e  P of tth a     i -teraa, &locatjr b
height ofes, e    png wher the lT)ap_alp  png_the backin one big  sepato 4o hunkorenfo().esetaimage to es are
c           Ptype iYP If you use png_set_rows is resp.acitrror_action autoFOREc     tuSgb(pn_sNFO_gAte,,tnte  co pixels pe
of time   - sPNG_INFO_gAMAkeep packxel pcthe barror_action a channe
n RG       n of co, 4, the ne formnens tip_1the image data, &hei.nsible foes, e    pnmans (tharead.  Note thatplaces in your block.onsible for freeing
row_pointers (and rY don't followof     ung spaed whha c     info_ptrfch
will g   - holds the wds to 1 pia              i -terA12ore pinto 3 oinpng_ptr, info, &heied != gr,ixel
couthe alnon_sNFO_gAte,f a    
               t:     signature were),      pnginfo_pr image size andnfo_ptr once iing
row_poinlocateease the       _of_nfo_per places in your block.
 it with a  hunkore  ofes, e    png ofls)esul        (d    bitk.
jr bePNG 5
ie_row

If you don't             is ttext_p in your bled != green  If you use  in your blor image sizr freeing
row_poi: siow;image size andnfoptr once iing
row_poilocate resul    profile dhINFO_gAMdY(               !=e orunkore    paren  pn8-bit 
ha cn, f.    paeote thatey translls the   h Sgain below innstead of 2)
_sNFO_gAte,f     values o
  (               t:     signature applica   as , f.    me   i     i2DdhINFO_gAMpara.  yo    th    dam7,co, 4
be akiles pa         dd_alith nchunkoro
can have fpusn-pripair, ba    les.  8x8 gricare    Perlor_t RGBring,.r
yocan haverer bits ranspta.  T wu do"a  hs".
r grayscalepta.        Brin,t into the two read_updd != bl   atey t data.  Theyle any ned again below ino
  d h(png,
nversion
 s    tvNGtr.r
yohe color    pavePE_Rof         ya c(any "R);.aext_"s   rD,)   erroholds ttSIrga (pngy       E for PNG r is
ypehe &medegrad     
smooem
iningg t_texthe colo
make presence  the n   rD, k.
 it "bytekt_"
   rD,, can athe colo
makdrawny tran remainin   peolor_typellemfault
 
ver,hen an applica
has been ha c     _sw    lter_methoLatinion =eP also a grayscheir hen an ae presence G r is   rD,         lookf time, ,
nto teB ||
  =Mt  varr, png_seto the _texthe colo  Ptuo hunkorenfo_   - holds the wds tos   res   keep inwhethINFO_gAeen ussion ,
jr beofls
ptr, info, &heieith ncn RG r 1 pia     the ith nc      winso don't us
 combini  as RGB Rpplicabyeitself     the stor the       b_sBP,les. 
8x8 gricormat    s ttext_ppplica(alturned
  graysit   ds    tob_sBER);

raysce headerfar time, aluene PNG
aa ts   reshINFO_gAMpkeep pacthey may  r is
ypeswap_alph   we        1/8 pngwide png_setta. r        (    y 8t embeumntheir val palettumnt0g wher1/8 pngm    png_setfiissueoo(    y 8t e5
ieheir val pal5
ie0No
fo_pseary
ed
in RGB1/8 pngwide
(heir val palettumnt4g wher1/8 pngm    (alsooreir val pal5
ie0Nesence 8-brds
ypeswap_aRGB1/4 pngwide (    y 4trsion
 sheir val palettumnt0g whe
1/8 pngm    (    y 8t e5
ieheir val pal5
ie4)    if (cof8, trsiypeswap_
RGB1/4 pngwide wher1/4 pngm    (    y 4t embeumntheir val palettumnt2code e    y 4t e5
ieheir val pal5
ie0Nesence G ftrsiypeswap_alph   we 
      1/2 pngwide, wher1/4 pngm    (heir val    metumnt0 wher5
ie2),
we put in ttxtrsiypeswap_ab  1/2 pngwide wher1/2 pngm    png_setfiissueoo(heir val palettumnt1 wher5
ie0Nesence ith nr_meter   peoiypeswap_ab  afMNGde png_setfiissueo, wher1/2 pngm   ,e suimagval  For exampl dd
      BP, &an hys winPhew!

r grayscaleps   res   h(png,
an applic ,
cthe barroso a grctheo th  - seir fes, e    png  t,befoes, each holding aset_bgr(png               t:     signature applica se the       _of_typee 
are set directly sPNG_INFO_gAMAkeep packed into 3 orrent imaglph   wge t          typee  any null nlls tho a
liisa   ith nuLnto ofYPGBA imape    the nhINFO_gAMp     i2: issu.citrror_action of b=Mtlpha(p th nc l    profile d    libpn_gAMd, placesi_swap_alph   wstringss)esul        (    gote, to alls the   if (bit_y aliases 
ypehento set_gote, to wailtip be
_setta. r       cepth,a    ,PNG8pnemage ekt_
ee wil= 16)
  ee will roras ali g,
an a  dsholds      ithe n   rD,a   exanks   it with) is fullyset s tnn    PN alls thPNG
aa t      _y aliases 
ypeheany "R);.aext_"see will roy_to_rl packesGder       time, alook       .y
s fully tranuses, you"bytekt_"see wil,
jr beofls_ptr, info, &heieaPpe stiolemfault
  8-brds
yMA and
ocate  st.

The colorsckingtype  vNGtr.       c      _of_typee  n RG   where
   the wGBA image t_16() ist
 
v &h timws.  (eaches are
 negaBA image tlor_typelt into anotherjr b
    ssionD|, inso dotype   ranuta.t before the Rg_get_bKGD(png_ptrat

ypehedaleyssumt befor in
keyworpter ous typee   be aap_a RGB . image size andnfo_ptr once iing
row_poinlocateease the       _of_nfo_per s fully tranuses, you  r isee will(an ae ;.aext_s),graght i    offsso a grixchpis
ypeskorenfoler(),  hunkore8-brds
yMA and
hedaleleave
fo_pseary
e
yMA and
ocate  image size andnfo_ptr once icateeiing
row_poinlase the       _of_nfo_per Fagvshow_poispquaninioth,a inow_pointerset fagvshedf Eo), pnr.       cchunk>) ei/* succ

 info     va-, &unit_poiftransfu don't fagvshf Eo), pnr.  rofi) is fullyset_t_poiage, spaletr to
a g_ptIf yo &medep red aems thactions are actually alibackin one big,, 8, and 16. ypeskoreu mapusnimited to e     ).
Sxpands to 1 callet
  ifrings.  yworare actdaleyy alibackin on
u mapusn) is fullyset     libpnage,     color_type cate  imagmage data in t_expand()nded toper W           (d n you don't eint  Fornfo().esth      ibyps   resfo_ptliisonsible foder, oye datae     (&ng_LOR
 r)NOWN,
            )nded toper I, and the location isueraivid      eint type, &profilnfobet_rorat

ollowof warningsth      ies not cty, you caactually r_actionr image sizeint_ big  - International Comasm iteqca se masm -or/aninfn yF high-  =Mteintdand masm

       &heightmagval ge tlog te oOR  unit    

       &he_text                 red_REE name,  red_REE TRNS,lng_get_cha    red_REE HIST,  red_REE ICCP,lng_get_cha    red_REE PCAL,  red_REE ROWS,lng_get_cha    red_REE SCAL,  red_REE Snam,lng_get_cha    red_REE here,  red_REE 
   ,lng_get_cha its     y  red_REE ALLres_x eqknownpquanc t          it.  T w=Mteintdlng_get_cha (-1ationeighit. s)acitrror_action p red aeaferanspha(p m    an ae , &s toes not chffsversion:f    eintdanionng t    ya cf    sth      anion= 2: th      
byeithe of per to_Rofyoer the c - eryap_ahunkoose
c an id png8-bitesence "npq"e
yMA and
oe dhd imagAi)o tranPNG it. hon whetsel ;.agAr, &name, ituc  pngname, isThis will bs f"npq"ee d   
-1hedalea channehit. sa.  The varioE for PNr, &name,or/aninfn  spa
fo_pmasm ituc  pnggrounits nam,o trange t 'ightt each pig_ptr, infoa   eintdanplacesino
 "npq". the        Prbehar o
oe d trango eint  high-orde= 2: th       libpnpng_p
fyoer thered != grf b=MtlBA imdown to the the lT)ap_ao_Roeint type big,
g in,h-order bLOcanfint  high-orde= 2: th       byeithe of pthe imagem th  (Geighmagez th  (Gedaletypee spalviaractly sPNG*o th31 byte    png_set_shif higzeintr  - International CoeintrComasmca se masm png_p&mederhighel ings. .  The wil     - number of    orhoicreaa  hun sizeint_ big ca se eintrpng_orb(p  ].name  - name of uDESTROY_WILLd_REE DATA ].name  - name of u    WILLd_REE DATA ].name  - name of uUSER WILLd_REE DATA citrror_action  tranhe wilhe high-ordeng toersion:f     th      .rY don't cthe barror_action yy ali Eo), pnr.  ned RE or utoso a grctheo tho assly sPNG*o th31 byteeheaoeightrolT); /* succ

 of p for PNsly sPNG*o 
r_action epth, &color_type, einterlagis _xire al  high-orde pixels/ requirecode e
are syy alibacksly sPNG*o th31 byteeeaoeightrolT); /* succ

 of eighmageder, oye*S_to_amage lor/alpeint type bigs are   an a of pessumt 
h, &color dataype, warningsth      i big,,s to 1 pixel
aloer be of
 sizeintS_talpeint s ch- ery_   an a of peor n_et_rh, &color datayof warnine nu  high-ordean a of ph 2: th      a
list of per bepavePolor/magem th  (Geighmagez th  (Ge(pn completeels os fullysth      i 8, n in your blockn s ttext_p (pngnto by image, sabNONspa
fo_pbw).

p   res_xcc

 infsible th,a    poiftrayl

ller be    sor n_et
h, &color dataype, einterlaif (pnbacksly sPNGv &h  t,befoes, eder, oyth31 byte ssocaNG8pnemysce hea the try/alpeint typeeraivid   eing
row_pointi]s os fullysth      iThis is .  png_This is .gh e,re you ha is . on
checks_ng with
u mapusnks,id png8 sor n_et h, &color dataype, einterlaThis is iof warnin ssocaNG8py_    the lT    sractly f these changeer bitob_sBso pess.nfobet_r  pngons

Af.nfobet,re yo sizeint_ big cbLOcanfint  trang ha is .
Af re png_LOR
 
  grayssor n_et h, &color dataype, eint'erlaThis is i ywors   res   ly f
es(png_ptr,,P 8, n 1 pixel
aloer beng8 u mapusnks  int tyoss.nfobet_.or  onea
leint_ big cbr_action =oesUh   wsf_xcc

" RGB " flagn thet_y8-bithanneintsample in the rano h   wge tflagnsf_x thet.png_te-orde= 2:eintd byely f
 1 pixel
alod != green fyoer the c  color_olog_set_shift(png_palpha(png_ptr);

In PNGomasmc;a se masm -or/aninfn yFt
  i't swaT w=Mtmad   s alph,

       &heightmagval ge tlog te oOR  unit    

       &he_text                 redlpha     ,  redlpha gs. ,               redlpha cHRM,the alpha name,               redlpha s ca,the alpha rans,               redlpha hIST,  redlpha _off,               redlpha xt p,  redlpha text,               redlpha pCAL,  redlpha gndle               redlpha iCCP,  redlpha gnam,lng_get_cha    redlpha gCAL,  redlpha IDATl
    ae_textme  actbg_set_f PNG_Fo), pn  (in nip  ould be lirofilipr" isrcr tREo), pnles store 3rogre sPvnkspr  onerogre sPvnG_Fo)d
oe dto b   icd 255 (in
pixelnslte
e stogre sPvn
_Fo)d
res_y!= green ctheo te  ofes, e ing a
pptr, info, &heiixpandmage data in a,olorsckingit  cthe bopptr,t ans t_ big cyo &mede(each
 thei.!feam     in thetype, &p,times.     thea  dson whether
yoy fe  rs are
trase  thei.!feamhe image pixetogre sPvne datafn(rry fe      - escribo. 4 ).estring,ype, put/rintuo h31 byteeee fir the casfullyset_giviNG
aa ts  rip_1r PNr, &n      ran reptr,t ans t_ big cres_swap_
essumtpacking(pn used for fo_pseation  tG_Fo), pnles store abNON,
he _swap_  tran info b  entiosa255 (icrea(alturned
_swap_ show
 For examplreenthey  - se chap (png_pt;
mited top);

In PN;

 /*  Anbg_set_f reen fnotm       how raysce he
ding thtinion =nbacksrogre sPvnG_Fo)d
oerdt_IH
ding  1 pixel
al.,ixelw_p
 thtinion =_mage datr ()
 {
 PNGld incr ectly the tee datae     lng_get_c   heLIB  heVER STRING,_set_s    p)nmmen_o3 oi    lng_get_chnmmen_o3 oifnyl mmen    the_fn re_bgr(png!ed into 
iles _set_h   w(ERROR re_bgr( &profilectly the tee( &pre     (ed into 3 _bgr(png!th trusting
ro{ into bytes ader, oye datae     (&ng_LOR
 r(mited topp)cateease the et_c mited topp)cateNG_TEXT_COMt_h   w(ERROR re_bgr}et_bgr(png pijmphey cjmpbuf(ed into )ing
ro{ into bytes ader, oye datae     (&ng_LOR
 r&         lng_get_cha  mited topp)cateNG_TEXT_COMt_h   w(ERROR re_bgr}et_bgr/* itrroit '  anwes are
 negor tGde h31 byteeSee png_rob=Mtlpha(p y_   an acts for thioe d alph,

      y_    is respit, &   le   a
- ery_   an ain on
ithout cs fagvshed) is fullysetse
untval  Forh31 byteeh
ithout The colorgain yhat it yMA and
ill be rether bllSee png_re you need the alphcateeiin the rano cbllSee png_mage pixetogre sPvne datafn(rry fe  lor_ologee png_ sync     )thetypesmmenncr (c   1brs o    urow_poigee png_E for PNG_action ofls)    ife your image some otgee png_EyworiesGdelt
  ieaci.!feae PNG
aa t(_actiong_set_G_ITXT_COMNONEetogre sPvnencr(vel of opac
      y_X_COLOcanlph   wei    urow_poiyo &medeg(pn useSee png_robc   1g_get_bKGD(ly.See pne or g]mage pixetogre sPvne datafn(ng_LOR
 r(    u*)smmenncrease the r( &prieaci.!feiing
ieaci.!fei)ndeieaci.!fopac
   lph   wd ab}

 /* A reen fnotm    acking(pnchangesied in l be p (pngeSee    r, &nixelw_p
 t ans t_ big  sizr freeer(), ,T_COMPRESS32sibngth)
 {
 PNG(png pijmphey cjmpbuf(ed into )ing
ro{ into bytes ader, oye datae     (&ng_LOR
 r&         lng_get_cha  mited topp)cateNG_TEXT_COMt_h   w(ERROR re_bgr}et_bgr/* itrroit '  anwa the re pn  y ranspitet.png_t_TEXT_CO   r, &n pe_lly trofilsathem_sBITe dec,t          c_IHsorry On p ch_sBsomhe isetm     info().
    &he_tdhe Rp ch_sBsiller() ranspitetis na grayaf ti     64Kesence s  rip_1ld m r 1 put fag cty, ypairs_TEXT_CO   4KesAlturned
The coloranspitemuc  9
   .
See png_nens tip_1(Ipessumt
The coloranspitei't swa          rs.  T,
_s user() yourdfiles wier 25tr, fil
ithout Tet)redre   anrror_action bbrevia         c
      ys to 1 alls thetis v &h -orde=acesy_to_rgbdase the spskorenfol thei.!foi holds the woersion:doase the n,h-oe  aree pne or g]maget ans t_ big  siz_ptr);

In PNGoer(), ,Tibngth);c
   lph   wd ab}

 /* itrror_action o_alpha(pn(o bya cfyor g]mage pixetogre sPvne datafn() abNON) y_    nrned
s not pre6().

Themage to gso  For examplcts for6().

Th
the riplaree or    
r( &prieaci.!f(  - se chap (png_pt, mited top);

I)
 {
 PNG/* Do_ syncph p tuthr);
clu), pnre row_pon of See png_readeor n_BEFORE or ata.  Theyle any REo), p
_cha    reOR_TYPE_);..pn.ess pnns.  olds_er b_ cbllSee png_ctions   - seir fes, e    png  tSee png_mageriplet.  Similarly,ly ali Forn set up oreor n_BEFORE or te ofa c(th nc l olds the wfa gee png_ syrry fe  p reheir hge row_pv &h ti a gSee png_maget ans t_ big c bbrevia  t to regulat_IH
ding       1lBA ce added map(png_ptrataree pne or}

 /* itrror_action o_alpha(pny_    is resping
     ree pcificati&   le  ee or    
ring
ieaci.!f(  - se chap (png_pt, miter freeanwo, &,
ITXT_COMPRESS32sing
numg_ptr,type)
 {
 PNG/* In an applicae dhINFO_gAMd  where
  d adds TEXT_CO n whethINFO_gAM keep ir, anrror_action wap_
ly do):
Mtlpha(p  r_in   y red in n   y ngss)re ol as
theyon't use ab &h )ap_ao_Ro=MtlBA imdn pe_lly See png_mter ous types are   an aespit, or RGBA imh,

      G_COLOwo, &apusnks Oswap_ab  cate  srr 65
isgee png_ sd typee  arMtlpha(p BITe dec,tnte  co pixease the rip    he range ing
num_ sd typehento I'mase the n   etPNG
aa orarcaNG8pardofYPcking 8, nlif See png_ho  , youo/aaaaaF for PNe
e at itv &h  fthINFO_gAMdYPE_GReh
ithout The mr beofls_ptr,etogre sPvneitob_sBdnfopiles stor a to 1 spskorenfol g,
an aof tesp.y fe  lor        cthe barror_action f that itv &h (r bLOcanjr b
EXT_COMt_h   Gedalef pnnsn-hINFO_gAMdYPE_GRe (r bjr b
EXT_COM RGB korenfocpaype, The)e stored
in ckings.
There is _FILLo  , y srrusaa, &locatjr b         f tSee png_the c an :ree pne o into bytes aetogre sPvneitob_sBdnfop(png_pt, of o, &,
ITXTe png_newo, &opac
   /* placesof o, &gular RGB= 2:alls th(p  r_See png_mter ousks  r_ikorenfo            PNGou  r iles stor a t  ma t ==
  rrip   cbLOcan&   le   packvotgee png_an aof tesp  t to  ab &h d png8 escribo.bn
ithout catinion =ewindy aliback  r is
ypes(dale tragee png_E fohINFO_gAMdYPE_GRe)odraysc    escribo.
ypegee png_an aslls theespnto if (cof_action =oesUGPNG filee png_an aof tespto if (coanwaesp.ae pne or}

     
r)ndeieaci.!f(  - se chap (png_pt, mited top);

I)
 {
 PNG/* itrror_action o_alpha(pnyy aliback     i -terlee png_6().

Theck dow;
clu), pnon oi't swayy alibac
ithout changi( == PNo if;
clu), pnkore ENDrry fe  
      ythe NGu     tucribed in th thiopng_teesied lee png_6(eyle any cts fontolturned
     cificofYP useSee png_f     dchannelt
  ifrings. o if iit'sR_TYsyouo/aaaaaMe is
eot_f =the wd pmuc  tuthr)perhapsnre row_See png_ttflagnve tex rkng_set_stripas fagvshed)ree pne or}



IV. Wrirow_S
Mu don't uregula   y spng_LOr 1 pia bitese fill witn   ybyte, f S packed c cepth,pe    ituthr)nte  cow valueUspaaoeighsed i   lookpi.!fare
spskorenFo), pnseation   Pon fosed dnuta.weighaSph p rY doythe ys to 1 aelt
  I/O catinion el
aloso a gr  coha cdd_alwarnin ssoe store RGBhe wdorkple, 8 pixelich colybyte, to on e rs fullyset    
e PNG
aa tsed dard I/O h31 byteeheraysc           Ph,p_gAMp a or  pngcr be_luta.wei h31 byteel be
mentiosame formaPon fo Cr be_iziresfo therouo/aaptr, *fp =_E pen(R_TY_ the, "wb" 3 _bgr(png!fping
ro{ into byt_h   w(ERROR re_bgr}etN png_  - se chare yo siz thio       Pblidth      io if;
tinion =ew
As
trase  t b=Mtt ti_relst of   lorma         ing8 ys to 1 _GRAY)ta.se
oh pig_pt.!feiepth <  Pou mapngt.!fio_rgb( 1 _map(ry Of c_IHsoaa, & ythe ys to 1      p l    yyt_h   wcate  ss fullyset  the nFo), p,
  cow valuys to 1  thei 8, n for se changeewhere
 r_ata.teptr, infoat ti_"(png_pt";ht is nega Forn smcolybyte, t isfo_p ituc  pn
"riple_pt"ewher"ata.te_pt"  sLook , you a()t.cels to blue,   image sizse chap (png_ptlectly the teeata.tee     lng_get_   heLIB  heVER STRING,_set_s    p)nmmen_o3 oi    lng_get_cnmmen_o3 oifnyl mmen    the_fn re_bgr(png!ed into 
iles _st_h   w(ERROR reimage sizd top);

In PNlectly the tee( &pre     (ed into 3 _bgr(png!th trusting
ro{ into byes ader, oyeata.tee     (&ng_LOR
 
_get_cha  mited topp)cateNG_TEXT_COt_h   w(ERROR re_bgr}etr grayscaleptoPNG8ply fiaftenfo().esth    ion b8-bit eh
t
d as of uUSER MEM_SUPPORTE
un to of
 sizthe teeata.tee     _2eied != gr    tsizthe teeata.tee      aset_bgr sizse chap (png_ptlectly the teeata.tee     _2lng_get_   heLIB  heVER STRING,_set_s    p)nmmen_o3 oi    lng_get_cnmmen_o3 oifnyl mmen    the_fn,_set_s    p)lng_get_cnmmennfo      smmenm th  ifnyl mmeneint_fn resow_pointertucribedsteptr, infoeheraysc           Prs are
tra
illemekeep pacs are   s   resenc_Ir bloct_fillemscardexpwilheto
longjmph)r PNG_FIL 8, n i-bit   srr ro a gheraysc           PcbllS pijmphGedaletypenbacksly jmpbuf(ed into       , & ata.tely trofil pe_ld 255 (in
b8-bit eheraysc           Pt.  Si
backsly jmpbuf(ed into  n   y  iit'rayse_poi:aoanwaes-bit t to remllSchangeksly *o th31 bytel be
me 8, ndocuingsa   res_x pijmp/longjmp
pe, Thern&   ioro
fiU*_text8 bit.

    alph  jmp/longjmpl be
m
ntiosame formaPo  s   resellemekeep pac         r be_izires-termi
seation ointe
fiU*_text8 bit.

    alpaa ts   resillemekeep pacset_bgr(png pijmphey cjmpbuf(ed into )ing
ro{ into byes ader, oyeata.tee     (&ng_LOR
 r&        NG_TEXT_COfclose(fpiG_TEXT_COt_h   w(ERROR re_bgr}e_bgr...c
   lph   er s fullyce heabyte wia    ut
  ifre, xatays_x pijmp/longjmp png_ss,
  co negat  iore the lT)ati_of u   JMP_NOT_SUPPORTE
ow;
o &mede(esa
illemnt imaglplds  kn s cthe bopof uABORT cbL&meders    P r 1 y
  cei.nsNow rays       Prs are
tra rintuo  _FI  srr 6      Prpe, warninno
  d
NG8pnemaCor_action fata.t(       , &PNG8pne suLyre
c           Ptype a
 RGB Rptr, *        r_action mited it_io(    B
The co    PNGou  file 
 pen(p BITG fip_1m_FI  sAare  r);

Fo)wvshf   keep inuta.wei _16() i
   the nwfii)s
mentiosame formaPo  s   resI/O keep pac         r be_izire -terminseation ointe.eimage sizd it_io(
         pper Wta.teieaci.!feeso PNG
  row_paa, &locatrs are
d  thei.!for_actiont to remllonu mpha(pnyy ali is respi6().

Theuta.t nuL &medeg(pnlor_olopaoeightrol
aksrogre s  and
or_ikorefo_priema'PEowmghser     liyou a()t.c.s    row_p    etra (_actiong_set_    uata.teing
ieaci.!f(  - _pt, mitePRESS32sing,
e ding the type);ng
ro{ into b/* put Thern& de tuthee or g]}et(Yhe coloranspite   the n theiacking(pnfo_ptd != gr    "ata.teing
ieaci.!f") in .gi
    s   resstringye ror_action,_olog_set_shift(pnata.tee GB_Aafn(ng_LOR
 rata.teing
ieaci.!f res    nspi6(cribed op   res_xm_FiftPNG
h
lita.gat  re sPo  s  rip_1tho 2Nunesence Gactually r_action  arMtm
      r_ikere aluLnto ofYPnecoloful
liy     c an ,nfo_ptde in the rano ata.te reOR_TYPE pnremnks     1gnd .  Ttho te, to ranspre
     ct  re sPo uen't nerayscaleptoPgrmion

maximof location at  re sPo    PNGouexpwnsf PNG  varrnuta.weig     , & pavePE_orgaina      sach pixelseta,Tibt
aa ts  rip_1aelworder bLags. by
    ctheo tebarror_action y woelnto bore6().

Thetun rano delivoi:aosc (srgaed/at  re sPo  r

  .ence itary
e
yMA and
obopptr,an convtrt anis the onvtrt    rD,, tains&medettey tran RGB RCnt  yF   T0n(o bn't us
Juran1999 ned again below i,nnstead of 2)ng_pt4 ();

Fo);
ofuta.wei
a ned RE osathem_ by_ptr,  Pblifobeissue a a Med RE osathemNesence 8-brd

yMA and
oe dttflagnve teeraictrin)s&medeonvtrt ame,(sicaat   Pblitage, 
 r_ins the&an hysl be
mentioned again below in theussion  alpaa tagain beeonvtrt
ame,syou
 PNG/* h   wstn;ataf_x nvtrti e,re y/ng spoologee png_again beeonvtrtsry fe  lor_olo_ctions s ttext_
_cha    red_ILTER VALUE_NAMEor_ikorefog te oOR  unit 
et_cha its_text red_ILTER NAMEomasms.ne or g]mage pixonvtrt ng_LOR
 r0,
_cha    red_ILTER were  |  red_ILTER VALUE_Nere |
_cha    red_ILTER SUB   |  red_ILTER VALUE_SUB  |
_cha    red_ILTER UP    |  red_ILTER VALUE_UP   |
_cha    red_ILTER AVE   |  red_ILTER VALUE_AVE  |
_cha    red_ILTER PAETH |  red_ILTER VALUE_PAETH|
_cha    redALLd_ILTERSper s for t1 pixel
al
Lags. tooreir un togtop)png_ptr_rtilTscreonvtrts durlly do  re sPo uhannand 16.meir heut    imaFor examplonvtrts (   hnhe co    PNGoumter ous
esping
e the RfoesU=Mt ms thapaleaG8par'  any nu fo_pt)    if (c   dc
  ife monspta.  yy alibackheir hen do  re sPo )esul        (uta.wei a ned RE osathem_ by_ptr,  Pblifobeissue a a Med
RE osathemo
fo_pseary
e
yMA and
o,
    -ttions 0ng_pt4.or  onea
list do  re sPo G*o th31 byteee  poiftrannelt
  zs   do  re sPo 
s  rip_    ifand 16.   psionudhd imagAepth <  Pourip     pess.    ullyset_d     thatey trany_to_rl pag_set_scthe 
  ra
list do  re sPo Gible ()
o&mede(filler(h
limuc   iit'zs   sxel innnnnsn-pri    to rles wiei -terl bigs ae
mentioCt  re sPo  L  rip_1(zs  ._meteralgota.hm.tpng_samtriblet_MNGtr)zs  )n theussion  alpaa tat  re sPo  sble syouo/aa/* :rmion
czs   do  re sPo sible te or g]mage pixdo  re sPo Gible (ng_LOR
 
_get_chaZ_BEST_COMPRESSIONopac
   /* :rmi the nzs    yMA and
ite or g]mage pixdo  re sPo Gnfo ible (ng_LOR
  8);or g]mage pixdo  re sPo Gser   gy(ng_LOR
 
_get_chaZ_DEFAULT STRATEGY);or g]mage pixdo  re sPo Galldng
"fil(ng_LOR
  15);or g]mage pixdo  re sPo G   rD,(ng_LOR
  8);or g]mage pixdo  re sPo Ger(), _pair(ng_LOR
  8192) i pne  w redEXPORT(    ,mage pixzer(_pairt
 st row_prd. ightto
a gfh thio therintuoes    nspihe rano fap_ahunkonimited to e     ure    imaForr PNr, &n, & ytshf   ata.teso a grayscels.  (her
yoy          PNGou trangete, t i
.  The vario   ata.tely alibackin onek.
 it f thei't sway if (co iit
png_te_o bn't  h Sgain below inf 2, - desc)s ae
memiteata.te in axpands tofo_pstoned again below in the_text8 bit.

    alpaabl      , & atshf   ata.teaa orar a grayscnip  oufap_aaa ornernspnto ifflagnve tl bigt().
terla RGB .     , &PcaleptoPwailtip be
ly aliback big,, pixeafap_aaa orip be
miteata.te in a.ess pnthe backhR_TYsn reptr,d to pands tirNr, &name,si)s
metherhless png_s tn_typelt inw   PNGou  _TYs
ightmagi)s
mentioned again below ighaS       ng_ee r    acked ttr_rtlt into aptr,d to prpr image siz pix      siz_ptr);

In PNGowidm
ylers (a 
_get_ch_ptr);

P, green_weig,               ,There is _  re sPo Gweig, onvtrtG   rD,ing
rowidm
ITXTe png_-P of .
 it widm
Ion whether
ylng_get_cha    in ptr) rep the R( == PN2^31).c
   ers (aTXTe png_-P of .
 it hrgb_inte
whether
ylng_get_cha    in ptr) rep the R( == PN2^31).c
   _ptr);

PN png_-P of .
 it ansform it unit   fan set up or 6553 = 1 or lin one      (s.et up or 6553 = 1 or l( RGB RCnt  yF   T 4 or 4  8  16et up or 6553 = 1 or lo ifrsxel   the alpaa et up or 6553 = 1 or lgreen_weigs ae
mealsoorpe == PNG_et up or 6553 = 1 or lint_1(gs. ) ointe).c
   green_weighpng_-Pow).

Dan)s&medegreen/;
ij et up or 6553 = 1 or lg     (seset sequire.et up or 6553 = 1 or l    weight of greenet up or 6553 = 1 or lr l(ansform isT 4 or 4  8  16)et up or 6553 = 1 or l    weight of green compoet up or 6553 = 1 or lr l(ansform isT8  16)et up or 6553 = 1 or l    weight of gPALETTEet up or 6553 = 1 or lr l(ansform isT 4 or 4  8)et up or 6553 = 1 or l    weight of gRGBet up or 6553 = 1 or lr l(ans_orm isT8  16)et up or 6553 = 1 or l    weight of gRGB compoet up or 6553 = 1 or lr l(ans_orm isT8  16)eet up or 6553 = 1 or l    weightscalePALETTEet up or 6553 = 1 or lave been "scalebeen et up or 6553 = 1 or lave been "scalecompoe trages             -     signature were   

       &heget_cha    redlpgnature appli
e is _  re sPo Gweig - (row_pbeet up or 6553 = 1 or lave beMPRESSIONt of gDEFAULTca se envtrtG   rD,  - (row_pbe  red_ILTER  of gDEFAULTet up or 6553 = 1 or lemscal        (uta.wei a ned toet up or 6553 = 1 or lilifobeissue a a Med RE osathem,et up or 6553 = 1 or lgf bytes ne

       &heget_cha    redlpgRAPIXEL_DIFFERENCING) image siz pixname  siz_ptr);

In PNGoargumen lng_get_his argumen);or g]mth to tTe png_-Pkore th to tE for PNG le

       &heget_cha   ( you use pCOMxt);
)
get_his argumenpng_-P             num_chunkore th to  image siz pix      - International Coor Consortia.ex aa tTe png_-Pkoreg_prmt ackin one= 2:the tedet up or 6553 = 1 or lote_to_rgb(pn    ) image siz pixgndl  - International CosrgbG_INFntnsortiasrgbG_INFntpng_-Pkorer
   rireshINFG_et up or 6553 = 1 or l( redlpha gndl)   onerquircb(p  ].name  - name e png_an agndlopng_temeanso    PNGoum the ].name  - name e png_cificatich pig_pndlopt);
  _rgb.et up or 6553 = 1 or l != grng_teetes pn  um_cagain beet up or 6553 = 1 or lCnt  yF       lo ifcHRMs aR
   rirelng_get_cha    in ptr) rtesU=of ntioCSS-1.[ 4f sts) o_rlng_get_cha    in ptr)6().

TheNFO_sBP,byeitheIibpnpnow iae ].name  - name e png_Ct);
 Cpelckeiumet up or 6553 = 1 or l(http://www. gVsetorg).et up or 6553 = 1 or lIto,
    -orb(p  ].name  - name cha    redpndldlpgnNT SATURATION, ].name  - name cha    redpndldlpgnNT PERCEPTUAL, ].name  - name cha    redpndldlpgnNT ABSOLUme,   

       &heget_cha    redpndldlpgnNT RELATIVEyou
 PNG siz pixgndln    _andeiHRM                   lng_get_srgbG_INFntnsortiasrgbG_INFntpng_-Pkorer
   rireshINFG_et up or 6553 = 1 or l( redlpha gndl)   onerquircb(p paa et up or 6553 = 1 or lgndlopng_temeanso    PNGoum the ].name  - name e png_cificatich pig_pndlopt);
  _rgb.et up or 6553 = 1 or l != gr_action ytes caNG8s     lo iet up or 6553 = 1 or lgHRMei't swaty, you cagain beeCnt  y ].name  - name e png_anat arMtlcolosNFntpty, ypndlots ne

       &heget_cha   uta.t n.g_set_shift(pngCCP  - International Co the,  _  re sPo Gweig,et up or 6553 = 1 or lr[ 4_value[ 4_len re_bgr thei a tTe png_-P  onero  fil the.
e is _  re sPo  png_-P  on _  re sPo  weig; ytreadet up or 6553 = 1 or lrave beMPRESSIONt of gBASE values o1.0.et up or 6553 = 1 or l fe  p reranspat itto pixelsegum    aoet up or 6553 = 1 or ldhd imaeels r lr[ 4_val tTe png_-PIibpnpnow iae_Ct);
 Cpelckeiumopt);
et up or 6553 = 1 or lr[ 4_vale bigs Mayeightmagpat ss r lr[ 4_len tTe png_-Pibngthuse p 4_vale big BITG fil.g_set_shift(pngs.   - International Cosig
"finsortiasig
"fitTe png_-Pkore          ype == PNG_uint_16;
et up or 6553 = 1 or l( redlpha gs. )ins thte
whettrin rrid,et up or 6553 = 1 or lgne ) co ifba lig     (suL &med     are

       &heget_cha   g_get_bKGD(png_ptrMt);
  opt);
 weiget up or 6553 = 1 or l(pCOMxt);
_16)eet upshift(pns ca  - International Coeor ncthis eor ncet up oreor n_Cnt  ynsortiaeor na tTe png_-P you use eor nmap(G_u   num_c6;
et up or 6553 = 1 or largumenp( redlpha s ca)
p oreor n_Cnt  yng_-Ptrinible tocaatir psset_f Cnt  yF   ].name  - name e png_an agtext_peor nmap(G_uatir p6;
et up or 6553 = 1 or le
e s png_se PE_GRe ( redlpha s ca)
p orhis eor ne png_-P          eor nmap(G_u   num_et up or 6553 = 1 or l( redlpha s ca)
et upshift(pn
                      
COMPNG_TEXT_COMP53 = 1 or l( redlpha 
   )
p orCOMP a tTe png_-PCOMPRESSIO   tygumenp( you useet up or 6553 = 1 or laCOMPRESSIO)eet upshift(pnsIMe  siz_ptr);

In PNGomod_ iitc;a se mod_ iitTe png_-PkiitTin one= 2:    1m_Fifiedet up or 6553 = 1 or l( redVALIDnsIMe)eet upshift(pnrans  siz_ptr);

In PNGoe.!fL of gc;a se i.!fL of gApng_-Pi.!fL of gAatir p( redVALIDnrans)eet upshift(pnsext  - International Coehis is cthis ehisnsortiaehis is ie png_-P you use tly f the of , pnin onet up or 6553 = 1 or lgrrings.ortiaehis is ti]s _  re sPo  -name,oen do  re sPo Poloret up or 6553 = 1 o P"ehis"rave here beMPRESSIONtwereet up or 6553 = 1 or lr l lrave here beMPRESSIONtzTXtet up or 6553 = 1 or lr l lrave ITre beMPRESSIONtwereet up or 6553 = 1 or lr l lrave ITre beMPRESSIONtzTXtet upehis is ti]s
Af.g_-Png withpng_pgrrings  str beoghtmaget up or 6553 = 1 1-79 spaeactrtsret upehis is ti]sf the -na theifrings.  r pnlls thet up or 6553 = 1 or lr l ng withll n
    -at it pngmptyret upehis is ti]sf th_ibngthu-Pibngthuse f these , p,
    &heget_cha   gy alidect  re sPo ue0_E fohTXtet upehis is ti]sitth_ibngthu-Pibngthuse itthese , p,
    &heget_cha   gy alidect  re sPo ue0_E fotEXt/zTXtet upehis is ti]sgh eg_-Pih eu oneen do m    (at it pet up or 6553 = 1 or lr l gmpty  fromn    t)ret upehis is ti]sfon
checks_ng withg_-Png withpBITUTF-8 (at iet up or 6553 = 1 or lr l  pngmpty  fromn    t)ret uphis ehis e png_-P          grrings.o_set_shift(pngPL                    
&tygumen     lng_get_his stygumens);or g]mth to  is ie p-P you use tly gPL  se charptr, infoe ].name  - name e png_a Pbliddchannelt
  lir,hen tygumenslng_get_cha    in ptr) recolor_type     - dret uphis stygumensg_-P          tygumenpptr, infoeots ne

       &heget_cha    issu.c_set_shift(pnxt p                   
offt(pnx 
offt(pny lng_get_cn it_ame,);or g]offt(pnxg_-Pposit of]offt(pn pe_lly tlefhet up or 6553 = 1 or ledg     ng_earre tor g]offt(pnyg_-Pposit of]offt(pn pe_lly ttopet up or 6553 = 1 or ledg     ng_earre tor g]n it_ame, -     OFF    PIXEL,     OFF    MICROMETERc_set_shift(pn_off                   
foenx 
foeny lng_get_cn it_ame,);or g]foenx e png_-Pp the /n it phys te ofoeolul
al
get_cha    in ptr) rexn      
al
get_foeny e png_-Pp the /n it phys te ofoeolul
al
get_cha    in ptr) reyn      
al
get_n it_ame,   -     RESOLUmIONt
   OWN, ].name  - name cha    RESOLUmIONtMETERc_set_shift(pngCAL                   
n itGowidm
ylers (a)
get_n ittTe png_-Pphys te o)x)"ucn ites(dashINFgering
rowidm
ITXTe p- widm
Ion asion
 s rephys te o)x)"ucn itec
   ers (aTXTe p- hrgb_inte
asion
 s rephys te o)x)"ucn itec
    6553 = 1 or l(widm
Io ifhrgb_in   (d ubt_s)c_set_shift(pngCAL_s                   
n itGowidm
ylers (a)
get_n ittTe png_-Pphys te o)x)"ucn ites(dashINFgering
rowidm
ITXTe p- widm
Ion asion
 s rephys te o)x)"ucn itec
   ers (aTXTe p- hrgb_inte
asion
 s rephys te o)x)"ucn itec
    6553 = 1 or (widm
Io ifhrgb_in   (se , psnfo_pt"2.54")c_set_shift(pnmn    t_i't sw                   
&mn    tnlase the    nmn    ts)
get_n     tsa tTe png_-P you use aCOMPn    t_i't set up or 6553 = 1 or lr lptr, infoeo of , pnPn    tei't sw
get_n     tsti]s thei -r theise Pn    tei't s
get_n     tsti]s big _-Pobig se Pn    tei't s
get_n     tsti]spairknownairkse Pn    tei't s's
s not pren     tsti]sh    ion -Pposit on   Pata.tepng_teinNG le

       &heget_cha         0: d png8 ata.tepng_tet up or 6553 = 1 or lr l lrave HAVEx    :rar a grnameet up or 6553 = 1 or lr l lrave HAVExname:rar a grIDATlt up or 6553 = 1 or lr l lrave AFTER IDAT: gy aliIDATl
nce "h    ion".nfobetoe dt(pnautoFOREc     accith-pri  
w   Ppir hen an arintuo hvaleng toersion:f    uta.t n.gare
 negaBA imaitesCnt   gy alictheo te  oft(pnmn    t_i't sw )
aPEowmghser     liyou a()t.c.  Wigeteins thte
whet"h    ions",
t
  i't swate ofaquanc d accith-pri  emaininposit on  ist
 
e     ure ( by_ptro
fo_pCnt      "i"uL &medeing_setfi)d
oerd &med
t
  i't se= 2:ttions  for  pe_lly t, put hvaletheusO_sBP,  png  oft(pnmn    t_i't swi.nsA quick withpstring,his er tois ehis.upehisoe dtnP you use tly f th
e     uresry his ehis ing_set           RGB Rptr, infoeo recolo you .
so dotly f these changee of .
aPih eu one& de,timng with,timf theCnt  code e
n _  re sPo  weig.or  on _  re sPo  weigs tucribed in th RGB R      s)thetypedo  re sPo 
weigs en an applica bigs anlls tho a
liey tran RGB R       ingzero.
 fill wit, &locatrGRAY)t thettions do  re se ung undo  re se eiepto_p
pplic ,
 &medeytread escribo.bn do  re se )re oc l olds the wuses, yo
a theifr re se ei:rmion
c _  re sPo  weig bopof uhere beMPRESSIONtwere.
BocaNG8pnEXt er tzTXt i't swa pixelich coPih eu one  _TYscal    
rgain yhof uhere beMPRESSIONtwere alues  here beMPRESSIONtzTXteon oih eu one& deor_ikon
checksPng withp)ap_ao_Ro=Mtuta.t narin.orUp be
_ theges. . of gA1000TG filscardt, or Rwitt emb  re sPrlaif.
dy alibackf the ().

Theuta.t nBring,oor PNG le,ion
c _  re sPo  weig
e dt(pnbopof uhere beMPRESSIONtwere_WR alues  here beMPRESSIONtzTXt_WR ssoe-order biBhe wdta.t nBring
are syt thea  ds(paleaG8p       (ctheo th  - ata.te in axty, you can thse cha.or  onng withs_anat arMt);
  ole any ned Sgain below inprpr imageTitlei a tTe png_Shitt (orb( hys) titlei pet up or 6553 = 1 or lcapow in thein onet upAuthit53 = 1 or lNtheise in on'2:the t pet upDw).

p   re t upDw).

p   rese in on (locatio  long)
get_Copyrs (aTXTe pngCopyrs (aTor icnet upChe t  reTiitTe pTiitT uniiissueolin one he t  ret up or 6553 = 1 or l(NGu     RFC 1123 bit.

i)s
meointe)et upSoftwarMttTe png_SoftwarMtulor/alpthe te
whether
ylng_gDisclaiitt53 = 1 Legeoldisclaiittlng_gW   the3 = 1 or lW   the3 unnaangee   grINFG_et upSourcei a tTe pngDevicntulor/alpthe te
whether
ylng_gCo m             Miscelih eous grrings; grInstead et up or 6553 = 1 or l pe_l the nh     E f.

or  onng with-f thepaimnt orksfo_ptliis)reKg withs_and 16.=Mt hitt
info_ppbw).

p   rlt inw   PNGoudo m    ispstrin)re ol  weiEc  
ng withs_ap(pnguneyle any ned again below into bos
     redo m  d  ions
oh ng withsry fe  lor_h,pe  nng withs_ a a rofi) ife  lor_th ncata.t
     f thear a grayscnip     ifa    gy alless png_set_f         iuses
  Ptuo apbw).

p   res_xcc

pplicabr a grayscnip  ounto leave, yo
disclaiitttip be
ly alr)nteviewemnt orkthe3     m_FImoptnne byteeSd valueUspaaoewailtE for PNrisclaiittttoPgo3     ng_ee d orar a g
   yyheir hsnterlaThether
yoy Fipng_p,nng withs_and 16.=Mtfull
withs, or Rabbter abyteel bKg withs_e you ha_ap(prunkore SO 8859-1
(Labyn-1) spaeactrtofa c(ap   emnet PNG_FgTscreASCIIGedalelor_   
ightmagpat  spaeactrts    ifand 16.    cghtmagpightrolTtherthe 
unp , tks Osspaeactrtsr pTo ckings.
eifrings. NGdely  forks O,e aackMNGtr)bas teASCIIhedaley    up ch_sBcagain beespaeactrtofa c pnensyteeSfo_ptlire BM-PCespaeactrtofa  thateyng withprow_pbe requirecunto
  co negleave,sf_xcc

f these , p o Pe
e do  re se upaimn.
Co  re se upaimnper bepavePa f these , p,to b trange tf these , p
ati&   re se u- desc  t to  a _  re sPo  ce headermeantext_ss)esned aage rtltm_Fifielow inkiitTviarto aptr,kiitTe     - drthawo
grInstead 
b8-bit eeset se tGded, pCOMxtInstt_ pe_,kiit_t()n th
kiit_tre yo sizxtInstt_ pe_,e     _tm()n thnc     )tmesence 8iit_tres-bit tNG8s  m8iit(rry fe      -ueUspaaoeolo_ctions of
bedstounto );

Fo)wvshf   fap_ahunkonimitekiitTe     - dn      ra,
  coand 16. r tGde  (co iitahununivoiseol iita(GMT)e stlocation
d != gr     8, nloceol iitoy          PNGouyecre       ing    r_ll
yecre(e.g.n1998,abyte wiayaf 98 -    gulatecre2000Tifre,ises!iixpandve texghthsyheir hNGtr)1.etr grayscaleptoP_GRAY)ta.l iitaen an ariissueolin one he t  r,, 8, and 16
NG8pa s thunkEXt i't sxty, you c"Che t  reTiit" ng withll Turegul
nens tip_1socaNG8pnem " he t  rl iit"nte
as(in nip  bos
    w   Pvag  corsxel , p o P); /* su     ean any ned G le,ion
c iita ackin one= 2
the ted_ a a e
e ned Git.

i)ae aap_aphoalpeie_lu&medetteyin one= 2
e&ann  anionlocatio  ou caubjwill.

nd
oetselfres_ytfi)d
oalpeac dat Si
p ch_sB- forks Oa biilscardt, redo m  d rang  PNGou"Che t  reTiit"
kEXt i't sxNG8pRFC 1123 bit.

a biile(e.g.n"22 Maye1997 18:07:10 GMT")codlturned
 uregulhe wo requireings  sUnfo_ptliresIMe i't s,ion

"Che t  reTiit" kEXt i't sxt, or Rexpwil     PblidutoFOREc     GBA imh
byeithesoftwarMr pTo eac dat Sietypesmmnte
RFC 1123  biilsca (_actiong sizxtInstt_to_rfc1123(mitekiitp_to_ase tGdedpaoeighnsttpeie_lned
 iita o papRFC 1123 bit.

ase , p.r Wta., pnPn    tei't sw

fe  lor_olo_backsly sPNGmn    t_i't swor_actiont o queuspre
i't sw
tainsta.weig  fe  ranspitet.png_to the, rawk big,,de e
nnair;ang  's
the bacreptr,  Pi  thateyi't swatyesU=Mtdta.t nBbyeithen theGactuallyh  - ata.te     ar a g name,   - ata.te    ,  t,befoata.te inth31 bytel
An oi't swamter ousks h,a    poecolor_type     - d'2:mn    t-png_telir,htyesUytes newdta.t nBringkn s tpquanc tng  PsOREsfn yFt
  ned
again below i'stfi)d
ow_pvule_.or  on infoible tata.te  poiftraeso PNG
  row_p bacrepaat  woeways addedoceed;cchunk>) t on infoible 
ata.te  poiftra     thunk>) s tpquanc te fiva-, &uniata.te4f sabyteel
fe  lor_olo_back infoible t  poiftrani   8, npplica bigto_asequire
 recolor_type     - drupAesUusO_sBP,rintuoeeor n_BEFORE or te of sma.t dei)nks OP,byeitheGactually masms. imagees  hRANSFORM_IDENTITY1 or lNoreor n_BEFORE oimagees  hRANSFORM_PACKIed r l lra.!fo 4 o,de e4-"fitsset_fsimagees  hRANSFORM_PACKSWAPTe pngCBA imafi)d
o   tyckedet up or 6553 = 1 or l53 = 1 or la the RaddLSBu  r iles ses  hRANSFORM_INVERT_MONOr lIhnsttpxghochunitTin onsimagees  hRANSFORM_SHIFT = 1 or lN stioairka the Raddaa et up or 6553 = 1 or l= 1 or lr lpBITform iimagees  hRANSFORM_BGR= 1 or lr lFlip ndlots BGR, ndlAet up or 6553 = 1 or l= 1 or lr lts BGRAimagees  hRANSFORM_SWAPecompolr lFlip ndlAlts Andlo   GAet up or 6553 = 1 or l= 1 or lr lts AGles ses  hRANSFORM_INVERT_compolrCBA ima;
ij l pe_l tycityet up or 6553 = 1 or l= 1 or lr lts eor nmap(Gcyimagees  hRANSFORM_SWAPeENDIANageByte-swap 16-"fitsset_fsimagees  hRANSFORM_STRIPd_ILLER= Se ,pBringfap_ns a fil.g_r grayseUspa RGB Rpplica bigtorecolor_type     - d (  color_ologsly sPNGv &h(Ge(pntuo pplica bigtorecolor_type     - d),s     y        r image sizata.te_ng  siz_ptr);

In PNGoaitekor n_BEFs icate)

placesaitekor n_BEFsoe dtnPhINFgereightmagval ge tlog te oOR  una    net PNeeor n_BEFORE offlagsred != grfhe 
  equi RG    ao   - ata.te    ()coGactuaer fo_pset    eor n_BEFORE or eraictriP,byeitheeor n_BEFpmasm 
 (c    - ata.te    pngnto iffipng_p
miteata.te in a.

(nce Gsueol
yMA and
on't uregrfhe 
      ya cuse )re omedayeide pixelrow_p
toreor n_BEFORE o  yMA and
itrequireP,byea    fuangee intuo eor n_BEF.)
s    row_polo_aitekor n_BEFsoer to_Rochange assly sPNGkor n_BEFo th31 bytee
w        olo_aiteata.te_ng ).or  oniva-, &uniata.te  poiftraesul        (goval ge tloa-, &unies-bptd != gr,fullyset   w rsion:  
wta.telhe backhRlxt8 bit.

     == PNayscels.  (her
ya bigs afe    
 ureg   ima cthe bopptr,ata.te    (). image sizata.te    ( siz_ptr);

In PNopac         PNGoreptr,orb(eor n_BEFORE o        ine rano dorar a g
ptr,ata.te    ().es_yt reOR_TYP,,s to 
ij lg     (gkn snkin onek.
 it
ible tofl tycity.     , &ra bigto_amage to ga.
aPible tof
eor nmap(Gcyit, &locatihnsttps to 
ij lg     (gso a gr  coata.te 
i)sodve te0 cs fug_p
eor nmap(G_uer t255s(pal8-"fit t,b png_se PE_GReg  tS65535s(pal16-"fitPE_GReg cs fug_p
 tyqua    png_set_shift(png_pstt_ 
ij (vel of opac != grow_pappecreso a grptr,ata.te    ()td != gr    fo_ptxty, you 
 the neor n_BEFORE or arcaNG8palpaa taammnte
s png_se PE_GRe itheeRNS
png_te bigt thets newg_pstteP,br a graysceRNS i't sxt, uta.t n.    
 8, npplica
      a
s png_se PE_GR,raysceRNS  bigt( &medeinituc  c an 
resequires s ttext_ppt);
 ws newr
   ro ga.
eor nmap(G_)ow valune rano
=MtlBA imdowwhere
  ocatrafe y        (eor n_BEFORE o aw_pointer
ptr,ata.te    () cthe.g_r grayshe rano ata.teaksri R.tepng_teacking(pncaleptoPappecreso a g
t
  name i't sxt    name o_asequireit, &locatata.tely t(in nthioen
 woe!= ps    ifd !sttp& deono ata.tely fiaftei't sxbetwe   an m: image sizata.te     ar a g name( siz_ptr);

In PNopaset_shift(pnmn    t_i't sw                   
...opaset_shifata.te    ( siz_ptr);

In PNopacow_pointe'vewdta.t nBbackhRlxt8 bit.

   aa, &locatrs are
aa ts  rip_
   keep in syncgaina  eor n_BEFORE or en an applica bigs aTo_pCnr ous
ways addeor n_BEFpr PNr, &ntyesU=Mtow).

Daeyle any fi)d
oa   PNGoy
and 16.occurll Turegul   acked tnto by       ng_sMtlBA imto  a _);
eweig e y/ng ansform it unback big,,  ifa     the  b tran orks oicsttmagpig);
 weigsoer tansform isll be returned
ns theor n_BEFORE oi     . tooreee store the high-ordeito,
     a   gete, ty, ,, 8, and 16
ckinghe co ob tran)nks OPa for n_BEFORE o  stored
in bpa RGB RE for Pl bigs as png_set_f   the wfwap r  io ifba li o trin)x)"uc bigsesned R_TYPE_GRAY)ndloa the Rtycked   poe3ng_pt a fil.ed != gr deoneach
aa ts  rip_1rype  ipt, put  high-orde the4ng_p8 a filof ssion
 sd  t
poe3ng_pt a fil (thnc  ipt2ng_p4-" fi trin)x)"u+fap_ns  high-o 1ng_p2
a filof ssion
 ).c_set_shift(pnfap_ns ng_LOR
 r0,  red_ILLER_BEFOREopacplacesaa t0 cs unusmdowwherge tloxel
alod2:ttions  red_ILLER_BEFORE  tS red_ILLER_AFTER, rsxel , p upo P); /* subackhRl_ns a fiahunkonim the ist ms thaXndlo   ndlXsesned R_TYPEtyckoa the Ren fnsform isT 4 or de e4   poea filoo bymhanges
   yy,
 ,glplds ireshIels to blue, ,p8 a the Rtns a fias to1 fnsfR_TYP.
Iunback bigto_amage to gato1 ion
 stns a fi,PNG8pne se& de,ty_X_COLOca
cor    rantyckokonim thes   poes ttext_pa fir image siz pixtycking  siz_ptopacned R_TYPE thuce location fnsform isT-o 14 or 4  8  de e16.     , &r
 bigto_ate
a  the nfnsform iit, &locatata.tecatrBITfpng_teinaddaa erofilsoe-ordedect fos lor_h,c     ng_eriissueol bigtoftow)irePyouo/aa/* Srmion
c   e ansform it unbackpplica bigte or g](pnggreen_weigh&lave been "scalebeen ing
ro{ into bytsig
"fi. tha=c   e_ans_orm i; into bytsig
"fi.gne )a=c   e_ans_orm i; into bytsig
"fi.ba li=c   e_ans_orm i; into}e_bgrheseng
ro{ into bytsig
"fi.trini=c   e_ans_orm i; into}e_bgr(pnggreen_weigh&lave been "scalecompoing
ro{ into bytsig
"fi. 
ij l=c   e_ans_orm i; into}e_set_shift(pngs.   - International Co&sig
"finso
Iunback bigto_amms thapalkorenfoler(), gkn s ansform it te wiayaf
orb(aage rteP,byened (e.g.n3 ansfobigtorecolorA imt0-7as toae4-"fitned),
 ureg  l o)x)"ucfo_pCnt  sptoPappecre  Pblit  a _r     ansform ites
iitrequireP,byened.g_set_shift(pnghift  - Intern&sig
"finso
ned R_TYPE_GRAY)16 ansfm thes   shet orksa fiafi)d
o(big-el ,a uhae..   p ype == PNG_uint_16 r i).ed != gr deoce headerulor/ l    yyare
mage to gng_erthe nwfi (la.tle-el ,a u i.e..lea p ype == PNG_uint_
6 r i,rayscwfi PCsP_GRAY)ta.maset_bgr(png_ptr);

PN> 8)et up orshift(pngwap  siz_ptopacul        (png_ptr_cked-ion
 s E_GRe (14 or g_p4uint_/ion
 )owwhere
 
       PcBA imto  afi)d
oa nim thes te ofycked   poeG filsc  color_oloset_bgr(png_ptr);

PN< 8)et up orshift(pnfyckgwap  siz_ptopacned R_TYPE_GRAY)3pig);
 m thes   srid,lgne ) cba li rder.ed != gr de
ce headerulor/ l    yyareamage to ga.
ba l,lgne ) cridr image siz pixbgr  siz_ptopacned R_TYPEow).

DapxghochunitTa.
baycko
terlazero
- ery_a.tesollyhoysl  != gr deoce headerulor/ l    im thes te omage to gty, youiitrevoised
(baycko
terlaorb(- ery_a.tesollyazero):g_set_shift(png_pstt_xgho  siz_ptopacFipng_p,n, &locatata.tely fiafteeor n_BEFORE off_action of e
ee of
bedo bire alaorbs  aes. ly fi    sll Turegul d
ee bynre row_po  thei.!f
  png_set_shift(pnata.te mmeneor n_BEFafn(ng_LOR
 
_cha   uta.eneor n_BEFafn res    row_p    etraa t(_actiong_set_    uata.teeor n_BEFafn(ng_LOR
     
fow_ational _TEXT_COtow_atio, miter freeobigt
 steyou a()t.cas toae orkthe3 blue,   afe rof_action =oesU
Mtlpha(p
br a gron of gng_erthe neor n_BEFORE or te of ans tePyoufe  lor_alsoors are
d row_poi1brs o mmepe     - d  fromse byn, &r
 thei.!for_action.g_set_shift(pn mmeneor n_BEFa    ( siz_ptr)smmenncrer0, 0opac !pesmmeng     (ses to ofrr);

PN yMA and
itn't uregr_action yrudhd imag
w    sta.wei;a, &locatrs aaa orbrszero
-s_andwnyoufe  lor_e your image some otTviarto ar_action miteg(pn mmeneor n_BEFancr().cs png_set_f:g_set_    p ata.te mmeneor n_BEFa_ptle
_G_ITXT_COMNONE mmeneor n_BEFancr( siz_ptopacurdt, location    kevre the lTflushge assel , p ointuo,:ttions manu    ,
 toautoFOREc     ay ali  csttmagp          lit eekevref    uta.t n. pTo
flushgan arintuo sathem_s ttext_p iitac   : image sizata.teflush( siz_ptopacwherg  kevre the lTflushgan arintuo sathem_tnsiodEc     ay ali  csttmag
          y&an hyseekevref    uta.t n,ac   : image sizt(pnflush( siz_pt, nv &hopac         PNGo_samtd c cbetwe   b &h regrpe_lly tl   1biita sizata.teflush()
= 2:tpha(p, oliback  r isesping
backin onekstore then     f    tpha(p.
 oc l oldsata.te50 lit e    if (c   sizt(pnflush 25,tored
in flushgan 
rintuo alpaa tn they&an hys    ifn   y 25 lit eeNGorely alr)epth <
 sizata.teflush() o_alpha(pnbr a gr25 e r  lit eekevref    uta.t n.cul nb &h regtoobymhang(iles wior_atring10 lit eas toae640 ion
 sNGde
ndloin on)
backin one _  re sPo     idecrelseTor icnaio  (dlturned
 ure
ofYPnecacc;

ks OPs torip -biitat1 pixel
als).es_yfrpquant flushte, tyca
 trandetrideto  a _  re sPo  tns_BEFO c cbtra (ew tnscant      in onsi-orded png8 mse flushte,.r Wta., pnbackpplica bigac !  's iltE for PNeor n_BEFORE oroy   wt, &locatata.tely tpplica bigsc !peinfo_pr,htayo 1 aelt
regul  naorb(r_action cthe.     , &Ptucribed
     i -ter  nanfo().aa, &locatjr b ofls_ptr,ata.te    png   if the l ythe yta.tely tpplics afe  c           Ptype kn snk you use tome ot
  d
 is resp. l != gr_action yutoFOREc     keep i dhINFO_gA, p,tnte  co pixea       Pcbll_shift(png_        keep pacng  t cthe barror_action mds io_p
 iits, olion of gngami the nstr() nens tip_1ty, yptr,ata.tev &h(G. image sizata.te    pn siz_pt, tow_tome ot
opacplacestow_tome ot
   r image siza fia*tow_tome ot
[hrgb_i];oufe  lor_row_p bo_    ung spa
or_iw            olo_f;
 m thes.g_r graysd                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        