Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibPNG/libpng.3  view on Meta::CPAN

otherwise sRGB system.

Both these values are reserved (not simple gamma values) in order to allow
more precise correction internally in the future.

NOTE: the values can be passed to either the fixed or floating
point APIs, but the floating point API will also accept floating point
values.

The second thing you may need to tell libpng about is how your system handles
alpha channel information.  Some, but not all, PNG files contain an alpha
channel.  To display these files correctly you need to compose the data onto a
suitable background, as described in the PNG specification.

Libpng only supports composing onto a single color (using png_set_background;
see below).  Otherwise you must do the composition yourself and, in this case,
you may need to call png_set_alpha_mode:

   #if PNG_LIBPNG_VER >= 10504
      png_set_alpha_mode(png_ptr, mode, screen_gamma);
   #else
      png_set_gamma(png_ptr, screen_gamma, 1.0/screen_gamma);
   #endif

The screen_gamma value is the same as the argument to png_set_gamma; however,
how it affects the output depends on the mode.  png_set_alpha_mode() sets the
file gamma default to 1/screen_gamma, so normally you don't need to call
png_set_gamma.  If you need different defaults call png_set_gamma() before
png_set_alpha_mode() - if you call it after it will override the settings made
by png_set_alpha_mode().

The mode is as follows:

    PNG_ALPHA_PNG: The data is encoded according to the PNG
specification.  Red, green and blue, or gray, components are
gamma encoded color values and are not premultiplied by the
alpha value.  The alpha value is a linear measure of the
contribution of the pixel to the corresponding final output pixel.

You should normally use this format if you intend to perform
color correction on the color values; most, maybe all, color
correction software has no handling for the alpha channel and,
anyway, the math to handle pre-multiplied component values is
unnecessarily complex.

Before you do any arithmetic on the component values you need
to remove the gamma encoding and multiply out the alpha
channel.  See the PNG specification for more detail.  It is
important to note that when an image with an alpha channel is
scaled, linear encoded, pre-multiplied component values must
be used!

The remaining modes assume you don't need to do any further color correction or
that if you do, your color correction software knows all about alpha (it
probably doesn't!).  They 'associate' the alpha with the color information by
storing color channel values that have been scaled by the alpha.  The
advantage is that the color channels can be resampled (the image can be
scaled) in this form.  The disadvantage is that normal practice is to store
linear, not (gamma) encoded, values and this requires 16-bit channels for
still images rather than the 8-bit channels that are just about sufficient if
gamma encoding is used.  In addition all non-transparent pixel values,
including completely opaque ones, must be gamma encoded to produce the final
image.  These are the 'STANDARD', 'ASSOCIATED' or 'PREMULTIPLIED' modes
described below (the latter being the two common names for associated alpha
color channels). Note that PNG files always contain non-associated color
channels; png_set_alpha_mode() with one of the modes causes the decoder to
convert the pixels to an associated form before returning them to your
application. 

Since it is not necessary to perform arithmetic on opaque color values so
long as they are not to be resampled and are in the final color space it is
possible to optimize the handling of alpha by storing the opaque pixels in
the PNG format (adjusted for the output color space) while storing partially
opaque pixels in the standard, linear, format.  The accuracy required for
standard alpha composition is relatively low, because the pixels are
isolated, therefore typically the accuracy loss in storing 8-bit linear
values is acceptable.  (This is not true if the alpha channel is used to
simulate transparency over large areas - use 16 bits or the PNG mode in
this case!)  This is the 'OPTIMIZED' mode.  For this mode a pixel is
treated as opaque only if the alpha value is equal to the maximum value.

    PNG_ALPHA_STANDARD:  The data libpng produces is encoded in the
standard way assumed by most correctly written graphics software.
The gamma encoding will be removed by libpng and the
linear component values will be pre-multiplied by the
alpha channel.

With this format the final image must be re-encoded to
match the display gamma before the image is displayed.
If your system doesn't do that, yet still seems to
perform arithmetic on the pixels without decoding them,
it is broken - check out the modes below.

With PNG_ALPHA_STANDARD libpng always produces linear
component values, whatever screen_gamma you supply.  The
screen_gamma value is, however, used as a default for
the file gamma if the PNG file has no gamma information.

If you call png_set_gamma() after png_set_alpha_mode() you
will override the linear encoding.  Instead the
pre-multiplied pixel values will be gamma encoded but
the alpha channel will still be linear.  This may
actually match the requirements of some broken software,
but it is unlikely.

While linear 8-bit data is often used it has
insufficient precision for any image with a reasonable
dynamic range.  To avoid problems, and if your software
supports it, use png_set_expand_16() to force all
components to 16 bits.

    PNG_ALPHA_OPTIMIZED: This mode is the same as PNG_ALPHA_STANDARD
except that completely opaque pixels are gamma encoded according to
the screen_gamma value.  Pixels with alpha less than 1.0
will still have linear components.

Use this format if you have control over your
compositing software and so don't do other arithmetic
(such as scaling) on the data you get from libpng.  Your
compositing software can simply copy opaque pixels to
the output but still has linear values for the

src/Source/LibPNG/libpng.3  view on Meta::CPAN

   png_set_alpha_mode(png_ptr, PNG_ALPHA_STANDARD,
       screen_gamma);
   png_set_expand_16(png_ptr);

If you are using the high level interface, don't call png_set_expand_16();
instead pass PNG_TRANSFORM_EXPAND_16 to the interface.

With this mode you can't do color correction, but you can do arithmetic,
including composition and scaling, on the data without further processing.

   png_set_alpha_mode(png_ptr, PNG_ALPHA_OPTIMIZED,
       screen_gamma);

You can avoid the expansion to 16-bit components with this mode, but you
lose the ability to scale the image or perform other linear arithmetic.
All you can do is compose the result onto a matching output.  Since this
mode is libpng-specific you also need to write your own composition
software.

The following are examples of calls to png_set_alpha_mode to achieve the
required overall gamma correction and, where necessary, alpha
premultiplication.

    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);

