Alien-FreeImage
view release on metacpan or search on metacpan
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
png_alloc_size_t size);
void free_fn(png_structp png_ptr, png_voidp ptr);
Your malloc_fn() must return NULL in case of failure. The png_malloc()
function will normally call png_error() if it receives a NULL from the
system memory allocator or from your replacement malloc_fn().
Your free_fn() will never be called with a NULL ptr, since libpng's
png_free() checks for NULL before calling free_fn().
Input/Output in libpng is done through png_read() and png_write(),
which currently just call fread() and fwrite(). The FILE * is stored in
png_struct and is initialized via png_init_io(). If you wish to change
the method of I/O, the library supplies callbacks that you can set
through the function png_set_read_fn() and png_set_write_fn() at run
time, instead of calling the png_init_io() function. These functions
also provide a void pointer that can be retrieved via the function
png_get_io_ptr(). For example:
png_set_read_fn(png_structp read_ptr,
voidp read_io_ptr, png_rw_ptr read_data_fn)
png_set_write_fn(png_structp write_ptr,
voidp write_io_ptr, png_rw_ptr write_data_fn,
png_flush_ptr output_flush_fn);
voidp read_io_ptr = png_get_io_ptr(read_ptr);
voidp write_io_ptr = png_get_io_ptr(write_ptr);
The replacement I/O functions must have prototypes as follows:
void user_read_data(png_structp png_ptr,
png_bytep data, png_size_t length);
void user_write_data(png_structp png_ptr,
png_bytep data, png_size_t length);
void user_flush_data(png_structp png_ptr);
The user_read_data() function is responsible for detecting and
handling end-of-data errors.
Supplying NULL for the read, write, or flush functions sets them back
to using the default C stream functions, which expect the io_ptr to
point to a standard *FILE structure. It is probably a mistake
to use NULL for one of write_data_fn and output_flush_fn but not both
of them, unless you have built libpng with PNG_NO_WRITE_FLUSH defined.
It is an error to read from a write stream, and vice versa.
Error handling in libpng is done through png_error() and png_warning().
Errors handled through png_error() are fatal, meaning that png_error()
should never return to its caller. Currently, this is handled via
setjmp() and longjmp() (unless you have compiled libpng with
PNG_NO_SETJMP, in which case it is handled via PNG_ABORT()),
but you could change this to do things like exit() if you should wish,
as long as your function does not return.
On non-fatal errors, png_warning() is called
to print a warning message, and then control returns to the calling code.
By default png_error() and png_warning() print a message on stderr via
fprintf() unless the library is compiled with PNG_NO_CONSOLE_IO defined
(because you don't want the messages) or PNG_NO_STDIO defined (because
fprintf() isn't available). If you wish to change the behavior of the error
functions, you will need to set up your own message callbacks. These
functions are normally supplied at the time that the png_struct is created.
It is also possible to redirect errors and warnings to your own replacement
functions after png_create_*_struct() has been called by calling:
png_set_error_fn(png_structp png_ptr,
png_voidp error_ptr, png_error_ptr error_fn,
png_error_ptr warning_fn);
png_voidp error_ptr = png_get_error_ptr(png_ptr);
If NULL is supplied for either error_fn or warning_fn, then the libpng
default function will be used, calling fprintf() and/or longjmp() if a
problem is encountered. The replacement error functions should have
parameters as follows:
void user_error_fn(png_structp png_ptr,
png_const_charp error_msg);
void user_warning_fn(png_structp png_ptr,
png_const_charp warning_msg);
The motivation behind using setjmp() and longjmp() is the C++ throw and
catch exception handling methods. This makes the code much easier to write,
as there is no need to check every return code of every function call.
However, there are some uncertainties about the status of local variables
after a longjmp, so the user may want to be careful about doing anything
after setjmp returns non-zero besides returning itself. Consult your
compiler documentation for more details. For an alternative approach, you
may wish to use the "cexcept" facility (see http://cexcept.sourceforge.net),
which is illustrated in pngvalid.c and in contrib/visupng.
Beginning in libpng-1.4.0, the png_set_benign_errors() API became available.
You can use this to handle certain errors (normally handled as errors)
as warnings.
png_set_benign_errors (png_ptr, int allowed);
allowed: 0: treat png_benign_error() as an error.
1: treat png_benign_error() as a warning.
As of libpng-1.6.0, the default condition is to treat benign errors as
warnings while reading and as errors while writing.
Custom chunks
If you need to read or write custom chunks, you may need to get deeper
into the libpng code. The library now has mechanisms for storing
and writing chunks of unknown type; you can even declare callbacks
for custom chunks. However, this may not be good enough if the
library code itself needs to know about interactions between your
chunk and existing `intrinsic' chunks.
If you need to write a new intrinsic chunk, first read the PNG
specification. Acquire a first level of understanding of how it works.
Pay particular attention to the sections that describe chunk names,
and look at how other chunks were designed, so you can do things
src/Source/LibPNG/libpng-manual.txt view on Meta::CPAN
the image, you should start with flags set for all of the filters
you intend to use so that libpng can initialize its internal
structures appropriately for all of the filter types. (Note that this
means the first row must always be adaptively filtered, because libpng
currently does not allocate the filter buffers until png_write_row()
is called for the first time.)
filters = PNG_FILTER_NONE | PNG_FILTER_SUB
PNG_FILTER_UP | PNG_FILTER_AVG |
PNG_FILTER_PAETH | PNG_ALL_FILTERS;
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE,
filters);
The second parameter can also be
PNG_INTRAPIXEL_DIFFERENCING if you are
writing a PNG to be embedded in a MNG
datastream. This parameter must be the
same as the value of filter_method used
in png_set_IHDR().
It is also possible to influence how libpng chooses from among the
available filters. This is done in one or both of two ways - by
telling it how important it is to keep the same filter for successive
rows, and by telling it the relative computational costs of the filters.
double weights[3] = {1.5, 1.3, 1.1},
costs[PNG_FILTER_VALUE_LAST] =
{1.0, 1.3, 1.3, 1.5, 1.7};
png_set_filter_heuristics(png_ptr,
PNG_FILTER_HEURISTIC_WEIGHTED, 3,
weights, costs);
The weights are multiplying factors that indicate to libpng that the
row filter should be the same for successive rows unless another row filter
is that many times better than the previous filter. In the above example,
if the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
"sum of absolute differences" 1.5 x 1.3 times higher than other filters
and still be chosen, while the NONE filter could have a sum 1.1 times
higher than other filters and still be chosen. Unspecified weights are
taken to be 1.0, and the specified weights should probably be declining
like those above in order to emphasize recent filters over older filters.
The filter costs specify for each filter type a relative decoding cost
to be considered when selecting row filters. This means that filters
with higher costs are less likely to be chosen over filters with lower
costs, unless their "sum of absolute differences" is that much smaller.
The costs do not necessarily reflect the exact computational speeds of
the various filters, since this would unduly influence the final image
size.
Note that the numbers above were invented purely for this example and
are given only to help explain the function usage. Little testing has
been done to find optimum values for either the costs or the weights.
Requesting debug printout
The macro definition PNG_DEBUG can be used to request debugging
printout. Set it to an integer value in the range 0 to 3. Higher
numbers result in increasing amounts of debugging information. The
information is printed to the "stderr" file, unless another file
name is specified in the PNG_DEBUG_FILE macro definition.
When PNG_DEBUG > 0, the following functions (macros) become available:
png_debug(level, message)
png_debug1(level, message, p1)
png_debug2(level, message, p1, p2)
in which "level" is compared to PNG_DEBUG to decide whether to print
the message, "message" is the formatted string to be printed,
and p1 and p2 are parameters that are to be embedded in the string
according to printf-style formatting directives. For example,
png_debug1(2, "foo=%d", foo);
is expanded to
if (PNG_DEBUG > 2)
fprintf(PNG_DEBUG_FILE, "foo=%d\n", foo);
When PNG_DEBUG is defined but is zero, the macros aren't defined, but you
can still use PNG_DEBUG to control your own debugging:
#ifdef PNG_DEBUG
fprintf(stderr, ...
#endif
When PNG_DEBUG = 1, the macros are defined, but only png_debug statements
having level = 0 will be printed. There aren't any such statements in
this version of libpng, but if you insert some they will be printed.
VII. MNG support
The MNG specification (available at http://www.libpng.org/pub/mng) allows
certain extensions to PNG for PNG images that are embedded in MNG datastreams.
Libpng can support some of these extensions. To enable them, use the
png_permit_mng_features() function:
feature_set = png_permit_mng_features(png_ptr, mask)
mask is a png_uint_32 containing the bitwise OR of the
features you want to enable. These include
PNG_FLAG_MNG_EMPTY_PLTE
PNG_FLAG_MNG_FILTER_64
PNG_ALL_MNG_FEATURES
feature_set is a png_uint_32 that is the bitwise AND of
your mask with the set of MNG features that is
supported by the version of libpng that you are using.
It is an error to use this function when reading or writing a standalone
PNG file with the PNG 8-byte signature. The PNG datastream must be wrapped
in a MNG datastream. As a minimum, it must have the MNG 8-byte signature
and the MHDR and MEND chunks. Libpng does not provide support for these
or any other MNG chunks; your application must provide its own support for
them. You may wish to consider using libmng (available at
http://www.libmng.com) instead.
VIII. Changes to Libpng from version 0.88
It should be noted that versions of libpng later than 0.96 are not
distributed by the original libpng author, Guy Schalnat, nor by
Andreas Dilger, who had taken over from Guy during 1996 and 1997, and
distributed versions 0.89 through 0.96, but rather by another member
of the original PNG Group, Glenn Randers-Pehrson. Guy and Andreas are
still alive and well, but they have moved on to other things.
The old libpng functions png_read_init(), png_write_init(),
png_info_init(), png_read_destroy(), and png_write_destroy() have been
moved to PNG_INTERNAL in version 0.95 to discourage their use. These
functions will be removed from libpng version 1.4.0.
The preferred method of creating and initializing the libpng structures is
via the png_create_read_struct(), png_create_write_struct(), and
png_create_info_struct() because they isolate the size of the structures
from the application, allow version error checking, and also allow the
use of custom error handling routines during the initialization, which
the old functions do not. The functions png_read_destroy() and
png_write_destroy() do not actually free the memory that libpng
allocated for these structs, but just reset the data structures, so they
can be used instead of png_destroy_read_struct() and
png_destroy_write_struct() if you feel there is too much system overhead
allocating and freeing the png_struct for each image read.
Setting the error callbacks via png_set_message_fn() before
( run in 1.178 second using v1.01-cache-2.11-cpan-63c85eba8c4 )