










=pod

=encoding UTF-8

=head1 NAME

Image::PNG::Libpng - Perl interface to the C library "libpng".

=head1 SYNOPSIS

Libpng-like interface:

    
    use Image::PNG::Libpng ':all';
    my $png = create_read_struct ();
    open my $file, '<:raw', 'nice.png' 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), "\n";
    # Print image information
    my $header = $png->get_IHDR ();
    for my $k (keys %$header) {
        print "$k: $header->{$k}\n";
    }

(This example is included as L<F<examples/synopsis.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/synopsis.pl>
in the distribution.)


Simple interface:

    
    use Image::PNG::Libpng ':all';
    my $png = read_png_file ('../t/tantei-san.png');
    # Get all valid chunks
    my $valid = $png->get_valid ();
    my @valid_chunks = sort grep {$valid->{$_}} keys %$valid;
    print "Valid chunks are ", join (", ", @valid_chunks), "\n";
    # Print image information
    my $header = $png->get_IHDR ();
    for my $k (keys %$header) {
        if ($k eq 'color_type') {
            print "$k: " . color_type_name ($header->{$k}) . "\n";
        }
        else {
            print "$k: $header->{$k}\n";
        }
    }
    my $wpng = $png->copy_png ();
    $wpng->write_png_file ('new.png');
    

(This example is included as L<F<examples/synopsis-easy.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/synopsis-easy.pl>
in the distribution.)


=head1 VERSION

This document describes Image::PNG::Libpng version 0.59, corresponding to git commit L<1b99f6eb7a1bf68bb4d3c392454d0ace5fb1d81c|https://github.com/benkasminbullock/image-png-libpng/commit/1b99f6eb7a1bf68bb4d3c392454d0ace5fb1d81c> at Mon Feb 24 15:00:50 2025 +0900.

Unless otherwise qualified, comments in this document on the libpng
source code and documentation refer to libpng version 1.6.45. Libpng is not bundled with this distribution, so
your installed version may vary.

=head1 DESCRIPTION

Image::PNG::Libpng is a Perl library for accessing the contents of PNG
(Portable Network Graphics) images. Image::PNG::Libpng enables Perl to
use the "libpng" library to read and write files in PNG
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.

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 PNG data in Perl. 

For those familiar with libpng, the section L</Differences
from libpng> explains the differences with libpng.

=head1 FUNCTIONS

The functions in the module are gathered into the following
categories: L</Simple input and output>, which describes some
convenience functions, L</Libpng-style input and output>, which
describes functions which closely mirror libpng, L</The image header>,
which describes functions for reading and writing the meta-information
about PNG images, L</Image data>, which describes functions for
accessing the image data itself, L</Text chunks>, L</Private chunks>,
L</Library version functions>, L</Compression and filtering>, L</Other
chunks>, L</Libpng transformations>, L</Other libpng functions>,
functions from libpng which don't fit elsewhere, and L</Other
functions>, which are functions specific to this module.

=head1 Simple input and output

These convenience functions combine common operations. They are not
part of the original libpng API.

=head2 copy_png

    my $outpng = $png->copy_png ();

Copy a PNG from a read to a write structure. This function bridges two
kinds of object, "read a png" objects created by
L</create_read_struct> and "write a png" objects created by
L</create_write_struct>. This function copies all the valid chunks
from a read structure to a write structure.

The following example demonstrates copying a PNG.

    
    use utf8;
    use FindBin '$Bin';
    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 => 'Name', text => 'Shunsaku Kudo'}]); 
    # $pngout->write_png_file ('copy.png');

(This example is included as L<F<examples/copy-png.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/copy-png.pl>
in the distribution.)


=head2 create_reader

     my $png = create_reader ('file.png');
     $png->read_png ();

This combines L</create_read_struct>, C<open>, and L</init_io> 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.

=head3 Setting the background

In the following example, the user sets the background with
L</set_background> to replace the alpha channel.

    
    use utf8;
    use FindBin '$Bin';
    use Image::PNG::Libpng ':all';
    use Image::PNG::Const ':all';
    my $file = "$Bin/luv.png";
    my %color = (red => 0xC0, green => 0xFF, blue => 0xFF);
    my $png = create_reader ($file);
    $png->set_background (\%color, PNG_BACKGROUND_GAMMA_SCREEN, 0);
    $png->read_png ();
    my $wpng = copy_png ($png);
    $wpng->write_png_file ("$Bin/set-background.png");

(This example is included as L<F<examples/set-background.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/set-background.pl>
in the distribution.)




L<examples/luv.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/luv.png> is included in the distribution.

=begin html

<p>The input image has a transparent background:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/luv.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/luv.png'>examples/luv.png</a>
</th>
</tr>
</table>

=end html




L<examples/set-background.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/set-background.png> is included in the distribution.

=begin html

<p>The output image has a blue background:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/set-background.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/set-background.png'>examples/set-background.png</a>
</th>
</tr>
</table>

=end html


This function was added to the module in version 0.53.

=head2 create_writer

     my $png = create_writer ('file.png');
     $png->set_IHDR (\%ihdr);
     $png->set_rows (\@rows);
     $png->write_png ();

This combines L</create_write_struct>, C<open>, and L</init_io> 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.

This function was added to the module in version 0.53.

=head2 read_from_scalar

     my $png = read_from_scalar ($string);

This creates an image structure C<$png> from the contents of a Perl
scalar variable C<$string> containing PNG image data, for example data
read from a file, or data obtained from a web page. The first argument, C<$png>, is a PNG structure created with 
L</create_read_struct>. It
reads in all the data from the structure on being called.

This is useful when image data is stored in a Perl scalar. For example

    
    use Image::PNG::Libpng 'read_from_scalar';
    use LWP::Simple;
    use JSON::Create;
    my $image_data = get 'http://libpng.org/pub/png/img_png/libpng-88x31.png';
    # 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);

(This example is included as L<F<examples/get-www-png.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/get-www-png.pl>
in the distribution.)


The output looks like this:

    {
            "bit_depth":4,
            "color_type":3,
            "height":31,
            "interlace_method":0,
            "width":88
    }


See also L</Input and output manipulation functions>.

=head2 read_png_file

     my $png = read_png_file ('q.png');

Open F<q.png> and read its contents into C<$png>.

This combines L</create_read_struct>, C<open>, L</init_io>, and
L</read_png>. The return value is the same as that of
L</create_read_struct> with the entire PNG image already read in.

The optional argument to L</read_png> can be specified using an
optional C<transforms> argument:

    my $png = read_png_file ('file.png', transforms => PNG_TRANSFORM_EXPAND);

L<Carp/croak> is used to signal errors opening or closing the file.

=head2 set_transforms

    $png->set_transforms (PNG_TRANSFORM_BGR);

Set transforms for reading and writing. This is the same as the
optional argument to L</read_png> or L</write_png>. If both this and
the optional argument are given, the optional argument overrides what
is set here.

=head2 write_png_file

    $png->write_png_file ('nice.png');

This combines open, L</init_io>, and L</write_png> to write an entire
PNG image out to the file name specified by the argument. C<$png> must
be the object created by L</create_write_struct>, so L</read_png_file>
followed by a call to this does not work. See L</copy_png> if you need
to do that kind of operation.

The optional argument to L</write_png> can be specified using
L</set_transforms>.

L<Carp/croak> is used to signal errors opening or closing the file.

=head2 write_to_scalar

    my $image_data = $png->write_to_scalar ();

This writes the PNG image data in C<$png> into a Perl scalar. The first argument, C<$png>, is a writeable PNG structure created with 
L</create_write_struct>. The return value of the subroutine is the Perl scalar
containing the image data.

So, for example,

    
    
    # This CGI script prints a PNG in a random colour.
    
    use Image::PNG::Libpng ':all';
    use Image::PNG::Const ':all';
    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 (\@rows);
    my $img = $png->write_to_scalar ();
    binmode STDOUT;
    print "Content-Type:image/png\r\n\r\n$img";
    exit;
    sub randcol
    {
        return int (rand () * 0x100);
    }

(This example is included as L<F<examples/png-cgi.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/png-cgi.pl>
in the distribution.)


See also L</Input and output manipulation functions>.

The optional argument to L</write_png> can be specified using
L</set_transforms>.

=head1 Libpng-style input and output

There are two different "new"-like functions, depending on whether you
want to read or write a PNG, L</create_read_struct> and
L</create_write_struct>. These are based on the libpng API. Input uses
C<open> plus L</init_io> followed by L</read_png> or L</write_png>.

=head2 Examples

=head3 A self-pixellating program

This example demonstrates writing a monochrome PNG by creating a write
structure with L</create_write_struct>, opening a filehandle to write
it, associating the filehandle with the PNG structure with
L</init_io>, then using the functions L</write_info>, L</write_image>,
and then L</write_end> to actually write the PNG data to the file.

    
    use utf8;
    use FindBin '$Bin';
    use Image::PNG::Libpng ':all';
    use Image::PNG::Const ':all';
    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 => 'silly', text => 'finely-tuned breakfast cereal',}]);
    $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't open '$file': $!";
        my $width = 0;
        my @lines;
        while (<$in>) {
            chomp;
            s/\t/        /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 ' ') {
                    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, \@rows);
    }

(This example is included as L<F<examples/libpng-write.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/libpng-write.pl>
in the distribution.)




L<examples/mono.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/mono.png> is included in the distribution.

=begin html

<p>The output has a bit depth of 1:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/mono.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/mono.png'>examples/mono.png</a>
</th>
</tr>
</table>

=end html


=head2 create_read_struct

     my $png = create_read_struct ();

Create a structure for reading a PNG. 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>.

This function corresponds to C<png_create_read_struct> in libpng plus C<create_info_struct> (see L</No info structure>) with the error and warning handler variables set up to use
Perl's error reporting.

=head2 create_write_struct

     my $png = create_write_struct ();

Create a structure for writing a PNG. This can be used as an object
with the other functions as methods.

This function corresponds to C<png_create_write_struct> in libpng plus C<create_info_struct> (see L</No info structure>)  with the error and warning handler variables set up to use
Perl's error reporting.

=head2 init_io

     open my $file, "<", 'nice.png';
     $png->init_io ($file);

Set the file which C<$png> reads or writes to C<$file>. C<$file> must
be an already-opened Perl file handle. If C<$png> was created with
L</create_write_struct>, C<$file> must be opened for writing. If
C<$png> was created with L</create_read_struct>, C<$file> must be open
for reading.

Since PNG files are binary files, it is safest to specify the "raw"
pragma or use "binmode" with the file to override any default text
file encoding which Perl might be using:

     open my $file, ">:raw", 'output.png';

or

     open my $file, ">", 'output.png';
     binmode $file;

This function corresponds to C<png_init_io> in libpng, with a Perl
file handle substituting for the C C<FILE *>.

=head3 Caveats when using init_io

=head4 Check the return value of open

On some versions of Perl, L</init_io> may crash in some circumstances
with an error like "segmentation fault", if you use code like

    my $png = create_read_struct ();
    open my $file, "<:raw", "some.png";
    $png->init_io ($file);

and you do not check whether the call to C<open> was successful, and
F<some.png> does not exist. The crash occurs within Perl's conversion
of C<$file> into a C C<FILE *> 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 C<open>.

=head4 Cannot deal with non-file filehandles

Since C<init_io> is a Perl access to an underlying C function
C<png_init_io>, it requires something which can be passed to the
underlying C as a C<FILE *>, C's file structure. If, for example you
use L<IO::String> or open a scalar reference as a file handle, since
these actions do not create a C file structure, an error of the form
C<scalar's file handle is NULL> will occur. 

If you have a PNG in the form of a Perl scalar, use
L</read_from_scalar> instead of C<init_io>, which uses a C function
called C<png_set_read_fn> so that the C library can access the data in
the Perl scalar. See also L</Input and output manipulation functions>.

=head2 read_end

     $png->read_end ();

Read the part of the PNG file after the image data.

This function corresponds to C<png_read_end> in libpng.

=head2 read_image

     my $rows = $png->read_image ();

Read the image data of the PNG file.

This function corresponds to C<png_read_image> in libpng.

=head2 read_info

    $png->read_info ();

Read the part of the PNG file before the image data.

This function corresponds to C<png_read_info> in libpng.

=head2 read_png

     $png->read_png ();

Read the entire PNG file into memory. 