This is the default libpng handling of the alpha channel - it is not
pre-multiplied into the color components.  In addition the call states
that the output is for a sRGB system and causes all PNG files without gAMA
chunks to be assumed to be encoded using sRGB.

    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);

In this case the output is assumed to be something like an sRGB conformant
display preceeded by a power-law lookup table of power 1.45.  This is how
early Mac systems behaved.

    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_GAMMA_LINEAR);

This is the classic Jim Blinn approach and will work in academic
environments where everything is done by the book.  It has the shortcoming
of assuming that input PNG data with no gamma information is linear - this
is unlikely to be correct unless the PNG files where generated locally.
Most of the time the output precision will be so low as to show
significant banding in dark areas of the image.

    png_set_expand_16(pp);
    png_set_alpha_mode(pp, PNG_ALPHA_STANDARD, PNG_DEFAULT_sRGB);

This is a somewhat more realistic Jim Blinn inspired approach.  PNG files
are assumed to have the sRGB encoding if not marked with a gamma value and
the output is always 16 bits per component.  This permits accurate scaling
and processing of the data.  If you know that your input PNG files were
generated locally you might need to replace PNG_DEFAULT_sRGB with the
correct value for your system.

    png_set_alpha_mode(pp, PNG_ALPHA_OPTIMIZED, PNG_DEFAULT_sRGB);

If you just need to composite the PNG image onto an existing background
and if you control the code that does this you can use the optimization
setting.  In this case you just copy completely opaque pixels to the
output.  For pixels that are not completely transparent (you just skip
those) you do the composition math using png_composite or png_composite_16
below then encode the resultant 8-bit or 16-bit values to match the output
encoding.

    Other cases

If neither the PNG nor the standard linear encoding work for you because
of the software or hardware you use then you have a big problem.  The PNG
case will probably result in halos around the image.  The linear encoding
will probably result in a washed out, too bright, image (it's actually too
contrasty.)  Try the ALPHA_OPTIMIZED mode above - this will probably
substantially reduce the halos.  Alternatively try:

    png_set_alpha_mode(pp, PNG_ALPHA_BROKEN, PNG_DEFAULT_sRGB);

This option will also reduce the halos, but there will be slight dark
halos round the opaque parts of the image where the background is light.
In the OPTIMIZED mode the halos will be light halos where the background
is dark.  Take your pick - the halos are unavoidable unless you can get
your hardware/software fixed!  (The OPTIMIZED approach is slightly
faster.)

When the default gamma of PNG files doesn't match the output gamma.
If you have PNG files with no gamma information png_set_alpha_mode allows
you to provide a default gamma, but it also sets the ouput gamma to the
matching value.  If you know your PNG files have a gamma that doesn't
match the output you can take advantage of the fact that
png_set_alpha_mode always sets the output gamma but only sets the PNG
default if it is not already set:

    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_DEFAULT_sRGB);
    png_set_alpha_mode(pp, PNG_ALPHA_PNG, PNG_GAMMA_MAC);

