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 )