You can provide an argument containing transformations to apply to the
image:

     use Image::PNG::Const qw/PNG_TRANSFORM_STRIP_ALPHA/;
     $png->read_png (PNG_TRANSFORM_STRIP_ALPHA);

If the argument is omitted, the default value of
C<PNG_TRANSFORM_IDENTITY> (the "do nothing" value) is applied. The
possible transformations which can be applied are

=over


=item PNG_TRANSFORM_BGR

Flip RGB to BGR, RGBA to BGRA. See also L</set_bgr>.



=item PNG_TRANSFORM_EXPAND

Perform set_expand(). See also L</set_expand>.



=item PNG_TRANSFORM_EXPAND_16

Expand samples to 16 bits. See also L</set_expand_16>.



=item PNG_TRANSFORM_GRAY_TO_RGB

Expand grayscale samples to RGB (or GA to RGBA). See also L</set_gray_to_rgb>.



=item PNG_TRANSFORM_IDENTITY

No transformation. 



=item PNG_TRANSFORM_INVERT_ALPHA

Change alpha from opacity to transparency. See also L</set_invert_alpha>.



=item PNG_TRANSFORM_INVERT_MONO

Invert monochrome images. See also L</set_invert_mono>.



=item PNG_TRANSFORM_PACKING

Expand 1, 2 and 4-bit samples to bytes. See also L</set_packing>.



=item PNG_TRANSFORM_PACKSWAP

Change order of packed pixels to LSB first. See also L</set_packswap>.



=item PNG_TRANSFORM_SCALE_16

Strip 16-bit samples to 8-bit accurately. See also L</set_scale_16>.



=item PNG_TRANSFORM_SHIFT

Normalize pixels to the sBIT depth. 



=item PNG_TRANSFORM_STRIP_16

Chop 16-bit samples to 8-bit less accurately. See also L</set_strip_16>.



=item PNG_TRANSFORM_STRIP_ALPHA

Discard the alpha channel. 







=item PNG_TRANSFORM_SWAP_ALPHA

Flip RGBA to ARGB or GA to AG. See also L</set_swap_alpha>.



=item PNG_TRANSFORM_SWAP_ENDIAN

Byte-swap 16-bit samples. See also L</set_swap>.


=back

This function corresponds to C<png_read_png> in libpng with a default value for the third
argument. The fourth, unused, argument to C<png_read_png> does not
need to be supplied. See L<Unused arguments omitted>.

It does not take a second "info" argument. See L</No info structure>.

=head2 read_update_info

    $png->read_update_info ();

⛐🤪⚠ Inside Image::PNG::Libpng, the libpng function
C<png_read_update_info> is called before reading image data.
According to L</The libpng documentation>, 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.

This function corresponds to C<png_read_update_info> in libpng

=head2 write_end

    $png->write_end ();

Write the final part of the PNG file.

This function corresponds to C<png_write_end> in libpng.

=head2 write_image

    $png->write_image ($rows);

Write the image of the PNG file. C<$rows> is an array reference as per
L</set_rows>.

This function corresponds to C<png_write_image> in libpng.

=head2 write_info

    $png->write_info ();

Write the first part of the PNG file.

This function corresponds to C<png_write_info> in libpng.

=head2 write_png

    $png->write_png ();

This writes the PNG to the file stream which was associated with it
using L</init_io>. For example,

    open my $output, ">:raw", 'out.png';
    $png->init_io ($output);
    $png->write_png ();
    close $output;

An optional argument consists of transformations to apply to the PNG
image before writing it:

    use Image::PNG::Const qw/PNG_TRANSFORM_STRIP_ALPHA/;
    $png->write_png (PNG_TRANSFORM_STRIP_ALPHA);

The transformations which can be applied are as follows:

=over


=item PNG_TRANSFORM_BGR

Flip RGB to BGR, RGBA to BGRA. See also L</set_bgr>. 











=item PNG_TRANSFORM_INVERT_ALPHA

Change alpha from opacity to transparency. See also L</set_invert_alpha>. 



=item PNG_TRANSFORM_INVERT_MONO

Invert monochrome images. See also L</set_invert_mono>. 



=item PNG_TRANSFORM_PACKING

Expand 1, 2 and 4-bit samples to bytes. See also L</set_packing>. 



=item PNG_TRANSFORM_PACKSWAP

Change order of packed pixels to LSB first. See also L</set_packswap>. 





=item PNG_TRANSFORM_SHIFT

Normalize pixels to the sBIT depth. 







=item PNG_TRANSFORM_STRIP_FILLER_AFTER

Strip out trailing filler bytes. 



=item PNG_TRANSFORM_STRIP_FILLER_BEFORE

Strip out leading filler bytes. 



=item PNG_TRANSFORM_SWAP_ALPHA

Flip RGBA to ARGB or GA to AG. See also L</set_swap_alpha>. 



=item PNG_TRANSFORM_SWAP_ENDIAN

Byte-swap 16-bit samples. See also L</set_swap>. 


=back

This function corresponds to C<png_write_png> in libpng.

=head1 The image header

These functions handle the header part of PNG image data. See L<this subsection|http://www.w3.org/TR/PNG/#11IHDR>
of L</The PNG specification> for information on the PNG standards for the image
header.

=head2 color_type_name

    $name = color_type_name ($color_type);

This is a convenience function which returns a string corresponding to
the numerical color type in C<$color_type>. The name is in upper
case, with words separated by underscores, as in C<RGB_ALPHA>.

    
    use Image::PNG::Libpng ':all';
    my $png = read_png_file ('tantei-san.png');
    my $name = color_type_name ($png->get_IHDR->{color_type});
    print "Your PNG has colour type $name.\n";

(This example is included as L<F<examples/color-type-name.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/color-type-name.pl>
in the distribution.)


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, C<png.h>.

=head2 get_bit_depth

    my $bit_depth = $png->get_bit_depth ();

Get the bit depth, the number of bits for one channel of one pixel.

This function corresponds to C<png_get_bit_depth> in libpng

=head2 get_channels

    my $channels = $png->get_channels ();

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
C<PNG_COLOR_TYPE_GRAY> and C<PNG_COLOR_TYPE_PALETTE>, 2 for
C<PNG_COLOR_TYPE_GRAY_ALPHA>, 3 for C<PNG_COLOR_TYPE_RGB> and 4 for
C<PNG_COLOR_TYPE_RGB_ALPHA> or C<PNG_COLOR_TYPE_RGB> 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>.

This function corresponds to C<png_get_channels> in libpng

=head2 get_color_type

    my $color_type = $png->get_color_type ();

This returns an integer value. If you want to get a name for the
color type, use L</color_type_name>.

This function corresponds to C<png_get_color_type> in libpng.

=head2 get_IHDR

    my $IHDR = $png->get_IHDR ();

Read the IHDR information from the PNG file. The return value is a
hash reference containing the following key/value pairs:

=over


=item width

The width of the image in pixels.


=item height

The height of the image in pixels. 


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

=item color_type

The color type.
This can take the values PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA.

=item interlace_method

The method of interlacing.
This can take the values PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7.




=back

So, for example, to get the width and height of an image,

    my $ihdr = $png->get_IHDR ();
    printf "Your image is %d x %d\n", $ihdr->{width}, $ihdr->{height};

This function corresponds to C<png_get_IHDR> in libpng, with a single Perl hash reference used
instead of the several pointers to integers used in libpng. 

It does not return the fields C<filter_type> and
C<compression_type>, since these are always 0. See L<Unused arguments omitted>.

=head2 get_image_height

    my $height = $png->get_image_height ();

Get the image's height from the header.

This function corresponds to C<png_get_image_height> in libpng

=head2 get_image_width

    my $width = $png->get_image_width ();

Get the image's width from the header.

This function corresponds to C<png_get_image_width> in libpng

=head2 get_interlace_type

    my $interlace_type = $png->get_interlace_type ();

Get the interlace type. This is either PNG_INTERLACE_NONE or
PNG_INTERLACE_ADAM7.

This function corresponds to C<png_get_interlace_type> in libpng

=head2 get_valid

    my $valid = $png->get_valid ();
    if ($valid->{oFFs}) {
        print "The PNG has valid screen offsets.\n";
    }

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>, L</cHRM>, L</eXIf>, L</gAMA>, L</hIST>, L</hIST>, L</iCCP>, L<IDAT|/Image data>, L<IHDR|/The image header>, L</iTXt>, L</oFFs>, L</pCAL>, L</pHYs>, L</PLTE>, L</sBIT>, L</sCAL>, L</sPLT>, L</sRGB>, L</tEXt>, L</tIME>, L</tRNS>, and L</zTXt>.

Whereas L</libpng_supports> tells you whether the installed libpng on
your system supports various chunks, this tells you whether the chunks
are present in a particular PNG image file.

The first argument, C<$png>, is a PNG structure created with 
L</create_read_struct>.

This function corresponds to C<png_get_valid> in libpng, with the difference being that the
return value is a hash containing a key for each possible chunk.

=head2 height

    my $height = $png->height ();

Alias for L</get_image_height>. This is not exported, it's
intended for use with the object only.

=head2 set_IHDR

    my $ihdr = {width => 10, height => 10, bit_depth => 8,
                color_type => PNG_COLOR_TYPE_RGB};
    $png->set_IHDR ($ihdr);

Set the IHDR chunk (the image header) of the PNG image. 

The first argument, C<$png>, is a writeable PNG structure created with 
L</create_write_struct>. The second argument is a hash with the following values:

=over


=item width

The width of the image in pixels.
 This cannot be zero, negative, or omitted. 

=item height

The height of the image in pixels. 
 This cannot be zero, negative, or omitted. 

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

=item color_type

The color type.
 This cannot be omitted. This can have the values PNG_COLOR_TYPE_GRAY, PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, PNG_COLOR_TYPE_RGB_ALPHA.

=item interlace_method

The method of interlacing.
 If this is omitted, it's set to PNG_INTERLACE_NONE. This can have the values PNG_INTERLACE_NONE, PNG_INTERLACE_ADAM7.




=back

Other fields in the hash are ignored.

This function corresponds to C<png_set_IHDR> in libpng, with a single Perl hash reference
used instead of the seven integers. 

The values
C<compression_method>, C<filter_method>, 
may be supplied by the user but are ignored since they may only take
the value 0. See L<Unused arguments omitted>.

=head2 sig_cmp

    if (sig_cmp ($should_be_png)) {
        print "Your data does not have a PNG signature.\n";
    }

This subroutine looks at C<$should_be_png> and checks whether its
first bytes correspond to a valid PNG signature. It returns a true
value if they do not. 

It can also take two further arguments consisting of a byte offset and
a number of bytes to check respectively:

    sig_cmp ($should_be_png, 0, 8);

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.

This function corresponds to C<png_sig_cmp> in libpng, with default arguments of
0 and 8 if second and third arguments are not supplied.

=head2 width

    my $width = $png->width ();

Alias for L</get_image_width>. This is not exported, it's
intended for use with the object only.

=head1 Image data

These functions deal with accessing the image data itself.

=head2 get_rowbytes

    my $bytes_in_a_row = $png->get_rowbytes ();

This returns the number of bytes needed to hold a transformed row of
an image.

This function corresponds to C<png_get_rowbytes> in libpng.

=head2 get_rows

    my $rows = $png->get_rows ();
    my $pixel = substr ($rows->[10], 20, 1);

This returns the rows of the PNG image, after uncompressing and
unfiltering, as binary data. The return value, C<$rows> in the
example, is an array reference with a number of rows equal to the
height of the PNG 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 C<substr> or C<unpack>. This binary data is likely to contain
bytes equal to zero.

L</get_rowbytes> gives the number of bytes in each row.

Each row is a Perl string. Perl terminates each row of data with an
extra zero byte at the end.

This function corresponds to C<png_get_rows> in libpng.

=head2 set_rows

    $png->set_rows (\@rows);

Set the rows of data to be written in to the PNG to C<@rows>. C<@rows>
needs to contain at least the same number of rows of data as the
height of the PNG image set with L</set_IHDR>, 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.

This function was changed to copy the data in version 0.46.

This function corresponds to C<png_set_rows> in libpng.

=head1 Text chunks

See L<this subsection|http://www.w3.org/TR/PNG/#11textinfo>
of L</The PNG specification> for information on the PNG standards for
text information.

=head2 get_text

    my $text_chunks = $png->get_text ();

