.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Image::PNG::Libpng 3pm" .TH Image::PNG::Libpng 3pm "2022-10-19" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" Image::PNG::Libpng \- Perl interface to the C library "libpng". .SH "SYNOPSIS" .IX Header "SYNOPSIS" Libpng-like interface: .PP .Vb 10 \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& my $png = create_read_struct (); \& open my $file, \*(Aq<:raw\*(Aq, \*(Aqnice.png\*(Aq or die $!; \& $png\->init_io ($file); \& $png\->read_png (); \& close $file; \& # Get all valid chunks \& my $valid = $png\->get_valid (); \& my @valid_chunks = sort grep {$valid\->{$_}} keys %$valid; \& print "Valid chunks are ", join (", ", @valid_chunks), "\en"; \& # Print image information \& my $header = $png\->get_IHDR (); \& for my $k (keys %$header) { \& print "$k: $header\->{$k}\en"; \& } .Ve .PP (This example is included as \fIexamples/synopsis.pl\fR in the distribution.) .PP Simple interface: .PP .Vb 10 \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& my $png = read_png_file (\*(Aq../t/tantei\-san.png\*(Aq); \& # Get all valid chunks \& my $valid = $png\->get_valid (); \& my @valid_chunks = sort grep {$valid\->{$_}} keys %$valid; \& print "Valid chunks are ", join (", ", @valid_chunks), "\en"; \& # Print image information \& my $header = $png\->get_IHDR (); \& for my $k (keys %$header) { \& if ($k eq \*(Aqcolor_type\*(Aq) { \& print "$k: " . color_type_name ($header\->{$k}) . "\en"; \& } \& else { \& print "$k: $header\->{$k}\en"; \& } \& } \& my $wpng = $png\->copy_png (); \& $wpng\->write_png_file (\*(Aqnew.png\*(Aq); .Ve .PP (This example is included as \fIexamples/synopsis\-easy.pl\fR in the distribution.) .SH "VERSION" .IX Header "VERSION" This document describes Image::PNG::Libpng version 0.57, corresponding to git commit unknown at unknown. .PP Unless otherwise qualified, comments in this document on the libpng source code and documentation refer to libpng version 1.6.37. Libpng is not bundled with this distribution, so your installed version may vary. .SH "DESCRIPTION" .IX Header "DESCRIPTION" Image::PNG::Libpng is a Perl library for accessing the contents of \s-1PNG\s0 (Portable Network Graphics) images. Image::PNG::Libpng enables Perl to use the \*(L"libpng\*(R" library to read and write files in \s-1PNG\s0 format. Image::PNG::Libpng does not contain the libpng library. The libpng library must be installed on your computer prior to installing Image::PNG::Libpng. .PP Image::PNG::Libpng consists of Perl subroutines which mirror the C functions in libpng, plus helper subroutines to make it easier to read and write \s-1PNG\s0 data in Perl. .PP For those familiar with libpng, the section \*(L"Differences from libpng\*(R" explains the differences with libpng. .SH "FUNCTIONS" .IX Header "FUNCTIONS" The functions in the module are gathered into the following categories: \*(L"Simple input and output\*(R", which describes some convenience functions, \*(L"Libpng-style input and output\*(R", which describes functions which closely mirror libpng, \*(L"The image header\*(R", which describes functions for reading and writing the meta-information about \s-1PNG\s0 images, \*(L"Image data\*(R", which describes functions for accessing the image data itself, \*(L"Text chunks\*(R", \*(L"Private chunks\*(R", \&\*(L"Library version functions\*(R", \*(L"Compression and filtering\*(R", \*(L"Other chunks\*(R", \*(L"Libpng transformations\*(R", \*(L"Other libpng functions\*(R", functions from libpng which don't fit elsewhere, and \*(L"Other functions\*(R", which are functions specific to this module. .SH "Simple input and output" .IX Header "Simple input and output" These convenience functions combine common operations. They are not part of the original libpng \s-1API.\s0 .SS "copy_png" .IX Subsection "copy_png" .Vb 1 \& my $outpng = $png\->copy_png (); .Ve .PP Copy a \s-1PNG\s0 from a read to a write structure. This function bridges two kinds of object, \*(L"read a png\*(R" objects created by \&\*(L"create_read_struct\*(R" and \*(L"write a png\*(R" objects created by \&\*(L"create_write_struct\*(R". This function copies all the valid chunks from a read structure to a write structure. .PP The following example demonstrates copying a \s-1PNG.\s0 .PP .Vb 7 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng qw(read_png_file write_png_file) ; \& my $pngin = read_png_file ("$Bin/../t/tantei\-san.png"); \& my $pngout = $pngin\->copy_png (); \& $pngout\->set_text ([{key => \*(AqName\*(Aq, text => \*(AqShunsaku Kudo\*(Aq}]); \& # $pngout\->write_png_file (\*(Aqcopy.png\*(Aq); .Ve .PP (This example is included as \fIexamples/copy\-png.pl\fR in the distribution.) .SS "create_reader" .IX Subsection "create_reader" .Vb 2 \& my $png = create_reader (\*(Aqfile.png\*(Aq); \& $png\->read_png (); .Ve .PP This combines \*(L"create_read_struct\*(R", \f(CW\*(C`open\*(C'\fR, and \*(L"init_io\*(R" on the specified file name but does not read the file in. This is for the case that the user wants to apply some kind of transformation. .PP \fISetting the background\fR .IX Subsection "Setting the background" .PP In the following example, the user sets the background with \&\*(L"set_background\*(R" to replace the alpha channel. .PP .Vb 11 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& my $file = "$Bin/luv.png"; \& my %color = (red => 0xC0, green => 0xFF, blue => 0xFF); \& my $png = create_reader ($file); \& $png\->set_background (\e%color, PNG_BACKGROUND_GAMMA_SCREEN, 0); \& $png\->read_png (); \& my $wpng = copy_png ($png); \& $wpng\->write_png_file ("$Bin/set\-background.png"); .Ve .PP (This example is included as \fIexamples/set\-background.pl\fR in the distribution.) .PP examples/luv.png is included in the distribution. .PP examples/set\-background.png is included in the distribution. .PP This function was added to the module in version 0.53. .SS "create_writer" .IX Subsection "create_writer" .Vb 4 \& my $png = create_writer (\*(Aqfile.png\*(Aq); \& $png\->set_IHDR (\e%ihdr); \& $png\->set_rows (\e@rows); \& $png\->write_png (); .Ve .PP This combines \*(L"create_write_struct\*(R", \f(CW\*(C`open\*(C'\fR, and \*(L"init_io\*(R" on the specified file name but does not read the file in. This is for the case that the user wants to apply some kind of transformation before writing. .PP This function was added to the module in version 0.53. .SS "read_from_scalar" .IX Subsection "read_from_scalar" .Vb 1 \& my $png = read_from_scalar ($string); .Ve .PP This creates an image structure \f(CW$png\fR from the contents of a Perl scalar variable \f(CW$string\fR containing \s-1PNG\s0 image data, for example data read from a file, or data obtained from a web page. The first argument, \f(CW$png\fR, is a \s-1PNG\s0 structure created with \&\*(L"create_read_struct\*(R". It reads in all the data from the structure on being called. .PP This is useful when image data is stored in a Perl scalar. For example .PP .Vb 11 \& use Image::PNG::Libpng \*(Aqread_from_scalar\*(Aq; \& use LWP::Simple; \& use JSON::Create; \& my $image_data = get \*(Aqhttp://libpng.org/pub/png/img_png/libpng\-88x31.png\*(Aq; \& # Now $image_data contains the PNG file \& my $png = read_from_scalar ($image_data); \& # Now $png contains the PNG information from the image. \& # Get the header. \& my $header = $png\->get_IHDR (); \& my $jc = JSON::Create\->new (indent => 1, sort => 1); \& print $jc\->run ($header); .Ve .PP (This example is included as \fIexamples/get\-www\-png.pl\fR in the distribution.) .PP The output looks like this: .PP .Vb 7 \& { \& "bit_depth":4, \& "color_type":3, \& "height":31, \& "interlace_method":0, \& "width":88 \& } .Ve .PP See also \*(L"Input/output manipulation functions\*(R". .SS "read_png_file" .IX Subsection "read_png_file" .Vb 1 \& my $png = read_png_file (\*(Aqq.png\*(Aq); .Ve .PP Open \fIq.png\fR and read its contents into \f(CW$png\fR. .PP This combines \*(L"create_read_struct\*(R", \f(CW\*(C`open\*(C'\fR, \*(L"init_io\*(R", and \&\*(L"read_png\*(R". The return value is the same as that of \&\*(L"create_read_struct\*(R" with the entire \s-1PNG\s0 image already read in. .PP The optional argument to \*(L"read_png\*(R" can be specified using an optional \f(CW\*(C`transforms\*(C'\fR argument: .PP .Vb 1 \& my $png = read_png_file (\*(Aqfile.png\*(Aq, transforms => PNG_TRANSFORM_EXPAND); .Ve .PP \&\*(L"croak\*(R" in Carp is used to signal errors opening or closing the file. .SS "set_transforms" .IX Subsection "set_transforms" .Vb 1 \& $png\->set_transforms (PNG_TRANSFORM_BGR); .Ve .PP Set transforms for reading and writing. This is the same as the optional argument to \*(L"read_png\*(R" or \*(L"write_png\*(R". If both this and the optional argument are given, the optional argument overrides what is set here. .SS "write_png_file" .IX Subsection "write_png_file" .Vb 1 \& $png\->write_png_file (\*(Aqnice.png\*(Aq); .Ve .PP This combines open, \*(L"init_io\*(R", and \*(L"write_png\*(R" to write an entire \&\s-1PNG\s0 image out to the file name specified by the argument. \f(CW$png\fR must be the object created by \*(L"create_write_struct\*(R", so \*(L"read_png_file\*(R" followed by a call to this does not work. See \*(L"copy_png\*(R" if you need to do that kind of operation. .PP The optional argument to \*(L"write_png\*(R" can be specified using \&\*(L"set_transforms\*(R". .PP \&\*(L"croak\*(R" in Carp is used to signal errors opening or closing the file. .SS "write_to_scalar" .IX Subsection "write_to_scalar" .Vb 1 \& my $image_data = $png\->write_to_scalar (); .Ve .PP This writes the \s-1PNG\s0 image data in \f(CW$png\fR into a Perl scalar. The first argument, \f(CW$png\fR, is a writeable \s-1PNG\s0 structure created with \&\*(L"create_write_struct\*(R". The return value of the subroutine is the Perl scalar containing the image data. .PP So, for example, .PP .Vb 1 \& # This CGI script prints a PNG in a random colour. \& \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& my $png = create_write_struct (); \& my $size = 100; \& $png\->set_IHDR ({height => $size, width => $size, bit_depth => 8, \& color_type => PNG_COLOR_TYPE_RGB}); \& my $bytes = pack "CCC", randcol (), randcol (), randcol (); \& my @rows = ($bytes x $size) x $size; \& $png\->set_rows (\e@rows); \& my $img = $png\->write_to_scalar (); \& binmode STDOUT; \& print "Content\-Type:image/png\er\en\er\en$img"; \& exit; \& sub randcol \& { \& return int (rand () * 0x100); \& } .Ve .PP (This example is included as \fIexamples/png\-cgi.pl\fR in the distribution.) .PP See also \*(L"Input/output manipulation functions\*(R". .PP The optional argument to \*(L"write_png\*(R" can be specified using \&\*(L"set_transforms\*(R". .SH "Libpng-style input and output" .IX Header "Libpng-style input and output" There are two different \*(L"new\*(R"\-like functions, depending on whether you want to read or write a \s-1PNG,\s0 \*(L"create_read_struct\*(R" and \&\*(L"create_write_struct\*(R". These are based on the libpng \s-1API.\s0 Input uses \&\f(CW\*(C`open\*(C'\fR plus \*(L"init_io\*(R" followed by \*(L"read_png\*(R" or \*(L"write_png\*(R". .SS "Examples" .IX Subsection "Examples" \fIA self-pixellating program\fR .IX Subsection "A self-pixellating program" .PP This example demonstrates writing a monochrome \s-1PNG\s0 by creating a write structure with \*(L"create_write_struct\*(R", opening a filehandle to write it, associating the filehandle with the \s-1PNG\s0 structure with \&\*(L"init_io\*(R", then using the functions \*(L"write_info\*(R", \*(L"write_image\*(R", and then \*(L"write_end\*(R" to actually write the \s-1PNG\s0 data to the file. .PP .Vb 10 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& my $outfile = "$Bin/mono.png"; \& my ($height, $width, $rows) = pixelate (_\|_FILE_\|_, 5); \& my $png = create_write_struct (); \& open my $out, ">:raw", $outfile or die $!; \& $png\->init_io ($out); \& $png\->set_IHDR ({height => $height, width => $width, bit_depth => 1, \& color_type => PNG_COLOR_TYPE_GRAY}); \& $png\->set_text ([{key => \*(Aqsilly\*(Aq, text => \*(Aqfinely\-tuned breakfast cereal\*(Aq,}]); \& $png\->set_tIME ({year => 1999}); \& $png\->write_info (); \& $png\->set_invert_mono (); \& # PNG puts the leftmost pixel in the high\-order part of the byte. \& $png\->set_packswap (); \& $png\->write_image ($rows); \& $png\->write_end (); \& close $out or die $!; \& exit; \& \& sub pixelate \& { \& my ($file, $box) = @_; \& open my $in, "<", $file or die "Can\*(Aqt open \*(Aq$file\*(Aq: $!"; \& my $width = 0; \& my @lines; \& while (<$in>) { \& chomp; \& s/\et/ /g; \& push @lines, $_; \& if (length ($_) > $width) { \& $width = length ($_); \& } \& } \& close $in or die $!; \& $width *= $box; \& my $height = scalar (@lines) * $box; \& my $zero = pack "C", 0; \& my $bwidth = int(($width+7)/8); \& my @rows = ($zero x $bwidth) x $height; \& for my $r (0..$height\-1) { \& my $y = int ($r/$box); \& my $line = $lines[$y]; \& for my $x (0..length ($line) \- 1) { \& if (substr ($line, $x, 1) ne \*(Aq \*(Aq) { \& for my $c (0..$box \- 1) { \& my $offset = $x*$box + $c; \& my $byte = int ($offset / 8); \& my $bit = $offset % 8; \& my $octet = ord (substr ($rows[$r], $byte, 1)); \& substr ($rows[$r], $byte, 1) = chr ($octet | 1<<$bit); \& } \& } \& } \& } \& return ($height, $width, \e@rows); \& } .Ve .PP (This example is included as \fIexamples/libpng\-write.pl\fR in the distribution.) .PP examples/mono.png is included in the distribution. .SS "create_read_struct" .IX Subsection "create_read_struct" .Vb 1 \& my $png = create_read_struct (); .Ve .PP Create a structure for reading a \s-1PNG.\s0 The return value can be used as an object with the other functions as methods. It can be copied to a write structure with \*(L"copy_png\*(R". .PP This function corresponds to \f(CW\*(C`png_create_read_struct\*(C'\fR in libpng plus \f(CW\*(C`create_info_struct\*(C'\fR (see \*(L"No info structure\*(R") with the error and warning handler variables set up to use Perl's error reporting. .SS "create_write_struct" .IX Subsection "create_write_struct" .Vb 1 \& my $png = create_write_struct (); .Ve .PP Create a structure for writing a \s-1PNG.\s0 This can be used as an object with the other functions as methods. .PP This function corresponds to \f(CW\*(C`png_create_write_struct\*(C'\fR in libpng plus \f(CW\*(C`create_info_struct\*(C'\fR (see \*(L"No info structure\*(R") with the error and warning handler variables set up to use Perl's error reporting. .SS "init_io" .IX Subsection "init_io" .Vb 2 \& open my $file, "<", \*(Aqnice.png\*(Aq; \& $png\->init_io ($file); .Ve .PP Set the file which \f(CW$png\fR reads or writes to \f(CW$file\fR. \f(CW$file\fR must be an already-opened Perl file handle. If \f(CW$png\fR was created with \&\*(L"create_write_struct\*(R", \f(CW$file\fR must be opened for writing. If \&\f(CW$png\fR was created with \*(L"create_read_struct\*(R", \f(CW$file\fR must be open for reading. .PP Since \s-1PNG\s0 files are binary files, it is safest to specify the \*(L"raw\*(R" pragma or use \*(L"binmode\*(R" with the file to override any default text file encoding which Perl might be using: .PP .Vb 1 \& open my $file, ">:raw", \*(Aqoutput.png\*(Aq; .Ve .PP or .PP .Vb 2 \& open my $file, ">", \*(Aqoutput.png\*(Aq; \& binmode $file; .Ve .PP This function corresponds to \f(CW\*(C`png_init_io\*(C'\fR in libpng, with a Perl file handle substituting for the C \f(CW\*(C`FILE *\*(C'\fR. .PP On some versions of Perl, \*(L"init_io\*(R" may crash in some circumstances with an error like \*(L"segmentation fault\*(R", if you use code like .PP .Vb 3 \& my $png = create_read_struct (); \& open my $file, "<:raw", "some.png"; \& $png\->init_io ($file); .Ve .PP and you do not check whether the call to \f(CW\*(C`open\*(C'\fR was successful, and \&\fIsome.png\fR does not exist. The crash occurs within Perl's conversion of \f(CW$file\fR into a C \f(CW\*(C`FILE *\*(C'\fR pointer, before this module's code runs. This bug was fixed in Perls after version 5.24.1. To avoid trouble, please check the return value of \f(CW\*(C`open\*(C'\fR. .SS "read_end" .IX Subsection "read_end" .Vb 1 \& $png\->read_end (); .Ve .PP Read the part of the \s-1PNG\s0 file after the image data. .PP This function corresponds to \f(CW\*(C`png_read_end\*(C'\fR in libpng. .SS "read_image" .IX Subsection "read_image" .Vb 1 \& my $rows = $png\->read_image (); .Ve .PP Read the image data of the \s-1PNG\s0 file. .PP This function corresponds to \f(CW\*(C`png_read_image\*(C'\fR in libpng. .SS "read_info" .IX Subsection "read_info" .Vb 1 \& $png\->read_info (); .Ve .PP Read the part of the \s-1PNG\s0 file before the image data. .PP This function corresponds to \f(CW\*(C`png_read_info\*(C'\fR in libpng. .SS "read_png" .IX Subsection "read_png" .Vb 1 \& $png\->read_png (); .Ve .PP Read the entire \s-1PNG\s0 file into memory. .PP You can provide an argument containing transformations to apply to the image: .PP .Vb 2 \& use Image::PNG::Const qw/PNG_TRANSFORM_STRIP_ALPHA/; \& $png\->read_png (PNG_TRANSFORM_STRIP_ALPHA); .Ve .PP If the argument is omitted, the default value of \&\f(CW\*(C`PNG_TRANSFORM_IDENTITY\*(C'\fR (the \*(L"do nothing\*(R" value) is applied. The possible transformations which can be applied are .IP "\s-1PNG_TRANSFORM_BGR\s0" 4 .IX Item "PNG_TRANSFORM_BGR" Flip \s-1RGB\s0 to \s-1BGR, RGBA\s0 to \s-1BGRA.\s0 See also \*(L"set_bgr\*(R". .IP "\s-1PNG_TRANSFORM_EXPAND\s0" 4 .IX Item "PNG_TRANSFORM_EXPAND" Perform \fBset_expand()\fR. See also \*(L"set_expand\*(R". .IP "\s-1PNG_TRANSFORM_EXPAND_16\s0" 4 .IX Item "PNG_TRANSFORM_EXPAND_16" Expand samples to 16 bits. See also \*(L"set_expand_16\*(R". .IP "\s-1PNG_TRANSFORM_GRAY_TO_RGB\s0" 4 .IX Item "PNG_TRANSFORM_GRAY_TO_RGB" Expand grayscale samples to \s-1RGB\s0 (or \s-1GA\s0 to \s-1RGBA\s0). See also \*(L"set_gray_to_rgb\*(R". .IP "\s-1PNG_TRANSFORM_IDENTITY\s0" 4 .IX Item "PNG_TRANSFORM_IDENTITY" No transformation. .IP "\s-1PNG_TRANSFORM_INVERT_ALPHA\s0" 4 .IX Item "PNG_TRANSFORM_INVERT_ALPHA" Change alpha from opacity to transparency. See also \*(L"set_invert_alpha\*(R". .IP "\s-1PNG_TRANSFORM_INVERT_MONO\s0" 4 .IX Item "PNG_TRANSFORM_INVERT_MONO" Invert monochrome images. See also \*(L"set_invert_mono\*(R". .IP "\s-1PNG_TRANSFORM_PACKING\s0" 4 .IX Item "PNG_TRANSFORM_PACKING" Expand 1, 2 and 4\-bit samples to bytes. See also \*(L"set_packing\*(R". .IP "\s-1PNG_TRANSFORM_PACKSWAP\s0" 4 .IX Item "PNG_TRANSFORM_PACKSWAP" Change order of packed pixels to \s-1LSB\s0 first. See also \*(L"set_packswap\*(R". .IP "\s-1PNG_TRANSFORM_SCALE_16\s0" 4 .IX Item "PNG_TRANSFORM_SCALE_16" Strip 16\-bit samples to 8\-bit accurately. See also \*(L"set_scale_16\*(R". .IP "\s-1PNG_TRANSFORM_SHIFT\s0" 4 .IX Item "PNG_TRANSFORM_SHIFT" Normalize pixels to the sBIT depth. .IP "\s-1PNG_TRANSFORM_STRIP_16\s0" 4 .IX Item "PNG_TRANSFORM_STRIP_16" Chop 16\-bit samples to 8\-bit less accurately. See also \*(L"set_strip_16\*(R". .IP "\s-1PNG_TRANSFORM_STRIP_ALPHA\s0" 4 .IX Item "PNG_TRANSFORM_STRIP_ALPHA" Discard the alpha channel. .IP "\s-1PNG_TRANSFORM_SWAP_ALPHA\s0" 4 .IX Item "PNG_TRANSFORM_SWAP_ALPHA" Flip \s-1RGBA\s0 to \s-1ARGB\s0 or \s-1GA\s0 to \s-1AG.\s0 See also \*(L"set_swap_alpha\*(R". .IP "\s-1PNG_TRANSFORM_SWAP_ENDIAN\s0" 4 .IX Item "PNG_TRANSFORM_SWAP_ENDIAN" Byte-swap 16\-bit samples. See also \*(L"set_swap\*(R". .PP This function corresponds to \f(CW\*(C`png_read_png\*(C'\fR in libpng with a default value for the third argument. The fourth, unused, argument to \f(CW\*(C`png_read_png\*(C'\fR does not need to be supplied. See \*(L"Unused arguments omitted\*(R". .PP It does not take a second \*(L"info\*(R" argument. See \*(L"No info structure\*(R". .SS "read_update_info" .IX Subsection "read_update_info" .Vb 1 \& $png\->read_update_info (); .Ve .PP ⛐πŸ€ͺ⚠ Inside Image::PNG::Libpng, the libpng function \&\f(CW\*(C`png_read_update_info\*(C'\fR is called before reading image data. According to \*(L"The libpng documentation\*(R", this function may only be called once for any particular info structure. So although the above Perl interface exists in the module, it is strongly recommended to not use this unless you know exactly what you are doing, since it will usually cause an error when the image data is read. .PP This function corresponds to \f(CW\*(C`png_read_update_info\*(C'\fR in libpng .SS "write_end" .IX Subsection "write_end" .Vb 1 \& $png\->write_end (); .Ve .PP Write the final part of the \s-1PNG\s0 file. .PP This function corresponds to \f(CW\*(C`png_write_end\*(C'\fR in libpng. .SS "write_image" .IX Subsection "write_image" .Vb 1 \& $png\->write_image ($rows); .Ve .PP Write the image of the \s-1PNG\s0 file. \f(CW$rows\fR is an array reference as per \&\*(L"set_rows\*(R". .PP This function corresponds to \f(CW\*(C`png_write_image\*(C'\fR in libpng. .SS "write_info" .IX Subsection "write_info" .Vb 1 \& $png\->write_info (); .Ve .PP Write the first part of the \s-1PNG\s0 file. .PP This function corresponds to \f(CW\*(C`png_write_info\*(C'\fR in libpng. .SS "write_png" .IX Subsection "write_png" .Vb 1 \& $png\->write_png (); .Ve .PP This writes the \s-1PNG\s0 to the file stream which was associated with it using \*(L"init_io\*(R". For example, .PP .Vb 4 \& open my $output, ">:raw", \*(Aqout.png\*(Aq; \& $png\->init_io ($output); \& $png\->write_png (); \& close $output; .Ve .PP An optional argument consists of transformations to apply to the \s-1PNG\s0 image before writing it: .PP .Vb 2 \& use Image::PNG::Const qw/PNG_TRANSFORM_STRIP_ALPHA/; \& $png\->write_png (PNG_TRANSFORM_STRIP_ALPHA); .Ve .PP The transformations which can be applied are as follows: .IP "\s-1PNG_TRANSFORM_BGR\s0" 4 .IX Item "PNG_TRANSFORM_BGR" Flip \s-1RGB\s0 to \s-1BGR, RGBA\s0 to \s-1BGRA.\s0 See also \*(L"set_bgr\*(R". .IP "\s-1PNG_TRANSFORM_INVERT_ALPHA\s0" 4 .IX Item "PNG_TRANSFORM_INVERT_ALPHA" Change alpha from opacity to transparency. See also \*(L"set_invert_alpha\*(R". .IP "\s-1PNG_TRANSFORM_INVERT_MONO\s0" 4 .IX Item "PNG_TRANSFORM_INVERT_MONO" Invert monochrome images. See also \*(L"set_invert_mono\*(R". .IP "\s-1PNG_TRANSFORM_PACKING\s0" 4 .IX Item "PNG_TRANSFORM_PACKING" Expand 1, 2 and 4\-bit samples to bytes. See also \*(L"set_packing\*(R". .IP "\s-1PNG_TRANSFORM_PACKSWAP\s0" 4 .IX Item "PNG_TRANSFORM_PACKSWAP" Change order of packed pixels to \s-1LSB\s0 first. See also \*(L"set_packswap\*(R". .IP "\s-1PNG_TRANSFORM_SHIFT\s0" 4 .IX Item "PNG_TRANSFORM_SHIFT" Normalize pixels to the sBIT depth. .IP "\s-1PNG_TRANSFORM_STRIP_FILLER_AFTER\s0" 4 .IX Item "PNG_TRANSFORM_STRIP_FILLER_AFTER" Strip out trailing filler bytes. .IP "\s-1PNG_TRANSFORM_STRIP_FILLER_BEFORE\s0" 4 .IX Item "PNG_TRANSFORM_STRIP_FILLER_BEFORE" Strip out leading filler bytes. .IP "\s-1PNG_TRANSFORM_SWAP_ALPHA\s0" 4 .IX Item "PNG_TRANSFORM_SWAP_ALPHA" Flip \s-1RGBA\s0 to \s-1ARGB\s0 or \s-1GA\s0 to \s-1AG.\s0 See also \*(L"set_swap_alpha\*(R". .IP "\s-1PNG_TRANSFORM_SWAP_ENDIAN\s0" 4 .IX Item "PNG_TRANSFORM_SWAP_ENDIAN" Byte-swap 16\-bit samples. See also \*(L"set_swap\*(R". .PP This function corresponds to \f(CW\*(C`png_write_png\*(C'\fR in libpng. .SH "The image header" .IX Header "The image header" These functions handle the header part of \s-1PNG\s0 image data. See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for the image header. .SS "color_type_name" .IX Subsection "color_type_name" .Vb 1 \& $name = color_type_name ($color_type); .Ve .PP This is a convenience function which returns a string corresponding to the numerical color type in \f(CW$color_type\fR. The name is in upper case, with words separated by underscores, as in \f(CW\*(C`RGB_ALPHA\*(C'\fR. .PP .Vb 4 \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& my $png = read_png_file (\*(Aqtantei\-san.png\*(Aq); \& my $name = color_type_name ($png\->get_IHDR\->{color_type}); \& print "Your PNG has colour type $name.\en"; .Ve .PP (This example is included as \fIexamples/color\-type\-name.pl\fR in the distribution.) .PP This function does not correspond to anything in libpng. The names of the color types are taken from those defined in the libpng header file, \f(CW\*(C`png.h\*(C'\fR. .SS "get_bit_depth" .IX Subsection "get_bit_depth" .Vb 1 \& my $bit_depth = $png\->get_bit_depth (); .Ve .PP Get the bit depth, the number of bits for one channel of one pixel. .PP This function corresponds to \f(CW\*(C`png_get_bit_depth\*(C'\fR in libpng .SS "get_channels" .IX Subsection "get_channels" .Vb 1 \& my $channels = $png\->get_channels (); .Ve .PP Get the number of channels, from one to four. The channels are the components of pixels, for example the red channel or the alpha (transparency) channel. The return value is 1 for color type \&\f(CW\*(C`PNG_COLOR_TYPE_GRAY\*(C'\fR and \f(CW\*(C`PNG_COLOR_TYPE_PALETTE\*(C'\fR, 2 for \&\f(CW\*(C`PNG_COLOR_TYPE_GRAY_ALPHA\*(C'\fR, 3 for \f(CW\*(C`PNG_COLOR_TYPE_RGB\*(C'\fR and 4 for \&\f(CW\*(C`PNG_COLOR_TYPE_RGB_ALPHA\*(C'\fR or \f(CW\*(C`PNG_COLOR_TYPE_RGB\*(C'\fR with a filler byte. Note that the number of channels does not necessarily correspond to the number of bytes, since the bit depth can also be 1, 2, 4, 8, or 16, depending on the color type. See also the convenience function \&\*(L"color_type_channels\*(R". .PP This function corresponds to \f(CW\*(C`png_get_channels\*(C'\fR in libpng .SS "get_color_type" .IX Subsection "get_color_type" .Vb 1 \& my $color_type = $png\->get_color_type (); .Ve .PP This returns an integer value. If you want to get a name for the color type, use \*(L"color_type_name\*(R". .PP This function corresponds to \f(CW\*(C`png_get_color_type\*(C'\fR in libpng. .SS "get_IHDR" .IX Subsection "get_IHDR" .Vb 1 \& my $IHDR = $png\->get_IHDR (); .Ve .PP Read the \s-1IHDR\s0 information from the \s-1PNG\s0 file. The return value is a hash reference containing the following key/value pairs: .IP "width" 4 .IX Item "width" The width of the image in pixels. .IP "height" 4 .IX Item "height" The height of the image in pixels. .IP "bit_depth" 4 .IX Item "bit_depth" The bit depth of the image (the number of bits used for each color in a pixel). This can take the values 1, 2, 4, 8, 16. .IP "color_type" 4 .IX Item "color_type" The color type. This can take the values \s-1PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA.\s0 .IP "interlace_method" 4 .IX Item "interlace_method" The method of interlacing. This can take the values \s-1PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7.\s0 .PP So, for example, to get the width and height of an image, .PP .Vb 2 \& my $ihdr = $png\->get_IHDR (); \& printf "Your image is %d x %d\en", $ihdr\->{width}, $ihdr\->{height}; .Ve .PP This function corresponds to \f(CW\*(C`png_get_IHDR\*(C'\fR in libpng, with a single Perl hash reference used instead of the several pointers to integers used in libpng. .PP It does not return the fields \f(CW\*(C`filter_type\*(C'\fR and \&\f(CW\*(C`compression_type\*(C'\fR, since these are always 0. See \*(L"Unused arguments omitted\*(R". .SS "get_image_height" .IX Subsection "get_image_height" .Vb 1 \& my $height = $png\->get_image_height (); .Ve .PP Get the image's height from the header. .PP This function corresponds to \f(CW\*(C`png_get_image_height\*(C'\fR in libpng .SS "get_image_width" .IX Subsection "get_image_width" .Vb 1 \& my $width = $png\->get_image_width (); .Ve .PP Get the image's width from the header. .PP This function corresponds to \f(CW\*(C`png_get_image_width\*(C'\fR in libpng .SS "get_interlace_type" .IX Subsection "get_interlace_type" .Vb 1 \& my $interlace_type = $png\->get_interlace_type (); .Ve .PP Get the interlace type. This is either \s-1PNG_INTERLACE_NONE\s0 or \&\s-1PNG_INTERLACE_ADAM7.\s0 .PP This function corresponds to \f(CW\*(C`png_get_interlace_type\*(C'\fR in libpng .SS "get_valid" .IX Subsection "get_valid" .Vb 4 \& my $valid = $png\->get_valid (); \& if ($valid\->{oFFs}) { \& print "The PNG has valid screen offsets.\en"; \& } .Ve .PP This function returns a hash with a key for each possible chunk which may or may not be valid. The chunks which you can test for are \&\*(L"bKGD\*(R", \*(L"cHRM\*(R", \*(L"eXIf\*(R", \*(L"gAMA\*(R", \*(L"hIST\*(R", \*(L"hIST\*(R", \*(L"iCCP\*(R", \s-1IDAT\s0, \s-1IHDR\s0, \*(L"iTXt\*(R", \*(L"oFFs\*(R", \*(L"pCAL\*(R", \*(L"pHYs\*(R", \*(L"\s-1PLTE\*(R"\s0, \*(L"sBIT\*(R", \*(L"sCAL\*(R", \*(L"sPLT\*(R", \*(L"sRGB\*(R", \*(L"tEXt\*(R", \*(L"tIME\*(R", \*(L"tRNS\*(R", and \*(L"zTXt\*(R". .PP Whereas \*(L"libpng_supports\*(R" tells you whether the installed libpng on your system supports various chunks, this tells you whether the chunks are present in a particular \s-1PNG\s0 image file. .PP The first argument, \f(CW$png\fR, is a \s-1PNG\s0 structure created with \&\*(L"create_read_struct\*(R". .PP This function corresponds to \f(CW\*(C`png_get_valid\*(C'\fR in libpng, with the difference being that the return value is a hash containing a key for each possible chunk. .SS "height" .IX Subsection "height" .Vb 1 \& my $height = $png\->height (); .Ve .PP Alias for \*(L"get_image_height\*(R". This is not exported, it's intended for use with the object only. .SS "set_IHDR" .IX Subsection "set_IHDR" .Vb 3 \& my $ihdr = {width => 10, height => 10, bit_depth => 8, \& color_type => PNG_COLOR_TYPE_RGB}; \& $png\->set_IHDR ($ihdr); .Ve .PP Set the \s-1IHDR\s0 chunk (the image header) of the \s-1PNG\s0 image. .PP The first argument, \f(CW$png\fR, is a writeable \s-1PNG\s0 structure created with \&\*(L"create_write_struct\*(R". The second argument is a hash with the following values: .IP "width" 4 .IX Item "width" The width of the image in pixels. This cannot be zero, negative, or omitted. .IP "height" 4 .IX Item "height" The height of the image in pixels. This cannot be zero, negative, or omitted. .IP "bit_depth" 4 .IX Item "bit_depth" The bit depth of the image (the number of bits used for each color in a pixel). This cannot be omitted. This can have the values 1, 2, 4, 8, 16. .IP "color_type" 4 .IX Item "color_type" The color type. This cannot be omitted. This can have the values \s-1PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA.\s0 .IP "interlace_method" 4 .IX Item "interlace_method" The method of interlacing. If this is omitted, it's set to \s-1PNG_INTERLACE_NONE.\s0 This can have the values \s-1PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7.\s0 .PP Other fields in the hash are ignored. .PP This function corresponds to \f(CW\*(C`png_set_IHDR\*(C'\fR in libpng, with a single Perl hash reference used instead of the seven integers. .PP The values \&\f(CW\*(C`compression_method\*(C'\fR, \f(CW\*(C`filter_method\*(C'\fR, may be supplied by the user but are ignored since they may only take the value 0. See \*(L"Unused arguments omitted\*(R". .SS "sig_cmp" .IX Subsection "sig_cmp" .Vb 3 \& if (sig_cmp ($should_be_png)) { \& print "Your data does not have a PNG signature.\en"; \& } .Ve .PP This subroutine looks at \f(CW$should_be_png\fR and checks whether its first bytes correspond to a valid \s-1PNG\s0 signature. It returns a true value if they do not. .PP It can also take two further arguments consisting of a byte offset and a number of bytes to check respectively: .PP .Vb 1 \& sig_cmp ($should_be_png, 0, 8); .Ve .PP If these arguments are not supplied, the byte offset is assumed to be zero, and the number of bytes to check is assumed to be eight. .PP This function corresponds to \f(CW\*(C`png_sig_cmp\*(C'\fR in libpng, with default arguments of 0 and 8 if second and third arguments are not supplied. .SS "width" .IX Subsection "width" .Vb 1 \& my $width = $png\->width (); .Ve .PP Alias for \*(L"get_image_width\*(R". This is not exported, it's intended for use with the object only. .SH "Image data" .IX Header "Image data" These functions deal with accessing the image data itself. .SS "get_rowbytes" .IX Subsection "get_rowbytes" .Vb 1 \& my $bytes_in_a_row = $png\->get_rowbytes (); .Ve .PP This returns the number of bytes needed to hold a transformed row of an image. .PP This function corresponds to \f(CW\*(C`png_get_rowbytes\*(C'\fR in libpng. .SS "get_rows" .IX Subsection "get_rows" .Vb 2 \& my $rows = $png\->get_rows (); \& my $pixel = substr ($rows\->[10], 20, 1); .Ve .PP This returns the rows of the \s-1PNG\s0 image, after uncompressing and unfiltering, as binary data. The return value, \f(CW$rows\fR in the example, is an array reference with a number of rows equal to the height of the \s-1PNG\s0 image. Each element of the array reference is a string containing the binary data making up a row of the image. The values of individual pixels can be extracted from using a function such as \f(CW\*(C`substr\*(C'\fR or \f(CW\*(C`unpack\*(C'\fR. This binary data is likely to contain bytes equal to zero. .PP \&\*(L"get_rowbytes\*(R" gives the number of bytes in each row. .PP Each row is a Perl string. Perl terminates each row of data with an extra zero byte at the end. .PP This function corresponds to \f(CW\*(C`png_get_rows\*(C'\fR in libpng. .SS "set_rows" .IX Subsection "set_rows" .Vb 1 \& $png\->set_rows (\e@rows); .Ve .PP Set the rows of data to be written in to the \s-1PNG\s0 to \f(CW@rows\fR. \f(CW@rows\fR needs to contain at least the same number of rows of data as the height of the \s-1PNG\s0 image set with \*(L"set_IHDR\*(R", and the length of each entry needs to be at least the width of the image multiplied by the number of bytes required for each pixel. .PP This function was changed to copy the data in version 0.46. .PP This function corresponds to \f(CW\*(C`png_set_rows\*(C'\fR in libpng. .SH "Text chunks" .IX Header "Text chunks" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for text information. .SS "get_text" .IX Subsection "get_text" .Vb 1 \& my $text_chunks = $png\->get_text (); .Ve .PP This gets all of the text chunks in the \s-1PNG\s0 image and returns them as an array reference. Each element of the array represents one text chunk. This element is a hash reference with keys such as \f(CW\*(C`key\*(C'\fR, \&\f(CW\*(C`lang_key\*(C'\fR, or \f(CW\*(C`compression\*(C'\fR taken from the \s-1PNG\s0's information. .PP The text data is uncompressed by libpng. If it is international text (\f(CW\*(C`ITXT\*(C'\fR), it is put into Perl's internal Unicode encoding if it is found to be valid \s-1UTF\-8.\s0 (\s-1PNG\s0 \*(L"international text\*(R", \f(CW\*(C`ITXT\*(C'\fR is required to be in the \s-1UTF\-8\s0 encoding, and non-international text is required to contain whitespace and printable \s-1ASCII\s0 characters only. See \*(L"The \s-1PNG\s0 specification\*(R" for more on the requirements of a \s-1PNG\s0 text section.) .PP This function corresponds to \f(CW\*(C`png_get_text\*(C'\fR in libpng, with a Perl array of hash references substituted for the C array of structs used by libpng. See \&\*(L"set_text\*(R" for details of the keys and values which may be returned. .SS "set_text" .IX Subsection "set_text" .Vb 1 \& $png\->set_text ([\e%chunk1, \e%chunk2]); .Ve .PP This sets the text chunks in a writeable image. The input value is an array reference containing one or more hash references. Each hash reference must have a \f(CW\*(C`key\*(C'\fR value for the text. According to the \s-1PNG\s0 specification, this should be between one and 79 bytes in length. This module enforces that restriction, so if you supply a key longer than that, the chunk cannot be added. A hash reference may also have the following: .ie n .IP """compression""" 4 .el .IP "\f(CWcompression\fR" 4 .IX Item "compression" The value of \f(CW\*(C`compression\*(C'\fR controls the compression of the text. If \f(CW\*(C`compression\*(C'\fR is not supplied, a default value of \&\s-1PNG_TEXT_COMPRESSION_NONE\s0 is applied. The \f(CW\*(C`compression\*(C'\fR field can take the following values, available from Image::PNG::Const: .RS 4 .IP "\s-1PNG_TEXT_COMPRESSION_NONE\s0" 4 .IX Item "PNG_TEXT_COMPRESSION_NONE" \&\s-1TEXT\s0 = Printable \s-1ASCII\s0 and space characters. .IP "PNG_TEXT_COMPRESSION_zTXt" 4 .IX Item "PNG_TEXT_COMPRESSION_zTXt" \&\s-1TEXT\s0 = Printable \s-1ASCII\s0 and space characters. .IP "\s-1PNG_ITXT_COMPRESSION_NONE\s0" 4 .IX Item "PNG_ITXT_COMPRESSION_NONE" \&\s-1ITXT\s0 = International text, should be \s-1UTF\-8.\s0 .IP "PNG_ITXT_COMPRESSION_zTXt" 4 .IX Item "PNG_ITXT_COMPRESSION_zTXt" \&\s-1ITXT\s0 = International text, should be \s-1UTF\-8.\s0 .RE .RS 4 .RE .ie n .IP """itxt_length""" 4 .el .IP "\f(CWitxt_length\fR" 4 .IX Item "itxt_length" The string length of international text in bytes. .Sp ⛐πŸ€ͺ⚠ This is ignored by libpng when writing text chunks. When reading text chunks, if the text is marked as international text, libpng adds the length of the string in bytes in this field rather than in \*(L"text_length\*(R". .ie n .IP """lang""" 4 .el .IP "\f(CWlang\fR" 4 .IX Item "lang" This should be set to name of the language of the text, if the text chunk is iTXt. According to the \s-1PNG\s0 specification, \*(L"It is an \s-1ISO 646.IRV:1991\s0 [\s-1ISO 646\s0] string consisting of hyphen-separated words of 1\-8 alphanumeric characters each (for example cn, en-uk, no-bok, x\-klingon, x\-KlInGoN).\*(R" .Sp Support for writing \f(CW\*(C`lang\*(C'\fR was added in version 0.49 of this module. (Prior to that undocumented support existed via a differently-named key.) .Sp ⛐πŸ€ͺ⚠ This module does not attempt to check the supplied value, but merely passes it to libpng. libpng appears not to check the value either, nor to enforce restrictions on its length. .ie n .IP """lang_key""" 4 .el .IP "\f(CWlang_key\fR" 4 .IX Item "lang_key" This corresponds to the \*(L"Translated keyword\*(R" of the \s-1PNG\s0 specification. Note that the user needs to supply \f(CW\*(C`key\*(C'\fR and \*(L"lang\*(R" as well as \f(CW\*(C`lang_key\*(C'\fR. .Sp Support for writing \f(CW\*(C`lang_key\*(C'\fR was added in version 0.49 of this module. (Prior to that undocumented support existed via a differently-named key.) .ie n .IP """text""" 4 .el .IP "\f(CWtext\fR" 4 .IX Item "text" The value of \*(L"text\*(R" is added to the \s-1PNG\s0 as the text segment. This can be omitted if you just want to write a key value without any accompanying text. .ie n .IP """text_length""" 4 .el .IP "\f(CWtext_length\fR" 4 .IX Item "text_length" The string length in bytes. The user may set this, but it is ignored when writing \s-1PNG\s0 text chunks, instead this module uses the string length obtained from Perl. This key contains the length of the string when reading text chunks via \*(L"get_text\*(R", but if the text is marked as international text, \*(L"itxt_length\*(R" is used to return its length in bytes, rather than this. .PP Whether or not the value of \f(CW\*(C`text\*(C'\fR is an \s-1ITXT\s0 field is decided by the value of \f(CW\*(C`compression\*(C'\fR. .PP People who want to fiddle with the text compression applied can do so via \*(L"set_text_compression_level\*(R" and the other functions described below that. .PP If \f(CW\*(C`set_text\*(C'\fR is called more than once, the chunks are not overwritten but appended to the existing ones. (This behaviour is from libpng itself.) .PP Prior to version 0.50, \f(CW\*(C`set_text\*(C'\fR would fail silently if the user added invalid chunks, for example hash references without a valid \&\f(CW\*(C`key\*(C'\fR, or things which were not hash references at all. From version 0.50, all invalid inputs cause fatal errors. However, unknown keys in the hash references do not cause fatal errors. .PP This function corresponds to \f(CW\*(C`png_set_text\*(C'\fR in libpng. .PP \fIExample\fR .IX Subsection "Example" .PP .Vb 10 \& use utf8; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& my $png = create_write_struct (); \& $png\->set_IHDR ({width => 1, height => 1, bit_depth => 8, \& color_type => PNG_COLOR_TYPE_GRAY}); \& $png\->set_rows ([\*(AqX\*(Aq]); \& $png\->set_text ([{ \& compression => PNG_TEXT_COMPRESSION_NONE, \& key => "Copyright", \& text => "Copyright (C) 2020 Fat Cat", \& }, { \& compression => PNG_ITXT_COMPRESSION_zTXt, \& key => "Copyright", \& lang_key => \*(Aq著者権\*(Aq, \& lang => \*(Aqja_JP\*(Aq, \& text => \*(AqΒ©δ»€ε’ŒοΌ’εΉ΄θŒ‰θŽ‰γƒ‹γƒ£γƒ³γƒγƒΌγ‚¬γƒΌγ•γ‚“\*(Aq, \& }]); \& $png\->write_png_file (\*(Aqcopyright.png\*(Aq); .Ve .PP (This example is included as \fIexamples/set\-text.pl\fR in the distribution.) .SS "text_compression_name" .IX Subsection "text_compression_name" .Vb 1 \& my $name = Image::PNG::Libpng::text_compression_name ($text\->{compression}); .Ve .PP Given a numerical text compression type, return the equivalent name. The name is in upper case. The possible return values are .IP "\s-1TEXT_NONE\s0" 4 .IX Item "TEXT_NONE" .PD 0 .IP "TEXT_zTXt" 4 .IX Item "TEXT_zTXt" .IP "\s-1ITXT_NONE\s0" 4 .IX Item "ITXT_NONE" .IP "ITXT_zTXt" 4 .IX Item "ITXT_zTXt" .IP "an empty string" 4 .IX Item "an empty string" .PD if the compression method is unknown. .PP The compression field is also used to store the information about whether the text is \*(L"international text\*(R" in \s-1UTF\-8\s0 or not. .PP This function does not correspond to anything in libpng. The names of the text compression types are based on those in \f(CW\*(C`png.h\*(C'\fR, but without the word \*(L"\s-1COMPRESSION\*(R",\s0 so for example the libpng constant \&\f(CW\*(C`PNG_ITXT_COMPRESSION_zTXt\*(C'\fR corresponds to a return value of \&\f(CW\*(C`ITXT_zTXt\*(C'\fR. .SH "Private chunks" .IX Header "Private chunks" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for private chunks. .PP To test whether your version of libpng supports \f(CW\*(C`private chunks\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1UNKNOWN_CHUNKS\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqUNKNOWN_CHUNKS\*(Aq)) { \& # do something \& } .Ve .SS "get_chunk_malloc_max" .IX Subsection "get_chunk_malloc_max" .Vb 1 \& my $max = $png\->get_chunk_malloc_max (); .Ve .PP This gets the maximum amount of memory that a chunk can use. .PP To test whether your version of libpng supports \f(CW\*(C`get_chunk_malloc_max\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1CHUNK_MALLOC_MAX\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqCHUNK_MALLOC_MAX\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_get_chunk_malloc_max\*(C'\fR in libpng .SS "set_chunk_malloc_max" .IX Subsection "set_chunk_malloc_max" .Vb 1 \& $png\->set_chunk_malloc_max ($max); .Ve .PP This sets the maximum amount of memory that a chunk can use. The default value of libpng 1.6.37 is 8 megabytes. .PP To test whether your version of libpng supports \f(CW\*(C`get_chunk_malloc_max\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1CHUNK_MALLOC_MAX\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqCHUNK_MALLOC_MAX\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_chunk_malloc_max\*(C'\fR in libpng .SS "set_keep_unknown_chunks" .IX Subsection "set_keep_unknown_chunks" .Vb 2 \& use Image::PNG::Const \*(AqPNG_HANDLE_CHUNK_ALWAYS\*(Aq; \& $png\->set_keep_unknown_chunks (PNG_HANDLE_CHUNK_ALWAYS); .Ve .PP Tell libpng not to discard unknown chunks when reading the file. .SS "get_unknown_chunks" .IX Subsection "get_unknown_chunks" .Vb 5 \& my $private_chunks = $png\->get_unknown_chunks (); \& # Get some data from a private chunk \& my $chunk_three_data = $private_chunks\->[3]\->{data}; \& # Get the size of the data \& print length $chunk_three_data; .Ve .PP This gets all of the private chunks from the image. The return value is an array reference containing hash references. If there are no private chunks, this returns an undefined value. There is one element of the array for each chunk member. It is necessary to call \&\*(L"set_keep_unknown_chunks\*(R" with an appropriate value before reading the file, otherwise libpng discards unknown chunks when reading the file. .PP Each member hash reference has the following keys: .IP "name" 4 .IX Item "name" The name of the unknown chunk, in the \s-1PNG\s0 chunk format (four bytes). .IP "location" 4 .IX Item "location" The location of the unknown chunk. .IP "data" 4 .IX Item "data" The data of the unknown chunk .PP The \*(L"size\*(R" field of the \s-1PNG\s0 structure is not stored, because the \&\*(L"data\*(R" member of the hash contains information on its length. .PP This function corresponds to \f(CW\*(C`png_get_unknown_chunks\*(C'\fR in libpng .SS "set_unknown_chunks" .IX Subsection "set_unknown_chunks" .Vb 2 \& $png\->set_unknown_chunks (name => \*(AqdUCk\*(Aq, data => \*(Aqabcdefg\*(Aq, \& location => PNG_AFTER_IDAT); .Ve .PP ⛐πŸ€ͺ⚠ This currently does not fully function. .PP This function corresponds to \f(CW\*(C`png_set_unknown_chunks\*(C'\fR in libpng .SH "Library version functions" .IX Header "Library version functions" .SS "access_version_number" .IX Subsection "access_version_number" .Vb 1 \& my $libpng_version_number = Image::PNG::Libpng::access_version_number (); .Ve .PP This function returns the version of the libpng library which the module is using as an integer number. .PP This function corresponds to \f(CW\*(C`png_access_version_number\*(C'\fR in libpng. .SS "get_libpng_ver" .IX Subsection "get_libpng_ver" .Vb 1 \& my $libpng_version = Image::PNG::Libpng::get_libpng_ver (); .Ve .PP This function returns the version of the libpng library which the module is using. .PP This function corresponds to \f(CW\*(C`png_get_libpng_ver\*(C'\fR in libpng. However, it doesn't require the \&\f(CW\*(C`png_structp\*(C'\fR argument of the C function. See \*(L"Unused arguments omitted\*(R". .SH "Compression and filtering" .IX Header "Compression and filtering" .SS "get_compression_buffer_size" .IX Subsection "get_compression_buffer_size" .Vb 1 \& my $size = $png\->get_compression_buffer_size (); .Ve .PP Returns the value of the compression buffer size, which may be altered with \*(L"set_compression_buffer_size\*(R". .SS "set_compression_buffer_size" .IX Subsection "set_compression_buffer_size" .Vb 1 \& $png\->set_compression_buffer_size (100); .Ve .PP Set the size of the buffer which zlib uses to compress or decompress the image data. It takes one argument, an integer number. This cannot be less than 6. .SS "set_compression_level" .IX Subsection "set_compression_level" .Vb 1 \& $png\->set_compression_level ($number); .Ve .PP Set the compression level used to make the \s-1PNG. A\s0 value of 0 (\f(CW\*(C`Z_NO_COMPRESSION\*(C'\fR) corresponds to no compression at all, otherwise \&\f(CW$number\fR may take values of 1 (\f(CW\*(C`Z_BEST_SPEED\*(C'\fR) to 9 (\f(CW\*(C`Z_BEST_COMPRESSION\*(C'\fR), with smaller values giving faster, and larger values giving better, that is with smaller output, compression. These correspond to the \-1, \-2, ... \-9 options to the \&\f(CW\*(C`gzip\*(C'\fR utility, or the compression level parameter of \&\f(CW\*(C`zlib\*(C'\fR. Calling with \f(CW\*(C`\-1\*(C'\fR (\f(CW\*(C`Z_DEFAULT_COMPRESSION\*(C'\fR) reverts to the default compression. Calling with any other number outside the range 0 to 9 results in a fatal error. .PP This function was added to the module in version 0.49. .SS "set_compression_mem_level" .IX Subsection "set_compression_mem_level" .Vb 1 \& $png\->set_compression_mem_level ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_compression_mem_level\*(C'\fR. Takes one integer argument. .PP Sets the \f(CW\*(C`memLevel\*(C'\fR parameter of \f(CW\*(C`deflateInit2\*(C'\fR in zlib when writing \&\s-1PNG\s0 image data. Argument between 1 for minimum memory and 9 for maximum speed. The default is 8. See \*(L"zlib documentation\*(R". .SS "set_compression_window_bits" .IX Subsection "set_compression_window_bits" .Vb 1 \& $png\->set_compression_window_bits ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_compression_window_bits\*(C'\fR. Takes one integer argument. .PP Sets the \f(CW\*(C`windowBits\*(C'\fR parameter of \f(CW\*(C`deflateInit2\*(C'\fR in zlib when writing \s-1PNG\s0 image data. Argument value must be between 8 and 15 for libpng. The default is 15. See the \*(L"zlib documentation\*(R". .SS "set_compression_strategy" .IX Subsection "set_compression_strategy" .Vb 1 \& $png\->set_compression_strategy ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_compression_strategy\*(C'\fR. Takes one integer argument. .PP Sets the \f(CW\*(C`strategy\*(C'\fR parameter of \f(CW\*(C`deflateInit2\*(C'\fR when writing \s-1PNG\s0 image data. Setting this with libpng overrides libpng's default behaviour of changing the value depending on the filter in use. For zlib, the argument is either 0 for default behaviour, or 1 to 4. See the \*(L"zlib documentation\*(R". libpng uses the default strategy 0 (\f(CW\*(C`Z_DEFAULT_STRATEGY\*(C'\fR) for unfiltered image data, and 1 (\f(CW\*(C`Z_FILTERED\*(C'\fR) for filtered image data. .SS "set_filter" .IX Subsection "set_filter" .Vb 2 \& use Image::PNG::Const \*(AqPNG_FILTER_NONE\*(Aq; \& $png\->set_filter (PNG_FILTER_NONE); .Ve .PP This sets the filters which are allowed to be used for writing a \s-1PNG\s0 image. The possible values are .IP "\s-1PNG_NO_FILTERS\s0" 4 .IX Item "PNG_NO_FILTERS" .PD 0 .IP "\s-1PNG_FILTER_NONE\s0" 4 .IX Item "PNG_FILTER_NONE" .IP "\s-1PNG_FILTER_SUB\s0" 4 .IX Item "PNG_FILTER_SUB" .IP "\s-1PNG_FILTER_UP\s0" 4 .IX Item "PNG_FILTER_UP" .IP "\s-1PNG_FILTER_AVG\s0" 4 .IX Item "PNG_FILTER_AVG" .IP "\s-1PNG_FILTER_PAETH\s0" 4 .IX Item "PNG_FILTER_PAETH" .IP "\s-1PNG_ALL_FILTERS\s0" 4 .IX Item "PNG_ALL_FILTERS" .PD .PP These can be combined using \f(CW\*(C`|\*(C'\fR (logical or): .PP .Vb 2 \& use Image::PNG::Const \*(Aq:all\*(Aq; \& set_filter ($png, PNG_FILTER_UP | PNG_FILTER_AVG); .Ve .PP Please see this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for the meanings of these filter types. .PP This function corresponds to \f(CW\*(C`png_set_filter\*(C'\fR in libpng with the second (unused) argument omitted. See \*(L"Unused arguments omitted\*(R". .SS "set_text_compression_level" .IX Subsection "set_text_compression_level" .Vb 1 \& $png\->set_text_compression_level ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_text_compression_level\*(C'\fR. Takes one integer argument. .PP As \*(L"set_compression_level\*(R" but for compressed text. .SS "set_text_compression_mem_level" .IX Subsection "set_text_compression_mem_level" .Vb 1 \& $png\->set_text_compression_mem_level ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_text_compression_mem_level\*(C'\fR. Takes one integer argument. .PP As \*(L"set_compression_mem_level\*(R" but for compressed text. .SS "set_text_compression_window_bits" .IX Subsection "set_text_compression_window_bits" .Vb 1 \& $png\->set_text_compression_window_bits ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_text_compression_window_bits\*(C'\fR. Takes one integer argument. .PP As \*(L"set_compression_window_bits\*(R" but for compressed text. .SS "set_text_compression_strategy" .IX Subsection "set_text_compression_strategy" .Vb 1 \& $png\->set_text_compression_strategy ($argument); .Ve .PP ⛐πŸ€ͺ⚠ Untested function corresponding to \f(CW\*(C`png_set_text_compression_strategy\*(C'\fR. Takes one integer argument. .PP As \*(L"set_compression_strategy\*(R" but for compressed text. .SH "Other chunks" .IX Header "Other chunks" These routines deal with the other possible chunks of PNGs. .PP The getter and setter routines for all other chunks are designed so that the return value of \f(CW\*(C`get_wXYZ\*(C'\fR is able to be used directly as the value for \f(CW\*(C`set_wXYZ\*(C'\fR, so the values of chunks can easily be copied from one \s-1PNG\s0 to another. .PP .Vb 2 \& my $values = $png1\->get_wXYZ (); \& $png2\->set_wXYZ ($values); .Ve .PP If the chunk is not present, or if the chunk is not supported by the user's version of libpng, the return value of \f(CW\*(C`get_wXYZ\*(C'\fR is the undefined value. .SS "bKGD" .IX Subsection "bKGD" The background color of the \s-1PNG\s0 image. .PP See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for the background chunk. .PP \fIget_bKGD\fR .IX Subsection "get_bKGD" .PP .Vb 1 \& my $bkgd = $png\->get_bKGD (); .Ve .PP Get the bKGD (background) chunk of the image. .PP The return value is a hash with the following keys, depending on the color type of the image: .IP "index" 4 .IX Item "index" For palette color types, this is the offset into the palette. .IP "gray" 4 .IX Item "gray" For grayscale color types. .IP "red" 4 .IX Item "red" .PD 0 .IP "green" 4 .IX Item "green" .IP "blue" 4 .IX Item "blue" .PD .PP This function corresponds to \f(CW\*(C`png_get_bKGD\*(C'\fR in libpng with a hash function instead of a \&\f(CW\*(C`png_color\*(C'\fR struct. .PP \fIset_bKGD\fR .IX Subsection "set_bKGD" .PP .Vb 1 \& $png\->set_bKGD ($bkgd); .Ve .PP Set the bKGD (background) chunk of the image. \f(CW$bkgd\fR is a hash reference. The keys of the hash reference are as described in \&\*(L"get_bKGD\*(R". .PP This function corresponds to \f(CW\*(C`png_set_bKGD\*(C'\fR in libpng with a hash function instead of a \&\f(CW\*(C`png_color\*(C'\fR struct. .SS "cHRM" .IX Subsection "cHRM" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" \*(L"cHRM Primary chromaticities and white point\*(R". .PP \fIget_cHRM\fR .IX Subsection "get_cHRM" .PP .Vb 1 \& my $cHRM = $png\->get_cHRM (); .Ve .PP Get the cHRM chunk as a hash reference. .PP The keys of the hash are white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y. .PP The values of the hash are floating point numbers between 0 and 1. .PP This function corresponds to \f(CW\*(C`png_get_cHRM\*(C'\fR in libpng with a hash reference supplying the arguments. The hash's keys correspond to the names of the \f(CW\*(C`double\*(C'\fR arguments in libpng. .PP \fIget_cHRM_XYZ\fR .IX Subsection "get_cHRM_XYZ" .PP .Vb 1 \& my $cHRM = $png\->get_cHRM_XYZ (); .Ve .PP Get the cHRM chunk as a hash reference for the \s-1XYZ\s0 color space. .PP The keys of the hash are red_x, red_y, red_z, green_x, green_y, green_z, blue_x, blue_y, blue_z. .PP The values of the hash are floating point numbers between 0 and 1. .PP This function corresponds to \f(CW\*(C`png_get_cHRM_XYZ\*(C'\fR in libpng with a hash reference supplying the arguments. The hash's keys correspond to the names of the \f(CW\*(C`double\*(C'\fR arguments in libpng. .PP \fIset_cHRM\fR .IX Subsection "set_cHRM" .PP .Vb 1 \& $png\->set_cHRM (\e%cHRM); .Ve .PP Set the cHRM chunk from a hash reference. .PP The keys of the hash are as for \*(L"get_cHRM\*(R". The values are floating point numbers between 0 and 1. .PP This function corresponds to \f(CW\*(C`png_set_cHRM\*(C'\fR in libpng with a hash reference instead of the \f(CW\*(C`double\*(C'\fR arguments. .PP \fIset_cHRM_XYZ\fR .IX Subsection "set_cHRM_XYZ" .PP .Vb 1 \& $png\->set_cHRM_XYZ (\e%cHRM); .Ve .PP Set the cHRM chunk from a hash reference for the \s-1XYZ\s0 color space. .PP The keys of the hash are as for \*(L"get_cHRM_XYZ\*(R". The values are floating point numbers between 0 and 1. The \f(CW\*(C`Y\*(C'\fR values \f(CW\*(C`red_y\*(C'\fR, \&\f(CW\*(C`green_y\*(C'\fR, and \f(CW\*(C`blue_y\*(C'\fR should sum to 1. If you supply values outside the allowed range, libpng corrects them silently on writing rather than producing an error. .PP This function corresponds to \f(CW\*(C`png_set_cHRM_XYZ\*(C'\fR in libpng with a hash reference instead of the \f(CW\*(C`double\*(C'\fR arguments. .SS "eXIf" .IX Subsection "eXIf" The \f(CW\*(C`eXIf\*(C'\fR chunk is an extension to the \s-1PNG\s0 specification. See . Support for this chunk was added in version 0.50 of this module. .PP \fIget_eXIf\fR .IX Subsection "get_eXIf" .PP .Vb 1 \& my $exif = $png\->get_eXIf (); .Ve .PP This retrieves the \f(CW\*(C`eXIf\*(C'\fR chunk from \f(CW$png\fR but does not process the internal information. .PP \fIset_eXIf\fR .IX Subsection "set_eXIf" .PP .Vb 1 \& $png\->set_eXIf ($exif); .Ve .PP libpng checks whether the chunk's first two bytes are either \f(CW\*(C`II\*(C'\fR for little-endian (from Intel) or \f(CW\*(C`MM\*(C'\fR for big-endian (from Motorola) then adds the entire chunk, including the first two bytes, to the \s-1PNG.\s0 .PP ⛐πŸ€ͺ⚠ As of December 2020, there appears to be a bug in libpng in which the eXIf chunk is added twice, causing a warning of the form \&\f(CW\*(C`libpng warning: eXIf: duplicate\*(C'\fR on reading a \s-1PNG\s0 file back in. See . .SS "gAMA" .IX Subsection "gAMA" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_gAMA\fR .IX Subsection "get_gAMA" .PP .Vb 1 \& my $gamma = $png\->get_gAMA (); .Ve .PP Get the gamma value or gAMA chunk. The return value is a floating-point number. .PP This function corresponds to \f(CW\*(C`png_get_gAMA\*(C'\fR in libpng .PP \fIset_gAMA\fR .IX Subsection "set_gAMA" .PP .Vb 1 \& $png\->set_gAMA (0.2); .Ve .PP Set the gamma value or gAMA chunk. .PP This function corresponds to \f(CW\*(C`png_set_gAMA\*(C'\fR in libpng .SS "hIST" .IX Subsection "hIST" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_hIST\fR .IX Subsection "get_hIST" .PP .Vb 1 \& my $hist = $png\->get_hIST (); .Ve .PP If the \s-1PNG\s0 file contains a histogram, the return value is array reference, otherwise it is the undefined value. The number of entries in the array reference is the same as in the palette. .PP This function corresponds to \f(CW\*(C`png_get_hIST\*(C'\fR in libpng .PP \fIset_hIST\fR .IX Subsection "set_hIST" .PP .Vb 1 \& $png\->set_hIST (\e@hist); .Ve .PP Set the histogram of frequencies of the colors of a paletted (\*(L"\s-1PLTE\*(R"\s0) image. The entries of the histogram are 16 bit unsigned integers, so the maximum value that can be entered is 65535 = 2^16 \- 1. Larger numbers and floating point numbers will cause a warning to be printed and the value to be set to zero. The histogram must have exactly the same number of entries as the palette or the call will fail with a warning. A histogram cannot be added to an image without a palette. A call to set_hIST for an image without a palette will cause a warning and return without setting the value. .PP (I'm not sure of the best form of error handling for this function so it may change in future versions to have errors for a bad histogram rather than warnings.) .PP This function corresponds to \f(CW\*(C`png_set_hIST\*(C'\fR in libpng .SS "iCCP" .IX Subsection "iCCP" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_iCCP\fR .IX Subsection "get_iCCP" .PP .Vb 1 \& my $iccp = $png\->get_iCCP (); .Ve .PP The return value is a hash with two keys, .IP "name" 4 .IX Item "name" The name of the profile. .IP "profile" 4 .IX Item "profile" The color profile. .PP The \f(CW\*(C`compression_type\*(C'\fR value, which is always 0, is not returned. See \*(L"Unused arguments omitted\*(R". .PP This function corresponds to \f(CW\*(C`png_get_iCCP\*(C'\fR in libpng. .PP \fIset_iCCP\fR .IX Subsection "set_iCCP" .PP .Vb 1 \& $png\->set_iCCP ({name => \*(Aqname\*(Aq, profile => \*(Aqprofile\*(Aq}); .Ve .PP This function corresponds to \f(CW\*(C`png_set_iCCP\*(C'\fR in libpng. For details of the arguments, see \&\*(L"get_iCCP\*(R". A \f(CW\*(C`compression_type\*(C'\fR argument, which must always be 0 anyway, is ignored. See \*(L"Unused arguments omitted\*(R". .SS "oFFs" .IX Subsection "oFFs" This is an extension to the \s-1PNG\s0 specification. See . .PP \fIget_oFFs\fR .IX Subsection "get_oFFs" .PP .Vb 1 \& my $phys = $png\->get_oFFs (); .Ve .PP Get oFFs chunk. Return value is a hash reference .PP This function corresponds to \f(CW\*(C`png_get_oFFs\*(C'\fR in libpng .PP \fIset_oFFs\fR .IX Subsection "set_oFFs" .PP .Vb 1 \& $png\->set_oFFs ({x_offset => 1, y_offset => 1, unit_type => 0}); .Ve .PP Set oFFs chunk. See the specification linked above for the meanings of the parameters. If \f(CW\*(C`unit_type\*(C'\fR is not 0 or 1, a warning is produced. .PP This function corresponds to \f(CW\*(C`png_set_oFFs\*(C'\fR in libpng .SS "pCAL" .IX Subsection "pCAL" pCAL is an extension of the \s-1PNG\s0 specification which allows one to associate pixels in the \s-1PNG\s0 image with non-image data such as a heat map. See . .PP To test whether your version of libpng supports \f(CW\*(C`the pCAL extension\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"pCAL\*(R"': .PP .Vb 3 \& if (libpng_supports (\*(AqpCAL\*(Aq)) { \& # do something \& } .Ve .PP \fIget_pCAL\fR .IX Subsection "get_pCAL" .PP .Vb 1 \& my $pcal = $png\->get_pCAL (); .Ve .PP The return value is a hash reference with the following keys: .IP "params" 4 .IX Item "params" If this exists, its value is a reference to an array containing the parameter list of the pCAL chunk, which are floating point numbers. Within the \s-1PNG\s0 file chunk, these parameters are stored as strings representing floating point numbers, but you can pass in Perl floating point numbers rather than strings. The number of parameters you should set is fixed by the \f(CW\*(C`type\*(C'\fR parameter. Refer to the \s-1PNG\s0 specification for full details. .IP "purpose" 4 .IX Item "purpose" The purpose string of the pCAL chunk. .IP "type" 4 .IX Item "type" The equation type as a number, from 0 to 3. See the \s-1PNG\s0 specification for the meanings. Other numbers cause an error. .IP "units" 4 .IX Item "units" The units as a string. See the \s-1PNG\s0 specification for details. .IP "x0" 4 .IX Item "x0" The zero value for the equation, an integer. .IP "x1" 4 .IX Item "x1" The max value for the equation, an integer. .PP This function corresponds to \f(CW\*(C`png_get_pCAL\*(C'\fR in libpng .PP \fIset_pCAL\fR .IX Subsection "set_pCAL" .PP .Vb 1 \& $png\->set_pCAL (\e%values); .Ve .PP See \*(L"get_pCAL\*(R" for the parameters of \f(CW%values\fR. .PP This function corresponds to \f(CW\*(C`png_set_pCAL\*(C'\fR in libpng .SS "pHYs" .IX Subsection "pHYs" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_pHYs\fR .IX Subsection "get_pHYs" .PP .Vb 1 \& my $phys = $png\->get_pHYs (); .Ve .PP The return value is a hash reference with the keys .IP "res_x" 4 .IX Item "res_x" .PD 0 .IP "res_y" 4 .IX Item "res_y" .IP "unit_type" 4 .IX Item "unit_type" .PD Is either 0 or 1. .PP This function corresponds to \f(CW\*(C`png_get_pHYs\*(C'\fR in libpng .PP \fIset_pHYs\fR .IX Subsection "set_pHYs" .PP .Vb 1 \& $png\->set_pHYs ({res_x => 1, res_y => 1, unit_type => 1}); .Ve .PP This function corresponds to \f(CW\*(C`png_set_pHYs\*(C'\fR in libpng .SS "\s-1PLTE\s0" .IX Subsection "PLTE" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for the palette chunk. .PP \fIget_palette_max\fR .IX Subsection "get_palette_max" .PP .Vb 1 \& my $pmax = $png\->get_palette_max (); .Ve .PP If your libpng supports it, this will return the maximum palette index found in the image, or \*(L"\-1\*(R" if the palette was not checked, or \*(L"0\*(R" if no palette was found. .PP To test whether your version of libpng supports \f(CW\*(C`get_palette_max\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1GET_PALETTE_MAX\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqGET_PALETTE_MAX\*(Aq)) { \& # do something \& } .Ve .PP ⛐πŸ€ͺ⚠ This function is implemented but so far it is not very clear to me what it does, since, for example, it returns zero for the test image \fIt/tantei\-san.png\fR which is an image with a fully-used 256\-color palette. I've asked about it on the libpng mailing list , but so far nobody has responded. .PP \fIget_PLTE\fR .IX Subsection "get_PLTE" .PP .Vb 3 \& my $colors = $png\->get_PLTE (); \& # Get the green value of the twentieth entry in the palette. \& my $green = $colors\->[20]\->{green}; .Ve .PP This function gets the palette from the \s-1PNG.\s0 The return value is an array reference containing the palette. This array contains hash references with the values \*(L"green\*(R", \*(L"blue\*(R" and \*(L"red\*(R" for the color of each pixel in the palette. If the \s-1PNG\s0 has no palette, it returns an undefined value. .PP A \s-1PNG\s0 image may or may not contain a palette. To check whether the image contains a palette, use something of the following form: .PP .Vb 5 \& use Image::PNG::Const \*(Aq:all\*(Aq; \& my $color_type = $png\->get_color_type (); \& if ($color_type == PNG_COLOR_TYPE_PALETTE) { \& # The PNG uses a palette. \& } .Ve .PP A \s-1PNG\s0 image may also contain a palette even when the \*(L"color_type\*(R" does not indicate that. To check for that case, use \*(L"get_valid\*(R". .PP This function corresponds to \f(CW\*(C`png_get_PLTE\*(C'\fR in libpng. .PP \fIset_PLTE\fR .IX Subsection "set_PLTE" .PP .Vb 1 \& $png\->set_PLTE ($palette); .Ve .PP Set the palette of \f(CW$png\fR. The argument is an array reference containing hash references. There is one hash reference for each palette entry. The hash references contain three fields, red, green, and blue, corresponding to the pixel value for that palette entry. Other values in the hash references are ignored. For example, .PP .Vb 2 \& $png\->set_PLTE ([{red => 1, green => 99, blue => 0x10}, \& {red => 0xFF, green => 0xFF, blue => 0xFF}]); .Ve .PP creates a palette with two entries in \f(CW$png\fR. .PP This function corresponds to \f(CW\*(C`png_set_PLTE\*(C'\fR in libpng. .SS "sBIT" .IX Subsection "sBIT" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_sBIT\fR .IX Subsection "get_sBIT" .PP .Vb 1 \& my $sbit = $png\->get_sBIT (); .Ve .PP The return value is a hash reference containing integer values for the keys \f(CW\*(C`red\*(C'\fR, \f(CW\*(C`blue\*(C'\fR, \f(CW\*(C`green\*(C'\fR, \f(CW\*(C`gray\*(C'\fR and \f(CW\*(C`alpha\*(C'\fR, depending on the \&\f(CW\*(C`color_type\*(C'\fR of \f(CW$png\fR. .PP ⛐πŸ€ͺ⚠ Prior to version 0.50 of this module, get_sBIT wrote values of 0 for all of the keys, regardless of the \f(CW\*(C`color_type\*(C'\fR, causing errors in some circumstances. From version 0.50, hash keys are not entered if the \f(CW\*(C`color_type\*(C'\fR of the image makes them invalid. .PP This function corresponds to \f(CW\*(C`png_get_sBIT\*(C'\fR in libpng .PP \fIset_sBIT\fR .IX Subsection "set_sBIT" .PP .Vb 1 \& $png\->set_sBIT ({red => 1, blue => 2, green => 3}); .Ve .PP The argument is a hash reference containing integer values for the keys \f(CW\*(C`red\*(C'\fR, \f(CW\*(C`blue\*(C'\fR, \f(CW\*(C`green\*(C'\fR, \f(CW\*(C`gray\*(C'\fR, and \f(CW\*(C`alpha\*(C'\fR, as required by the \f(CW\*(C`color_type\*(C'\fR of \f(CW$png\fR. .PP This function corresponds to \f(CW\*(C`png_set_sBIT\*(C'\fR in libpng .SS "sCAL" .IX Subsection "sCAL" This is an extension to the \s-1PNG\s0 specification. See . .PP To test whether your version of libpng supports \f(CW\*(C`the sCAL chunk\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"sCAL\*(R"': .PP .Vb 3 \& if (libpng_supports (\*(AqsCAL\*(Aq)) { \& # do something \& } .Ve .PP \fIget_sCAL\fR .IX Subsection "get_sCAL" .PP .Vb 1 \& my $scal = $png\->get_sCAL (); .Ve .PP The returned hash value contains the following keys: .IP "unit" 4 .IX Item "unit" The unit type, which is either \s-1PNG_SCALE_UNKNOWN, PNG_SCALE_METER,\s0 or \&\s-1PNG_SCALE_RADIAN.\s0 .IP "width" 4 .IX Item "width" The width, as a string. .IP "height" 4 .IX Item "height" The height, as a string. .PP This function corresponds to \f(CW\*(C`png_get_sCAL_s\*(C'\fR in libpng. Note that this uses the sCAL_s function rather than the get_sCAL and the returned values are the strings themselves rather than parsed numbers. .PP \fIset_sCAL\fR .IX Subsection "set_sCAL" .PP .Vb 1 \& $png\->set_sCAL ($scal); .Ve .PP \&\f(CW$scal\fR is a hash reference containing the keys described in \&\*(L"get_sCAL\*(R". .PP This function corresponds to \f(CW\*(C`png_set_sCAL_s\*(C'\fR in libpng. Note that this uses the \f(CW\*(C`set_sCAL_s\*(C'\fR function rather than \f(CW\*(C`set_sCAL\*(C'\fR and the input values are the strings themselves rather than numbers. .SS "sPLT" .IX Subsection "sPLT" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_sPLT\fR .IX Subsection "get_sPLT" .PP ⛐πŸ€ͺ⚠ Provisional. See \*(L"set_sPLT\*(R" for documentation, the return value is like the input of that. .PP \fIset_sPLT\fR .IX Subsection "set_sPLT" .PP .Vb 1 \& $png\->set_sPLT ([{ name => \*(Aqpalette\*(Aq, depth => 8, entries => [{red => 1, blue => 2},]}]); .Ve .PP Set suggested palettes. The input is an array reference containing hash references with the following fields: .IP "name" 4 .IX Item "name" The name of the suggested palette. .IP "depth" 4 .IX Item "depth" The depth of the suggested palette. .IP "entries" 4 .IX Item "entries" The entries of the palette. This is an array reference containing hash references with keys as follows: .RS 4 .IP "red" 4 .IX Item "red" .PD 0 .IP "blue" 4 .IX Item "blue" .IP "green" 4 .IX Item "green" .IP "frequency" 4 .IX Item "frequency" .IP "alpha" 4 .IX Item "alpha" .RE .RS 4 .RE .PD .PP The field \f(CW\*(C`nentries\*(C'\fR which is returned by \*(L"get_sPLT\*(R" does not need to be specified, it is calculated from the length of \f(CW\*(C`entries\*(C'\fR. .SS "sRGB" .IX Subsection "sRGB" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_sRGB\fR .IX Subsection "get_sRGB" .PP .Vb 1 \& my $sRGB = $png\->get_sRGB (); .Ve .PP The return value is an integer number corresponding to one of the following: .IP "PNG_sRGB_INTENT_SATURATION" 4 .IX Item "PNG_sRGB_INTENT_SATURATION" .PD 0 .IP "PNG_sRGB_INTENT_PERCEPTUAL" 4 .IX Item "PNG_sRGB_INTENT_PERCEPTUAL" .IP "PNG_sRGB_INTENT_ABSOLUTE" 4 .IX Item "PNG_sRGB_INTENT_ABSOLUTE" .IP "PNG_sRGB_INTENT_RELATIVE" 4 .IX Item "PNG_sRGB_INTENT_RELATIVE" .PD .PP This function corresponds to \f(CW\*(C`png_get_sRGB\*(C'\fR in libpng .PP \fIset_sRGB\fR .IX Subsection "set_sRGB" .PP .Vb 1 \& $png\->set_sRGB ($srgb); .Ve .PP \&\f(CW$srgb\fR is one of the values described in \*(L"get_sRGB\*(R". .PP This function corresponds to \f(CW\*(C`png_set_sRGB\*(C'\fR in libpng .SS "tIME" .IX Subsection "tIME" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R" for information on the \s-1PNG\s0 standards for time stamp information. .PP \fIget_tIME\fR .IX Subsection "get_tIME" .PP .Vb 4 \& my $time = $png\->get_tIME (); \& if ($time && $time\->{year} < 2005) { \& warn "Your PNG is now getting old. Don\*(Aqt forget to oil it to prevent rust."; \& } .Ve .PP The return value is either the undefined value, if no \f(CW\*(C`tIME\*(C'\fR chunk exists in the \s-1PNG,\s0 or a hash reference containing fields \f(CW\*(C`year\*(C'\fR, \&\f(CW\*(C`month\*(C'\fR, \f(CW\*(C`day\*(C'\fR, \f(CW\*(C`hour\*(C'\fR, \f(CW\*(C`minute\*(C'\fR and \f(CW\*(C`second\*(C'\fR. \f(CW\*(C`month\*(C'\fR and \&\f(CW\*(C`day\*(C'\fR start from 1 rather than 0. .PP The \*(L"modification time value\*(R" of the \s-1PNG\s0 image is a chunk written into the \s-1PNG\s0 file itself, and may not have the same value as the operating system's modification time for the file. The tIME chunk is not a compulsory requirement for \s-1PNG\s0 files, and most \s-1PNG\s0 image files do not contain this chunk. \s-1PNG\s0 tIME chunks do not contain a time zone. According to this subsection of \*(L"The \s-1PNG\s0 specification\*(R", \*(L"Universal Time (\s-1UTC\s0) should be specified rather than local time.\*(R" .PP This function corresponds to \f(CW\*(C`png_get_tIME\*(C'\fR in libpng, with a Perl hash reference substituted for the C struct \f(CW\*(C`png_timep\*(C'\fR used in libpng. .PP \fIset_tIME\fR .IX Subsection "set_tIME" .PP .Vb 4 \& # Set the time to "now" \& $png\->set_tIME (); \& # Set the time \& $png\->set_tIME ({year => 1999, month => 12}); .Ve .PP Set the modification time of the \s-1PNG\s0 to the values given by the argument, a hash reference containing the fields \f(CW\*(C`year\*(C'\fR, \f(CW\*(C`month\*(C'\fR, \&\f(CW\*(C`day\*(C'\fR for the day of the month, \f(CW\*(C`hour\*(C'\fR, \f(CW\*(C`minute\*(C'\fR, and \f(CW\*(C`second\*(C'\fR. The numbering for \f(CW\*(C`month\*(C'\fR and \f(CW\*(C`day\*(C'\fR is from 1, not 0. If any of year, hour, minute or second is omitted from the hash reference, these are set to zero. If month or day are omitted, these are set to 1. \s-1PNG\s0 tIME chunks do not contain a time zone. According to this subsection of \*(L"The \s-1PNG\s0 specification\*(R", \*(L"Universal Time (\s-1UTC\s0) should be specified rather than local time.\*(R" If the entire argument is omitted or contains an invalid value, the time is set to the current time. .PP This function corresponds to \f(CW\*(C`png_set_tIME\*(C'\fR in libpng, with a Perl hash reference substituted for the C struct \f(CW\*(C`png_timep\*(C'\fR used in libpng. .SS "tRNS" .IX Subsection "tRNS" See this subsection of \*(L"The \s-1PNG\s0 specification\*(R". .PP \fIget_tRNS\fR .IX Subsection "get_tRNS" .PP .Vb 1 \& my $trns = $png\->get_tRNS (); .Ve .PP Get the \f(CW\*(C`tRNS\*(C'\fR chunk. If the image is a palette type, this is an array reference. If the image is a non-palette type, this is a hash containing values for the keys red, green, blue, and gray. .PP \fIset_tRNS\fR .IX Subsection "set_tRNS" .PP .Vb 1 \& $png\->set_tRNS ($trns); .Ve .PP Set the \f(CW\*(C`tRNS\*(C'\fR chunk. If the image is a palette type, \f(CW$trns\fR is a reference to an array of positive or zero values between 0 and 255 of the same size as the palette. It must not contain more than 256 values. If the image is not a palette type, \f(CW$trns\fR is a hash reference containing values for the keys red, green, blue and gray. .SH "Libpng transformations" .IX Header "Libpng transformations" .SS "set_bgr" .IX Subsection "set_bgr" .Vb 1 \& $png\->set_bgr (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. Flips \s-1RGB\s0 to \s-1BGR.\s0 See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_bgr\*(C'\fR, for a read object, use \*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_BGR\*(R"\s0'. .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_BGR\*(Aq)) { \& # do something \& } .Ve .PP For a write object, use argument '\*(L"\s-1WRITE_BGR\*(R"\s0'. .PP This function corresponds to \f(CW\*(C`png_set_bgr\*(C'\fR in libpng .SS "set_expand" .IX Subsection "set_expand" .Vb 1 \& $png\->set_expand (); .Ve .PP Set transformation in \f(CW$png\fR such that paletted images are expanded to \s-1RGB,\s0 grayscale images of bit-depth less than 8 are expanded to 8\-bit images, and tRNS chunks are expanded to alpha channels. .PP To test whether your version of libpng supports \f(CW\*(C`set_expand\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_EXPAND\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_EXPAND\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_expand\*(C'\fR in libpng .SS "set_expand_16" .IX Subsection "set_expand_16" .Vb 1 \& $png\->set_expand_16 (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. .PP To test whether your version of libpng supports \f(CW\*(C`set_expand_16\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_EXPAND_16\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_EXPAND_16\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_expand_16\*(C'\fR in libpng .SS "set_expand_gray_1_2_4_to_8" .IX Subsection "set_expand_gray_1_2_4_to_8" .Vb 1 \& $png\->set_expand_gray_1_2_4_to_8 (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. .PP To test whether your version of libpng supports \f(CW\*(C`set_expand_gray_1_2_4_to_8\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_EXPAND\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_EXPAND\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_expand_gray_1_2_4_to_8\*(C'\fR in libpng .SS "set_gray_to_rgb" .IX Subsection "set_gray_to_rgb" .Vb 1 \& $png\->set_gray_to_rgb (); .Ve .PP Convert a grayscale \s-1PNG\s0 file to \s-1RGB\s0 format on reading. .PP To test whether your version of libpng supports \f(CW\*(C`set_gray_to_rgb\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_GRAY_TO_RGB\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_GRAY_TO_RGB\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_gray_to_rgb\*(C'\fR in libpng .SS "set_invert_alpha" .IX Subsection "set_invert_alpha" .Vb 1 \& $png\->set_invert_alpha (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_invert_alpha\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_INVERT_ALPHA\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_INVERT_ALPHA\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_invert_alpha\*(C'\fR in libpng .SS "set_invert_mono" .IX Subsection "set_invert_mono" .Vb 1 \& $png\->set_invert_mono (); .Ve .PP Invert monochrome images. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_invert_mono\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_INVERT\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_INVERT\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_invert_mono\*(C'\fR in libpng .SS "set_packing" .IX Subsection "set_packing" .Vb 1 \& $png\->set_packing (); .Ve .PP When reading a \s-1PNG,\s0 expand the image to 1 pixel per byte for bit-depths 1, 2 and 4 without changing the order of the pixels. If this is not called, the pixels of bit_depths 1, 2 and 4 are packed into bytes as small as possible, for example, 8 pixels per byte for 1\-bit files. See the libpng manual for details. See also \*(L"set_packswap\*(R". .PP To test whether your version of libpng supports \f(CW\*(C`set_packing\*(C'\fR, for a read object, use \*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_PACK\*(R"\s0'. .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_PACK\*(Aq)) { \& # do something \& } .Ve .PP For a write object, use argument '\*(L"\s-1WRITE_PACK\*(R"\s0'. .PP This function corresponds to \f(CW\*(C`png_set_packing\*(C'\fR in libpng .SS "set_packswap" .IX Subsection "set_packswap" .Vb 1 \& $png\->set_packswap (); .Ve .PP Swaps the bits of 1, 2, or 4 bits/pixel images. The default for \s-1PNG\s0 image is to put the left pixel into the highest part of the byte, so for example if the bit depth is 1, the pixels from left to right go into a byte as values 128 for the leftmost, 64, 32, 16, 8, 4, 2, then 1 for the rightmost pixel. This call reverses that behavior so that the pixels in a byte go 1 for the leftmost, 2, ..., then 128 for the rightmost. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_packswap\*(C'\fR, for a read object, use \*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_PACKSWAP\*(R"\s0'. .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_PACKSWAP\*(Aq)) { \& # do something \& } .Ve .PP For a write object, use argument '\*(L"\s-1WRITE_PACKSWAP\*(R"\s0'. .PP This function corresponds to \f(CW\*(C`png_set_packswap\*(C'\fR in libpng .SS "set_palette_to_rgb" .IX Subsection "set_palette_to_rgb" .Vb 1 \& $png\->set_palette_to_rgb (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_palette_to_rgb\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_EXPAND\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_EXPAND\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_palette_to_rgb\*(C'\fR in libpng .SS "set_scale_16" .IX Subsection "set_scale_16" .Vb 1 \& $png\->set_scale_16 () .Ve .PP ⛐πŸ€ͺ⚠ Untested. .PP To test whether your version of libpng supports \f(CW\*(C`set_scale_16\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_SCALE_16_TO_8\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_SCALE_16_TO_8\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_scale_16\*(C'\fR in libpng .SS "set_strip_16" .IX Subsection "set_strip_16" .Vb 1 \& $png\->set_strip_16 (); .Ve .PP Strip the pixels of a \s-1PNG\s0 stream with 16 bits per channel to 8 bits per channel. .PP To test whether your version of libpng supports \f(CW\*(C`set_strip_16\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_STRIP_16_TO_8\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_STRIP_16_TO_8\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_strip_16\*(C'\fR in libpng .SS "set_strip_alpha" .IX Subsection "set_strip_alpha" .Vb 1 \& $png\->set_strip_alpha (); .Ve .PP Strip the alpha channel of a \s-1PNG\s0 stream. .PP To test whether your version of libpng supports \f(CW\*(C`set_strip_alpha\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_STRIP_ALPHA\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_STRIP_ALPHA\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_strip_alpha\*(C'\fR in libpng .SS "set_swap" .IX Subsection "set_swap" .Vb 1 \& $png\->set_swap (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. Swaps around the bytes of 16 bits/pixel images. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_swap\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_SWAP\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_SWAP\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_swap\*(C'\fR in libpng .SS "set_swap_alpha" .IX Subsection "set_swap_alpha" .Vb 1 \& $png\->set_swap_alpha (); .Ve .PP ⛐πŸ€ͺ⚠ Untested. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_swap_alpha\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_SWAP_ALPHA\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_SWAP_ALPHA\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_swap_alpha\*(C'\fR in libpng .SS "set_tRNS_to_alpha" .IX Subsection "set_tRNS_to_alpha" .Vb 1 \& $png\->set_tRNS_to_alpha .Ve .PP ⛐πŸ€ͺ⚠ Untested. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_tRNS_to_alpha\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_EXPAND\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_EXPAND\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_tRNS_to_alpha\*(C'\fR in libpng .SH "Other libpng functions" .IX Header "Other libpng functions" .SS "get_chunk_cache_max" .IX Subsection "get_chunk_cache_max" .Vb 1 \& my $max = $png\->get_chunk_cache_max (); .Ve .PP Get the maximum number of ancilliary chunks allowed. See also \*(L"set_chunk_cache_max\*(R". .PP To test whether your version of libpng supports \f(CW\*(C`get_chunk_cache_max\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1CHUNK_CACHE_MAX\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqCHUNK_CACHE_MAX\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_png_get_chunk_cache_max\*(C'\fR in libpng .SS "get_rgb_to_gray_status" .IX Subsection "get_rgb_to_gray_status" .Vb 1 \& my $badpixels = $png\->get_rgb_to_gray_status (); .Ve .PP Returns a true value if there were some non-gray pixels in an \s-1RGB\s0 image after calling \*(L"set_rgb_to_gray\*(R". .PP \fISaving bandwidth\fR .IX Subsection "Saving bandwidth" .PP Try this one weird old \f(CW\*(C`get_rgb_to_gray_status\*(C'\fR trick to check whether an image marked as \s-1RGB\s0 is really monochrome or not. .PP .Vb 4 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& \& my $file = \*(Aqlife.png\*(Aq; \& print "Size before: ", \-s $file, "\en"; \& my $png = create_reader ($file); \& $png\->read_info (); \& $png\->set_rgb_to_gray (); \& if ($png\->get_rgb_to_gray_status ()) { \& print "The image contained non\-gray pixels.\en"; \& } \& else { \& print "The image was grayscale already.\en"; \& } \& $png\->read_image (); \& $png\->read_end (); \& my $wpng = $png\->copy_png (); \& my $ihdr = $wpng\->get_IHDR (); \& $ihdr\->{color_type} = PNG_COLOR_TYPE_GRAY; \& $wpng\->set_IHDR ($ihdr); \& my $after = "life\-gray.png"; \& $wpng\->write_png_file ($after); \& print "Size after: ", \-s $after, "\en"; \& \& if (! png_compare ($file, $after)) { \& print "The two files contain exactly the same image data.\en"; \& } \& else { \& print "The two files contain different image data.\en"; \& } .Ve .PP (This example is included as \fIexamples/xkcd.pl\fR in the distribution.) .PP The output looks like this: .PP .Vb 4 \& Size before: 97299 \& The image was grayscale already. \& Size after: 46956 \& The two files contain exactly the same image data. .Ve .PP examples/life\-gray.png is included in the distribution. .PP Correct use of Image::PNG::Libpng could have spared as many as 50,000 bytes from the indignity of being sent around the internet. .PP This also illustrates the use of \*(L"png_compare\*(R". .PP Original image, licence statement and copyright notice here . .SS "get_user_height_max" .IX Subsection "get_user_height_max" .Vb 1 \& $png\->get_user_height_max (); .Ve .PP Get the maximum height allowed for a \s-1PNG\s0 file. The default is 1 million pixels. These values can be changed by \*(L"set_user_limits\*(R". .PP This function corresponds to \f(CW\*(C`png_get_user_height_max\*(C'\fR in libpng .SS "get_user_width_max" .IX Subsection "get_user_width_max" .Vb 1 \& $png\->get_user_width_max (); .Ve .PP Get the maximum width allowed for a \s-1PNG\s0 file. The default is 1 million pixels. These values can be changed by \*(L"set_user_limits\*(R". .PP This function corresponds to \f(CW\*(C`png_get_user_width_max\*(C'\fR in libpng .SS "permit_mng_features" .IX Subsection "permit_mng_features" .Vb 1 \& $png\->permit_mng_features ($mask); .Ve .PP ⛐πŸ€ͺ⚠ Untested. \f(CW$mask\fR is an integer containing flags. See the libpng manual for details. .PP (\s-1MNG,\s0 'Multiple\-image Network Graphics', is an image animation format related to \s-1PNG.\s0 It has not been widely adopted.) .PP To test whether your version of libpng supports \f(CW\*(C`permit_mng_features\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1MNG_FEATURES\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqMNG_FEATURES\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_permit_mng_features\*(C'\fR in libpng .SS "set_add_alpha" .IX Subsection "set_add_alpha" .Vb 1 \& $png\->set_add_alpha ($filler, $filler_loc); .Ve .PP ⛐πŸ€ͺ⚠ Untested. Change \f(CW$png\fR to add an alpha channel. This only works for grayscale or \s-1RGB\s0 images with bit depth of 8 or 16. \f(CW$filler\fR contains the alpha value to assign to each pixel, and \&\f(CW$filler_loc\fR is either \f(CW\*(C`PNG_FILLER_BEFORE\*(C'\fR or \&\f(CW\*(C`PNG_FILLER_AFTER\*(C'\fR. The function of \f(CW\*(C`set_add_alpha\*(C'\fR is \&\*(L"set_filler\*(R" and a change of the color type to add an alpha channel. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_add_alpha\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_FILLER\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_FILLER\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_add_alpha\*(C'\fR in libpng .SS "set_alpha_mode" .IX Subsection "set_alpha_mode" .Vb 1 \& $png\->set_alpha_mode ($mode, $screen_gamma); .Ve .PP ⛐πŸ€ͺ⚠ Untested. \f(CW$mode\fR is an integer, one of the \&\f(CW\*(C`PNG_ALPHA_*\*(C'\fR constants. \f(CW$screen_gamma\fR is a floating point number. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_alpha_mode\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_ALPHA_MODE\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_ALPHA_MODE\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_alpha_mode\*(C'\fR in libpng .SS "set_background" .IX Subsection "set_background" .Vb 1 \& $png\->set_background (\e%color, $bkgd_gamma_code, $need_expand, $gamma); .Ve .PP \&\f(CW\*(C`set_background\*(C'\fR sets the background of an image with an alpha channel or simple transparency (a \*(L"tRNS\*(R" chunk) with the color specified by \f(CW%color\fR. If \f(CW$bkgd_gamma_code\fR is set to \&\f(CW\*(C`PNG_BACKGROUND_GAMMA_SCREEN\*(C'\fR, it indicates that the supplied background color is in the gamma space of the display, else if it is set to \f(CW\*(C`PNG_BACKGROUND_GAMMA_FILE\*(C'\fR, the color is in the gamma space of the file. If \f(CW$bkgd_gamma_code\fR is set to \&\f(CW\*(C`PNG_BACKGROUND_GAMMA_UNIQUE\*(C'\fR, the value of \f(CW$gamma\fR is used, otherwise \f(CW$gamma\fR appears to be ignored and can be omitted. (This is not documented in the libpng manual or elsewhere. See .) .PP If the background color is supplied at the original bit-depth for a grayscale image that is expanded to truecolor or to a higher bit-depth, \f(CW$need_expand\fR must be set to a true value, but if the background color is supplied at the expanded bit-depth, \&\f(CW$need_expand\fR must be set to a false value. Similarly for paletted images, if \f(CW%color\fR is supplied as a palette index (\f(CW$color{index}\fR), \f(CW$need_expand\fR must be set to a true value, but if \f(CW%color\fR is an \s-1RGB\s0 triplet, \f(CW$need_expand\fR must be set to a false value. .PP See \*(L"Setting the background\*(R" for an example. .PP To test whether your version of libpng supports \f(CW\*(C`set_background\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_BACKGROUND\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_BACKGROUND\*(Aq)) { \& # do something \& } .Ve .SS "set_chunk_cache_max" .IX Subsection "set_chunk_cache_max" .Vb 1 \& $png\->set_chunk_cache_max (42); .Ve .PP Set the maximum number of ancilliary chunks allowed. The default is 1000. See also \*(L"get_chunk_cache_max\*(R". .PP To test whether your version of libpng supports \f(CW\*(C`set_chunk_cache_max\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1CHUNK_CACHE_MAX\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqCHUNK_CACHE_MAX\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_png_set_chunk_cache_max\*(C'\fR in libpng .SS "set_filler" .IX Subsection "set_filler" .Vb 1 \& $png\->set_filler ($filler, $flags); .Ve .PP Set transformations in \f(CW$png\fR such that a filler byte \f(CW$filler\fR is added when an 8\-bit grayscale image or 24\-bit \s-1RGB\s0 image is read, and a filler byte is deleted when an 8\-bit grayscale image or 24\-bit \s-1RGB\s0 image is written. \f(CW$flags\fR may be \f(CW\*(C`PNG_FILLER_BEFORE\*(C'\fR or \&\f(CW\*(C`PNG_FILLER_AFTER\*(C'\fR. An error is produced if \f(CW$png\fR has bit depth less than 8. .PP This does not change the color type of the image. See the related function \*(L"set_add_alpha\*(R" if you want to add an alpha channel. .PP To test whether your version of libpng supports \f(CW\*(C`set_filler\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_FILLER\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_FILLER\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_filler\*(C'\fR in libpng .SS "set_gamma" .IX Subsection "set_gamma" .Vb 1 \& $png\->set_gamma ($screen_gamma, $output_gamma); .Ve .PP ⛐πŸ€ͺ⚠ Untested. \f(CW$screen_gamma\fR and \f(CW$output_gamma\fR should contain floating-point arguments. See the libpng manual for details. .PP To test whether your version of libpng supports \f(CW\*(C`set_gamma\*(C'\fR, use \&\*(L"libpng_supports\*(R" with argument '\*(L"\s-1READ_GAMMA\*(R"\s0': .PP .Vb 3 \& if (libpng_supports (\*(AqREAD_GAMMA\*(Aq)) { \& # do something \& } .Ve .PP This function corresponds to \f(CW\*(C`png_set_gamma\*(C'\fR in libpng .SS "set_quantize" .IX Subsection "set_quantize" .Vb 1 \& $png\->set_quantize (\e@palette, $ncolors, \e@histogram, $full_quantize); .Ve .PP The \f(CW@palette\fR part must be set to a palette similar to \&\*(L"set_PLTE\*(R". \f(CW$ncolors\fR must be the length of \f(CW@palette\fR or shorter. \f(CW@histogram\fR can be an empty array or if not it needs to be an array of integers of exactly the same length as \f(CW@palette\fR. The integers represent the frequency of the colors in \f(CW@palette\fR. These integers can range from 0 to 65355. Larger values or negative values cause an error. The final argument, \f(CW$full_quantize\fR, should be 1 for \&\s-1RGB\s0 images or 0 for paletted images. .PP \fIExperiments in quantization\fR .IX Subsection "Experiments in quantization" .PP This example program experiments with two ways to quantize a \s-1PNG\s0 image, first of all using a completely random palette, and second using colors picked from the image at random: .PP .Vb 11 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& my $file = "wave.png"; \& my $ncolors = 40; \& my $palette = randompalette ($ncolors); \& write_with_palette ($file, $palette, $ncolors, [], "random"); \& my $picked = points ($file, $ncolors); \& my @hist = (1) x $ncolors; \& write_with_palette ($file, $picked, $ncolors, \e@hist, "picked"); \& exit; \& \& sub write_with_palette \& { \& my ($file, $palette, $ncolors, $hist, $name) = @_; \& my $rpng = create_reader ($file); \& $rpng\->set_quantize ($palette, $ncolors, $hist, 1); \& $rpng\->read_png (); \& my $wpng = copy_png ($rpng); \& $wpng\->set_PLTE ($palette); \& $wpng\->write_png_file ("$name\-$file"); \& } \& \& sub points \& { \& my ($pngfile, $ncolors) = @_; \& my $png = read_png_file ($pngfile); \& my $rows = $png\->get_rows (); \& my $h = $png\->height (); \& my $w = $png\->width (); \& my $ch = $png\->get_channels (); \& my @p; \& for (0..$ncolors\-1) { \& my $x = int (rand ($w)); \& my $y = int (rand ($h)); \& my $row = $rows\->[$y]; \& my @pix = split (\*(Aq\*(Aq, substr ($row, $x*$ch, $ch)); \& push @p, { \& red => ord ($pix[0]), \& green => ord ($pix[1]), \& blue => ord ($pix[2]), \& }; \& } \& return \e@p; \& } \& \& sub randompalette \& { \& my ($n) = @_; \& my @p; \& for (0..$n\-1) { \& my %color; \& for my $c (qw!red green blue!) { \& $color{$c} = int (rand (256)) \& } \& push @p, \e%color; \& } \& return \e@p; \& } .Ve .PP (This example is included as \fIexamples/q.pl\fR in the distribution.) .PP examples/wave.png is included in the distribution. .PP examples/random\-wave.png is included in the distribution. .PP examples/picked\-wave.png is included in the distribution. .SS "set_rgb_to_gray" .IX Subsection "set_rgb_to_gray" .Vb 1 \& $png\->set_rgb_to_gray (); \& \& $png\->set_rgb_to_gray ($error_action, $red_weight, $green_weight); .Ve .PP Convert a \s-1PNG\s0 image from \s-1RGB\s0 (colored) to gray. See the libpng manual for details. .PP Without arguments, the libpng default values are used for \&\f(CW$red_weight\fR and \f(CW$green_weight\fR, and an error action of \*(L"none\*(R" is chosen. If the error action is set to a value of \&\f(CW\*(C`PNG_ERROR_ACTION_WARN\*(C'\fR or \f(CW\*(C`PNG_ERROR_ACTION_ERROR\*(C'\fR, pixels in the \&\s-1RGB\s0 image where the R, G and B values are not equal will cause a warning or error respectively. To get the default values for \&\f(CW$red_weight\fR or \f(CW$green_weight\fR, use any negative value. See the libpng manual for details. .PP If you choose \f(CW\*(C`PNG_ERROR_ACTION_NONE\*(C'\fR you can find out whether there were non-RGB pixels in your image using \*(L"get_rgb_to_gray_status\*(R". .PP This function corresponds to \f(CW\*(C`png_png_set_rgb_to_gray\*(C'\fR in libpng with \f(CW$error_action\fR having a default value of \f(CW\*(C`PNG_ERROR_ACTION_NONE\*(C'\fR, and \f(CW$red_weight\fR and \&\f(CW$green_weight\fR both set to negative values. .PP \fIConvert a colored image to gray\fR .IX Subsection "Convert a colored image to gray" .PP .Vb 4 \& use utf8; \& use FindBin \*(Aq$Bin\*(Aq; \& use Image::PNG::Libpng \*(Aq:all\*(Aq; \& use Image::PNG::Const \*(Aq:all\*(Aq; \& \& my $png = create_reader ("$Bin/luv.png"); \& $png\->read_info (); \& $png\->set_rgb_to_gray (); \& $png\->read_image (); \& $png\->read_end (); \& my $wpng = $png\->copy_png (); \& my $ihdr = $wpng\->get_IHDR (); \& $ihdr\->{color_type} = PNG_COLOR_TYPE_GRAY_ALPHA; \& $wpng\->set_IHDR ($ihdr); \& $wpng\->write_png_file ("$Bin/grayface.png"); .Ve .PP (This example is included as \fIexamples/rgb\-to\-gray.pl\fR in the distribution.) .PP examples/grayface.png is included in the distribution. .SS "set_user_limits" .IX Subsection "set_user_limits" .Vb 1 \& $png\->set_user_limits ($width, $height); .Ve .PP This enables a user to override libpng's restrictions to one million pixels in width and one million pixels in height for a \s-1PNG\s0 image. .PP This function corresponds to \f(CW\*(C`png_set_user_limits\*(C'\fR in libpng .SH "Other functions" .IX Header "Other functions" This section contains other functions which don't correspond to anything in libpng itself, but which have been added to the module for utility. .SS "any2gray8" .IX Subsection "any2gray8" .Vb 1 \& my $wpng = any2gray8 ("any.png"); .Ve .PP Convert any type of \s-1PNG\s0 file whatsoever into a bit-depth 8 grayscale image without an alpha channel (\s-1PNG_COLOR_TYPE_GRAY\s0). The return value is a writing structure as made by \*(L"create_write_struct\*(R". .PP Currently the \*(L"tRNS\*(R" chunk is ignored by this. .PP By default the alpha channel is set to either the value of the \&\*(L"bKGD\*(R" chunk if there is one, or white if not. You can set another background using the option \f(CW\*(C`bkgd\*(C'\fR: .PP .Vb 1 \& my $wpng = any2gray8 (\*(Aqany.png\*(Aq, bkgd => {red => 255, green => 0, blue => 99}); .Ve .PP This will of course be ignored if \fIany.png\fR does not contain an alpha channel. \s-1RGB\s0 to gray conversion is done using \*(L"set_rgb_to_gray\*(R" with the default values. .PP This function is not supported for versions of libpng earlier than 1.6.14. .SS "color_type_channels" .IX Subsection "color_type_channels" .Vb 1 \& my $channels = color_type_channels (\*(AqPNG_COLOR_TYPE_RGB_ALPHA\*(Aq); .Ve .PP Returns the number of channels (the number of components of one pixel) of the specified color type. .SS "copy_row_pointers" .IX Subsection "copy_row_pointers" .Vb 1 \& $png\->copy_row_pointers ($row_pointers); .Ve .PP This allows \s-1XS\s0 routines to directly set the value of the row pointers for the \s-1PNG\s0 image. The memory is copied, so whatever is in the row pointers can be freed immediately after calling this. However, the image data it points to is not copied, so this needs to be valid until the \s-1PNG\s0 is written. .PP The Perl scalar \f(CW$row_pointers\fR should be set up something like the following (where \f(CW\*(C`rp\*(C'\fR is the C pointer): .PP .Vb 1 \& RETVAL = newSViv (PTR2IV (rp)); .Ve .PP It's extracted from the Perl scalar using .PP .Vb 1 \& rp = INT2PTR (png_byte **, SvIV (row_pointers)); .Ve .PP where row_pointers is the \f(CW\*(C`SV *\*(C'\fR corresponding to \f(CW$row_pointers\fR in the Perl script. See also \*(L"set_row_pointers\*(R" which does the same thing but takes ownership of the memory. .SS "get_chunk" .IX Subsection "get_chunk" .Vb 1 \& my $timechunk = $png\->get_chunk (\*(AqtIME\*(Aq); .Ve .PP Get the specified chunk. This produces a fatal error if asked for the \&\f(CW\*(C`IDAT\*(C'\fR (image data) chunk, use \*(L"get_rows\*(R" instead. Returns \f(CW\*(C`undef\*(C'\fR if asked for an unknown chunk name. .PP This is used by pnginspect to get the valid chunks. See also \&\*(L"set_chunk\*(R". .SS "get_internals" .IX Subsection "get_internals" .Vb 1 \& my ($png_struct, $png_info) = get_internals ($png); .Ve .PP This function returns the \f(CW\*(C`png_structp\*(C'\fR and \f(CW\*(C`png_infop\*(C'\fR contained in \&\f(CW$png\fR. The return value is a list containing the \f(CW\*(C`png_structp\*(C'\fR as the first argument and the \f(CW\*(C`png_infop\*(C'\fR as the second argument, wrapped up as references to objects of type \&\f(CW\*(C`Image::PNG::Libpng::png_struct\*(C'\fR and \f(CW\*(C`Image::PNG::Libpng::png_info\*(C'\fR. .PP To access the values of the pointers, use something like this: .PP .Vb 9 \& void access_png_internals (png, info) \& SV * png; \& SV * info; \& PREINIT: \& png_struct * cpng; \& png_info * cinfo; \& CODE: \& cpng = INT2PTR (png_struct *, SvIV (png)); \& cinfo = INT2PTR (png_info *, SvIV (info)); .Ve .PP An example exists in Image::PNG::Cairo. .SS "get_tRNS_palette" .IX Subsection "get_tRNS_palette" .Vb 1 \& $png\->get_tRNS_palette (); .Ve .PP This is not a libpng-equivalent function. .SS "image_data_diff" .IX Subsection "image_data_diff" .Vb 1 \& my $diff = image_data_diff (\*(Aqa.png\*(Aq, \*(Aqb.png\*(Aq); .Ve .PP This returns the undefined value if the image data in \fIa.png\fR is the same as the image data in \fIb.png\fR. If the image data is different, it returns a readable text message describing the first difference found, for example the height is different, or row 0 of the image data is different, etc. .PP This function is used in testing this module. See also \*(L"png_compare\*(R". .SS "libpng_supports" .IX Subsection "libpng_supports" .Vb 3 \& if (libpng_supports (\*(AqiTXt\*(Aq)) { \& print "Your libpng supports international text.\en"; \& } .Ve .PP This function returns true or false depending on whether the version of libpng which this was compiled with supports or does not support a particular facility. For the most part, these are taken directly from the C macros of libpng. .PP The possible arguments to \f(CW\*(C`libpng_supports\*(C'\fR are: .IP "16BIT" 4 .IX Item "16BIT" .PD 0 .IP "\s-1ALIGNED_MEMORY\s0" 4 .IX Item "ALIGNED_MEMORY" .IP "\s-1ARM_NEON_API\s0" 4 .IX Item "ARM_NEON_API" .IP "\s-1BENIGN_ERRORS\s0" 4 .IX Item "BENIGN_ERRORS" .IP "\s-1BENIGN_READ_ERRORS\s0" 4 .IX Item "BENIGN_READ_ERRORS" .IP "\s-1BENIGN_WRITE_ERRORS\s0" 4 .IX Item "BENIGN_WRITE_ERRORS" .IP "bKGD" 4 .IX Item "bKGD" .PD Does the libpng support the \*(L"bKGD\*(R" chunk? .IP "\s-1BUILD_GRAYSCALE_PALETTE\s0" 4 .IX Item "BUILD_GRAYSCALE_PALETTE" .PD 0 .IP "\s-1BUILTIN_BSWAP16\s0" 4 .IX Item "BUILTIN_BSWAP16" .IP "\s-1CHECK_FOR_INVALID_INDEX\s0" 4 .IX Item "CHECK_FOR_INVALID_INDEX" .IP "cHRM" 4 .IX Item "cHRM" .PD Does the libpng support the \*(L"cHRM\*(R" chunk? .IP "cHRM_XYZ" 4 .IX Item "cHRM_XYZ" This is local to Image::PNG::Libpng and not a part of libpng itself. .Sp It was necessary to extend libpng because the conditional compilation macro for \*(L"set_cHRM_XYZ\*(R" and \*(L"get_cHRM_XYZ\*(R", \f(CW\*(C`PNG_cHRM_SUPPORTED\*(C'\fR is defined (true) for old libpngs which do not actually contain these functions. .IP "\s-1CHUNK_CACHE_MAX\s0" 4 .IX Item "CHUNK_CACHE_MAX" This is local to Image::PNG::Libpng and not a part of libpng itself. .Sp It was necessary to extend libpng because the conditional compilation macro for \*(L"set_chunk_cache_max\*(R" and \*(L"get_chunk_cache_max\*(R", \&\f(CW\*(C`PNG_USER_LIMITS_SUPPORTED\*(C'\fR is defined (true) for old libpngs which do not actually contain these functions. .IP "\s-1CHUNK_MALLOC_MAX\s0" 4 .IX Item "CHUNK_MALLOC_MAX" This is local to Image::PNG::Libpng and not a part of libpng itself. .Sp The reasons for this are identical to those for \*(L"\s-1CHUNK_CACHE_MAX\*(R"\s0. .IP "\s-1COLORSPACE\s0" 4 .IX Item "COLORSPACE" .PD 0 .IP "\s-1CONSOLE_IO\s0" 4 .IX Item "CONSOLE_IO" .IP "CONVERT_tIME" 4 .IX Item "CONVERT_tIME" .PD This is related to two deprecated functions, \&\*(L"png_convert_from_time_t\*(R" and \*(L"png_convert_from_struct_tm\*(R". .IP "CONVERT_tIME" 4 .IX Item "CONVERT_tIME" .PD 0 .IP "\s-1EASY_ACCESS\s0" 4 .IX Item "EASY_ACCESS" .IP "\s-1ERROR_NUMBERS\s0" 4 .IX Item "ERROR_NUMBERS" .IP "\s-1ERROR_TEXT\s0" 4 .IX Item "ERROR_TEXT" .IP "eXIf" 4 .IX Item "eXIf" .PD Does the libpng support the \*(L"eXIf\*(R" chunk? .IP "\s-1FIXED_POINT\s0" 4 .IX Item "FIXED_POINT" .PD 0 .IP "\s-1FIXED_POINT_MACRO\s0" 4 .IX Item "FIXED_POINT_MACRO" .IP "\s-1FLOATING_ARITHMETIC\s0" 4 .IX Item "FLOATING_ARITHMETIC" .IP "\s-1FLOATING_POINT\s0" 4 .IX Item "FLOATING_POINT" .IP "\s-1FORMAT_AFIRST\s0" 4 .IX Item "FORMAT_AFIRST" .IP "\s-1FORMAT_BGR\s0" 4 .IX Item "FORMAT_BGR" .IP "gAMA" 4 .IX Item "gAMA" .PD Does the libpng support the \*(L"gAMA\*(R" chunk? .IP "\s-1GAMMA\s0" 4 .IX Item "GAMMA" .PD 0 .IP "\s-1GET_PALETTE_MAX\s0" 4 .IX Item "GET_PALETTE_MAX" .PD Does your libpng support \*(L"get_palette_max\*(R"? .IP "\s-1HANDLE_AS_UNKNOWN\s0" 4 .IX Item "HANDLE_AS_UNKNOWN" .PD 0 .IP "\s-1HANDLE_AS_UNKNOWN\s0" 4 .IX Item "HANDLE_AS_UNKNOWN" .IP "hIST" 4 .IX Item "hIST" .PD Does the libpng support the \*(L"hIST\*(R" chunk? .IP "iCCP" 4 .IX Item "iCCP" Does the libpng support the \*(L"iCCP\*(R" chunk? .IP "\s-1INCH_CONVERSIONS\s0" 4 .IX Item "INCH_CONVERSIONS" .PD 0 .IP "\s-1INFO_IMAGE\s0" 4 .IX Item "INFO_IMAGE" .IP "\s-1IO_STATE\s0" 4 .IX Item "IO_STATE" .IP "iTXt" 4 .IX Item "iTXt" .PD Does the libpng support international text? .IP "\s-1MIPS_MSA_API\s0" 4 .IX Item "MIPS_MSA_API" .PD 0 .IP "\s-1MNG_FEATURES\s0" 4 .IX Item "MNG_FEATURES" .IP "oFFs" 4 .IX Item "oFFs" .PD Does the libpng support the \*(L"oFFs\*(R" chunk? .IP "pCAL" 4 .IX Item "pCAL" Does the libpng support the \*(L"pCAL\*(R" extension? .IP "\s-1PEDANTIC_WARNINGS\s0" 4 .IX Item "PEDANTIC_WARNINGS" .PD 0 .IP "pHYs" 4 .IX Item "pHYs" .PD Does the libpng support the \*(L"pHYs\*(R" chunk? .IP "\s-1POINTER_INDEXING\s0" 4 .IX Item "POINTER_INDEXING" .PD 0 .IP "\s-1POWERPC_VSX_API\s0" 4 .IX Item "POWERPC_VSX_API" .IP "\s-1PROGRESSIVE_READ\s0" 4 .IX Item "PROGRESSIVE_READ" .IP "\s-1READ\s0" 4 .IX Item "READ" .PD Can libpng read PNGs? .IP "\s-1READ_16_TO_8\s0" 4 .IX Item "READ_16_TO_8" .PD 0 .IP "\s-1READ_ALPHA_MODE\s0" 4 .IX Item "READ_ALPHA_MODE" .PD See \*(L"set_alpha_mode\*(R". .IP "\s-1READ_BACKGROUND\s0" 4 .IX Item "READ_BACKGROUND" See \*(L"set_background\*(R". .IP "\s-1READ_BGR\s0" 4 .IX Item "READ_BGR" See \*(L"set_bgr\*(R". .IP "\s-1READ_COMPOSITE_NODIV\s0" 4 .IX Item "READ_COMPOSITE_NODIV" .PD 0 .IP "\s-1READ_COMPRESSED_TEXT\s0" 4 .IX Item "READ_COMPRESSED_TEXT" .IP "\s-1READ_EXPAND\s0" 4 .IX Item "READ_EXPAND" .IP "\s-1READ_EXPAND_16\s0" 4 .IX Item "READ_EXPAND_16" .IP "\s-1READ_FILLER\s0" 4 .IX Item "READ_FILLER" .IP "\s-1READ_GAMMA\s0" 4 .IX Item "READ_GAMMA" .PD See \*(L"set_gamma\*(R". .IP "\s-1READ_GRAY_TO_RGB\s0" 4 .IX Item "READ_GRAY_TO_RGB" .PD 0 .IP "\s-1READ_INTERLACING\s0" 4 .IX Item "READ_INTERLACING" .IP "\s-1READ_INT_FUNCTIONS\s0" 4 .IX Item "READ_INT_FUNCTIONS" .IP "\s-1READ_INVERT\s0" 4 .IX Item "READ_INVERT" .IP "\s-1READ_INVERT_ALPHA\s0" 4 .IX Item "READ_INVERT_ALPHA" .IP "\s-1READ_OPT_PLTE\s0" 4 .IX Item "READ_OPT_PLTE" .IP "\s-1READ_PACK\s0" 4 .IX Item "READ_PACK" .IP "\s-1READ_PACKSWAP\s0" 4 .IX Item "READ_PACKSWAP" .IP "\s-1READ_QUANTIZE\s0" 4 .IX Item "READ_QUANTIZE" .IP "\s-1READ_RGB_TO_GRAY\s0" 4 .IX Item "READ_RGB_TO_GRAY" .IP "\s-1READ_SCALE_16_TO_8\s0" 4 .IX Item "READ_SCALE_16_TO_8" .IP "\s-1READ_SHIFT\s0" 4 .IX Item "READ_SHIFT" .IP "\s-1READ_STRIP_16_TO_8\s0" 4 .IX Item "READ_STRIP_16_TO_8" .IP "\s-1READ_STRIP_ALPHA\s0" 4 .IX Item "READ_STRIP_ALPHA" .IP "\s-1READ_SWAP\s0" 4 .IX Item "READ_SWAP" .IP "\s-1READ_SWAP_ALPHA\s0" 4 .IX Item "READ_SWAP_ALPHA" .IP "READ_tEXt" 4 .IX Item "READ_tEXt" .IP "\s-1READ_TRANSFORMS\s0" 4 .IX Item "READ_TRANSFORMS" .IP "\s-1READ_USER_TRANSFORM\s0" 4 .IX Item "READ_USER_TRANSFORM" .IP "READ_zTXt" 4 .IX Item "READ_zTXt" .IP "\s-1SAVE_INT_32\s0" 4 .IX Item "SAVE_INT_32" .IP "\s-1SAVE_UNKNOWN_CHUNKS\s0" 4 .IX Item "SAVE_UNKNOWN_CHUNKS" .IP "sBIT" 4 .IX Item "sBIT" .PD Does the libpng support the \*(L"sBIT\*(R" chunk? .IP "sCAL" 4 .IX Item "sCAL" Does the libpng support the \*(L"sCAL\*(R" extension? This actually tests for the presence of the \f(CW\*(C`get_sCAL_s\*(C'\fR/\f(CW\*(C`set_sCAL_s\*(C'\fR functions, so its behaviour is dependent on other factors for versions 1.2 and 1.4 of libpng. .IP "\s-1SEQUENTIAL_READ\s0" 4 .IX Item "SEQUENTIAL_READ" .PD 0 .IP "\s-1SETJMP\s0" 4 .IX Item "SETJMP" .IP "\s-1SET_OPTION\s0" 4 .IX Item "SET_OPTION" .IP "\s-1SET_UNKNOWN_CHUNKS\s0" 4 .IX Item "SET_UNKNOWN_CHUNKS" .IP "\s-1SET_USER_LIMITS\s0" 4 .IX Item "SET_USER_LIMITS" .IP "\s-1SIMPLIFIED_READ\s0" 4 .IX Item "SIMPLIFIED_READ" .IP "\s-1SIMPLIFIED_READ_AFIRST\s0" 4 .IX Item "SIMPLIFIED_READ_AFIRST" .IP "\s-1SIMPLIFIED_WRITE\s0" 4 .IX Item "SIMPLIFIED_WRITE" .IP "\s-1SIMPLIFIED_WRITE_AFIRST\s0" 4 .IX Item "SIMPLIFIED_WRITE_AFIRST" .IP "\s-1SIMPLIFIED_WRITE_BGR\s0" 4 .IX Item "SIMPLIFIED_WRITE_BGR" .IP "\s-1SIMPLIFIED_WRITE_STDIO\s0" 4 .IX Item "SIMPLIFIED_WRITE_STDIO" .IP "sPLT" 4 .IX Item "sPLT" .PD Does the libpng support \*(L"sPLT\*(R" chunks? .IP "sRGB" 4 .IX Item "sRGB" Does the libpng support the \*(L"sRGB\*(R" chunk? .IP "\s-1STDIO\s0" 4 .IX Item "STDIO" .PD 0 .IP "\s-1STORE_UNKNOWN_CHUNKS\s0" 4 .IX Item "STORE_UNKNOWN_CHUNKS" .IP "\s-1TEXT\s0" 4 .IX Item "TEXT" .PD Does the libpng support text? .IP "tEXt" 4 .IX Item "tEXt" Does the libpng support tEXt chunks? .IP "tIME" 4 .IX Item "tIME" Does the libpng support the \*(L"tIME\*(R" chunk? .IP "\s-1TIME_RFC1123\s0" 4 .IX Item "TIME_RFC1123" .PD 0 .IP "tRNS" 4 .IX Item "tRNS" .PD Does the libpng support the \*(L"tRNS\*(R" chunk? .IP "\s-1UNKNOWN_CHUNKS\s0" 4 .IX Item "UNKNOWN_CHUNKS" Does the libpng support unknown chunks (see \*(L"Private chunks\*(R")? .IP "\s-1USER_CHUNKS\s0" 4 .IX Item "USER_CHUNKS" .PD 0 .IP "\s-1USER_LIMITS\s0" 4 .IX Item "USER_LIMITS" .PD Does the libpng support \*(L"set_user_limits\*(R" and the related functions \&\*(L"get_user_width_max\*(R", and \*(L"get_user_height_max\*(R"? .IP "\s-1USER_LIMITS\s0" 4 .IX Item "USER_LIMITS" .PD 0 .IP "\s-1USER_MEM\s0" 4 .IX Item "USER_MEM" .IP "\s-1USER_TRANSFORM_INFO\s0" 4 .IX Item "USER_TRANSFORM_INFO" .IP "\s-1USER_TRANSFORM_PTR\s0" 4 .IX Item "USER_TRANSFORM_PTR" .IP "\s-1WARNINGS\s0" 4 .IX Item "WARNINGS" .IP "\s-1WRITE\s0" 4 .IX Item "WRITE" .PD Can libpng write pngs? .IP "\s-1WRITE_BGR\s0" 4 .IX Item "WRITE_BGR" .PD 0 .IP "\s-1WRITE_COMPRESSED_TEXT\s0" 4 .IX Item "WRITE_COMPRESSED_TEXT" .IP "\s-1WRITE_CUSTOMIZE_COMPRESSION\s0" 4 .IX Item "WRITE_CUSTOMIZE_COMPRESSION" .PD Does the libpng support \*(L"set_compression_level\*(R" and similar functions? .Sp ⛐πŸ€ͺ⚠ It's not very clear that this returns a useful value, since \*(L"set_compression_level\*(R" seems to be in libpngs from at least as far back as \f(CW1.5.1\fR, and yet this macro was only added to libpng in version \f(CW1.6.13\fR. .IP "\s-1WRITE_CUSTOMIZE_ZTXT_COMPRESSION\s0" 4 .IX Item "WRITE_CUSTOMIZE_ZTXT_COMPRESSION" Does the libpng support \*(L"set_text_compression_level\*(R" and similar functions? .IP "\s-1WRITE_FILLER\s0" 4 .IX Item "WRITE_FILLER" .PD 0 .IP "\s-1WRITE_FILTER\s0" 4 .IX Item "WRITE_FILTER" .IP "\s-1WRITE_FLUSH\s0" 4 .IX Item "WRITE_FLUSH" .IP "\s-1WRITE_FLUSH_AFTER_IEND\s0" 4 .IX Item "WRITE_FLUSH_AFTER_IEND" .IP "\s-1WRITE_INTERLACING\s0" 4 .IX Item "WRITE_INTERLACING" .IP "\s-1WRITE_INT_FUNCTIONS\s0" 4 .IX Item "WRITE_INT_FUNCTIONS" .IP "\s-1WRITE_INVERT\s0" 4 .IX Item "WRITE_INVERT" .IP "\s-1WRITE_INVERT_ALPHA\s0" 4 .IX Item "WRITE_INVERT_ALPHA" .IP "\s-1WRITE_OPTIMIZE_CMF\s0" 4 .IX Item "WRITE_OPTIMIZE_CMF" .IP "\s-1WRITE_PACK\s0" 4 .IX Item "WRITE_PACK" .IP "\s-1WRITE_PACKSWAP\s0" 4 .IX Item "WRITE_PACKSWAP" .IP "\s-1WRITE_SHIFT\s0" 4 .IX Item "WRITE_SHIFT" .IP "\s-1WRITE_SWAP\s0" 4 .IX Item "WRITE_SWAP" .IP "\s-1WRITE_SWAP_ALPHA\s0" 4 .IX Item "WRITE_SWAP_ALPHA" .IP "\s-1WRITE_TRANSFORMS\s0" 4 .IX Item "WRITE_TRANSFORMS" .IP "\s-1WRITE_USER_TRANSFORM\s0" 4 .IX Item "WRITE_USER_TRANSFORM" .IP "\s-1WRITE_WEIGHTED_FILTER\s0" 4 .IX Item "WRITE_WEIGHTED_FILTER" .IP "zTXt" 4 .IX Item "zTXt" .PD Does the libpng support \f(CW\*(C`zTXt\*(C'\fR chunks? .SS "png_compare" .IX Subsection "png_compare" .Vb 3 \& if (png_compare (\*(Aqa.png\*(Aq, \*(Aqb.png\*(Aq) == 0) { \& print "The PNGs are the same.\en"; \& } .Ve .PP This compares the image data in two PNGs and returns 0 if they contain exactly the same image data, or 1 if they contain different image data. For a more detailed comparison, see \*(L"image_data_diff\*(R". This does not compare to see if the \s-1PNG\s0 files \*(L"look like\*(R" each other, but whether each pixel contains exactly the same values. Please see Image::Similar for a looser comparison of images. .PP This uses the \*(L"expand\*(R" transform of libpng to read both the images, so it is able to compare images of different color types. It compares the alpha values as well as the color pixels. See \*(L"Saving bandwidth\*(R" for an example of comparing an \s-1RGB\s0 and a grayscale image. .SS "read_struct" .IX Subsection "read_struct" .Vb 3 \& if ($png\->read_struct ()) { \& warn "Can\*(Aqt write this, use copy_png to copy it"; \& } .Ve .PP This returns a true value if \f(CW$png\fR was created with \&\*(L"create_read_struct\*(R" or allied functions like \*(L"read_from_scalar\*(R", and a false value if \f(CW$png\fR was created with \*(L"create_write_struct\*(R" or allied functions like \*(L"copy_png\*(R". .SS "set_chunk" .IX Subsection "set_chunk" .Vb 1 \& $png\->set_chunk (\*(AqtIME\*(Aq, $timechunk); .Ve .PP Set the specified chunk. This produces a fatal error if given an \&\f(CW\*(C`IDAT\*(C'\fR (image data) chunk, use \*(L"set_rows\*(R" instead. This produces a fatal error if given an unknown chunk name. .PP The first argument is the chunk name and then the second argument is a scalar containing whatever the chunk requires, for example a hash reference for the \f(CW\*(C`tIME\*(C'\fR chunk as described under \*(L"set_tIME\*(R" and \&\*(L"get_tIME\*(R". .PP This is essentially a convenience function for the benefit of \&\*(L"copy_png\*(R" which, together with \*(L"get_valid\*(R", enables the \s-1PNG\s0 chunks to be copied in a loop rather than one-by-one. .SS "set_image_data" .IX Subsection "set_image_data" .Vb 1 \& $png\->set_image_data ($image_data); .Ve .PP Set the internal image data pointer to \f(CW$image_data\fR. \f(CW$image_data\fR should contain a pointer to memory stored as an \f(CW\*(C`SvIV\*(C'\fR allocated with \&\f(CW\*(C`Newx\*(C'\fR or a similar function. This transfers ownership of the memory to \f(CW$png\fR, which will free it with \f(CW\*(C`Safefree\*(C'\fR when \f(CW$png\fR is destroyed. Calling this function with any value does not actually change the content of the \s-1PNG\s0 image itself. .SS "set_row_pointers" .IX Subsection "set_row_pointers" .Vb 1 \& $png\->set_row_pointers ($row_pointers); .Ve .PP This sets the rows of the \s-1PNG\s0 image to \f(CW$row_pointers\fR using \&\f(CW\*(C`png_set_rows\*(C'\fR. \f(CW$row_pointers\fR must contain a pointer to memory stored as an SvIV allocated with a Perl memory allocator like \f(CW\*(C`Newx\*(C'\fR or a similar function. This also transfers ownership of the memory to \&\f(CW$png\fR, which will free it with \f(CW\*(C`Safefree\*(C'\fR when \f(CW$png\fR is destroyed. See also \*(L"copy_row_pointers\*(R", which does the same thing except for the freeing of the memory. .SS "split_alpha" .IX Subsection "split_alpha" .Vb 3 \& my $split = $png\->split_alpha (); \& my $alpha = $split\->{alpha}; \& my $color = $split\->{data}; .Ve .PP Split the alpha channel away from the other data. This only works for images with color types \f(CW\*(C`PNG_COLOR_TYPE_RGB_ALPHA\*(C'\fR and \&\f(CW\*(C`PNG_COLOR_TYPE_GRAY_ALPHA\*(C'\fR. This is not part of the libpng \s-1API.\s0 This function was added to this module to assist the author of PDF::Builder due to problems with very slow access to \s-1PNG\s0 images using Perl. .PP To remove the alpha channel from an image, use \*(L"set_background\*(R". See \&\*(L"Setting the background\*(R" for an example. You can also use the transform \f(CW\*(C`PNG_TRANSFORM_STRIP_ALPHA\*(C'\fR in \*(L"read_png_file\*(R", or \&\*(L"set_strip_alpha\*(R", but this may leave spurious pixel values in transparent parts of the image. .SH "EXPORTS" .IX Header "EXPORTS" Nothing is exported by default, but all the functions in this module, including the object methods, can be exported on request. The export tag 'all' exports everything in the module: .PP .Vb 1 \& use Image::PNG::Libpng \*(Aq:all\*(Aq; .Ve .PP This includes all the methods, which can then be used with the \f(CW$png\fR argument as the first argument. .SH "Differences from libpng" .IX Header "Differences from libpng" The functions in Image::PNG::Libpng are closely based on those of libpng, with the following differences. .SS "No info structure" .IX Subsection "No info structure" This module does not use the \*(L"info\*(R" structure of libpng. Almost all libpng functions require two initial arguments, a \f(CW\*(C`png_structp\*(C'\fR and a \&\f(CW\*(C`png_infop\*(C'\fR. However, in Image::PNG::Libpng, both the \*(L"png\*(R" and the \&\*(L"info\*(R" are contained in the object. People who need access to the internals of an \f(CW\*(C`Image::PNG::Libpng\*(C'\fR object (C programmers or \s-1XS\s0 programmers) can use \*(L"get_internals\*(R" to access them. .PP This module does not support the \*(L"end info\*(R" structure of PNGs when writing, although these are handled when reading. .SS "Unused arguments omitted" .IX Subsection "Unused arguments omitted" This module eliminates unevaluated arguments of libpng. For example, libpng requires the user to pass a pointer to a \f(CW\*(C`png_struct\*(C'\fR to call the libpng version number function, (see \*(L"get_libpng_ver\*(R"), but it actually ignores this structure. There are many similar instances of unevaluated arguments, which have all been eliminated from this module. .PP If you are interested in exactly which libpng arguments are omitted, you can find each instance in the file \f(CW\*(C`perl\-libpng.c\*(C'\fR in the top directory of the distribution in the macro \&\f(CW\*(C`UNUSED_ZERO_ARG\*(C'\fR. .SS "Useless functions omitted" .IX Subsection "Useless functions omitted" The functions from libpng which don't do anything have been omitted from this module. .SS "Function return values are used to return values" .IX Subsection "Function return values are used to return values" libpng is very inconsistent in its calling conventions. Some functions return results using references, and some return results using the function's return value. For example \f(CW\*(C`png_get_rows\*(C'\fR (see \&\*(L"get_rows\*(R") uses the return value of the function to return an array of pointers, but \f(CW\*(C`png_get_PLTE\*(C'\fR (see \*(L"get_PLTE\*(R") uses a pointer reference to return an array of pointers, and the return value to indicate errors. .PP Image::PNG::Libpng uses only the return value. Errors and non-existence are indicated by a return value of the undefined value. .PP Further to this, libpng's error handling is also very inconsistent. Some functions use the return value to indicate errors, and some of the functions don't indicate errors at all, but just fail silently. Even more inconsistently, some of the functions which use the return value to indicate an error use a non-zero value, and some use a zero value, to indicate an error. .SS "No destructors" .IX Subsection "No destructors" Freeing the memory allocated by \*(L"create_read_struct\*(R" and \&\*(L"create_write_struct\*(R" is automatically handled by Perl. .PP Older versions of this module (pre\-0.18) had functions called \&\f(CW\*(C`destroy_read_struct\*(C'\fR and \f(CW\*(C`destroy_write_struct\*(C'\fR corresponding to the functions with similar names in libpng. From version 0.18, these functions still exist, but they no longer do anything. The memory freeing is now handled by Perl automatically. .SS "Other unimplemented parts of libpng" .IX Subsection "Other unimplemented parts of libpng" .IP "Memory management functions" 4 .IX Item "Memory management functions" The management of memory for libpng objects is handled automatically by this module, and so it does not offer an interface to \f(CW\*(C`png_malloc\*(C'\fR and \f(CW\*(C`png_free\*(C'\fR or other libpng memory handling functions. .IP "Error handling functions" 4 .IX Item "Error handling functions" This module does not offer an interface to \f(CW\*(C`png_error\*(C'\fR and \&\f(CW\*(C`png_get_error_ptr\*(C'\fR or any of the other error handling functions of libpng. It redirects the error and warning handlers to Perl's error stream. .IP "Input/output manipulation functions" 4 .IX Item "Input/output manipulation functions" This module does not offer a direct interface to \f(CW\*(C`png_set_write_fn\*(C'\fR and \f(CW\*(C`png_set_read_fn\*(C'\fR. However, it is possible to use their functionality to access Perl data via \*(L"read_from_scalar\*(R" and \&\*(L"write_to_scalar\*(R". .IP "Fixed point functions" 4 .IX Item "Fixed point functions" There is currently no support for the \s-1PNG\s0 fixed point functions in this Perl module, the functions with suffix \f(CW\*(C`_fixed\*(C'\fR. .SS "List of unsupported functions" .IX Subsection "List of unsupported functions" The following functions from the libpng \s-1API\s0 are unsupported by this module. .IP "png_benign_error" 4 .IX Item "png_benign_error" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_build_grayscale_palette" 4 .IX Item "png_build_grayscale_palette" ⛐πŸ€ͺ⚠ Undocumented function, but it is part of the public \s-1API.\s0 See . .Sp This function builds an evenly-spaced grayscale palette at a specified bit depth into a user-supplied array. It is not used elsewhere in libpng. .IP "png_chunk_benign_error" 4 .IX Item "png_chunk_benign_error" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_chunk_warning" 4 .IX Item "png_chunk_warning" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_convert_from_struct_tm" 4 .IX Item "png_convert_from_struct_tm" πŸ‘Ž Deprecated in libpng. This function related to the \f(CW\*(C`tIME\*(C'\fR chunk is deprecated in libpng 1.7. .IP "png_convert_from_time_t" 4 .IX Item "png_convert_from_time_t" πŸ‘Ž Deprecated in libpng. This function related to the \f(CW\*(C`tIME\*(C'\fR chunk is deprecated in libpng 1.7. .IP "png_convert_to_rfc1123" 4 .IX Item "png_convert_to_rfc1123" πŸ‘Ž Deprecated in libpng. This function related to the \f(CW\*(C`tIME\*(C'\fR chunk is deprecated in libpng 1.7. .IP "png_convert_to_rfc1123_buffer" 4 .IX Item "png_convert_to_rfc1123_buffer" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp This function is related to the \f(CW\*(C`tIME\*(C'\fR chunk; it seems fairly superfluous with the many other ways to manipulate time strings already in Perl. .IP "png_data_freer" 4 .IX Item "png_data_freer" 🐘 See \*(L"Memory management functions\*(R". .IP "png_free" 4 .IX Item "png_free" 🐘 See \*(L"Memory management functions\*(R". .IP "png_free_data" 4 .IX Item "png_free_data" 🐘 See \*(L"Memory management functions\*(R". .IP "png_get_cHRM_XYZ_fixed" 4 .IX Item "png_get_cHRM_XYZ_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_cHRM_fixed" 4 .IX Item "png_get_cHRM_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_compression_type" 4 .IX Item "png_get_compression_type" πŸ™ƒπŸ€‘ See \*(L"Useless functions omitted\*(R". Useless function which returns 0 since there is only one type of compression. .IP "png_get_copyright" 4 .IX Item "png_get_copyright" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp This function gives you the copyright string for libpng. .IP "png_get_current_pass_number" 4 .IX Item "png_get_current_pass_number" .PD 0 .IP "png_get_current_row_number" 4 .IX Item "png_get_current_row_number" .IP "png_get_error_ptr" 4 .IX Item "png_get_error_ptr" .PD πŸ’” See \*(L"Error handling functions\*(R". .IP "png_get_filter_type" 4 .IX Item "png_get_filter_type" πŸ™ƒπŸ€‘ See \*(L"Useless functions omitted\*(R". This function returns the value of the unused field \f(CW\*(C`filter_type\*(C'\fR in the \s-1PNG\s0 header, which is always 0. See \*(L"Unused arguments omitted\*(R". .IP "png_get_gAMA_fixed" 4 .IX Item "png_get_gAMA_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_header_ver" 4 .IX Item "png_get_header_ver" This function was omitted from this module because it merely duplicates another function. .Sp Identical to \*(L"get_libpng_ver\*(R". .IP "png_get_header_version" 4 .IX Item "png_get_header_version" This function was omitted from this module because it merely duplicates another function. .Sp Identical to \*(L"get_libpng_ver\*(R". .IP "png_get_io_chunk_type" 4 .IX Item "png_get_io_chunk_type" .PD 0 .IP "png_get_io_ptr" 4 .IX Item "png_get_io_ptr" .IP "png_get_io_state" 4 .IX Item "png_get_io_state" .IP "png_get_mem_ptr" 4 .IX Item "png_get_mem_ptr" .IP "png_get_pHYs_dpi" 4 .IX Item "png_get_pHYs_dpi" .IP "png_get_pixel_aspect_ratio" 4 .IX Item "png_get_pixel_aspect_ratio" .IP "png_get_pixel_aspect_ratio_fixed" 4 .IX Item "png_get_pixel_aspect_ratio_fixed" .PD πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_pixels_per_inch" 4 .IX Item "png_get_pixels_per_inch" .PD 0 .IP "png_get_pixels_per_meter" 4 .IX Item "png_get_pixels_per_meter" .IP "png_get_progressive_ptr" 4 .IX Item "png_get_progressive_ptr" .PD Incremental reading of PNGs is not handled yet. .IP "png_get_sCAL_fixed" 4 .IX Item "png_get_sCAL_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_signature" 4 .IX Item "png_get_signature" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp Returns the \s-1PNG\s0 signature of a \s-1PNG\s0 you read in. .IP "png_get_uint_31" 4 .IX Item "png_get_uint_31" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp This produces an error if the unsigned integer argument is too big for a 31 bit number. .IP "png_get_user_chunk_ptr" 4 .IX Item "png_get_user_chunk_ptr" .PD 0 .IP "png_get_user_height_max" 4 .IX Item "png_get_user_height_max" .IP "png_get_user_transform_ptr" 4 .IX Item "png_get_user_transform_ptr" .IP "png_get_x_offset_inches" 4 .IX Item "png_get_x_offset_inches" .IP "png_get_x_offset_inches_fixed" 4 .IX Item "png_get_x_offset_inches_fixed" .PD πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_x_offset_microns" 4 .IX Item "png_get_x_offset_microns" .PD 0 .IP "png_get_x_offset_pixels" 4 .IX Item "png_get_x_offset_pixels" .PD Duplicates \*(L"get_oFFs\*(R". .IP "png_get_x_pixels_per_inch" 4 .IX Item "png_get_x_pixels_per_inch" .PD 0 .IP "png_get_x_pixels_per_meter" 4 .IX Item "png_get_x_pixels_per_meter" .PD Duplicates \*(L"get_oFFs\*(R". .IP "png_get_y_offset_inches" 4 .IX Item "png_get_y_offset_inches" .PD 0 .IP "png_get_y_offset_inches_fixed" 4 .IX Item "png_get_y_offset_inches_fixed" .PD πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_get_y_offset_microns" 4 .IX Item "png_get_y_offset_microns" .PD 0 .IP "png_get_y_offset_pixels" 4 .IX Item "png_get_y_offset_pixels" .PD Duplicates \*(L"get_oFFs\*(R". .IP "png_get_y_pixels_per_inch" 4 .IX Item "png_get_y_pixels_per_inch" .PD 0 .IP "png_get_y_pixels_per_meter" 4 .IX Item "png_get_y_pixels_per_meter" .PD Duplicates \*(L"get_oFFs\*(R". .IP "png_handle_as_unknown" 4 .IX Item "png_handle_as_unknown" .PD 0 .IP "png_image_begin_read_from_file" 4 .IX Item "png_image_begin_read_from_file" .IP "png_image_begin_read_from_stdio" 4 .IX Item "png_image_begin_read_from_stdio" .IP "png_image_finish_read" 4 .IX Item "png_image_finish_read" .IP "png_image_free" 4 .IX Item "png_image_free" .PD 🐘 See \*(L"Memory management functions\*(R". .IP "png_image_write_to_file" 4 .IX Item "png_image_write_to_file" .PD 0 .IP "png_image_write_to_memory" 4 .IX Item "png_image_write_to_memory" .PD 🐘 See \*(L"Memory management functions\*(R". .IP "png_image_write_to_stdio" 4 .IX Item "png_image_write_to_stdio" .PD 0 .IP "png_process_data" 4 .IX Item "png_process_data" .IP "png_process_data_pause" 4 .IX Item "png_process_data_pause" .IP "png_process_data_skip" 4 .IX Item "png_process_data_skip" .IP "png_progressive_combine_row" 4 .IX Item "png_progressive_combine_row" .IP "png_read_row" 4 .IX Item "png_read_row" .IP "png_read_rows" 4 .IX Item "png_read_rows" .IP "png_reset_zstream" 4 .IX Item "png_reset_zstream" .PD πŸ‘Ž Deprecated in libpng. Resets the zstream of the zlib instance used for the image data. .IP "png_save_int_32" 4 .IX Item "png_save_int_32" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp Writes a 32 bit signed number into an octet buffer. Perl programmers will probably use \f(CW\*(C`pack\*(C'\fR for this. .IP "png_save_uint_16" 4 .IX Item "png_save_uint_16" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp Writes a 16 bit number into an octet buffer. Perl programmers will probably use \f(CW\*(C`pack\*(C'\fR for this. .IP "png_save_uint_32" 4 .IX Item "png_save_uint_32" πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .Sp Writes a 32 bit unsigned number into an octet buffer. Perl programmers will probably use \f(CW\*(C`pack\*(C'\fR for this. .IP "png_set_alpha_mode_fixed" 4 .IX Item "png_set_alpha_mode_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_background_fixed" 4 .IX Item "png_set_background_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_benign_errors" 4 .IX Item "png_set_benign_errors" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_set_cHRM_XYZ_fixed" 4 .IX Item "png_set_cHRM_XYZ_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_cHRM_fixed" 4 .IX Item "png_set_cHRM_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_check_for_invalid_index" 4 .IX Item "png_set_check_for_invalid_index" .PD 0 .IP "png_set_compression_method" 4 .IX Item "png_set_compression_method" .PD πŸ™ƒπŸ€‘ See \*(L"Useless functions omitted\*(R". This function in libpng corresponds to the unused \&\f(CW\*(C`method\*(C'\fR parameter of zlib functions like \f(CW\*(C`deflateInit2\*(C'\fR. See \&\*(L"zlib documentation\*(R". The libpng function just produces a warning if the user sets the value to anything but 8, the value of the macro \&\f(CW\*(C`Z_DEFLATED\*(C'\fR, and then lets zlib produce an error. .IP "png_set_crc_action" 4 .IX Item "png_set_crc_action" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_set_error_fn" 4 .IX Item "png_set_error_fn" πŸ’” See \*(L"Error handling functions\*(R". .IP "png_set_filter_heuristics" 4 .IX Item "png_set_filter_heuristics" πŸ‘Ž Deprecated in libpng. .IP "png_set_filter_heuristics_fixed" 4 .IX Item "png_set_filter_heuristics_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_flush" 4 .IX Item "png_set_flush" .PD 0 .IP "png_set_gAMA_fixed" 4 .IX Item "png_set_gAMA_fixed" .PD πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_gamma_fixed" 4 .IX Item "png_set_gamma_fixed" πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_interlace_handling" 4 .IX Item "png_set_interlace_handling" Incremental writing is not handled. .IP "png_set_invalid" 4 .IX Item "png_set_invalid" 🐘 See \*(L"Memory management functions\*(R". .IP "png_set_longjmp_fn" 4 .IX Item "png_set_longjmp_fn" ⛐πŸ€ͺ⚠ Undocumented function, but it is part of the public \s-1API.\s0 .IP "png_set_mem_fn" 4 .IX Item "png_set_mem_fn" 🐘 See \*(L"Memory management functions\*(R". .IP "png_set_option" 4 .IX Item "png_set_option" .PD 0 .IP "png_set_progressive_read_fn" 4 .IX Item "png_set_progressive_read_fn" .IP "png_set_read_status_fn" 4 .IX Item "png_set_read_status_fn" .IP "png_set_read_user_chunk_fn" 4 .IX Item "png_set_read_user_chunk_fn" .IP "png_set_read_user_transform_fn" 4 .IX Item "png_set_read_user_transform_fn" .IP "png_set_sCAL_fixed" 4 .IX Item "png_set_sCAL_fixed" .PD πŸ“ See \*(L"Fixed point functions\*(R". .IP "png_set_sRGB_gAMA_and_cHRM" 4 .IX Item "png_set_sRGB_gAMA_and_cHRM" .PD 0 .IP "png_set_shift" 4 .IX Item "png_set_shift" .IP "png_set_sig_bytes" 4 .IX Item "png_set_sig_bytes" .PD πŸ‘ŽπŸͺ This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers. .IP "png_set_strip_error_numbers" 4 .IX Item "png_set_strip_error_numbers" πŸ™ƒπŸ€‘ See \*(L"Useless functions omitted\*(R". According to the libpng manual, \*(L"we never got around to actually numbering the error messages\*(R", so I assume this is not very useful. .IP "png_set_text_compression_method" 4 .IX Item "png_set_text_compression_method" πŸ™ƒπŸ€‘ See \*(L"Useless functions omitted\*(R". Unsupported for the same reasons as \&\*(L"png_set_compression_method\*(R". .IP "png_set_unknown_chunk_location" 4 .IX Item "png_set_unknown_chunk_location" This is related to some kind of bug in version 1.5 and previous of libpng. .IP "png_set_user_transform_info" 4 .IX Item "png_set_user_transform_info" .PD 0 .IP "png_set_write_status_fn" 4 .IX Item "png_set_write_status_fn" .PD πŸ’” See \*(L"Error handling functions\*(R". .IP "png_set_write_user_transform_fn" 4 .IX Item "png_set_write_user_transform_fn" .PD 0 .IP "png_start_read_image" 4 .IX Item "png_start_read_image" .IP "png_write_chunk" 4 .IX Item "png_write_chunk" .IP "png_write_chunk_data" 4 .IX Item "png_write_chunk_data" .IP "png_write_chunk_end" 4 .IX Item "png_write_chunk_end" .IP "png_write_chunk_start" 4 .IX Item "png_write_chunk_start" .IP "png_write_flush" 4 .IX Item "png_write_flush" .IP "png_write_info_before_PLTE" 4 .IX Item "png_write_info_before_PLTE" .IP "png_write_row" 4 .IX Item "png_write_row" .IP "png_write_rows" 4 .IX Item "png_write_rows" .IP "png_write_sig" 4 .IX Item "png_write_sig" .PD .PP This is an exhaustive list of unsupported libpng \s-1API\s0 functions, extracted from the libpng source code using \fIutil/api.pl\fR in this module's repository. .SS "Conditional compilation and old libpng versions" .IX Subsection "Conditional compilation and old libpng versions" It is possible to compile a version of the libpng library without support for various things. For example, a libpng without support for text chunks may be created by undefining the C macro \&\f(CW\*(C`PNG_TEXT_SUPPORTED\*(C'\fR. This module supports the conditional compilation choices which we're aware of, but if you encounter problems using this module because of a conditionally-compiled libpng, then let us know and we'll add the necessary facility. .PP Currently we test this module against vanilla libpng versions \&\f(CW1.2.59\fR, \f(CW1.4.22\fR, \f(CW1.5.30\fR, and \f(CW1.6.37\fR before releases. There doesn't seem to have been a 1.3 or a 1.1 version of libpng. See . Versions 1.0 and earlier of libpng are not tested against. .PP The following issues with older libpng versions may affect users of this module: .PP \fIcHRM chunk\fR .IX Subsection "cHRM chunk" .PP The \*(L"get_cHRM_XYZ\*(R" and \*(L"set_cHRM_XYZ\*(R" functions for the \*(L"cHRM\*(R" chunk are not present in pre\-1.5.5 versions of libpng, but the conditional compilation macro of libpng for these newer functions is the same as for \*(L"get_cHRM\*(R" and \*(L"set_cHRM\*(R" functions, which are present on older versions of libpng. Because of this, this module includes its own protection macro, accessible via \&\*(L"libpng_supports\*(R" as \*(L"cHRM_XYZ\*(R". These functions are disabled for libpng versions earlier than 1.5.5. .PP \fIchunk_cache_max\fR .IX Subsection "chunk_cache_max" .PP The functions \*(L"set_chunk_cache_max\*(R" and \*(L"get_chunk_cache_max\*(R" are not protected by a libpng macro, so this module includes its own protection macro, accessible via \*(L"libpng_supports\*(R" as \&\*(L"\s-1CHUNK_CACHE_MAX\*(R"\s0. These functions are disabled for libpng versions earlier than 1.4.0. .PP \fICompression level\fR .IX Subsection "Compression level" .PP Versions of libpng up to 1.5 behave erratically when \&\*(L"set_compression_level\*(R" or other \f(CW\*(C`set_compression_*\*(C'\fR functions are used to alter the compression of the image data. Testing of compression-related functions is disabled by this Perl module for pre\-1.6.13 versions of libpng. .PP \fIsCAL chunk\fR .IX Subsection "sCAL chunk" .PP Support for the sCAL chunk is disabled within this module for pre\-1.6 versions of libpng. .PP \fIText chunk handling\fR .IX Subsection "Text chunk handling" .PP Versions of libpng up to 1.6.3 produce erratic results with \f(CW\*(C`iTXt\*(C'\fR (international text) chunks. Testing of text-related chunks is disabled by this Perl module for pre\-1.6.13 versions of libpng. .SS "Not all constants are available" .IX Subsection "Not all constants are available" Some of the libpng constants are defined in \fIpnglibconf.h\fR or \&\fIpngconf.h\fR but Image::PNG::Const only looks at \fIpng.h\fR to make its constants. Because of this, some constant values like \&\f(CW\*(C`PNG_Z_DEFAULT_COMPRESSION\*(C'\fR aren't currently available in Image::PNG::Const. This probably should be fixed to extract the constants from the other files in a future version. .SH "STANDALONE SCRIPT" .IX Header "STANDALONE SCRIPT" A standalone script, pnginspect, is installed with the distribution. It prints out the contents of the chunks of the \s-1PNG\s0 file on the command line. .SH "SEE ALSO" .IX Header "SEE ALSO" .SS "The \s-1PNG\s0 specification" .IX Subsection "The PNG specification" The \s-1PNG\s0 specification (link to W3 consortium) explains the details of the \s-1PNG\s0 format. .PP \fI\s-1PNG\s0 The Definitive Guide by Greg Roelofs\fR .IX Subsection "PNG The Definitive Guide by Greg Roelofs" .PP The book \*(L"\s-1PNG\s0 \- The Definitive Guide\*(R" by Greg Roelofs, published in 1999 by O'Reilly is available online at or . .SS "The libpng documentation" .IX Subsection "The libpng documentation" .IP "Official documentation" 4 .IX Item "Official documentation" The starting point is the plain text libpng manual at and the manual page libpng.3, which you can read using \*(L"man 3 libpng\*(R". .Sp ⛐πŸ€ͺ⚠ The documentation which comes with libpng is rather sketchy. See \*(L"Differences from libpng\*(R". It doesn't contain full specifications (prototypes, return values) for all of the functions in the library. For programming in C using libpng, look at the header file \fIpng.h\fR. In some cases, you need to look at the source code of the library. .IP "Other documentation" 4 .IX Item "Other documentation" There is a collection of function definitions under the title \&\*(L"Interface Definitions for libpng12\*(R" at as part of the \*(L"Linux Standard Base Desktop Specification\*(R". These contain extensive information on the prototypes and return values for the libpng routines, something which is often only available elsewhere by actually looking at the libpng source code. These pages are usually the first hits on search engines if you search for a function name in libpng. .SS "zlib documentation" .IX Subsection "zlib documentation" See for the zlib documentation. .SS "Other Perl modules on \s-1CPAN\s0" .IX Subsection "Other Perl modules on CPAN" These other modules may also be useful. .IP "Alien::PNG" 4 .IX Item "Alien::PNG" Alien::PNG claims to be a way of \*(L"building, finding and using \s-1PNG\s0 binaries\*(R". It may help in installing libpng. We didn't use it as a dependency for this module because it seems not to work in batch mode, but stop and prompt the user. We're interested in hearing feedback from users whether this works or not on various platforms. .IP "Imager" 4 .IX Item "Imager" Imager, Imager::Files and \f(CW\*(C`Imager::Files::PNG\*(C'\fR contain support for reading and writing PNGs via libpng, as well as support for reading and writing various other kinds of image files, changing the images, converting, and more. .IP "Image::ExifTool" 4 .IX Item "Image::ExifTool" Image::ExifTool is a pure Perl (doesn't require a C compiler) solution for accessing the text segments of images. It supports \s-1PNG\s0 text segments. .IP "Image::Info" 4 .IX Item "Image::Info" Image::Info gets information out of images. It supports \s-1PNG\s0 and is written in pure Perl, so it doesn't require a C compiler. As well as basics such as height, width, and colour type, it can get text chunks, modification time, palette, gamma (gAMA chunk), resolution (pHYs chunk), and significant bits (sBIT chunk). At the time of writing (version 1.31) it doesn't support other chunks. .IP "Image::PNG::Rewriter" 4 .IX Item "Image::PNG::Rewriter" Image::PNG::Rewriter is a utility for unpacking and recompressing the \s-1IDAT\s0 (image data) part of a \s-1PNG\s0 image. The main purpose seems to be to recompress the image data with the module author's other module Compress::Deflate7. At the time of writing, that only works with Perl versions 5.12 or later. .IP "Image::Pngslimmer" 4 .IX Item "Image::Pngslimmer" Image::Pngslimmer reduces the size of dynamically created \s-1PNG\s0 images. It's very, very slow at reading \s-1PNG\s0 data, but seems to work \&\s-1OK.\s0 .IP "Image::PNG::Write::BW" 4 .IX Item "Image::PNG::Write::BW" Image::PNG::Write::BW writes black and white PNGs from strings. .IP "Image::Size" 4 .IX Item "Image::Size" If you only need to read the sizes of images, Image::Size works with \s-1PNG\s0 and other image formats. .SH "AUTHOR" .IX Header "AUTHOR" Ben Bullock, .SH "COPYRIGHT & LICENCE" .IX Header "COPYRIGHT & LICENCE" This package and associated files are copyright (C) 2011\-2021 Ben Bullock. .PP You can use, copy, modify and redistribute this package and associated files under the Perl Artistic Licence or the \s-1GNU\s0 General Public Licence.