The first call sets both the default and the output gamma values, the
second call overrides the output gamma without changing the default.  This
is easier than achieving the same effect with png_set_gamma.  You must use
PNG_ALPHA_PNG for the first call - internal checking in png_set_alpha will
fire if more than one call to png_set_alpha_mode and png_set_background is
made in the same read operation, however multiple calls with PNG_ALPHA_PNG
are ignored.

If you don't need, or can't handle, the alpha channel you can call
png_set_background() to remove it by compositing against a fixed color.  Don't
call png_set_strip_alpha() to do this - it will leave spurious pixel values in
transparent parts of this image.

   png_set_background(png_ptr, &background_color,
       PNG_BACKGROUND_GAMMA_SCREEN, 0, 1);

The background_color is an RGB or grayscale value according to the data format
libpng will produce for you.  Because you don't yet know the format of the PNG
file, if you call png_set_background at this point you must arrange for the
format produced by libpng to always have 8-bit or 16-bit components and then
store the color as an 8-bit or 16-bit color as appropriate.  The color contains
separate gray and RGB component values, so you can let libpng produce gray or
RGB output according to the input format, but low bit depth grayscale images
must always be converted to at least 8-bit format.  (Even though low bit depth
grayscale images can't have an alpha channel they can have a transparent
color!)

You set the transforms you need later, either as flags to the high level
interface or libpng API calls for the low level interface.  For reference the
settings and API calls required are:

8-bit values:
   PNG_TRANSFORM_SCALE_16 | PNG_EXPAND
   png_set_expand(png_ptr); png_set_scale_16(png_ptr);

   If you must get exactly the same inaccurate results
   produced by default in versions prior to libpng-1.5.4,
   use PNG_TRANSFORM_STRIP_16 and png_set_strip_16(png_ptr)
   instead.

16-bit values:
   PNG_TRANSFORM_EXPAND_16
   png_set_expand_16(png_ptr);

In either case palette image data will be expanded to RGB.  If you just want
color data you can add PNG_TRANSFORM_GRAY_TO_RGB or png_set_gray_to_rgb(png_ptr)
to the list.

Calling png_set_background before the PNG file header is read will not work
prior to libpng-1.5.4.  Because the failure may result in unexpected warnings or
errors it is therefore much safer to call png_set_background after the head has
been read.  Unfortunately this means that prior to libpng-1.5.4 it cannot be
used with the high level interface.

.SS 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_SCALE_16      Strip 16-bit samples to
                                8-bit accurately
    PNG_TRANSFORM_STRIP_16      Chop 16-bit samples to
                                8-bit less accurately
    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
    PNG_TRANSFORM_GRAY_TO_RGB   Expand grayscale samples
                                to RGB (or GA to RGBA)

src/Source/LibPNG/libpng.3  view on Meta::CPAN


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/(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*(sizeof (png_bytep)));

   for (int i=0; i<height, i++)
      row_pointers[i]=NULL;  /* security precaution */

   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 by libpng when you call png_destroy_*().

.SS 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.

This also copies some of the data from the PNG file into the decode structure
for use in later transformations.  Important information copied in is:

1) The PNG file gamma from the gAMA chunk.  This overwrites the default value
provided by an earlier call to png_set_gamma or png_set_alpha_mode.

2) Prior to libpng-1.5.4 the background color from a bKGd chunk.  This
damages the information provided by an earlier call to png_set_background
resulting in unexpected behavior.  Libpng-1.5.4 no longer does this.

3) The number of significant bits in each component value.  Libpng uses this to
optimize gamma handling by reducing the internal lookup table sizes.

4) The transparent color information from a tRNS chunk.  This can be modified by
a later call to png_set_tRNS.

.SS 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

    interlace_type - (PNG_INTERLACE_NONE or
                     PNG_INTERLACE_ADAM7)

    compression_type - (must be PNG_COMPRESSION_TYPE_BASE
                     for PNG 1.0)

    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)

    Any or all of interlace_type, compression_type, or
    filter_method can be NULL if you are
    not interested in their values.

    Note that png_get_IHDR() returns 32-bit data into
    the application's width and height variables.
    This is an unsafe situation if these are 16-bit
    variables.  In such situations, the
    png_get_image_width() and png_get_image_height()
    functions described below are safer.

    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);

    interlace_type   = png_get_interlace_type(png_ptr,
                         info_ptr);

    compression_type = png_get_compression_type(png_ptr,
                         info_ptr);

    filter_method    = png_get_filter_type(png_ptr,
                         info_ptr);

    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())).

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.