This gets all of the text chunks in the PNG 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 C<key>,
C<lang_key>, or C<compression> taken from the PNG's information.

The text data is uncompressed by libpng. If it is international text
(C<ITXT>), it is put into Perl's internal Unicode encoding if it is
found to be valid UTF-8. (PNG "international text", C<ITXT> is
required to be in the UTF-8 encoding, and non-international text is
required to contain whitespace and printable ASCII characters
only. See L</The PNG specification> for more on the requirements of a PNG text
section.)

This function corresponds to C<png_get_text> in libpng, with a Perl array of hash references
substituted for the C array of structs used by libpng. See
L</set_text> for details of the keys and values which may be returned.

=head2 set_text

    $png->set_text ([\%chunk1, \%chunk2]);

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 C<key> value for the text. According to the PNG
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:

=over

=item C<compression>

The value of C<compression> controls the compression of the
text. If C<compression> is not supplied, a default value of
PNG_TEXT_COMPRESSION_NONE is applied. The C<compression> field can
take the following values, available from L<Image::PNG::Const>:

=over

=item PNG_TEXT_COMPRESSION_NONE

TEXT = Printable ASCII and space characters.

=item PNG_TEXT_COMPRESSION_zTXt

TEXT = Printable ASCII and space characters.

=item PNG_ITXT_COMPRESSION_NONE

ITXT = International text, should be UTF-8.

=item PNG_ITXT_COMPRESSION_zTXt

ITXT = International text, should be UTF-8.

=back

=item C<itxt_length>

The string length of international text in bytes.

⛐🤪⚠ 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>.

=item C<lang>

This should be set to name of the language of the text, if the text
chunk is iTXt. According to the PNG specification, "It is an ISO
646.IRV:1991 [ISO 646] string consisting of hyphen-separated words of
1-8 alphanumeric characters each (for example cn, en-uk, no-bok,
x-klingon, x-KlInGoN)." 

Support for writing C<lang> was added in version 0.49 of this
module. (Prior to that undocumented support existed via a
differently-named key.)

⛐🤪⚠ 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.

=item C<lang_key>

This corresponds to the "Translated keyword" of the PNG
specification. Note that the user needs to supply C<key> and L</lang>
as well as C<lang_key>.

Support for writing C<lang_key> was added in version 0.49 of this
module.  (Prior to that undocumented support existed via a
differently-named key.)

=item C<text>

The value of "text" is added to the PNG as the text segment. This can
be omitted if you just want to write a key value without any
accompanying text.

=item C<text_length>

The string length in bytes. The user may set this, but it is ignored
when writing PNG 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>, but if the text is marked
as international text, L</itxt_length> is used to return its length in
bytes, rather than this.

=back

Whether or not the value of C<text> is an ITXT field is decided by the
value of C<compression>. 

People who want to fiddle with the text compression applied can do so
via L</set_text_compression_level> and the other functions described
below that.

If C<set_text> is called more than once, the chunks are not overwritten but
appended to the existing ones. (This behaviour is from libpng itself.)

Prior to version 0.50, C<set_text> would fail silently if the user
added invalid chunks, for example hash references without a valid
C<key>, 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.

This function corresponds to C<png_set_text> in libpng.

=head3 Example

    
    use utf8;
    use Image::PNG::Const ':all';
    use Image::PNG::Libpng ':all';
    my $png = create_write_struct ();
    $png->set_IHDR ({width => 1, height => 1, bit_depth => 8,
                     color_type => PNG_COLOR_TYPE_GRAY});
    $png->set_rows (['X']);
    $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 => '著者権',
        lang => 'ja_JP',
        text => '©令和２年茉莉ニャンバーガーさん',
    }]);
    $png->write_png_file ('copyright.png');

(This example is included as L<F<examples/set-text.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/set-text.pl>
in the distribution.)


=head2 text_compression_name

    my $name = Image::PNG::Libpng::text_compression_name ($text->{compression});

Given a numerical text compression type, return the equivalent
name. The name is in upper case. The possible return values are

=over

=item TEXT_NONE

=item TEXT_zTXt

=item ITXT_NONE

=item ITXT_zTXt

=item an empty string

if the compression method is unknown.

=back

The compression field is also used to store the information about
whether the text is "international text" in UTF-8 or not.

This function does not correspond to anything in libpng. The names of
the text compression types are based on those in C<png.h>, but without
the word "COMPRESSION", so for example the libpng constant
C<PNG_ITXT_COMPRESSION_zTXt> corresponds to a return value of
C<ITXT_zTXt>.

=head1 Private chunks

See L<this subsection|http://www.w3.org/TR/PNG/#12Use-of-private-chunks>
of L</The PNG specification> for information on the PNG
standards for private chunks.

To test whether your version of libpng supports C<private chunks>, use
L</libpng_supports> with argument 'L</UNKNOWN_CHUNKS>':

    if (libpng_supports ('UNKNOWN_CHUNKS')) {
        # do something
    }

=head2 get_chunk_malloc_max

    my $max = $png->get_chunk_malloc_max ();

This gets the maximum amount of memory that a chunk can use.

To test whether your version of libpng supports C<get_chunk_malloc_max>, use
L</libpng_supports> with argument 'L</CHUNK_MALLOC_MAX>':

    if (libpng_supports ('CHUNK_MALLOC_MAX')) {
        # do something
    }

This function corresponds to C<png_get_chunk_malloc_max> in libpng

=head2 set_chunk_malloc_max

    $png->set_chunk_malloc_max ($max);

This sets the maximum amount of memory that a chunk can use. The
default value of libpng 1.6.45 is 8 megabytes.

To test whether your version of libpng supports C<get_chunk_malloc_max>, use
L</libpng_supports> with argument 'L</CHUNK_MALLOC_MAX>':

    if (libpng_supports ('CHUNK_MALLOC_MAX')) {
        # do something
    }

This function corresponds to C<png_set_chunk_malloc_max> in libpng

=head2 set_keep_unknown_chunks

    use Image::PNG::Const 'PNG_HANDLE_CHUNK_ALWAYS';
    $png->set_keep_unknown_chunks (PNG_HANDLE_CHUNK_ALWAYS);

Tell libpng not to discard unknown chunks when reading the file.

=head2 get_unknown_chunks

    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;

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> with an appropriate value before reading
the file, otherwise libpng discards unknown chunks when reading the
file.

Each member hash reference has the following keys:

=over

=item name

The name of the unknown chunk, in the PNG chunk format (four bytes).


=item location

The location of the unknown chunk.


=item data

The data of the unknown chunk


=back

The "size" field of the PNG structure is not stored, because the
"data" member of the hash contains information on its length.

This function corresponds to C<png_get_unknown_chunks> in libpng

=head2 set_unknown_chunks

    $png->set_unknown_chunks (name => 'dUCk', data => 'abcdefg',
			      location => PNG_AFTER_IDAT);

⛐🤪⚠ This currently does not fully function.

This function corresponds to C<png_set_unknown_chunks> in libpng

=head1 Library version functions

=head2 access_version_number

    my $libpng_version_number = Image::PNG::Libpng::access_version_number ();

This function returns the version of the libpng library which the
module is using as an integer number.

This function corresponds to C<png_access_version_number> in libpng.

=head2 get_libpng_ver

    my $libpng_version = Image::PNG::Libpng::get_libpng_ver ();

This function returns the version of the libpng library which the
module is using.

This function corresponds to C<png_get_libpng_ver> in libpng. However, it doesn't require the
C<png_structp> argument of the C function. See L<Unused arguments omitted>.

=head1 Compression and filtering



=head2 get_compression_buffer_size

    my $size = $png->get_compression_buffer_size ();

Returns the value of the compression buffer size, which may be altered
with L</set_compression_buffer_size>.

=head2 set_compression_buffer_size

    $png->set_compression_buffer_size (100);

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.

=head2 set_compression_level

    $png->set_compression_level ($number);

Set the compression level used to make the PNG. A value of 0
(C<Z_NO_COMPRESSION>) corresponds to no compression at all, otherwise
C<$number> may take values of 1 (C<Z_BEST_SPEED>) to 9
(C<Z_BEST_COMPRESSION>), 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
C<gzip> utility, or the compression level parameter of
C<zlib>. Calling with C<-1> (C<Z_DEFAULT_COMPRESSION>)
reverts to the default compression. Calling with any other number
outside the range 0 to 9 results in a fatal error.

This function was added to the module in version 0.49.


=head2 set_compression_mem_level

    $png->set_compression_mem_level ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_compression_mem_level>. Takes one integer argument.


Sets the C<memLevel> parameter of C<deflateInit2> in zlib when writing
PNG image data. Argument between 1 for minimum memory and 9 for
maximum speed. The default is 8. See L</zlib documentation>.


=head2 set_compression_window_bits

    $png->set_compression_window_bits ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_compression_window_bits>. Takes one integer argument.


Sets the C<windowBits> parameter of C<deflateInit2> in zlib when
writing PNG image data. Argument value must be between 8 and 15 for
libpng. The default is 15. See the L</zlib documentation>.


=head2 set_compression_strategy

    $png->set_compression_strategy ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_compression_strategy>. Takes one integer argument.


Sets the C<strategy> parameter of C<deflateInit2> when writing PNG
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>. libpng uses the default strategy 0
(C<Z_DEFAULT_STRATEGY>) for unfiltered image data, and 1
(C<Z_FILTERED>) for filtered image data.

=head2 set_filter

    use Image::PNG::Const 'PNG_FILTER_NONE';
    $png->set_filter (PNG_FILTER_NONE);

This sets the filters which are allowed to be used for writing a PNG
image. The possible values are

=over

=item PNG_NO_FILTERS

=item PNG_FILTER_NONE

=item PNG_FILTER_SUB

=item PNG_FILTER_UP

=item PNG_FILTER_AVG

=item PNG_FILTER_PAETH

=item PNG_ALL_FILTERS

=back

These can be combined using C<|> (logical or):

    use Image::PNG::Const ':all';
    set_filter ($png, PNG_FILTER_UP | PNG_FILTER_AVG);

Please see L<this subsection|http://www.w3.org/TR/PNG/#9Filter-types>
of L</The PNG specification> for the meanings of these
filter types.

This function corresponds to C<png_set_filter> in libpng with the second (unused)
argument omitted. See L<Unused arguments omitted>.


=head2 set_text_compression_level

    $png->set_text_compression_level ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_text_compression_level>. Takes one integer argument.


As L</set_compression_level> but for compressed text.


=head2 set_text_compression_mem_level

    $png->set_text_compression_mem_level ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_text_compression_mem_level>. Takes one integer argument.


As L</set_compression_mem_level> but for compressed text.


=head2 set_text_compression_window_bits

    $png->set_text_compression_window_bits ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_text_compression_window_bits>. Takes one integer argument.


As L</set_compression_window_bits> but for compressed text.


=head2 set_text_compression_strategy

    $png->set_text_compression_strategy ($argument);

⛐🤪⚠ Untested function corresponding to C<png_set_text_compression_strategy>. Takes one integer argument.


As L</set_compression_strategy> but for compressed text.

=head1 Other chunks

These routines deal with the other possible chunks of PNGs.

The getter and setter routines for all other chunks are designed so
that the return value of C<get_wXYZ> is able to be used directly as
the value for C<set_wXYZ>, so the values of chunks can easily be
copied from one PNG to another.

    my $values = $png1->get_wXYZ ();
    $png2->set_wXYZ ($values);

If the chunk is not present, or if the chunk is not supported by the
user's version of libpng, the return value of C<get_wXYZ> is the
undefined value.

=head2 bKGD

The background color of the PNG image.

See L<this subsection|http://www.w3.org/TR/PNG/#11bKGD>
of L</The PNG specification> for information on the PNG standards for
the background chunk.

=head3 get_bKGD

    my $bkgd = $png->get_bKGD ();

Get the bKGD (background) chunk of the image.

The return value is a hash with the following keys, depending on the
color type of the image:

=over

=item index

For palette color types, this is the offset into the palette.

=item gray

For grayscale color types.

=item red

=item green

=item blue

=back

This function corresponds to C<png_get_bKGD> in libpng with a hash function instead of a
C<png_color> struct.

=head3 set_bKGD

    $png->set_bKGD ($bkgd);

Set the bKGD (background) chunk of the image. C<$bkgd> is a hash
reference. The keys of the hash reference are as described in
L</get_bKGD>.

