[%- libpng = "=head3 Correspondence to libpng" -%] [%- noinfo = "No info structure" -%] [%- xnoinfo = BLOCK -%] "[% noinfo %]" [%- END -%] [%- noinfoxref = BLOCK -%] It does not take a second "info" argument. [% noinfo -%] [%- END -%] [% transform_list = BLOCK %] =over [% FOR transform IN transforms %] =item [% transform.name %]
[% transform.text %] [% END %] =back [% END %] [% libpngdoc = "The libpng documentation" %] [% pngspec = "The PNG specification" %] [% MACRO spec(subsection) BLOCK -%] "/www.w3.org/TR/PNG/#[%- subsection -%]" in http: [%- END %] [%- wfirstpng = BLOCK -%] The first argument, $png
, is a writeable PNG structure created with "create_write_struct". [%- END -%] [%- rfirstpng = BLOCK -%] The first argument, $png
, is a PNG structure created with "create_read_struct". [%- END -%] [%- MACRO cor BLOCK -%] [% libpng %]
This function corresponds to png_[% fn %]
[%- END %] [% source_link = "http://cpansearch.perl.org/src/" _ config.author_pause _ "/" _ config.base_hyphen _ "-" _ config.version _ "/" %] [% perl_libpng_c = "in the file perl-libpng.c
in the top directory of the distribution" %] [% unused_title = "Unused arguments omitted" %] [% unused = "See " _ unused_title _ "." %]
NAME
[% config.base %]::Libpng - Perl interface to the C library "libpng".
[% INCLUDE "warning" %]
SYNOPSIS
use [% config.base %]::Libpng;
my $png = [% config.base %]::Libpng::create_read_struct ();
open my $file, '<:raw', 'nice.png';
[% config.base %]::Libpng::init_io ($png, $file);
[% config.base %]::Libpng::read_png ($png);
close $file;
[% config.base %]::Libpng::destroy_read_struct ($png);
[% config.base %]::Libpng enables Perl to use the "libpng" library for reading and writing files in the PNG (Portable Network Graphics) format.
[% config.base %]::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 an easy way to access PNG files, try the companion module "[% config.base %]", which offers a simplified interface to the functions in this module.
For those who are familiar with libpng, to know what the differences between this module and libpng are, please go to the section "Differences from libpng".
FUNCTIONS
create_read_struct
my $png = create_read_struct ();
Create a structure for reading a PNG.
[% cor(fn="create_read_struct") %] plus create_info_struct
(see [% xnoinfo %]) with the error and warning handler variables set up to use Perl's error reporting.
create_write_struct
my $png = create_write_struct ();
Create a structure for writing a PNG.
[% cor(fn="create_write_struct") %] plus create_info_struct
(see [% xnoinfo %]) with the error and warning handler variables set up to use Perl's error reporting.
destroy_read_struct
destroy_read_struct ($png);
This frees the memory associated with $png
.
[% cor(fn="destroy_read_struct") %], without the info and end_info arguments. See [% xnoinfo %].
destroy_write_struct
destroy_write_struct ($png);
This frees the memory associated with $png
.
[% cor(fn="destroy_write_struct") %].
Input and output
init_io
open my $file, "<", 'nice.png';
init_io ($png, $file);
Set the file which $png
reads or writes to $file
. $file
must be an already-opened Perl file handle. If $png
was created with create_write_struct, $file
must be opened for writing. If $png
was created with create_read_struct, $file
must be open for reading.
Since PNG files are binary files, it's safest to specify the "raw" pragma or use "binmode" with the file in order 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;
[% cor(fn="init_io") %], with a Perl file handle substituting for the C FILE *
.
read_from_scalar
my $png = create_read_struct ();
read_from_scalar ($png, $string);
This subroutine sets the image data of $png
to be the contents of a Perl scalar variable $string
. [% rfirstpng %] 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 LWP::Simple;
my $image_data = get 'http://www.example.com/example.png';
# Now $image_data contains the PNG file
my $png = create_read_struct ();
read_from_scalar ($png, $image_data);
# Now $png contains the PNG information from the image.
[% libpng %]
This uses png_set_read_fn
to set the reading function of $png
to a routine which reads data from Perl scalars. It then uses png_read_png
to read all the data.
The C function which does this is called perl_png_scalar_read
, [% perl_libpng_c %].
See also "Input/output manipulation functions".
write_to_scalar
my $image_data = write_to_scalar ($png);
This writes the PNG image data in $png
into a Perl scalar. So, for example,
my $img = write_to_scalar ($png);
open my $output, ">:raw", "test-write-scalar.png";
print $output $img;
close $output;
creates a PNG file called test-write-scalar.png
from the PNG data in $png
.
[% wfirstpng %] The return value of the subroutine is the Perl scalar containing the image data.
[% libpng %]
This subroutine doesn't correspond directly to anything in libpng. It uses png_set_write_fn
to set the writing function of $png
to be its own function, which writes data to the Perl scalar.
The C function which does this is called perl_png_scalar_write
, [% perl_libpng_c %].
See also "Input/output manipulation functions".
read_png
read_png ($png);
Read the entire PNG file. You can provide a second argument containing transformations to apply to the image:
use [% config.base %]::Const qw/PNG_TRANSFORM_STRIP_ALPHA/;
read_png ($png, PNG_TRANSFORM_STRIP_ALPHA);
In the absence of any third argument, the default value of PNG_TRANSFORM_IDENTITY
is applied. The possible transformations which can be applied are
[%- transform_list -%]
[% cor(fn="read_png") %] with a default value for the third argument. The fourth, unused, argument to png_read_png
does not need to be supplied. [% unused %]
[% noinfoxref %]
write_png
write_png ($png);
This writes the PNG to the file stream. Before using this, open a file for writing and set it up with "init_io". For example,
open my $output, ">:raw", 'out.png';
init_io ($png, $output);
write_png ($png);
close $output;
There is an optional second argument consisting of transformations to apply to the PNG image before writing it:
use [% config.base %]::Const qw/PNG_TRANSFORM_STRIP_ALPHA/;
write_png ($png, PNG_TRANSFORM_STRIP_ALPHA);
The transformations which can be applied are as follows:
[% transform_list %]
(NOTE: this list might be wrong, it is just copied from the linux lib pages & the linux lib pages have different transformations for the read and write png functions.)
[% cor(fn="write_png") %].
The image header
See [% spec("11IHDR") %] for information on the PNG standards for the image header.
sig_cmp
if (sig_cmp ($should_be_png)) {
print "Your data does not have a PNG signature.\n";
}
This subroutine looks at $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.
[% cor(fn="sig_cmp") %], with default arguments of 0 and 8 if second and third arguments are not supplied.
get_valid
my $valid = get_valid ($png);
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
[% rfirstpng %]
[% cor(fn = "get_valid") %], with the difference being that the return value is a hash containing a key for each possible chunk.
get_IHDR
my $IHDR = get_IHDR ($png);
Read the IHDR information from the PNG file. The return value is a reference to a hash.
The hash reference contains the following fields:
[% FOR field IN ihdr_fields -%] [%- IF ! field.unused %] =item [% field.name %]
[%- IF field.text %] [% field.text %] [%- END -%] [%- IF field.retvalues -%] This can take the values [% field.retvalues.join (", ") %]. [%- END %] [%- END %]
[%- END %]
So, for example, to get the width and height of an image,
my $ihdr = get_IHDR ($png);
printf "Your image is %d x %d\n", $ihdr->{width}, $ihdr->{height};
[% cor(fn="get_IHDR") %], with a single Perl hash reference used instead of the several pointers to integers used in libpng.
set_IHDR
my $ihdr = { width => 10, height => 10, bit_depth => 8,
color_type => PNG_COLOR_TYPE_RGB };
set_IHDR ($png, $ihdr);
Set the IHDR chunk (the image header) of the PNG image.
[% wfirstpng %] The second argument is a hash with the following values:
[% FOR field IN ihdr_fields -%] [%- IF ! field.unused %] =item [% field.name %]
[%- IF field.text %] [% field.text %] [%- END -%] [%- IF field.retvalues -%] This can have the values [% field.retvalues.join (", ") %]. [%- END %] [%- END %]
[%- END %]
Other fields in the hash are ignored.
[% cor(fn="set_IHDR") %], with a single Perl hash reference used instead of the seven integers. The variables [% FOR field IN ihdr_fields -%] [%- IF field.unused -%] [%- field.name %]
, [% END -%] [%- END %] in png_set_IHDR
can only take one possible value, so the routine ignores them. [% unused %]
get_color_type
my $color_type;
[% config.base %]::Libpng::get_color_type ($png, \$color_type);
This returns an integer value. If you want to get a name for the colour type, use "color_type_name".
[% cor(fn="get_color_type") %].
PNG timestamps
See [% spec("11timestampinfo") %] for information on the PNG standards for time stamp information.
get_tIME
my $time = [% config.base %]::Libpng::get_tIME ($png);
if ($time && $time->{year} < 2005) {
warn "Your PNG is now getting old. Don't forget to oil it to prevent rust.";
}
This subroutine gets the modification time value of the PNG image and puts it into fields labelled "year", "month", "day", "hour", "minute" and "second" of the hash reference given as the third argument. If there is no modification time it returns an undefined value.
[% cor(fn="get_tIME") %], with a Perl hash reference substituted for the C struct png_timep
used in libpng.
set_tIME
# Set the time to "now"
set_tIME ($png);
# Set the time
set_tIME ($png, {year => 1999, month => 12});
Set the modification time of the PNG to the hash value given by the second argument. If the second argument is omitted, the time is set to the current time. If any of year, month, day, hour, minute or second is omitted, these are set to zero.
[% cor(fn="set_tIME") %], with a Perl hash reference substituted for the C struct png_timep
used in libpng.
Text chunks
See [% spec("11textinfo") %] for information on the PNG standards for text information.
get_text
my $text_chunks = [% config.base %]::Libpng::get_text ($png);
This subroutine gets all the text chunks in the PNG image and returns them as an array reference. Each element of the array represents one text chunk. The element representing one chunk is a hash reference with the text fields such as "key", "lang_key", "compression" taken from the PNG's information.
The text data is uncompressed by libpng. If it is international text, [% config.base %]::Libpng automatically puts it into Perl's internal Unicode encoding (UTF-8).
Note that PNG international text is required to be in the UTF-8 encoding, and non-international text is required to contain whitespace and printable ASCII characters only. See "[% pngspec %]" for more on the requirements of a PNG text section.
[% cor(fn="get_text") %], with a Perl array of hash references substituted for the C array of structs used in libpng.
set_text
set_text ($png, $text_chunks);
This sets the text chunks in an array reference $text_chunks
. [% wfirstarg %]. If you call it more than once, the chunks are appended to the existing ones rather than replacing them.
set_text ($png, [{compression => PNG_TEXT_COMPRESSION_NONE,
keyword => "Copyright",
text => "Copyright (C) 1997 The Dukes of Hazzard",
}]);
[% cor(fn="set_text") %].
Private chunks
set_keep_unknown_chunks
use Image::PNG::Const 'PNG_HANDLE_CHUNK_ALWAYS';
set_keep_unknown_chunks ($png, PNG_HANDLE_CHUNK_ALWAYS);
Tell libpng not to discard unknown chunks when reading the file.
get_unknown_chunks
my $private_chunks = get_unknown_chunks ($png);
# 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. You need to call "set_keep_unknown_chunks" with an appropriate value before reading the file, otherwise libpng discards unknown chunks when reading the file.
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.
Each member hash reference has the following keys:
[% field.description %] [% END %] =back
The "size" field of the PNG structure is not stored, because the "data" member of the hash contains information on its length.
[% cor(fn="get_unknown_chunks") %]
set_unknown_chunks
set_unknown_chunks ($png, $private_chunks);
[% cor(fn="set_unknown_chunks") %]
Helper functions
These helper functions assist the programmer in the transition from libpng, which uses C conventions such as upper case macros standing for numerical constants and C structures, to Perl's string-based conventions.
color_type_name
my $name = [% config.base %]::Libpng::color_type_name ($color_type);
Given a numerical colour type in $color_type
, return the equivalent name. The name is in upper case, with words separated by underscores, as in RGB_ALPHA
.
[% libpng %]
This function does not correspond to anything in libpng. The names of the colour types are taken from those defined in the libpng header file, png.h
.
text_compression_name
my $name = [% config.base %]::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
For some reason the compression field is also used to store the information about whether the text is "international text" in UTF-8 or not.
[% libpng %]
This function does not correspond to anything in libpng. The names of the text compression types are based on those in png.h
, but without the word "COMPRESSION", so for example the libpng constant PNG_ITXT_COMPRESSION_zTXt
corresponds to a return value of ITXT_zTXt
.
Library version functions
get_libpng_ver
my $libpng_version = [% config.base %]::Libpng::get_libpng_ver ();
This function returns the version of the libpng library which the module is using.
[% cor(fn="get_libpng_ver") %]. However, it doesn't require the png_structp
argument of the C function. See "About libpng".
access_version_number
my $libpng_version_number = [% config.base %]::Libpng::access_version_number ();
This function returns the version of the libpng library which the module is using as an integer number.
[% cor(fn="access_version_number") %].
Palettes
See [% spec("11PLTE") %] for information on the PNG standards for the palette chunk.
get_PLTE
my $colours = [% config.base %]::Libpng::get_PLTE ($png);
# Get the green value of the twentieth entry in the palette.
my $green = $colours->[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 colour 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 [% config.base %]::Const ':all';
my $color_type = [% config.base %]::Libpng::get_color_type ($png);
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 "get_valid".
[% cor(fn="get_PLTE") %].
set_PLTE
set_PLTE ($png, $palette);
Set the palette of $png
. [% wfirstpng %] The second 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,
set_PLTE ($png, [{red => 1, green => 99, blue => 0x10},
{red => 0xFF, green => 0xFF, blue => 0xFF}]);
creates a palette with two entries in $png
.
[% cor(fn="set_PLTE") %].
Image data
get_rows
my $rows = [% config.base %]::Libpng::get_rows ($png);
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, $rows
in the example, is an array reference with a number of rows equal to the height of the PNG image. Each row consists of the actual binary data, which you will need to cut out using a routine like substr or unpack to access pixel values. This binary data is likely to contain bytes equal to zero.
You can get the number of bytes in each row using "get_rowbytes".
Each row is a Perl string. Perl terminates each row of data with an extra zero byte at the end.
[% cor(fn="get_rows") %].
set_rows
set_rows ($png, \@rows);
Set the rows of data to be written in to the PNG to @rows
. @rows
needs to contain at least the same number of rows of data as the height of the PNG image, and the length of each entry needs to be at least the width of the entry times the number of bytes required for each pixel.
Please also note that this is a bit unreliable. See "set_rows is unreliable". I recommend that you only use this immediately before calling "write_png" in order to prevent problems occuring.
[% cor(fn="set_rows") %].
get_rowbytes
my $bytes_in_a_row = get_rowbytes ($png);
[% cor(fn="get_rowbytes") %].
Compression and filtering
set_filter
use Image::PNG::Const 'PNG_FILTER_NONE';
set_filter ($png, PNG_FILTER_NONE);
This sets the filters which are allowed to be used for writing a PNG image. The possible values are
These can be combined using |
(logical or):
use Image::PNG::Const ':all';
set_filter ($png, PNG_FILTER_UP | PNG_FILTER_AVG);
Please see [% spec("9Filter-types") %] for the meanings of these filter types.
[% cor(fn="set_filter") %] with the second (unused) argument omitted. [% unused %]
Other chunks
get_bKGD
Get the bKGD (background) chunk of the image.
[% cor(fn="get_bKGD") %] with a hash function instead of a png_color
struct.
set_bKGD
Set the bKGD (background) chunk of the image.
[% cor(fn="set_bKGD") %] with a hash function instead of a png_color
struct.
get_cHRM
Get the cHRM chunk as a hash.
The keys of the hash are
The values of the hash are floating point numbers between 0 and 1.
See section "4.2.2.2. cHRM Primary chromaticities" of the PNG specification.
[% cor(fn="get_cHRM") %] with a hash function instead of the double
arguments. The hash key names correspond to the names of the double
arguments in libpng.
set_cHRM
Set the cHRM chunk from a hash.
The keys of the hash are
The values of the hash are floating point numbers between 0 and 1.
See section "4.2.2.2. cHRM Primary chromaticities" of the PNG specification.
[% cor(fn="set_cHRM") %] with a hash function instead of the double
arguments.
EXPORTS
Nothing is exported by default, but all the functions in this module can be exported on request. The export tag 'all' exports everything in the module:
use [% config.base %]::Libpng ':all';
# Now everything in the module has been imported
Differences from libpng
The procedures in [% config.base %]::Libpng are closely based on those of libpng, with the following differences.
[% noinfo %]
This module, [% config.base %]::Libpng
does not use the "info" structure of libpng. Almost all libpng functions require two initial arguments, a png_structp
and a png_infop
. However, in [% config.base %]::Libpng, both the "png" and the "info" are contained in the first argument to each function.
[% unused_title %]
This module eliminates all the unevaluated arguments of libpng. For example, libpng requires the user to pass a pointer to a png_struct
before calling the library to ask for its version number (see "get_libpng_ver"), but the library ignores the this structure anyway, so this module does not duplicate this. 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 [% perl_libpng_c %] in the macro UNUSED_ZERO_ARG
.
Function return values are used to return values
In libpng, some functions return results using references, and some return results using the function's return value. For example png_get_rows
(see "get_rows") uses the return value of the function to return an array of pointers, but png_get_PLTE
(see "get_PLTE") uses a pointer reference to return an array of pointers, and the return value to indicate errors.
[% config.base %]::Libpng uses only the return value. Errors and non-existence are indicated by a return value of the undefined value. You can also choose to raise errors or print errors using the "raise_error" and "print_error" options.
In libpng, some functions use the return value to indicate errors, and some of the functions don't indicate errors but fail silently. Some of the functions which use the return value to indicate an error use a non-zero value to indicate an error, and some of them use a zero value to indicate an error.
Other unimplemented parts of libpng
Memory management functions
This module does not offer an interface to png_malloc
and png_free
.
Error handling functions
This module does not offer an interface to png_error
and png_get_error_ptr
. It redirects the error and warning handlers to Perl's error stream.
Input/output manipulation functions
This module does not offer a direct interface to png_set_write_fn
and png_set_read_fn
. However, it is possible to use their functionality to access Perl data via "read_from_scalar" and "write_to_scalar".
Partial read/write functions
This module does not yet offer an interface to the partial read and write functions of libpng. The reason is because I don't know enough about Perl's internal structures to be able to create a memory-safe interface to these functions. The partial read/write functions would rely on preserving pointers to data structures within the Perl program's data area between calls. So this module doesn't deal with png_write_chunk, png_write_end, png_write_info, png_write_row, or png_write_rows.
DIAGNOSTICS
The module may produce the following error or warning messages.
- [% diagnostic.message %]
-
( [%- IF diagnostic.type == "error" -%] F [%- ELSIF diagnostic.type == "warn" -%] W [%- END -%] ) [% IF diagnostic.comment %] [% diagnostic.comment %] [% END %]
[% END %]
BUGS
This section documents some known deficiencies in the module.
set_rows is unreliable
The method "set_rows" doesn't actually copy or write any information. All it does is set a pointer to the pointers to the rows in the PNG data structure. The actual data is only written when you ask to write it. So if you "set_rows" to some data, then delete or change that data before asking to write the png with "write_png", you will get a memory error.
Conditional compilation
It is possible to compile a version of the libpng library without support for various things. For example, it's possible to have a libpng without support for text chunks by undefining a macro PNG_TEXT_SUPPORTED
. The module supports some of the conditional compilation choices which I've found in practice, but it does not support every possible choice. If you encounter problems using this Perl module because of a conditionally-compiled libpng, then please let me know and I'll consider adding that facility to the module.
SEE ALSO
[% pngspec %]
[% INCLUDE "pngspec" %]
[% libpngdoc %]
"Official" documentation
The starting point is the plain text libpng manual at http://libpng.org/pub/png/libpng-manual.txt and the manual page libpng.3, which you can read using "man 3 libpng".
Be warned that the documentation which comes with libpng is rather sketchy. See "Differences from libpng". It doesn't contain full specifications (prototypes, return values) for all of the functions in the library. If you are considering programming in C using libpng, you will definitely also need to look at the header file "png.h". In some cases you will also need to look at the source code of the library.
Unofficial documentation
There is a collection of function definitions under the title "Interface Definitions for libpng12" at http://refspecs.freestandards.org/LSB_3.1.1/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.
[% INCLUDE "other_modules" %]
[% INCLUDE "examples_doc" %]
[% INCLUDE "author" %]
11 POD Errors
The following errors were encountered while parsing the POD:
- Around line 285:
=over should be: '=over' or '=over positive_number'
- Around line 296:
You forgot a '=back' before '=head2'
- Around line 485:
=over should be: '=over' or '=over positive_number'
- Around line 498:
You forgot a '=back' before '=head2'
- Around line 686:
=over should be: '=over' or '=over positive_number'
- Around line 703:
You forgot a '=back' before '=head1'
- Around line 725:
=over should be: '=over' or '=over positive_number'
- Around line 739:
You forgot a '=back' before '=head2'
- Around line 745:
=over should be: '=over' or '=over positive_number'
- Around line 758:
You forgot a '=back' before '=head1'
- Around line 848:
=over should be: '=over' or '=over positive_number'