The colorspace data from gAMA, cHRM, sRGB, iCCP, and sBIT chunks
is simply returned to give the application information about how the
image was encoded.  Libpng itself only does transformations using the file
gamma when combining semitransparent pixels with the background color, and,
since libpng-1.6.0, when converting between 8-bit sRGB and 16-bit linear pixels
within the simplified API.  Libpng also uses the file gamma when converting
RGB to gray, beginning with libpng-1.0.5, if the application calls
png_set_rgb_to_gray()).

    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, &file_gamma);
    png_get_gAMA_fixed(png_ptr, info_ptr, &int_file_gamma);

    file_gamma     - the gamma at which the file is
                     written (PNG_INFO_gAMA)

    int_file_gamma - 100,000 times the gamma at which the
                     file is written

    png_get_cHRM(png_ptr, info_ptr,  &white_x, &white_y, &red_x,
                     &red_y, &green_x, &green_y, &blue_x, &blue_y)
    png_get_cHRM_XYZ(png_ptr, info_ptr, &red_X, &red_Y, &red_Z,
                     &green_X, &green_Y, &green_Z, &blue_X, &blue_Y,
                     &blue_Z)
    png_get_cHRM_fixed(png_ptr, info_ptr, &int_white_x,
                     &int_white_y, &int_red_x, &int_red_y,
                     &int_green_x, &int_green_y, &int_blue_x,
                     &int_blue_y)
    png_get_cHRM_XYZ_fixed(png_ptr, info_ptr, &int_red_X, &int_red_Y,
                     &int_red_Z, &int_green_X, &int_green_Y,
                     &int_green_Z, &int_blue_X, &int_blue_Y,
                     &int_blue_Z)

    {white,red,green,blue}_{x,y}
                     A color space encoding specified using the
                     chromaticities of the end points and the
                     white point. (PNG_INFO_cHRM)

    {red,green,blue}_{X,Y,Z}
                     A color space encoding specified using the
                     encoding end points - the CIE tristimulus
                     specification of the intended color of the red,
                     green and blue channels in the PNG RGB data.
                     The white point is simply the sum of the three
                     end points. (PNG_INFO_cHRM)

    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_type - 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_alpha,
                     &num_trans, &trans_color);

    trans_alpha    - array of alpha (transparency)
                     entries for palette (PNG_INFO_tRNS)

    num_trans      - number of transparent entries
                     (PNG_INFO_tRNS)

    trans_color    - graylevel or color sample values of
                     the single transparent color for
                     non-paletted images (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 (of type
                     png_color_16p) (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).

    Note that the itxt_length, lang, and lang_key
    members of the text_ptr structure only exist when the
    library is built with iTXt chunk support.  Prior to
    libpng-1.4.0 the library was built by default without
    iTXt support. Also note that when iTXt is supported,
    they contain NULL pointers when the "compression"
    field contains PNG_TEXT_COMPRESSION_NONE or
    PNG_TEXT_COMPRESSION_zTXt.

src/Source/LibPNG/libpng.3  view on Meta::CPAN

major ommissions are conversion of grayscale to indexed images (which can be
done trivially in the application) and conversion of indexed to grayscale (which
can be done by a trivial manipulation of the palette.)

In the following table, the 01 means grayscale with depth<8, 31 means
indexed with depth<8, other numerals represent the color type, "T" means
the tRNS chunk is present, A means an alpha channel is present, and O
means tRNS or alpha is present but all pixels in the image are opaque.

  FROM  01  31   0  0T  0O   2  2T  2O   3  3T  3O  4A  4O  6A  6O
   TO
   01    -  [G]  -   -   -   -   -   -   -   -   -   -   -   -   -
   31   [Q]  Q  [Q] [Q] [Q]  Q   Q   Q   Q   Q   Q  [Q] [Q]  Q   Q
    0    1   G   +   .   .   G   G   G   G   G   G   B   B  GB  GB
   0T    lt  Gt  t   +   .   Gt  G   G   Gt  G   G   Bt  Bt GBt GBt
   0O    lt  Gt  t   .   +   Gt  Gt  G   Gt  Gt  G   Bt  Bt GBt GBt
    2    C   P   C   C   C   +   .   .   C   -   -  CB  CB   B   B
   2T    Ct  -   Ct  C   C   t   +   t   -   -   -  CBt CBt  Bt  Bt
   2O    Ct  -   Ct  C   C   t   t   +   -   -   -  CBt CBt  Bt  Bt
    3   [Q]  p  [Q] [Q] [Q]  Q   Q   Q   +   .   .  [Q] [Q]  Q   Q
   3T   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   +   t  [Qt][Qt] Qt  Qt
   3O   [Qt] p  [Qt][Q] [Q]  Qt  Qt  Qt  t   t   +  [Qt][Qt] Qt  Qt
   4A    lA  G   A   T   T   GA  GT  GT  GA  GT  GT  +   BA  G  GBA
   4O    lA GBA  A   T   T   GA  GT  GT  GA  GT  GT  BA  +  GBA  G
   6A    CA  PA  CA  C   C   A   T  tT   PA  P   P   C  CBA  +   BA
   6O    CA PBA  CA  C   C   A  tT   T   PA  P   P  CBA  C   BA  +

Within the matrix,
     "+" identifies entries where 'from' and 'to' are the same.
     "-" means the transformation is not supported.
     "." means nothing is necessary (a tRNS chunk can just be ignored).
     "t" means the transformation is obtained by png_set_tRNS.
     "A" means the transformation is obtained by png_set_add_alpha().
     "X" means the transformation is obtained by png_set_expand().
     "1" means the transformation is obtained by
         png_set_expand_gray_1_2_4_to_8() (and by png_set_expand()
         if there is no transparency in the original or the final
         format).
     "C" means the transformation is obtained by png_set_gray_to_rgb().
     "G" means the transformation is obtained by png_set_rgb_to_gray().
     "P" means the transformation is obtained by
         png_set_expand_palette_to_rgb().
     "p" means the transformation is obtained by png_set_packing().
     "Q" means the transformation is obtained by png_set_quantize().
     "T" means the transformation is obtained by
         png_set_tRNS_to_alpha().
     "B" means the transformation is obtained by
         png_set_background(), or png_strip_alpha().

When an entry has multiple transforms listed all are required to cause the
right overall transformation.  When two transforms are separated by a comma
either will do the job.  When transforms are enclosed in [] the transform should
do the job but this is currently unimplemented - a different format will result
if the suggested transformations are used.

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

src/Source/LibPNG/libpng.3  view on Meta::CPAN

    png_set_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.  Rendering
                     intent is the CSS-1 property that
                     has been defined by the International
                     Color Consortium
                     (http://www.color.org).
                     It can be one of
                     PNG_sRGB_INTENT_SATURATION,
                     PNG_sRGB_INTENT_PERCEPTUAL,
                     PNG_sRGB_INTENT_ABSOLUTE, or
                     PNG_sRGB_INTENT_RELATIVE.


    png_set_sRGB_gAMA_and_cHRM(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 function also causes gAMA and
                     cHRM chunks with the specific values
                     that are consistent with sRGB to be
                     written.

    png_set_iCCP(png_ptr, info_ptr, name, compression_type,
                       profile, proflen);

    name             - The profile name.

    compression_type - 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_set_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_set_tRNS(png_ptr, info_ptr, trans_alpha,
       num_trans, trans_color);

    trans_alpha    - array of alpha (transparency)
                     entries for palette (PNG_INFO_tRNS)

    num_trans      - number of transparent entries
                     (PNG_INFO_tRNS)

    trans_color    - graylevel or color sample values
                     (in order red, green, blue) of the
                     single transparent color for
                     non-paletted images (PNG_INFO_tRNS)

    png_set_hIST(png_ptr, info_ptr, hist);

    hist           - histogram of palette (array of
                     png_uint_16) (PNG_INFO_hIST)

    png_set_tIME(png_ptr, info_ptr, mod_time);

    mod_time       - time image was last modified
                     (PNG_VALID_tIME)

    png_set_bKGD(png_ptr, info_ptr, background);

    background     - background color (of type
                     png_color_16p) (PNG_VALID_bKGD)

    png_set_text(png_ptr, info_ptr, text_ptr, num_text);

    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 NULL or 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 (NULL or
                         empty for unknown).
    text_ptr[i].translated_keyword  - keyword in UTF-8 (NULL
                         or empty for unknown).

    Note that the itxt_length, lang, and lang_key
    members of the text_ptr structure only exist when the
    library is built with iTXt chunk support.  Prior to
    libpng-1.4.0 the library was built by default without
    iTXt support. Also note that when iTXt is supported,
    they contain NULL pointers when the "compression"
    field contains PNG_TEXT_COMPRESSION_NONE or
    PNG_TEXT_COMPRESSION_zTXt.

    num_text       - number of comments

    png_set_sPLT(png_ptr, info_ptr, &palette_ptr,
       num_spalettes);

    palette_ptr    - array of png_sPLT_struct structures
                     to be added to the list of palettes
                     in the info structure.
    num_spalettes  - number of palette structures to be
                     added.

src/Source/LibPNG/libpng.3  view on Meta::CPAN

    # endif
    #endif

.SS The high-level write interface

At this point there are two ways to proceed; through the high-level
write interface, or through a sequence of low-level write operations.
You can use the high-level interface if your image data is present
in the info structure.  All defined output
transformations are permitted, enabled by the following masks.

    PNG_TRANSFORM_IDENTITY      No transformation
    PNG_TRANSFORM_PACKING       Pack 1, 2 and 4-bit samples
    PNG_TRANSFORM_PACKSWAP      Change order of packed
                                pixels to LSB first
    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
    PNG_TRANSFORM_STRIP_FILLER        Strip out filler
                                      bytes (deprecated).
    PNG_TRANSFORM_STRIP_FILLER_BEFORE Strip out leading
                                      filler bytes
    PNG_TRANSFORM_STRIP_FILLER_AFTER  Strip out trailing
                                      filler bytes

If you have valid image data in the info structure (you can use
png_set_rows() to put image data in the info structure), simply do this:

    png_write_png(png_ptr, info_ptr, png_transforms, NULL)

where png_transforms is an integer containing the bitwise OR of some set of
transformation flags.  This call is equivalent to png_write_info(),
followed the set of transformations indicated by the transform mask,
then png_write_image(), and finally png_write_end().

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

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

.SS The low-level write interface

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

    png_write_info(png_ptr, info_ptr);

Note that there is one transformation you may need to do before
png_write_info().  In PNG files, the alpha channel in an image is the
level of opacity.  If your data is supplied as a level of transparency,
you can invert the alpha channel before you write it, so that 0 is
fully transparent and 255 (in 8-bit or paletted images) or 65535
(in 16-bit images) is fully opaque, with

    png_set_invert_alpha(png_ptr);

This must appear before png_write_info() instead of later with the
other transformations because in the case of paletted images the tRNS
chunk data has to be inverted before the tRNS chunk is written.  If
your image is not a paletted image, the tRNS data (which in such cases
represents a single color to be rendered as transparent) won't need to
be changed, and you can safely do this transformation after your
png_write_info() call.

If you need to write a private chunk that you want to appear before
the PLTE chunk when PLTE is present, you can write the PNG info in
two steps, and insert code to write your own chunk between them:

    png_write_info_before_PLTE(png_ptr, info_ptr);
    png_set_unknown_chunks(png_ptr, info_ptr, ...);
    png_write_info(png_ptr, info_ptr);

After you've written the file 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.

PNG files store RGB pixels packed into 3 or 6 bytes.  This code tells
the library to strip input data that has 4 or 8 bytes per pixel down
to 3 or 6 bytes (or strip 2 or 4-byte grayscale+filler data to 1 or 2
bytes per pixel).

    png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);

where the 0 is unused, and the location is either PNG_FILLER_BEFORE or
PNG_FILLER_AFTER, depending upon whether the filler byte in the pixel
is stored XRGB or RGBX.

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.
If the data is supplied at 1 pixel per byte, use this code, which will
correctly pack the pixels into a single byte:

    png_set_packing(png_ptr);

PNG files reduce possible bit depths to 1, 2, 4, 8, and 16.  If your
data is of another bit depth, you can write an sBIT chunk into the
file so that decoders can recover the original data if desired.

    /* Set the true bit depth of the image data */
    if (color_type & PNG_COLOR_MASK_COLOR)
    {
       sig_bit.red = true_bit_depth;
       sig_bit.green = true_bit_depth;
       sig_bit.blue = true_bit_depth;
    }

    else
    {
       sig_bit.gray = true_bit_depth;
    }

    if (color_type & PNG_COLOR_MASK_ALPHA)
    {
       sig_bit.alpha = true_bit_depth;
    }



( run in 0.454 second using v1.01-cache-2.11-cpan-2ed5026b665 )