This function corresponds to C<png_set_bKGD> in libpng with a hash function instead of a
C<png_color> struct.

=head2 cHRM

See L<this subsection|http://www.w3.org/TR/PNG/#11cHRM>
of L</The PNG specification> "cHRM Primary chromaticities and white
point".

=head3 get_cHRM

    my $cHRM = $png->get_cHRM ();

Get the cHRM chunk as a hash reference.

The keys of the hash are white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y.

The values of the hash are floating point numbers between 0 and 1.

This function corresponds to C<png_get_cHRM> in libpng with a hash reference supplying the
arguments. The hash's keys correspond to the names of the C<double>
arguments in libpng.

=head3 get_cHRM_XYZ

    my $cHRM = $png->get_cHRM_XYZ ();

Get the cHRM chunk as a hash reference for the XYZ color space.

The keys of the hash are red_x, red_y, red_z, green_x, green_y, green_z, blue_x, blue_y, blue_z.

The values of the hash are floating point numbers between 0 and 1.

This function corresponds to C<png_get_cHRM_XYZ> in libpng with a hash reference supplying the
arguments. The hash's keys correspond to the names of the C<double>
arguments in libpng.

=head3 set_cHRM

    $png->set_cHRM (\%cHRM);

Set the cHRM chunk from a hash reference.

The keys of the hash are as for L</get_cHRM>. The values are floating
point numbers between 0 and 1.

This function corresponds to C<png_set_cHRM> in libpng with a hash reference instead of the C<double>
arguments.

=head3 set_cHRM_XYZ

    $png->set_cHRM_XYZ (\%cHRM);

Set the cHRM chunk from a hash reference for the XYZ color space.

The keys of the hash are as for L</get_cHRM_XYZ>. The values are
floating point numbers between 0 and 1. The C<Y> values C<red_y>,
C<green_y>, and C<blue_y> should sum to 1. If you supply values
outside the allowed range, libpng corrects them silently on writing
rather than producing an error.

This function corresponds to C<png_set_cHRM_XYZ> in libpng with a hash reference instead of the C<double>
arguments.

=head2 eXIf

The C<eXIf> chunk is an extension to the PNG specification. See
L<http://www.simplesystems.org/png-group/proposals/eXIf/>. Support for
this chunk was added in version 0.50 of this module.

=head3 get_eXIf

    my $exif = $png->get_eXIf ();

This retrieves the C<eXIf> chunk from C<$png> but does not process the
internal information.

=head3 set_eXIf

    $png->set_eXIf ($exif);

libpng checks whether the chunk's first two bytes are either C<II> for
little-endian (from Intel) or C<MM> for big-endian (from Motorola)
then adds the entire chunk, including the first two bytes, to the PNG.

⛐🤪⚠ 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
C<libpng warning: eXIf: duplicate> on reading a PNG file back in. See
L<https://github.com/glennrp/libpng/pull/351>.

=head2 gAMA

See L<this subsection|http://www.w3.org/TR/PNG/#11gAMA>
of L</The PNG specification>.

=head3 get_gAMA

    my $gamma = $png->get_gAMA ();

Get the gamma value or gAMA chunk. The return value is a
floating-point number.

This function corresponds to C<png_get_gAMA> in libpng

=head3 set_gAMA

    $png->set_gAMA (0.2);

Set the gamma value or gAMA chunk.

This function corresponds to C<png_set_gAMA> in libpng

=head2 hIST

See L<this subsection|http://www.w3.org/TR/PNG/#11hIST>
of L</The PNG specification>.

=head3 get_hIST

    my $hist = $png->get_hIST ();

If the PNG 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.

This function corresponds to C<png_get_hIST> in libpng

=head3 set_hIST

    $png->set_hIST (\@hist);

Set the histogram of frequencies of the colors of a paletted (L</PLTE>)
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.

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

This function corresponds to C<png_set_hIST> in libpng

=head2 iCCP

See L<this subsection|http://www.w3.org/TR/PNG/#11iCCP>
of L</The PNG specification>.

=head3 get_iCCP

    my $iccp = $png->get_iCCP ();

The return value is a hash with two keys,

=over

=item name

The name of the profile.

=item profile

The color profile.

=back

The C<compression_type> value, which is always 0, is not returned. See L<Unused arguments omitted>.

This function corresponds to C<png_get_iCCP> in libpng.

=head3 set_iCCP

    $png->set_iCCP ({name => 'name', profile => 'profile'});

This function corresponds to C<png_set_iCCP> in libpng. For details of the arguments, see
L</get_iCCP>. A C<compression_type> argument, which must always be 0
anyway, is ignored. See L<Unused arguments omitted>.

=head2 oFFs

This is an extension to the PNG specification. See L<http://www.libpng.org/pub/png/spec/1.1/pngext-1.1.0-pdg.html#C.oFFs>.

=head3 get_oFFs

    my $phys = $png->get_oFFs ();

Get oFFs chunk. Return value is a hash reference

This function corresponds to C<png_get_oFFs> in libpng

=head3 set_oFFs

    $png->set_oFFs ({x_offset => 1, y_offset => 1, unit_type => 0});

Set oFFs chunk. See the specification linked above for the meanings of
the parameters. If C<unit_type> is not 0 or 1, a warning is produced.

This function corresponds to C<png_set_oFFs> in libpng

=head2 pCAL

pCAL is an extension of the PNG specification which allows one to
associate pixels in the PNG image with non-image data such as a heat
map. See
L<http://www.libpng.org/pub/png/spec/1.1/pngext-1.1.0-pdg.html#C.pCAL>.

To test whether your version of libpng supports C<the pCAL extension>, use
L</libpng_supports> with argument 'L</pCAL>':

    if (libpng_supports ('pCAL')) {
        # do something
    }

=head3 get_pCAL

    my $pcal = $png->get_pCAL ();

The return value is a hash reference with the following keys:

=over

=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 PNG 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 C<type> parameter. Refer to the PNG
specification for full details.

=item purpose

The purpose string of the pCAL chunk.

=item type

The equation type as a number, from 0 to 3. See the PNG specification
for the meanings. Other numbers cause an error.

=item units

The units as a string. See the PNG specification for details.

=item x0

The zero value for the equation, an integer.

=item x1

The max value for the equation, an integer.

=back

This function corresponds to C<png_get_pCAL> in libpng

=head3 set_pCAL

    $png->set_pCAL (\%values);

See L</get_pCAL> for the parameters of C<%values>.

This function corresponds to C<png_set_pCAL> in libpng

=head2 pHYs

See L<this subsection|http://www.w3.org/TR/PNG/#11pHYs>
of L</The PNG specification>.

=head3 get_pHYs

    my $phys = $png->get_pHYs ();

The return value is a hash reference with the keys

=over

=item res_x

=item res_y

=item unit_type

Is either 0 or 1.

=back

This function corresponds to C<png_get_pHYs> in libpng

=head3 set_pHYs

    $png->set_pHYs ({res_x => 1, res_y => 1, unit_type => 1});

This function corresponds to C<png_set_pHYs> in libpng

=head2 PLTE

See L<this subsection|http://www.w3.org/TR/PNG/#11PLTE>
of L</The PNG specification> for information on the PNG standards for
the palette chunk.

=head3 get_palette_max

    my $pmax = $png->get_palette_max ();

If your libpng supports it, this will return the maximum palette index
found in the image, or "-1" if the palette was not checked, or "0" if
no palette was found.

To test whether your version of libpng supports C<get_palette_max>, use
L</libpng_supports> with argument 'L</GET_PALETTE_MAX>':

    if (libpng_supports ('GET_PALETTE_MAX')) {
        # do something
    }

⛐🤪⚠ 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 F<t/tantei-san.png> which is an image with a fully-used
256-color palette. I've L<asked about it on the libpng mailing
list|https://sourceforge.net/p/png-mng/mailman/png-mng-implement/?viewmonth=202012&viewday=14>,
but so far nobody has responded.

=head3 get_PLTE

     my $colors = $png->get_PLTE ();
     # Get the green value of the twentieth entry in the palette.
     my $green = $colors->[20]->{green};

This function gets the palette from the PNG. The return value is an
array reference containing the palette. This array contains hash
references with the values "green", "blue" and "red" for the color of
each pixel in the palette. If the PNG has no palette, it returns an
undefined value.

A PNG image may or may not contain a palette. To check whether the
image contains a palette, use something of the following form:

     use Image::PNG::Const ':all';
     my $color_type = $png->get_color_type ();
     if ($color_type == PNG_COLOR_TYPE_PALETTE) {
         # The PNG uses a palette.
     }

A PNG image may also contain a palette even when the "color_type" does
not indicate that. To check for that case, use L</get_valid>.

This function corresponds to C<png_get_PLTE> in libpng.

=head3 set_PLTE

    $png->set_PLTE ($palette);

Set the palette of C<$png>. 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,

    $png->set_PLTE ([{red => 1, green => 99, blue => 0x10},
                     {red => 0xFF, green => 0xFF, blue => 0xFF}]);

creates a palette with two entries in C<$png>.

This function corresponds to C<png_set_PLTE> in libpng.

=head2 sBIT

See L<this subsection|http://www.w3.org/TR/PNG/#11sBIT>
of L</The PNG specification>.

=head3 get_sBIT

    my $sbit = $png->get_sBIT ();

The return value is a hash reference containing integer values for the
keys C<red>, C<blue>, C<green>, C<gray> and C<alpha>, depending on the
C<color_type> of C<$png>.

⛐🤪⚠ Prior to version 0.50 of this module, get_sBIT wrote
values of 0 for all of the keys, regardless of the C<color_type>,
causing errors in some circumstances. From version 0.50, hash keys are
not entered if the C<color_type> of the image makes them invalid.

This function corresponds to C<png_get_sBIT> in libpng

=head3 set_sBIT

    $png->set_sBIT ({red => 1, blue => 2, green => 3});

The argument is a hash reference containing integer values for the
keys C<red>, C<blue>, C<green>, C<gray>, and C<alpha>, as required by
the C<color_type> of C<$png>.

This function corresponds to C<png_set_sBIT> in libpng

=head2 sCAL

This is an extension to the PNG specification. See
L<http://www.libpng.org/pub/png/spec/1.1/pngext-1.1.0-pdg.html#C.sCAL>.

To test whether your version of libpng supports C<the sCAL chunk>, use
L</libpng_supports> with argument 'L</sCAL>':

    if (libpng_supports ('sCAL')) {
        # do something
    }

=head3 get_sCAL

    my $scal = $png->get_sCAL ();

The returned hash value contains the following keys:

=over

=item unit

The unit type, which is either PNG_SCALE_UNKNOWN, PNG_SCALE_METER, or
PNG_SCALE_RADIAN.

=item width

The width, as a string.

=item height

The height, as a string.

=back

This function corresponds to C<png_get_sCAL_s> 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.

=head3 set_sCAL

    $png->set_sCAL ($scal);

C<$scal> is a hash reference containing the keys described in
L</get_sCAL>.

This function corresponds to C<png_set_sCAL_s> in libpng. Note that this uses the C<set_sCAL_s>
function rather than C<set_sCAL> and the input values are the strings
themselves rather than numbers.

=head2 sPLT

See L<this subsection|http://www.w3.org/TR/PNG/#11sPLT>
of L</The PNG specification>.

=head3 get_sPLT

⛐🤪⚠ Provisional. See L</set_sPLT> for documentation, the
return value is like the input of that.

=head3 set_sPLT

    $png->set_sPLT ([{ name => 'palette', depth => 8, entries => [{red => 1, blue => 2},]}]);

Set suggested palettes. The input is an array reference containing
hash references with the following fields:

=over

=item name

The name of the suggested palette.

=item depth

The depth of the suggested palette.

=item entries

The entries of the palette. This is an array reference containing hash
references with keys as follows:

=over

=item red

=item blue

=item green

=item frequency

=item alpha

=back

=back

The field C<nentries> which is returned by L</get_sPLT> does not need
to be specified, it is calculated from the length of C<entries>.

=head2 sRGB

See L<this subsection|http://www.w3.org/TR/PNG/#11sRGB>
of L</The PNG specification>.

=head3 get_sRGB

    my $sRGB = $png->get_sRGB ();

The return value is an integer number corresponding to one of the
following:

=over

=item PNG_sRGB_INTENT_SATURATION

