Alien-FreeImage

 view release on metacpan or  search on metacpan

src/Source/LibPNG/libpng-manual.txt  view on Meta::CPAN

the existing ones meets your needs.  This is done by setting a callback
with

    png_set_write_user_transform_fn(png_ptr,
       write_transform_fn);

You must supply the function

    void write_transform_fn(png_structp png_ptr, png_row_infop
       row_info, png_bytep data)

See pngtest.c for a working example.  Your function will be called
before any of the other transformations are processed.  If supported
libpng also supplies an information routine that may be called from
your callback:

   png_get_current_row_number(png_ptr);
   png_get_current_pass_number(png_ptr);

This returns the current row passed to the transform.  With interlaced
images the value returned is the row in the input sub-image image.  Use
PNG_ROW_FROM_PASS_ROW(row, pass) and PNG_COL_FROM_PASS_COL(col, pass) to
find the output pixel (x,y) given an interlaced sub-image pixel (row,col,pass).

The discussion of interlace handling above contains more information on how to
use these values.

You can also set up a pointer to a user structure for use by your
callback function.

    png_set_user_transform_info(png_ptr, user_ptr, 0, 0);

The user_channels and user_depth parameters of this function are ignored
when writing; you can set them to zero as shown.

You can retrieve the pointer via the function png_get_user_transform_ptr().
For example:

    voidp write_user_transform_ptr =
       png_get_user_transform_ptr(png_ptr);

It is possible to have libpng flush any pending output, either manually,
or automatically after a certain number of lines have been written.  To
flush the output stream a single time call:

    png_write_flush(png_ptr);

and to have libpng flush the output stream periodically after a certain
number of scanlines have been written, call:

    png_set_flush(png_ptr, nrows);

Note that the distance between rows is from the last time png_write_flush()
was called, or the first row of the image if it has never been called.
So if you write 50 lines, and then png_set_flush 25, it will flush the
output on the next scanline, and every 25 lines thereafter, unless
png_write_flush() is called before 25 more lines have been written.
If nrows is too small (less than about 10 lines for a 640 pixel wide
RGB image) the image compression may decrease noticeably (although this
may be acceptable for real-time applications).  Infrequent flushing will
only degrade the compression performance by a few percent over images
that do not use flushing.

Writing the image data

That's it for the transformations.  Now you can write the image data.
The simplest way to do this is in one function call.  If you have the
whole image in memory, you can just call png_write_image() and libpng
will write the image.  You will need to pass in an array of pointers to
each row.  This function automatically handles interlacing, so you don't
need to call png_set_interlace_handling() or call this function multiple
times, or any of that other stuff necessary with png_write_rows().

    png_write_image(png_ptr, row_pointers);

where row_pointers is:

    png_byte *row_pointers[height];

You can point to void or char or whatever you use for pixels.

If you don't want to write the whole image at once, you can
use png_write_rows() instead.  If the file is not interlaced,
this is simple:

    png_write_rows(png_ptr, row_pointers,
       number_of_rows);

row_pointers is the same as in the png_write_image() call.

If you are just writing one row at a time, you can do this with
a single row_pointer instead of an array of row_pointers:

    png_bytep row_pointer = row;

    png_write_row(png_ptr, row_pointer);

When the file is interlaced, things can get a good deal more complicated.
The only currently (as of the PNG Specification version 1.2, dated July
1999) defined interlacing scheme for PNG files is the "Adam7" interlace
scheme, that breaks down an image into seven smaller images of varying
size.  libpng will build these images for you, or you can do them
yourself.  If you want to build them yourself, see the PNG specification
for details of which pixels to write when.

If you don't want libpng to handle the interlacing details, just
use png_set_interlace_handling() and call png_write_rows() the
correct number of times to write all the sub-images
(png_set_interlace_handling() returns the number of sub-images.)

If you want libpng to build the sub-images, call this before you start
writing any rows:

    number_of_passes = png_set_interlace_handling(png_ptr);

This will return the number of passes needed.  Currently, this is seven,
but may change if another interlace type is added.

Then write the complete image number_of_passes times.

    png_write_rows(png_ptr, row_pointers, number_of_rows);



( run in 0.762 second using v1.01-cache-2.11-cpan-13bb782fe5a )