=item PNG_sRGB_INTENT_PERCEPTUAL

=item PNG_sRGB_INTENT_ABSOLUTE

=item PNG_sRGB_INTENT_RELATIVE

=back

This function corresponds to C<png_get_sRGB> in libpng

=head3 set_sRGB

    $png->set_sRGB ($srgb);

C<$srgb> is one of the values described in L</get_sRGB>.

This function corresponds to C<png_set_sRGB> in libpng

=head2 tIME

See L<this subsection|http://www.w3.org/TR/PNG/#11timestampinfo>
of L</The PNG specification> for information on the PNG standards for
time stamp information.

=head3 get_tIME

    my $time = $png->get_tIME ();
    if ($time && $time->{year} < 2005) {
        warn "Your PNG is now getting old. Don't forget to oil it to prevent rust.";
    }

The return value is either the undefined value, if no C<tIME> chunk
exists in the PNG, or a hash reference containing fields C<year>,
C<month>, C<day>, C<hour>, C<minute> and C<second>. C<month> and
C<day> start from 1 rather than 0.

The "modification time value" of the PNG image is a chunk written into
the PNG 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 PNG files, and most PNG image files do not
contain this chunk. PNG tIME chunks do not contain a time zone. According to L<this subsection|http://www.w3.org/TR/PNG/#11tIME>
of L</The PNG specification>, "Universal Time (UTC) should be specified rather
than local time."

This function corresponds to C<png_get_tIME> in libpng, with a Perl hash reference
substituted for the C struct C<png_timep> used in libpng.

=head3 set_tIME

    # Set the time to "now"
    $png->set_tIME ();
    # Set the time
    $png->set_tIME ({year => 1999, month => 12});

Set the modification time of the PNG to the values given by the
argument, a hash reference containing the fields C<year>, C<month>,
C<day> for the day of the month, C<hour>, C<minute>, and C<second>.
The numbering for C<month> and C<day> 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.  PNG tIME chunks do not contain a time zone. According to L<this subsection|http://www.w3.org/TR/PNG/#11tIME>
of L</The PNG specification>, "Universal Time (UTC) should be specified rather
than local time." If the entire argument is omitted or contains an invalid
value, the time is set to the current time.

This function corresponds to C<png_set_tIME> in libpng, with a Perl hash reference
substituted for the C struct C<png_timep> used in libpng.

=head2 tRNS

See L<this subsection|http://www.w3.org/TR/PNG/#11tRNS>
of L</The PNG specification>.

=head3 get_tRNS

    my $trns = $png->get_tRNS ();

Get the C<tRNS> 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.

=head3 set_tRNS

    $png->set_tRNS ($trns);

Set the C<tRNS> chunk. If the image is a palette type, C<$trns> 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, C<$trns> is a hash
reference containing values for the keys red, green, blue and gray.

=head1 Libpng transformations

=head2 set_bgr

    $png->set_bgr ();

⛐🤪⚠ Untested. Flips RGB to BGR. See the libpng manual for details. 

To test whether your version of libpng supports C<set_bgr>, for a read
object, use L</libpng_supports> with argument 'L</READ_BGR>'.

    if (libpng_supports ('READ_BGR')) {
        # do something
    }

For a write object, use argument 'L</WRITE_BGR>'.

This function corresponds to C<png_set_bgr> in libpng

=head2 set_expand

    $png->set_expand ();

Set transformation in C<$png> such that paletted images are expanded
to RGB, grayscale images of bit-depth less than 8 are expanded to
8-bit images, and tRNS chunks are expanded to alpha channels.

To test whether your version of libpng supports C<set_expand>, use
L</libpng_supports> with argument 'L</READ_EXPAND>':

    if (libpng_supports ('READ_EXPAND')) {
        # do something
    }

This function corresponds to C<png_set_expand> in libpng

=head2 set_expand_16

    $png->set_expand_16 ();

⛐🤪⚠ Untested.

To test whether your version of libpng supports C<set_expand_16>, use
L</libpng_supports> with argument 'L</READ_EXPAND_16>':

    if (libpng_supports ('READ_EXPAND_16')) {
        # do something
    }

This function corresponds to C<png_set_expand_16> in libpng

=head2 set_expand_gray_1_2_4_to_8

    $png->set_expand_gray_1_2_4_to_8 ();

⛐🤪⚠ Untested.

To test whether your version of libpng supports C<set_expand_gray_1_2_4_to_8>, use
L</libpng_supports> with argument 'L</READ_EXPAND>':

    if (libpng_supports ('READ_EXPAND')) {
        # do something
    }

This function corresponds to C<png_set_expand_gray_1_2_4_to_8> in libpng

=head2 set_gray_to_rgb

    $png->set_gray_to_rgb ();

Convert a grayscale PNG file to RGB format on reading.

To test whether your version of libpng supports C<set_gray_to_rgb>, use
L</libpng_supports> with argument 'L</READ_GRAY_TO_RGB>':

    if (libpng_supports ('READ_GRAY_TO_RGB')) {
        # do something
    }

This function corresponds to C<png_set_gray_to_rgb> in libpng

=head2 set_invert_alpha

    $png->set_invert_alpha ();

⛐🤪⚠ Untested. See the libpng manual for details. 

To test whether your version of libpng supports C<set_invert_alpha>, use
L</libpng_supports> with argument 'L</READ_INVERT_ALPHA>':

    if (libpng_supports ('READ_INVERT_ALPHA')) {
        # do something
    }

This function corresponds to C<png_set_invert_alpha> in libpng

=head2 set_invert_mono

    $png->set_invert_mono ();

Invert monochrome images. See the libpng manual for details. 

To test whether your version of libpng supports C<set_invert_mono>, use
L</libpng_supports> with argument 'L</READ_INVERT>':

    if (libpng_supports ('READ_INVERT')) {
        # do something
    }

This function corresponds to C<png_set_invert_mono> in libpng

=head2 set_packing

    $png->set_packing ();

When reading a PNG, 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>.

To test whether your version of libpng supports C<set_packing>, for a read
object, use L</libpng_supports> with argument 'L</READ_PACK>'.

    if (libpng_supports ('READ_PACK')) {
        # do something
    }

For a write object, use argument 'L</WRITE_PACK>'.

This function corresponds to C<png_set_packing> in libpng

=head2 set_packswap

    $png->set_packswap ();

Swaps the bits of 1, 2, or 4 bits/pixel images. The default for PNG
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. 

To test whether your version of libpng supports C<set_packswap>, for a read
object, use L</libpng_supports> with argument 'L</READ_PACKSWAP>'.

    if (libpng_supports ('READ_PACKSWAP')) {
        # do something
    }

For a write object, use argument 'L</WRITE_PACKSWAP>'.

This function corresponds to C<png_set_packswap> in libpng

=head2 set_palette_to_rgb

    $png->set_palette_to_rgb ();

⛐🤪⚠ Untested. See the libpng manual for details. 

To test whether your version of libpng supports C<set_palette_to_rgb>, use
L</libpng_supports> with argument 'L</READ_EXPAND>':

    if (libpng_supports ('READ_EXPAND')) {
        # do something
    }

This function corresponds to C<png_set_palette_to_rgb> in libpng

=head2 set_scale_16

    $png->set_scale_16 ()

⛐🤪⚠ Untested. 

To test whether your version of libpng supports C<set_scale_16>, use
L</libpng_supports> with argument 'L</READ_SCALE_16_TO_8>':

    if (libpng_supports ('READ_SCALE_16_TO_8')) {
        # do something
    }

This function corresponds to C<png_set_scale_16> in libpng

=head2 set_strip_16

    $png->set_strip_16 ();

Strip the pixels of a PNG stream with 16 bits per channel to 8 bits
per channel.

To test whether your version of libpng supports C<set_strip_16>, use
L</libpng_supports> with argument 'L</READ_STRIP_16_TO_8>':

    if (libpng_supports ('READ_STRIP_16_TO_8')) {
        # do something
    }

This function corresponds to C<png_set_strip_16> in libpng

=head2 set_strip_alpha

    $png->set_strip_alpha ();

Strip the alpha channel of a PNG stream.

To test whether your version of libpng supports C<set_strip_alpha>, use
L</libpng_supports> with argument 'L</READ_STRIP_ALPHA>':

    if (libpng_supports ('READ_STRIP_ALPHA')) {
        # do something
    }

This function corresponds to C<png_set_strip_alpha> in libpng

=head2 set_swap

    $png->set_swap ();

⛐🤪⚠ Untested. Swaps around the bytes of 16 bits/pixel
images. See the libpng manual for details. 

To test whether your version of libpng supports C<set_swap>, use
L</libpng_supports> with argument 'L</READ_SWAP>':

    if (libpng_supports ('READ_SWAP')) {
        # do something
    }

This function corresponds to C<png_set_swap> in libpng

=head2 set_swap_alpha

    $png->set_swap_alpha ();

⛐🤪⚠ Untested.  See the libpng manual for details. 

To test whether your version of libpng supports C<set_swap_alpha>, use
L</libpng_supports> with argument 'L</READ_SWAP_ALPHA>':

    if (libpng_supports ('READ_SWAP_ALPHA')) {
        # do something
    }

This function corresponds to C<png_set_swap_alpha> in libpng

=head2 set_tRNS_to_alpha

    $png->set_tRNS_to_alpha

⛐🤪⚠ Untested. See the libpng manual for details. 

To test whether your version of libpng supports C<set_tRNS_to_alpha>, use
L</libpng_supports> with argument 'L</READ_EXPAND>':

    if (libpng_supports ('READ_EXPAND')) {
        # do something
    }

This function corresponds to C<png_set_tRNS_to_alpha> in libpng

=head1 Other libpng functions

=head2 get_chunk_cache_max

    my $max = $png->get_chunk_cache_max ();

Get the maximum number of ancilliary chunks
allowed. See also L</set_chunk_cache_max>.

To test whether your version of libpng supports C<get_chunk_cache_max>, use
L</libpng_supports> with argument 'L</CHUNK_CACHE_MAX>':

    if (libpng_supports ('CHUNK_CACHE_MAX')) {
        # do something
    }

This function corresponds to C<png_png_get_chunk_cache_max> in libpng

=head2 get_rgb_to_gray_status

    my $badpixels = $png->get_rgb_to_gray_status ();

Returns a true value if there were some non-gray pixels in an RGB
image after calling L</set_rgb_to_gray>.

=head3 Saving bandwidth

Try this one weird old C<get_rgb_to_gray_status> trick to check
whether an image marked as RGB is really monochrome or not.

    
    use utf8;
    use FindBin '$Bin';
    use Image::PNG::Libpng ':all';
    use Image::PNG::Const ':all';
    
    my $file = 'life.png';
    print "Size before: ", -s $file, "\n";
    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.\n";
    }
    else {
        print "The image was grayscale already.\n";
    }
    $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, "\n";
    
    if (! png_compare ($file, $after)) {
        print "The two files contain exactly the same image data.\n";
    }
    else {
        print "The two files contain different image data.\n";
    }

(This example is included as L<F<examples/xkcd.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/xkcd.pl>
in the distribution.)


The output looks like this:

    Size before: 97299
    The image was grayscale already.
    Size after: 46956
    The two files contain exactly the same image data.




L<examples/life-gray.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/life-gray.png> is included in the distribution.

=begin html

<p>The resulting image looks like this:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/life-gray.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/life-gray.png'>examples/life-gray.png</a>
</th>
</tr>
</table>

=end html


Correct use of Image::PNG::Libpng could have spared as many as 50,000
bytes from the indignity of being sent around the internet.

This also illustrates the use of L</png_compare>.

L<Original image, licence statement and copyright notice
here|https://xkcd.com/2391/>.



=head2 get_user_height_max

    $png->get_user_height_max ();

Get the maximum height allowed for a PNG file. The default is 1
million pixels. These values can be changed by L</set_user_limits>.

This function corresponds to C<png_get_user_height_max> in libpng



=head2 get_user_width_max

    $png->get_user_width_max ();

Get the maximum width allowed for a PNG file. The default is 1
million pixels. These values can be changed by L</set_user_limits>.

This function corresponds to C<png_get_user_width_max> in libpng



=head2 permit_mng_features

    $png->permit_mng_features ($mask);

⛐🤪⚠ Untested. C<$mask> is an integer containing flags. See the libpng manual for details. 

(MNG, 'Multiple-image Network Graphics', is an image animation format
related to PNG. It has not been widely adopted.)

To test whether your version of libpng supports C<permit_mng_features>, use
L</libpng_supports> with argument 'L</MNG_FEATURES>':

    if (libpng_supports ('MNG_FEATURES')) {
        # do something
    }

This function corresponds to C<png_permit_mng_features> in libpng

=head2 set_add_alpha

    $png->set_add_alpha ($filler, $filler_loc);

⛐🤪⚠ Untested. Change C<$png> to add an alpha channel. This
only works for grayscale or RGB images with bit depth of 8 or
16. C<$filler> contains the alpha value to assign to each pixel, and
C<$filler_loc> is either C<PNG_FILLER_BEFORE> or
C<PNG_FILLER_AFTER>. The function of C<set_add_alpha> is
L</set_filler> and a change of the color type to add an alpha
channel. See the libpng manual for details. 

To test whether your version of libpng supports C<set_add_alpha>, use
L</libpng_supports> with argument 'L</READ_FILLER>':

    if (libpng_supports ('READ_FILLER')) {
        # do something
    }

This function corresponds to C<png_set_add_alpha> in libpng

=head2 set_alpha_mode

    $png->set_alpha_mode ($mode, $screen_gamma);

⛐🤪⚠ Untested. C<$mode> is an integer, one of the
C<PNG_ALPHA_*> constants. C<$screen_gamma> is a floating point
number. See the libpng manual for details. 

To test whether your version of libpng supports C<set_alpha_mode>, use
L</libpng_supports> with argument 'L</READ_ALPHA_MODE>':

    if (libpng_supports ('READ_ALPHA_MODE')) {
        # do something
    }

This function corresponds to C<png_set_alpha_mode> in libpng

=head2 set_background

    $png->set_background (\%color, $bkgd_gamma_code, $need_expand, $gamma);

C<set_background> sets the background of an image with an alpha
channel or simple transparency (a L</tRNS> chunk) with the color
specified by C<%color>. If C<$bkgd_gamma_code> is set to
C<PNG_BACKGROUND_GAMMA_SCREEN>, it indicates that the supplied
background color is in the gamma space of the display, else if it is
set to C<PNG_BACKGROUND_GAMMA_FILE>, the color is in the gamma space
of the file. If C<$bkgd_gamma_code> is set to
C<PNG_BACKGROUND_GAMMA_UNIQUE>, the value of C<$gamma> is used,
otherwise C<$gamma> appears to be ignored and can be omitted. (This is
not documented in the libpng manual or elsewhere. See
L<https://github.com/glennrp/libpng/issues/358>.)

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, C<$need_expand> must be set to a true value, but if the
background color is supplied at the expanded bit-depth,
C<$need_expand> must be set to a false value. Similarly for paletted
images, if C<%color> is supplied as a palette index
(C<$color{index}>), C<$need_expand> must be set to a true value, but
if C<%color> is an RGB triplet, C<$need_expand> must be set to a false
value.

See L</Setting the background> for an example.

To test whether your version of libpng supports C<set_background>, use
L</libpng_supports> with argument 'L</READ_BACKGROUND>':

    if (libpng_supports ('READ_BACKGROUND')) {
        # do something
    }

=head2 set_chunk_cache_max

    $png->set_chunk_cache_max (42);

Set the maximum number of ancilliary chunks allowed. The default is
1000. See also L</get_chunk_cache_max>.

To test whether your version of libpng supports C<set_chunk_cache_max>, use
L</libpng_supports> with argument 'L</CHUNK_CACHE_MAX>':

    if (libpng_supports ('CHUNK_CACHE_MAX')) {
        # do something
    }

This function corresponds to C<png_png_set_chunk_cache_max> in libpng

=head2 set_filler

    $png->set_filler ($filler, $flags);

Set transformations in C<$png> such that a filler byte C<$filler> is
added when an 8-bit grayscale image or 24-bit RGB image is read, and a
filler byte is deleted when an 8-bit grayscale image or 24-bit RGB
image is written. C<$flags> may be C<PNG_FILLER_BEFORE> or
C<PNG_FILLER_AFTER>. An error is produced if C<$png> has bit depth
less than 8.

This does not change the color type of the image. See the related
function L</set_add_alpha> if you want to add an alpha channel.

To test whether your version of libpng supports C<set_filler>, use
L</libpng_supports> with argument 'L</READ_FILLER>':

    if (libpng_supports ('READ_FILLER')) {
        # do something
    }

This function corresponds to C<png_set_filler> in libpng

=head2 set_gamma

    $png->set_gamma ($screen_gamma, $output_gamma);

⛐🤪⚠ Untested. C<$screen_gamma> and C<$output_gamma> should
contain floating-point arguments.  See the libpng manual for details. 

To test whether your version of libpng supports C<set_gamma>, use
L</libpng_supports> with argument 'L</READ_GAMMA>':

    if (libpng_supports ('READ_GAMMA')) {
        # do something
    }

This function corresponds to C<png_set_gamma> in libpng

=head2 set_quantize

    $png->set_quantize (\@palette, $ncolors, \@histogram, $full_quantize);

The C<@palette> part must be set to a palette similar to
L</set_PLTE>. C<$ncolors> must be the length of C<@palette> or
shorter. C<@histogram> can be an empty array or if not it needs to be
an array of integers of exactly the same length as C<@palette>. The
integers represent the frequency of the colors in C<@palette>. These
integers can range from 0 to 65355. Larger values or negative values
cause an error. The final argument, C<$full_quantize>, should be 1 for
RGB images or 0 for paletted images.

=head3 Experiments in quantization

This example program experiments with two ways to quantize a PNG
image, first of all using a completely random palette, and second
using colors picked from the image at random:

    
    use utf8;
    use FindBin '$Bin';
    use Image::PNG::Libpng ':all';
    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, \@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 ('', substr ($row, $x*$ch, $ch));
            push @p, {
                red => ord ($pix[0]),
                green => ord ($pix[1]),
                blue => ord ($pix[2]),
            };
        }
        return \@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, \%color;
        }
        return \@p;
    }

(This example is included as L<F<examples/q.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/q.pl>
in the distribution.)




L<examples/wave.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/wave.png> is included in the distribution.

=begin html

<p>The input image is this:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/wave.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/wave.png'>examples/wave.png</a>
</th>
</tr>
</table>

=end html




L<examples/random-wave.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/random-wave.png> is included in the distribution.

=begin html

<p>Completely random colors gives this kind of output:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/random-wave.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/random-wave.png'>examples/random-wave.png</a>
</th>
</tr>
</table>

=end html




L<examples/picked-wave.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/picked-wave.png> is included in the distribution.

=begin html

<p>Picked colors gives this kind of output:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/picked-wave.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/picked-wave.png'>examples/picked-wave.png</a>
</th>
</tr>
</table>

=end html


=head2 set_rgb_to_gray

    $png->set_rgb_to_gray ();

    $png->set_rgb_to_gray ($error_action, $red_weight, $green_weight);

Convert a PNG image from RGB (colored) to gray. See the libpng manual for details. 

Without arguments, the libpng default values are used for
C<$red_weight> and C<$green_weight>, and an error action of "none" is
chosen. If the error action is set to a value of
C<PNG_ERROR_ACTION_WARN> or C<PNG_ERROR_ACTION_ERROR>, pixels in the
RGB image where the R, G and B values are not equal will cause a
warning or error respectively. To get the default values for
C<$red_weight> or C<$green_weight>, use any negative value. See the libpng manual for details. 

If you choose C<PNG_ERROR_ACTION_NONE> you can find out whether there
were non-RGB pixels in your image using L</get_rgb_to_gray_status>.

This function corresponds to C<png_png_set_rgb_to_gray> in libpng with C<$error_action> having a
default value of C<PNG_ERROR_ACTION_NONE>, and C<$red_weight> and
C<$green_weight> both set to negative values.

=head3 Convert a colored image to gray

    
    use utf8;
    use FindBin '$Bin';
    use Image::PNG::Libpng ':all';
    use Image::PNG::Const ':all';
    
    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");

(This example is included as L<F<examples/rgb-to-gray.pl>|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/rgb-to-gray.pl>
in the distribution.)




L<examples/grayface.png|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/grayface.png> is included in the distribution.

=begin html

<p>This is the output:</p>

<!-- metacpan doesn't allow figure/figcaption tags. -->
<table>
<tr>
<td>
<img src="https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/grayface.png">
</td>
</tr>
<tr>
<th>
<a href='https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/examples/grayface.png'>examples/grayface.png</a>
</th>
</tr>
</table>

=end html


=head2 set_user_limits

    $png->set_user_limits ($width, $height);

This enables a user to override libpng's restrictions to one million
pixels in width and one million pixels in height for a PNG image.

This function corresponds to C<png_set_user_limits> in libpng

=head1 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.

=head2 color_type_channels

    my $channels = color_type_channels ('PNG_COLOR_TYPE_RGB_ALPHA');

Returns the number of channels (the number of components of one pixel)
of the specified color type.

=head2 copy_row_pointers

    $png->copy_row_pointers ($row_pointers);

This allows XS routines to directly set the value of the row pointers
for the PNG 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 PNG is written.

The Perl scalar C<$row_pointers> should be set up something like the
following (where C<rp> is the C pointer):

    RETVAL = newSViv (PTR2IV (rp));

It's extracted from the Perl scalar using

    rp = INT2PTR (png_byte **, SvIV (row_pointers));

where row_pointers is the C<SV *> corresponding to C<$row_pointers> in
the Perl script. See also L</set_row_pointers> which does the same
thing but takes ownership of the memory.

=head2 get_chunk

    my $timechunk = $png->get_chunk ('tIME');

Get the specified chunk. This produces a fatal error if asked for the
C<IDAT> (image data) chunk, use L</get_rows> instead. Returns C<undef>
if asked for an unknown chunk name.

This is used by L<pnginspect> to get the valid chunks. See also
L</set_chunk>.

=head2 get_internals

    my ($png_struct, $png_info) = get_internals ($png);

This function returns the C<png_structp> and C<png_infop> contained in
C<$png>. The return value is a list containing the C<png_structp> as
the first argument and the C<png_infop> as the second argument,
wrapped up as references to objects of type
C<Image::PNG::Libpng::png_struct> and C<Image::PNG::Libpng::png_info>.

To access the values of the pointers, use something like this:

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

An example exists in L<Image::PNG::Cairo>.    

=head2 get_tRNS_palette

    $png->get_tRNS_palette ();

This is not a libpng-equivalent function.

=head2 image_data_diff

    my $diff = image_data_diff ('a.png', 'b.png');

This returns the undefined value if the image data in F<a.png> is the
same as the image data in F<b.png>. 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. 

This function is used in testing this module. See also L</png_compare>.

=head2 libpng_supports

    if (libpng_supports ('iTXt')) {
        print "Your libpng supports international text.\n";
    }

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.

The possible arguments to C<libpng_supports> are:

=over


=item 16BIT





=item ALIGNED_MEMORY





=item ARM_NEON_API





=item BENIGN_ERRORS





=item BENIGN_READ_ERRORS





=item BENIGN_WRITE_ERRORS





=item bKGD


Does the libpng support the L</bKGD> chunk?


=item BUILD_GRAYSCALE_PALETTE





=item BUILTIN_BSWAP16





=item CHECK_FOR_INVALID_INDEX





=item cHRM


Does the libpng support the L</cHRM> chunk?


=item cHRM_XYZ


This is local to Image::PNG::Libpng and not a part of libpng itself.

It was necessary to extend libpng because the conditional compilation
macro for L</set_cHRM_XYZ> and L</get_cHRM_XYZ>, C<PNG_cHRM_SUPPORTED>
is defined (true) for old libpngs which do not actually contain these
functions.


=item CHUNK_CACHE_MAX


This is local to Image::PNG::Libpng and not a part of libpng itself.

It was necessary to extend libpng because the conditional compilation
macro for L</set_chunk_cache_max> and L</get_chunk_cache_max>,
C<PNG_USER_LIMITS_SUPPORTED> is defined (true) for old libpngs which
do not actually contain these functions.


=item CHUNK_MALLOC_MAX


This is local to Image::PNG::Libpng and not a part of libpng itself.

The reasons for this are identical to those for L</CHUNK_CACHE_MAX>.


=item COLORSPACE





=item CONSOLE_IO





=item CONVERT_tIME


This is related to two deprecated functions,
L</png_convert_from_time_t> and L</png_convert_from_struct_tm>.


=item CONVERT_tIME





=item EASY_ACCESS





=item ERROR_NUMBERS





=item ERROR_TEXT





=item eXIf


Does the libpng support the L</eXIf> chunk?


=item FIXED_POINT





=item FIXED_POINT_MACRO





=item FLOATING_ARITHMETIC





=item FLOATING_POINT





=item FORMAT_AFIRST





=item FORMAT_BGR





=item gAMA


Does the libpng support the L</gAMA> chunk?


=item GAMMA





=item GET_PALETTE_MAX


Does your libpng support L</get_palette_max>?


=item HANDLE_AS_UNKNOWN





=item HANDLE_AS_UNKNOWN





=item hIST


Does the libpng support the L</hIST> chunk?


=item iCCP


Does the libpng support the L</iCCP> chunk?


=item INCH_CONVERSIONS





=item INFO_IMAGE





=item IO_STATE





=item iTXt


Does the libpng support international text?


=item MIPS_MSA_API





=item MNG_FEATURES





=item oFFs


Does the libpng support the L</oFFs> chunk?


=item pCAL


Does the libpng support the L</pCAL> extension?


=item PEDANTIC_WARNINGS





=item pHYs


Does the libpng support the L</pHYs> chunk?


=item POINTER_INDEXING





=item POWERPC_VSX_API





=item PROGRESSIVE_READ





=item READ


Can libpng read PNGs?


=item READ_16_TO_8





=item READ_ALPHA_MODE


See L</set_alpha_mode>.


=item READ_BACKGROUND


See L</set_background>.


=item READ_BGR


See L</set_bgr>.


=item READ_COMPOSITE_NODIV





=item READ_COMPRESSED_TEXT





=item READ_EXPAND





=item READ_EXPAND_16





=item READ_FILLER





=item READ_GAMMA


See L</set_gamma>.


=item READ_GRAY_TO_RGB





=item READ_INTERLACING





=item READ_INT_FUNCTIONS





=item READ_INVERT





=item READ_INVERT_ALPHA





=item READ_OPT_PLTE





=item READ_PACK





=item READ_PACKSWAP





=item READ_QUANTIZE





=item READ_RGB_TO_GRAY





=item READ_SCALE_16_TO_8





=item READ_SHIFT





=item READ_STRIP_16_TO_8





=item READ_STRIP_ALPHA





=item READ_SWAP





=item READ_SWAP_ALPHA





=item READ_tEXt





=item READ_TRANSFORMS





=item READ_USER_TRANSFORM





=item READ_zTXt





=item SAVE_INT_32





=item SAVE_UNKNOWN_CHUNKS





=item sBIT


Does the libpng support the L</sBIT> chunk?


=item sCAL


Does the libpng support the L</sCAL> extension?  This actually tests
for the presence of the C<get_sCAL_s>/C<set_sCAL_s> functions, so its
behaviour is dependent on other factors for versions 1.2 and 1.4 of
libpng.


=item SEQUENTIAL_READ





=item SETJMP





=item SET_OPTION





=item SET_UNKNOWN_CHUNKS





=item SET_USER_LIMITS





=item SIMPLIFIED_READ





=item SIMPLIFIED_READ_AFIRST





=item SIMPLIFIED_WRITE





=item SIMPLIFIED_WRITE_AFIRST





=item SIMPLIFIED_WRITE_BGR





=item SIMPLIFIED_WRITE_STDIO





=item sPLT


Does the libpng support L</sPLT> chunks?


=item sRGB


Does the libpng support the L</sRGB> chunk?


=item STDIO





=item STORE_UNKNOWN_CHUNKS





=item TEXT


Does the libpng support text?


=item tEXt


Does the libpng support tEXt chunks?


=item tIME


Does the libpng support the L</tIME> chunk?


=item TIME_RFC1123





=item tRNS


Does the libpng support the L</tRNS> chunk?


=item UNKNOWN_CHUNKS


Does the libpng support unknown chunks (see L<Private chunks>)?


=item USER_CHUNKS





=item USER_LIMITS


Does the libpng support L</set_user_limits> and the related functions
L</get_user_width_max>, and L</get_user_height_max>?


=item USER_LIMITS





=item USER_MEM





=item USER_TRANSFORM_INFO





=item USER_TRANSFORM_PTR





=item WARNINGS





=item WRITE


Can libpng write pngs?


=item WRITE_BGR





=item WRITE_COMPRESSED_TEXT





=item WRITE_CUSTOMIZE_COMPRESSION


Does the libpng support L</set_compression_level> and similar functions?

⛐🤪⚠ It's not very clear that this returns a useful value,
since L</set_compression_level> seems to be in libpngs from at least
as far back as C<1.5.1>, and yet this macro was only added to libpng
in version C<1.6.13>.


=item WRITE_CUSTOMIZE_ZTXT_COMPRESSION


Does the libpng support L</set_text_compression_level> and similar functions?


=item WRITE_FILLER





=item WRITE_FILTER





=item WRITE_FLUSH





=item WRITE_FLUSH_AFTER_IEND





=item WRITE_INTERLACING





=item WRITE_INT_FUNCTIONS





=item WRITE_INVERT





=item WRITE_INVERT_ALPHA





=item WRITE_OPTIMIZE_CMF





=item WRITE_PACK





=item WRITE_PACKSWAP





=item WRITE_SHIFT





=item WRITE_SWAP





=item WRITE_SWAP_ALPHA





=item WRITE_TRANSFORMS





=item WRITE_USER_TRANSFORM





=item WRITE_WEIGHTED_FILTER





=item zTXt


Does the libpng support C<zTXt> chunks?


=back

=head2 png_compare

    if (png_compare ('a.png', 'b.png') == 0) {
	print "The PNGs are the same.\n";
    }

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>. This
does not compare to see if the PNG files "look like" each other, but
whether each pixel contains exactly the same values. Please see
L<Image::Similar> for a looser comparison of images.

This uses the "expand" 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> for
an example of comparing an RGB and a grayscale image.

=head2 read_struct

    if ($png->read_struct ()) {
         warn "Can't write this, use copy_png to copy it";
    }

This returns a true value if C<$png> was created with
L</create_read_struct> or allied functions like L</read_from_scalar>,
and a false value if C<$png> was created with L</create_write_struct>
or allied functions like L</copy_png>.

=head2 set_chunk

    $png->set_chunk ('tIME', $timechunk);

Set the specified chunk. This produces a fatal error if given an
C<IDAT> (image data) chunk, use L</set_rows> instead. This produces a
fatal error if given an unknown chunk name.

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 C<tIME> chunk as described under L</set_tIME> and
L</get_tIME>.

This is essentially a convenience function for the benefit of
L</copy_png> which, together with L</get_valid>, enables the PNG
chunks to be copied in a loop rather than one-by-one.

=head2 set_image_data

    $png->set_image_data ($image_data);

Set the internal image data pointer to C<$image_data>. C<$image_data>
should contain a pointer to memory stored as an C<SvIV> allocated with
C<Newx> or a similar function. This transfers ownership of the memory
to C<$png>, which will free it with C<Safefree> when C<$png> is
destroyed. Calling this function with any value does not actually
change the content of the PNG image itself.

=head2 set_row_pointers

    $png->set_row_pointers ($row_pointers);

This sets the rows of the PNG image to C<$row_pointers> using
C<png_set_rows>. C<$row_pointers> must contain a pointer to memory
stored as an SvIV allocated with a Perl memory allocator like C<Newx>
or a similar function. This also transfers ownership of the memory to
C<$png>, which will free it with C<Safefree> when C<$png> is
destroyed. See also L</copy_row_pointers>, which does the same thing
except for the freeing of the memory.

=head2 split_alpha

    my $split = $png->split_alpha ();
    my $alpha = $split->{alpha};
    my $color = $split->{data};

Split the alpha channel away from the other data. This only works for
images with color types C<PNG_COLOR_TYPE_RGB_ALPHA> and
C<PNG_COLOR_TYPE_GRAY_ALPHA>. This is not part of the libpng API. This
function was added to this module to assist the author of
L<PDF::Builder> due to problems with very slow access to PNG images
using Perl.

To remove the alpha channel from an image, use L</set_background>. See
L</Setting the background> for an example. You can also use the
transform C<PNG_TRANSFORM_STRIP_ALPHA> in L</read_png_file>, or
L</set_strip_alpha>, but this may leave spurious pixel values in
transparent parts of the image.

=head1 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:

    use Image::PNG::Libpng ':all';

This includes all the methods, which can then be used with the C<$png>
argument as the first argument.

=head1 Differences from libpng

The functions in Image::PNG::Libpng are closely based on those of
libpng, with the following differences.

=head2 No info structure

This module does not use the "info" structure of libpng. Almost all
libpng functions require two initial arguments, a C<png_structp> and a
C<png_infop>. However, in Image::PNG::Libpng, both the "png" and the
"info" are contained in the object. People who need access to the
internals of an C<Image::PNG::Libpng> object (C programmers or XS
programmers) can use L</get_internals> to access them.

This module does not support the "end info" structure of PNGs when
writing, although these are handled when reading.

=head2 Unused arguments omitted

This module eliminates unevaluated arguments of libpng. For example,
libpng requires the user to pass a pointer to a C<png_struct> to call
the libpng version number function, (see L</get_libpng_ver>), but it
actually ignores this structure. There are many similar instances of
unevaluated arguments, which have all been eliminated from this
module.

If you are interested in exactly which libpng arguments are omitted,
you can find each instance L<in the file C<perl-libpng.c> in the top directory of the distribution|https://fastapi.metacpan.org/source/BKB/Image-PNG-Libpng-0.59/perl-libpng.c> in the macro
C<UNUSED_ZERO_ARG>.

=head2 Useless functions omitted

The functions from libpng which don't do anything have been omitted
from this module.

=head2 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 C<png_get_rows> (see
L</get_rows>) uses the return value of the function to return an array
of pointers, but C<png_get_PLTE> (see L</get_PLTE>) uses a pointer
reference to return an array of pointers, and the return value to
indicate errors.

Image::PNG::Libpng uses only the return value. Errors and
non-existence are indicated by a return value of the undefined
value.

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.

=head2 No destructors

Freeing the memory allocated by L</create_read_struct> and
L</create_write_struct> is automatically handled by Perl.

Older versions of this module (pre-0.18) had functions called
C<destroy_read_struct> and C<destroy_write_struct> 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.

=head2 Other unimplemented parts of libpng

=head3 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 C<png_malloc>
and C<png_free> or other libpng memory handling functions.

=head3 Error handling functions

This module does not offer an interface to C<png_error> and
C<png_get_error_ptr> or any of the other error handling functions of
libpng. It redirects the error and warning handlers to Perl's error
stream.

=head3 Input and output manipulation functions

This module does not offer a direct interface to C<png_set_write_fn>
and C<png_set_read_fn>. However, it is possible to use their
functionality to access Perl data via L</read_from_scalar> and
L</write_to_scalar>.

=head3 Fixed point functions

There is currently no support for the PNG fixed point functions in
this Perl module, the functions with suffix C<_fixed>.

=head2 List of unsupported functions

The following functions from the libpng API are unsupported by this
module.

=over


=item png_benign_error




💔 See L</Error handling functions>.

=item png_build_grayscale_palette


⛐🤪⚠ Undocumented function, but it is part of the public API. 
See L<https://github.com/glennrp/libpng/issues/353>.

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.

=item png_chunk_benign_error




💔 See L</Error handling functions>.

=item png_chunk_warning




💔 See L</Error handling functions>.

=item png_convert_from_struct_tm

👎 Deprecated in libpng. 
This function related to the C<tIME> chunk is deprecated in libpng
1.7.

=item png_convert_from_time_t

👎 Deprecated in libpng. 
This function related to the C<tIME> chunk is deprecated in libpng 1.7.

=item png_convert_to_rfc1123

👎 Deprecated in libpng. 
This function related to the C<tIME> chunk is deprecated in libpng 1.7.

=item png_convert_to_rfc1123_buffer


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

This function is related to the C<tIME> chunk; it seems fairly
superfluous with the many other ways to manipulate time strings
already in Perl.

=item png_data_freer




🐘 See L</Memory management functions>.

=item png_free




🐘 See L</Memory management functions>.

=item png_free_data




🐘 See L</Memory management functions>.

=item png_get_cHRM_XYZ_fixed




🍓 See L</Fixed point functions>.

=item png_get_cHRM_fixed




🍓 See L</Fixed point functions>.

=item png_get_compression_type

🙃🤡 See L</Useless functions omitted>.  
Useless function which returns 0 since there is only one type of
compression.

=item png_get_copyright


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

This function gives you the copyright string for libpng.

=item png_get_current_pass_number




=item png_get_current_row_number




=item png_get_error_ptr




💔 See L</Error handling functions>.

=item png_get_filter_type

🙃🤡 See L</Useless functions omitted>.  
This function returns the value of the unused field C<filter_type> in
the PNG header, which is always 0. See L<Unused arguments omitted>.

=item png_get_gAMA_fixed




🍓 See L</Fixed point functions>.

=item png_get_header_ver


This function was omitted from this module because it merely
duplicates another function.

Identical to L</get_libpng_ver>.

=item png_get_header_version


This function was omitted from this module because it merely
duplicates another function.

Identical to L</get_libpng_ver>.

=item png_get_io_chunk_type




=item png_get_io_ptr




=item png_get_io_state




=item png_get_mem_ptr




=item png_get_pHYs_dpi




=item png_get_pixel_aspect_ratio




=item png_get_pixel_aspect_ratio_fixed




🍓 See L</Fixed point functions>.

=item png_get_pixels_per_inch




=item png_get_pixels_per_meter




=item png_get_progressive_ptr


Incremental reading of PNGs is not handled yet.

=item png_get_sCAL_fixed




🍓 See L</Fixed point functions>.

=item png_get_signature


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

Returns the PNG signature of a PNG you read in.

=item png_get_uint_31


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

This produces an error if the unsigned integer argument is too big for
a 31 bit number.

=item png_get_user_chunk_ptr




=item png_get_user_height_max




=item png_get_user_transform_ptr




=item png_get_x_offset_inches




=item png_get_x_offset_inches_fixed




🍓 See L</Fixed point functions>.

=item png_get_x_offset_microns




=item png_get_x_offset_pixels


Duplicates L</get_oFFs>.

=item png_get_x_pixels_per_inch




=item png_get_x_pixels_per_meter


Duplicates L</get_oFFs>.

=item png_get_y_offset_inches




=item png_get_y_offset_inches_fixed




🍓 See L</Fixed point functions>.

=item png_get_y_offset_microns




=item png_get_y_offset_pixels


Duplicates L</get_oFFs>.

=item png_get_y_pixels_per_inch




=item png_get_y_pixels_per_meter


Duplicates L</get_oFFs>.

=item png_handle_as_unknown




=item png_image_begin_read_from_file




=item png_image_begin_read_from_stdio




=item png_image_finish_read




=item png_image_free




🐘 See L</Memory management functions>.

=item png_image_write_to_file




=item png_image_write_to_memory




🐘 See L</Memory management functions>.

=item png_image_write_to_stdio




=item png_process_data




=item png_process_data_pause




=item png_process_data_skip




=item png_progressive_combine_row




=item png_read_row




=item png_read_rows




=item png_reset_zstream

👎 Deprecated in libpng. 
Resets the zstream of the zlib instance used for the image data.

=item png_save_int_32


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

Writes a 32 bit signed number into an octet buffer. Perl programmers
will probably use C<pack> for this.

=item png_save_uint_16


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

Writes a 16 bit number into an octet buffer. Perl programmers
will probably use C<pack> for this.

=item png_save_uint_32


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.

Writes a 32 bit unsigned number into an octet buffer. Perl programmers
will probably use C<pack> for this.

=item png_set_alpha_mode_fixed




🍓 See L</Fixed point functions>.

=item png_set_background_fixed




🍓 See L</Fixed point functions>.

=item png_set_benign_errors




💔 See L</Error handling functions>.

=item png_set_cHRM_XYZ_fixed




🍓 See L</Fixed point functions>.

=item png_set_cHRM_fixed




🍓 See L</Fixed point functions>.

=item png_set_check_for_invalid_index




=item png_set_compression_method

🙃🤡 See L</Useless functions omitted>.  
This function in libpng corresponds to the unused
C<method> parameter of zlib functions like C<deflateInit2>. See
L</zlib documentation>. The libpng function just produces a warning if
the user sets the value to anything but 8, the value of the macro
C<Z_DEFLATED>, and then lets zlib produce an error.

=item png_set_crc_action




💔 See L</Error handling functions>.

=item png_set_error_fn




💔 See L</Error handling functions>.

=item png_set_filter_heuristics

👎 Deprecated in libpng. 


=item png_set_filter_heuristics_fixed




🍓 See L</Fixed point functions>.

=item png_set_flush




=item png_set_gAMA_fixed




🍓 See L</Fixed point functions>.

=item png_set_gamma_fixed




🍓 See L</Fixed point functions>.

=item png_set_interlace_handling


Incremental writing is not handled.

=item png_set_invalid




🐘 See L</Memory management functions>.

=item png_set_longjmp_fn


⛐🤪⚠ Undocumented function, but it is part of the public API. 


=item png_set_mem_fn




🐘 See L</Memory management functions>.

=item png_set_option




=item png_set_progressive_read_fn




=item png_set_read_status_fn




=item png_set_read_user_chunk_fn




=item png_set_read_user_transform_fn




=item png_set_sCAL_fixed




🍓 See L</Fixed point functions>.

=item png_set_sRGB_gAMA_and_cHRM




=item png_set_shift




=item png_set_sig_bytes


👎🐪 This function was deliberately omitted from this module because it doesn't seem useful for Perl programmers.



=item png_set_strip_error_numbers

🙃🤡 See L</Useless functions omitted>.  
According to the libpng manual, "we never got around to actually
numbering the error messages", so I assume this is not very useful.

=item png_set_text_compression_method

🙃🤡 See L</Useless functions omitted>.  
Unsupported for the same reasons as
L</png_set_compression_method>.

=item png_set_unknown_chunk_location


This is related to some kind of bug in version 1.5 and previous of
libpng.

=item png_set_user_transform_info




=item png_set_write_status_fn




💔 See L</Error handling functions>.

=item png_set_write_user_transform_fn




=item png_start_read_image




=item png_write_chunk




=item png_write_chunk_data




=item png_write_chunk_end




=item png_write_chunk_start




=item png_write_flush




=item png_write_info_before_PLTE




=item png_write_row




=item png_write_rows




=item png_write_sig





=back

This is an exhaustive list of unsupported libpng API functions,
extracted from the libpng source code using F<util/api.pl> in this
module's repository.

=head2 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
C<PNG_TEXT_SUPPORTED>. 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.

Currently we test this module against vanilla libpng versions
C<1.2.59>, C<1.4.22>, C<1.5.30>, C<1.6.47>, and C<1.6.45> before
releases. There doesn't seem to have been a 1.3 or a 1.1 version of
libpng. See
L<http://www.libpng.org/pub/png/pngnews.html|http://www.libpng.org/pub/png/pngnews.html>. Versions
1.0 and earlier of libpng are not tested against.

The following issues with older libpng versions may affect users of
this module:

=head3 cHRM chunk

The L</get_cHRM_XYZ> and L</set_cHRM_XYZ> functions for
the L</cHRM> 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> and L</set_cHRM> functions,
which are present on older versions of libpng. Because of this, this
module includes its own protection macro, accessible via
L</libpng_supports> as L</cHRM_XYZ>.  These functions are disabled for
libpng versions earlier than 1.5.5.

=head3 chunk_cache_max

The functions L</set_chunk_cache_max> and L</get_chunk_cache_max> are
not protected by a libpng macro, so this module includes its own
protection macro, accessible via L</libpng_supports> as
L</CHUNK_CACHE_MAX>. These functions are disabled for libpng versions
earlier than 1.4.0.

=head3 Compression level

Versions of libpng up to 1.5 behave erratically when
L</set_compression_level> or other C<set_compression_*> 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. 

=head3 Compression level and zlib-ng

Some people have compiled libpng with a new version of zlib known as
zlib-ng. This gives different values for compression than the original
zlib. On versions of this module earlier than 0.58, this caused some
unimportant but annoying test failures where this module was making
exact size comparisons. See
L<https://github.com/benkasminbullock/image-png-libpng/issues/40>. As
far as we know, there is no way to detect whether zlib-ng is being
used from Perl, so to support the use of zlib-ng, these tests have
been switched off. The disabled tests can be restored by setting the
environment variable C<ORIGINAL_ZLIB> to a true value, if you want
them.

    ORIGINAL_ZLIB=1 prove t/*.t

=head3 sCAL chunk

Support for the sCAL chunk is disabled within this module
for pre-1.6 versions of libpng.

=head3 Text chunk handling

Versions of libpng up to 1.6.3 produce erratic results
with C<iTXt> (international text) chunks. Testing of text-related
chunks is disabled by this Perl module for pre-1.6.13 versions of
libpng.

=head2 Not all constants are available

Some of the libpng constants are defined in F<pnglibconf.h> or
F<pngconf.h> but L<Image::PNG::Const> only looks at F<png.h> to make
its constants. Because of this, some constant values like
C<PNG_Z_DEFAULT_COMPRESSION> aren't currently available in
L<Image::PNG::Const>. This probably should be fixed to extract the
constants from the other files in a future version.

=head1 STANDALONE SCRIPT

A standalone script, L<pnginspect>, is installed with the
distribution. It prints out the contents of the chunks of the PNG file
on the command line.

=head1 SEE ALSO

=head2 The PNG specification

L<The PNG specification|http://www.w3.org/TR/PNG/> (link to W3
consortium) explains the details of the PNG format.


=head3 PNG The Definitive Guide by Greg Roelofs

The book "PNG - The Definitive Guide" by Greg Roelofs, published in
1999 by O'Reilly is available online at
L<http://www.faqs.org/docs/png/> or L<http://www.libpng.org/pub/png/book/>.

=head2 The libpng documentation

=over

=item Official documentation

The starting point is the plain text libpng manual at
L<http://libpng.org/pub/png/libpng-manual.txt> and the manual page
libpng.3, which you can read using "man 3 libpng".

⛐🤪⚠ The documentation which comes with libpng is rather
sketchy. See L</Differences from libpng>. 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 F<png.h>.  In some cases, you need to look at the source code of
the library.

=item Other documentation

There is a collection of function definitions under the title
"Interface Definitions for libpng12" at
L<https://refspecs.linuxbase.org/LSB_4.0.0/LSB-Desktop-generic/LSB-Desktop-generic/libpng12man.html>
as part of the "Linux Standard Base Desktop Specification". 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.

=back

=head2 zlib documentation

See L<https://zlib.net/manual.html> for the zlib documentation.

=head2 Other Perl modules on CPAN

These other modules may also be useful.

=over

=item Alien::PNG

L<Alien::PNG> claims to be a way of "building, finding and using PNG
binaries". 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.

=item Imager

L<Imager>, L<Imager::Files> and C<Imager::Files::PNG> 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.

=item Image::ExifTool

L<Image::ExifTool> is a pure Perl (doesn't require a C compiler)
solution for accessing the text segments of images. It supports PNG
text segments.

=item Image::Info

L<Image::Info> gets information out of images. It supports PNG 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.

=item Image::PNG::Rewriter

L<Image::PNG::Rewriter> is a utility for unpacking and recompressing
the IDAT (image data) part of a PNG image. The main purpose seems to
be to recompress the image data with the module author's other module
L<Compress::Deflate7>. At the time of writing, that only works with
Perl versions 5.12 or later.

=item Image::Pngslimmer

L<Image::Pngslimmer> reduces the size of dynamically created PNG
images. It's very, very slow at reading PNG data, but seems to work
OK.

=item Image::PNG::Write::BW

L<Image::PNG::Write::BW> writes black and white PNGs from strings.

=item Image::Size

If you only need to read the sizes of images, L<Image::Size> works
with PNG and other image formats.

=back




=head1 AUTHOR

Ben Bullock, <benkasminbullock@gmail.com>

=head1 COPYRIGHT & LICENCE

This package and associated files are copyright (C) 
2011-2025
Ben Bullock.

You can use, copy, modify and redistribute this package and associated
files under the Perl Artistic Licence or the GNU General Public
Licence.




