Imported from libpng-0.96.tar

This commit is contained in:
Andreas Dilger 1997-05-16 02:46:07 -05:00 committed by Glenn Randers-Pehrson
parent 02ad0efbc8
commit 47a0c422ca
40 changed files with 6833 additions and 3520 deletions

69
CHANGES
View File

@ -37,7 +37,7 @@ version 0.7
finished dithering and other stuff
added test program
changed name from pnglib to libpng
version 0.71
version 0.71 [June, 1995]
changed pngtest.png for zlib 0.93
fixed error in libpng.txt and example.c
version 0.8
@ -56,26 +56,28 @@ version 0.8
enabled png_set_shift to work with paletted images on read
added png_read_update_info() - updates info structure with
transformations
version 0.81
version 0.81 [August, 1995]
incorporated Tim Wegner's medium model code (thanks, Tim)
version 0.85
added more medium model code (almost everythings a far)
version 0.82 [September, 1995]
[unspecified changes]
version 0.85 [December, 1995]
added more medium model code (almost everything's a far)
added i/o, error, and memory callback functions
fixed some bugs (16 bit, 4 bit interlaced, etc.)
added first run progressive reader (barely tested)
version 0.86
version 0.86 [January, 1996]
fixed bugs
improved documentation
version 0.87
version 0.87 [January, 1996]
fixed medium model bugs
fixed other bugs introduced in 0.85 and 0.86
added some minor documentation
version 0.88
version 0.88 [January, 1996]
fixed progressive bugs
replaced tabs with spaces
cleaned up documentation
added callbacks for read/write and warning/error functions
version 0.89
version 0.89 [July, 1996]
added new initialization API to make libpng work better with shared libs
we now have png_create_read_struct(), png_create_write_struct(),
png_create_info_struct(), png_destroy_read_struct(), and
@ -101,14 +103,14 @@ version 0.89
into a binary when only reading or writing functionality is used
new pngtest image also has interlacing and zTXt
updated documentation to reflect new API
version 0.90
version 0.90 [January, 1997]
made CRC errors/warnings on critical and ancillary chunks configurable
libpng will use the zlib CRC routines by (compile-time) default
changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
added external C++ wrapper statements to png.h (Gilles Dauphin)
allow PNG file to be read when some or all of file signature has already
been read from the beginning of the stream (this affects the size of
info_struct and invalidates all programs that use a shared libpng)
been read from the beginning of the stream. ****This affects the size
of info_struct and invalidates all programs that use a shared libpng****
fixed png_filler() declarations
fixed? background color conversions
fixed order of error function pointers to match documentation
@ -120,3 +122,48 @@ version 0.90
routines can determine if the chunk is in the right place
- all chunk handling routines have the same prototypes, so we will
be able to handle all chunks via a callback mechanism
try to fix Linux "setjmp" buffer size problems
version 0.95 [March, 1997]
fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
fixed bug in PNG file signature compares when start != 0
changed parameter type of png_set_filler(...filler...) from png_byte
to png_uint_32
added test for MACOS to ensure that both math.h and fp.h are not #included
added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
added "packswap" transformation, which changes the endianness of
packed-pixel bytes (Kevin Bracey)
added "strip_alpha" transformation, which removes the alpha channel of
input images without using it (not neccesarily a good idea)
added "swap_alpha" transformation, which puts the alpha channel in front
of the color bytes instead of after
removed all implicit variable tests which assume NULL == 0 (I think)
changed several variables to "png_size_t" to show 16/32-bit limitations
added new pCAL chunk read/write support
added experimental filter selection weighting (Greg Roelofs)
removed old png_set_rgbx() and png_set_xrgb() functions that have been
obsolete for about 2 years now (use png_set_filler() instead)
added macros to read 16- and 32-bit ints directly from buffer, to be
used only on those systems that support it (namely PowerPC and 680x0)
With some testing, this may become the default for MACOS/PPC systems.
only calculate CRC on data if we are going to use it
added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
added macros for simple libpng debugging output selectable at compile time
removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
more description of info_struct in libpng.txt and png.h
more instructions in example.c
more chunk types tested in pngtest.c
renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
png_set_<chunk>. We now have corresponding png_get_<chunk>
functions in pngget.c to get infomation in info_ptr. This isolates
the application from the internal organization of png_info_struct
(good for shared library implementations).
version 0.96 [May, 1997]
fixed serious bug with < 8bpp images introduced in 0.95
fixed 256-color transparency bug (Greg Roelofs)
fixed up documentation (Greg Roelofs, Laszlo Nyul)
fixed "error" in pngconf.h for Linux setjmp() behaviour
fixed DOS medium model support (Tim Wegner)
fixed png_check_keyword() for case with error in static string text
added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
added typecasts to quiet compiler errors
added more debugging info

90
README
View File

@ -1,55 +1,54 @@
readme.txt - for libpng 0.90
README for libpng 0.96
This is the fourth beta version of libpng 1.0. The changes from
libpng-0.89 include bug fixes, a C++ wrapper for png.h, some
additions to the API, as well as internal changes to the library.
This is the sixth (and hopefully last) beta release of libpng 1.0.
The changes from libpng-0.90 include bug fixes, a C++ wrapper for
png.h, some additions to the API, as well as internal changes to
the library. See "CHANGES" for a detailed list of differences.
**
Note that some of the changes to the png_info structure render
this version of the library binary incompatible with libpng-0.89
if you are using a shared library. Re-compiling the application
should be enough to remove this problem.
**
****
Note that some of the changes to the png_info structure render this
version of the library binary incompatible with libpng-0.89 or
earlier versions if you are using a shared library. The type of the
"filler" parameter for png_set_filler() has changed from png_byte to
png_uint_32, which will affect shared-library applications which use
this function.
The additions to 0.89 include the ability to read from a PNG stream
which has had some (or all) of the signature bytes read by the
calling application. This also allows the reading of embedded PNG
streams that do not have the PNG file signature. As well, it is
now possible to set the library action on the detection of chunk
CRC errors. It is possible to set different actions based on
whether the error occurred in a critical or an ancillary chunk.
To avoid problems with changes to the internals of png_info_struct,
new APIs have been made available in 0.95 to avoid direct application
access to info_ptr. These functions are the png_set_<chunk> and
png_get_<chunk> functions. These functions should be used when
accessing/storing the info_struct data, rather than manipulating it
directly, to avoid such problems in the future.
****
The callback functions for the error/warning messages have changed
since the 0.88 release because their implementation was broken,
and it was thought best to change the API itself (which was only
introduced in libpng-0.88 itself) to alert the user to the change,
rather than mislead the user into thinking their application was
OK after re-compiling. This means that calls to png_set_message_fn()
no longer exist, because the previously suggested method of calling
them before png_read_init() or png_write_init() is now ineffective.
Additions since 0.90 include the ability to compile libpng as a
Windows DLL, and new APIs for accessing data in the info struct.
Experimental functions include the ability to set weighting and cost
factors for row filter selection, direct reads of integers from buffers
on big-endian processors that support misaligned data access, faster
methods of doing alpha composition, and more accurate 16->8 bit color
conversion.
The preferred method of setting the error and warning callbacks
has been incorporated into the allocation of the png_struct and
info_struct itself, which allow them to be safely used during the
initialization of the structure, as well as to keep the size of
the png_struct internal to the library, rather than at compile time
of the application. This will hopefully remove any problems with
dynamically linked libraries, and should be considered the preferred
method of creating these structures, although the previous
initialization API is still available for compatibility. See libpng.txt
for more information on the new API.
The additions since 0.89 include the ability to read from a PNG stream
which has had some (or all) of the signature bytes read by the calling
application. This also allows the reading of embedded PNG streams that
do not have the PNG file signature. As well, it is now possible to set
the library action on the detection of chunk CRC errors. It is possible
to set different actions based on whether the CRC error occurred in a
critical or an ancillary chunk.
The changes made to the library, and bugs fixed are based on discussions
on the PNG implementation mailing list <png-implement@dworking.wustl.edu>
and not on material submitted to Guy.
For a detailed description on using libpng, read libpng.txt. For
usage information and restrictions (what little they are) on libpng,
see png.h. For a description on using zlib (the compression library
used by libpng) and zlib's restrictions, see zlib.h
examples of libpng in a program, see example.c and pngtest.c. For usage
information and restrictions (what little they are) on libpng, see
png.h. For a description on using zlib (the compression library used by
libpng) and zlib's restrictions, see zlib.h
I have included a general makefile, as well as several machine and compiler
specific ones, but you may have to modify one for your own needs.
I have included a general makefile, as well as several machine and
compiler specific ones, but you may have to modify one for your own needs.
You should use zlib 1.0.4 or later to run this, but it MAY work with
versions as old as zlib 0.95. Even so, there are bugs in older zlib
@ -113,7 +112,7 @@ gladly listen. Even if your suggestion is not used for version
Files in this distribution:
CHANGES.txt => Description of changes between libpng versions
CHANGES => Description of changes between libpng versions
README => This file
TODO => Things not implemented in the current library
ansi2knr.c => Converts files to K&R style function declarations
@ -121,7 +120,7 @@ Files in this distribution:
descrip.mms => VMS project file
example.c => Example code for using libpng functions
libpng.txt => Description of libpng and its functions
makefile => Defualt makefile
makefile => Default Unixish makefile
makefile.aco => ACORN makefile
makefile.ama => Amiga makefile
makefile.atr => Atari makefile
@ -140,11 +139,11 @@ Files in this distribution:
pngerror.c => Error/warning message I/O functions
pngmem.c => Memory handling functions
pngpread.c => Progressive reading functions
pngrcb.c => Read callback (data handling) low-level functions
pngread.c => Read data/helper high-level functions
pngrio.c => Lowest-level data read I/O functions
pngrtran.c => Read data transformation functions
pngrutil.c => Read data utility functions
pngset.c => Functions for storing data into the info_struct
pngtest.c => Library test program
pngtest.png => Library test sample image
pngtrans.c => Common data transformation functions
@ -156,13 +155,12 @@ Files in this distribution:
Good luck, and happy coding.
-Andreas Eric Dilger
University of Calgary
Internet: adilger@enel.ucalgary.ca
Web: www-mddsp.enel.ucalgary.ca/People/adilger/
Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
-Guy Eric Schalnat
Group 42, Inc.
Internet: schalnat@group42.com
CompuServe: 75501,1625
Web: www.group42.com
Web: http://www.group42.com/

38
TODO
View File

@ -1,23 +1,19 @@
pngtodo.txt - list of things to do for libpng
for 0.9
improved dithering
final bug fixes
cHRM transformation
better documentation
multi-lingual message support
after 1.0
overlaying one image on top of another
optional palette creation
histogram creation
text conversion between different code types
support for application-defined chunk handlers
support for embedded PNG usage (MNG)
pull writer
better dithering
keep up with public chunks
better filter selection (counting huffman bits? filter type inertia?)
C++ wrapper
other languages (pascal, for one)
comments of > 64K for DOS
add "grayscale->palette" transformation and "palette->grayscale" detection
improved dithering
multi-lingual error and warning message support
cHRM transformation
sRGB chunk handling
man pages for function calls
high-level API for reading images
final bug fixes
better documentation
better filter selection
(counting huffman bits/precompression? filter inertia? filter costs?)
optional palette creation
histogram creation
support for application-defined chunk handlers
keep up with public chunks
better C++ wrapper/full C++ implementation?
text conversion between different code pages (Latin-1 -> Mac and DOS)

View File

@ -8,9 +8,9 @@ pref = /prefix=all
OBJS = png.obj, pngrcb.obj, pngrutil.obj, pngtrans.obj, pngwutil.obj,\
pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj, pngwtran.obj,\
pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\
pngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\
pngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
@ -35,7 +35,8 @@ clean :
# Other dependencies.
png.obj : png.h, pngconf.h
pngpread.obj : png.h, pngconf.h
pngrcb.obj : png.h, pngconf.h
pngset.obj : png.h, pngconf.h
pngget.obj : png.h, pngconf.h
pngread.obj : png.h, pngconf.h
pngrtran.obj : png.h, pngconf.h
pngrutil.obj : png.h, pngconf.h

565
example.c
View File

@ -1,92 +1,107 @@
/* example.c - an example of using libpng */
/* this is an example of how to use libpng to read and write
png files. The file libpng.txt is much more verbose then
this. If you have not read it, do so first. This was
designed to be a starting point of an implementation.
This is not officially part of libpng, and therefore
/* This is an example of how to use libpng to read and write PNG files.
The file libpng.txt is much more verbose then this. If you have not
read it, do so first. This was designed to be a starting point of an
implementation. This is not officially part of libpng, and therefore
does not require a copyright notice.
This file does not currently compile, because it is missing
certain parts, like allocating memory to hold an image.
You will have to supply these parts to get it to compile.
*/
This file does not currently compile, because it is missing certain
parts, like allocating memory to hold an image. You will have to
supply these parts to get it to compile. For an example of a minimal
working PNG reader/writer, see pngtest.c, included in this distribution.
*/
#include <png.h>
/* Check to see if a file is a png file using png_check_sig().
/* Check to see if a file is a PNG file using png_check_sig(). Returns
non-zero if the image is a PNG, and 0 if it isn't a PNG.
If this call is successful, and you are going to keep the file
open, you should call png_set_sig_bytes_read(png_ptr, 8);
once you have created the png_ptr, so that libpng knows it
doesn't have to read the signature again. Make sure you don't
call png_set_sig_bytes_read() with more than 8 bytes read or
give it an incorrect number of bytes read, or you will either
have read too many bytes (your fault), or you are telling libpng
to read the wrong number of magic bytes (also your fault). */
int check_png(char *file_name, FILE **fp)
If this call is successful, and you are going to keep the file open,
you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
you have created the png_ptr, so that libpng knows your application
has read that many bytes from the start of the file. Make sure you
don't call png_set_sig_bytes() with more than 8 bytes read or give it
an incorrect number of bytes read, or you will either have read too
many bytes (your fault), or you are telling libpng to read the wrong
number of magic bytes (also your fault).
Many applications already read the first 2 or 4 bytes from the start
of the image to determine the file type, so it would be easiest just
to pass the bytes to png_check_sig() or even skip that if you know
you have a PNG file, and call png_set_sig_bytes().
*/
#define PNG_BYTES_TO_CHECK 4
int check_if_png(char *file_name, FILE **fp)
{
char buf[8];
int ret;
char buf[PNG_BYTES_TO_CHECK];
*fp = fopen(file_name, "rb");
if (!fp)
return 0;
ret = fread(buf, 1, 8, *fp);
if (ret != 8)
/* Open the prospective PNG file. */
if ((*fp = fopen(file_name, "rb")) != NULL);
return 0;
/* Check the signature starting at byte 0, and check all 8 bytes */
ret = png_check_sig(buf, 0, 8);
/* Read in the signature bytes */
if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
return 0;
return (ret);
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. */
return(png_check_sig(buf, PNG_BYTES_TO_CHECK));
}
/* read a png file. You may want to return an error code if the read
/* Read a PNG file. You may want to return an error code if the read
fails (depending upon the failure). There are two "prototypes" given
here - one where we are given the filename, and we need to open the
file, and the other where we are given an open file (possibly with
some or all of the magic bytes read - see above) and an opened file
for reading. */
------- prototype 1 ----------
some or all of the magic bytes read - see comments above). */
**** prototype 1 ****
void read_png(char *file_name) /* We need to open the file */
{
png_structp png_ptr;
png_infop info_ptr;
unsigned int sig_read = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
FILE *fp;
if ((fp = fopen(file_name, "rb")) == NULL)
return;
------- prototype 2 ----------
**** prototype 2 ****
void read_png(FILE *fp, unsigned int sig_read) /* file is already open */
{
png_structp png_ptr;
png_infop info_ptr;
------- only use one! --------
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
**** only use one prototype! ****
/* Create and initialize the png_struct with the desired error handler
functions. If you want to use the default stderr and longjump method,
you can supply NULL for the last three parameters. We also check that
the header file is compatible with the library version. */
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also supply the
* the compiler header file version, so that we know if the application
* was compiled with a compatible version of the library. REQUIRED
*/
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(void *)user_error_ptr, user_error_fn, user_warning_fn);
if (!png_ptr)
if (png_ptr == NULL)
{
fclose(fp);
return;
}
/* Allocate/initialize the memory for image information. REQUIRED. */
info_ptr = png_create_info_struct();
if (!info_ptr)
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return;
}
/* set error handling if you are using the setjmp/longjmp method */
/* Set error handling if you are using the setjmp/longjmp method (this is
* the normal method of doing things with libpng). REQUIRED unless you
* set up your own error handlers in the png_create_read_struct() earlier.
*/
if (setjmp(png_ptr->jmpbuf))
{
/* Free all of the memory associated with the png_ptr and info_ptr */
@ -96,152 +111,221 @@ void read_png(FILE *fp, unsigned int sig_read) /* file is already open */
return;
}
/* set up the input control if you are using standard C streams */
/* One of the following I/O initialization methods is REQUIRED */
**** PNG file I/O method 1 ****
/* Set up the input control if you are using standard C streams */
png_init_io(png_ptr, fp);
/* if you are using replacement read functions, instead of calling
png_init_io() here you would call */
**** PNG file I/O method 2 ****
/* If you are using replacement read functions, instead of calling
* png_init_io() here you would call */
png_set_read_fn(png_ptr, (void *)user_io_ptr, user_read_fn);
/* where user_io_ptr is a structure you want available to the callbacks */
**** Use only one I/O method! ****
/* if we have already read some of the signature from the beginning call */
/* If we have already read some of the signature */
png_set_sig_bytes_read(png_ptr, sig_read);
/* The call to png_read_info() gives us all of the information
from the PNG file before the first IDAT (image data chunk). */
/* The call to png_read_info() gives us all of the information from the
* PNG file before the first IDAT (image data chunk). REQUIRED
*/
png_read_info(png_ptr, info_ptr);
/* set up the transformations you want. Note that these are
all optional. Only call them if you want them */
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, NULL, NULL);
/**** Set up the data transformations you want. Note that these are all
**** optional. Only call them if you want/need them. Many of the
**** transformations only work on specific types of images, and many
**** are mutually exclusive.
****/
/* tell libpng to strip 16 bit/color files down to 8 bits/color */
png_set_strip_16(png_ptr);
/* strip alpha bytes from the input data without combining with th
* background (not recommended) */
png_set_strip_alpha(png_ptr);
/* extract multiple pixels with bit depths of 1, 2, and 4 from a single
* byte into separate bytes (useful for paletted and grayscale images).
*/
png_set_packing(png_ptr);
/* change the order of packed pixels to least significant bit first
* (not useful if you are using png_set_packing). */
png_set_packswap(png_ptr);
/* expand paletted colors into true RGB triplets */
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
if (color_type == PNG_COLOR_TYPE_PALETTE)
png_set_expand(png_ptr);
/* expand grayscale images to the full 8 bits */
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY && info_ptr->bit_depth < 8)
/* expand grayscale images to the full 8 bits from 1, 2, or 4 bits/pixel */
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
/* expand paletted or RGB images with transparency to full alpha channels
* so the data will be available as RGBA quartets */
if (info_ptr->valid & PNG_INFO_tRNS)
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand(png_ptr);
/* Set the background color to draw transparent and alpha
images over. It is possible to set the red, green, and blue
components directly for paletted images. */
/* Set the background color to draw transparent and alpha images over.
* It is possible to set the red, green, and blue components directly
* for paletted images instead of supplying a palette index. Note that
* even if the PNG file supplies a background, you are not required to
* use it - you should use the (solid) application background if it has one.
*/
png_color_16 my_background;
png_color_16 my_background, *image_background);
if (info_ptr->valid & PNG_INFO_bKGD)
png_set_background(png_ptr, &(info_ptr->background),
if (png_get_bKGD(png_ptr, info_ptr, &image_background);
png_set_background(png_ptr, image_background),
PNG_BACKGROUND_GAMMA_FILE, 1, 1.0);
else
png_set_background(png_ptr, &my_background,
PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0);
/* tell libpng to handle the gamma conversion for you. We only
need the second call if the screen_gamma isn't the usual 2.2
or if it is controllable by the user. It may also be a good
idea to allow the user to set the file gamma if it is unknown. */
if (info_ptr->valid & PNG_INFO_gAMA)
png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
/* Some suggestions as to how to get a screen gamma value */
if (/* We have a user-defined screen gamma value */)
{
screen_gamma = user-defined screen_gamma;
}
/* This is one way that applications share the same screen gamma value */
else if ((gamma_str = getenv("DISPLAY_GAMMA")) != NULL)
{
screen_gamma = atof(gamma_str);
}
/* If we don't have another value */
else
{
screen_gamma = 2.2; /* A good guess for PC monitors */
screen_gamma = 1.7 or 1.0; /* A good guess for Mac systems */
}
/* Tell libpng to handle the gamma conversion for you. The second call
* is a good guess for PC generated images, but it should be configurable
* by the user at run time by the user. It is strongly suggested that
* your application support gamma correction.
*/
if (png_get_gAMA(png_ptr, info_ptr, &image_gamma);
png_set_gamma(png_ptr, screen_gamma, image_gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45);
/* tell libpng to strip 16 bit/color files down to 8 bits/color */
if (info_ptr->bit_depth == 16)
png_set_strip_16(png_ptr);
/* dither rgb files down to 8 bit palette & reduce palettes
/* Dither RGB files down to 8 bit palette or reduce palettes
to the number of colors available on your screen */
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
if (color_type & PNG_COLOR_MASK_COLOR)
{
if (info_ptr->valid & PNG_INFO_PLTE)
png_set_dither(png_ptr, info_ptr->palette, info_ptr->num_palette,
max_screen_colors, info_ptr->histogram);
else
png_uint_32 num_palette;
png_colorp palette;
/* This reduces the image to the application supplied palette */
if (we have our own palette)
{
png_color std_color_cube[MAX_SCREEN_COLORS] =
{/* ... colors ... */};
/* An array of colors to which the image should be dithered */
png_color std_color_cube[MAX_SCREEN_COLORS];
png_set_dither(png_ptr, std_color_cube, MAX_SCREEN_COLORS,
MAX_SCREEN_COLORS, NULL);
MAX_SCREEN_COLORS, NULL, 0);
}
/* This reduces the image to the palette supplied in the file */
else if (png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette)))
{
png_color16p histogram;
png_get_hIST(png_ptr, info_ptr, &histogram);
png_set_dither(png_ptr, palette, num_palette,
max_screen_colors, histogram, 0);
}
}
/* invert monocrome files to have 0 as white and 1 as black */
if (info_ptr->bit_depth == 1 && info_ptr->color_type == PNG_COLOR_GRAY)
png_set_invert(png_ptr);
png_set_invert(png_ptr);
/* shift the pixels down to their true bit depth */
if (info_ptr->valid & PNG_INFO_sBIT &&
info_ptr->bit_depth > info_ptr->sig_bit)
png_set_shift(png_ptr, &(info_ptr->sig_bit));
/* If you want to shift the pixel values from the range [0,255] or
* [0,65535] to the original [0,7] or [0,31], or whatever range the
* colors were originally in:
*/
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_sBIT))
{
png_color8p sig_bit;
/* pack multiple pixels with bit depths of 1, 2, and 4 into bytes
(useful only for paletted and grayscale images) */
if (info_ptr->bit_depth < 8)
png_set_packing(png_ptr);
png_get_sBIT(png_ptr, info_ptr, &sig_bit);
png_set_shift(png_ptr, sig_bit);
}
/* flip the rgb pixels to bgr */
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
png_set_bgr(png_ptr);
/* flip the RGB pixels to BGR (or RGBA to BGRA) */
png_set_bgr(png_ptr);
/* swap bytes of 16 bit files to least significant bit first */
if (info_ptr->bit_depth == 16)
png_set_swap(png_ptr);
/* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
png_set_swap_alpha(png_ptr);
/* add a filler byte to RGB files (before or after each RGB triplet) */
if (info_ptr->bit_depth == 8 && info_ptr->color_type == PNG_COLOR_TYPE_RGB)
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
/* swap bytes of 16 bit files to least significant byte first */
png_set_swap(png_ptr);
/* turn on interlace handling if you are not using png_read_image() */
/* Add filler (or alpha) byte (before/after each RGB triplet) */
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
/* Turn on interlace handling. REQUIRED if you are not using
* png_read_image(). To see how to handle interlacing passes,
* see the png_read_row() method below.
*/
number_passes = png_set_interlace_handling(png_ptr);
/* optional call to gamma correct and add the background to the palette
and update info structure. */
* and update info structure. REQUIRED if you are expecting libpng to
* update the palette for you (ie you selected such a transform above).
*/
png_read_update_info(png_ptr, info_ptr);
/* allocate the memory to hold the image using the fields
of png_info. */
/* allocate the memory to hold the image using the fields of info_ptr. */
/* the easiest way to read the image */
png_bytep row_pointers[height];
for (row = 0; row < height; row++)
{
row_pointers[row] = malloc(info_ptr->rowbytes);
row_pointers[row] = malloc(png_get_rowbytes(png_ptr, info_ptr));
}
/* Now it's time to read the image. One of these methods is REQUIRED */
**** Read the entire image in one go ****
png_read_image(png_ptr, row_pointers);
**** Read the image one or more scanlines at a time ****
/* the other way to read images - deal with interlacing */
for (pass = 0; pass < number_passes; pass++)
{
/* Read the image using the "sparkle" effect. */
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
/* If you are only reading on row at a time, this works */
[[[[[[[ Read the image a single row at a time ]]]]]]]
for (y = 0; y < height; y++)
{
png_bytep row_pointers = row[y];
png_read_rows(png_ptr, &row_pointers, NULL, 1);
}
/* to get the rectangle effect, use the third parameter */
png_read_rows(png_ptr, NULL, row_pointers, number_of_rows);
[[[[[[[ Read the image several rows at a time ]]]]]]]
for (y = 0; y < height; y += number_of_rows)
{
<<<<<<<<<< Read the image using the "sparkle" effect. >>>>>>>>>>
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
<<<<<<<<<< Read the image using the "rectangle" effect >>>>>>>>>>
png_read_rows(png_ptr, NULL, row_pointers, number_of_rows);
<<<<<<<<<< use only one of these two methods >>>>>>>>>>
}
/* if you want to display the image after every pass, do
so here */
[[[[[[[ use only one of these two methods ]]]]]]]
}
**** use only one of these two methods ****
/* read the rest of the file, getting any additional chunks in info_ptr */
/* read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr);
/* clean up after the read, and free any memory allocated */
/* clean up after the read, and free any memory allocated - REQUIRED */
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
/* close the file */
@ -257,15 +341,15 @@ int
initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
{
/* Create and initialize the png_struct with the desired error handler
functions. If you want to use the default stderr and longjump method,
you can supply NULL for the last three parameters. We also check that
the library version is compatible in case we are using dynamically
linked libraries.
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible in case we are using dynamically
* linked libraries.
*/
*png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(void *)user_error_ptr, user_error_fn, user_warning_fn);
if (! *png_ptr)
if (*png_ptr == NULL)
{
*info_ptr = NULL;
return ERROR;
@ -273,7 +357,7 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
*info_ptr = png_create_info_struct(png_ptr);
if (! *info_ptr)
if (*info_ptr == NULL)
{
png_destroy_read_struct(png_ptr, info_ptr, (png_infopp)NULL);
return ERROR;
@ -286,13 +370,14 @@ initialize_png_reader(png_structp *png_ptr, png_infop *info_ptr)
}
/* this one's new. You will need to provide all three
function callbacks, even if you aren't using them all.
These functions shouldn't be dependent on global or
static variables if you are decoding several images
simultaneously. You should store stream specific data
in a separate struct, given as the second parameter,
and retrieve the pointer from inside the callbacks using
the function png_get_progressive_ptr(png_ptr). */
* function callbacks, even if you aren't using them all.
* These functions shouldn't be dependent on global or
* static variables if you are decoding several images
* simultaneously. You should store stream specific data
* in a separate struct, given as the second parameter,
* and retrieve the pointer from inside the callbacks using
* the function png_get_progressive_ptr(png_ptr).
*/
png_set_progressive_read_fn(*png_ptr, (void *)stream_data,
info_callback, row_callback, end_callback);
@ -310,15 +395,16 @@ process_data(png_structp *png_ptr, png_infop *info_ptr,
return ERROR;
}
/* this one's new also. Simply give it chunks of data as
they arrive from the data stream (in order, of course).
On Segmented machines, don't give it any more than 64K.
The library seems to run fine with sizes of 4K, although
you can give it much less if necessary (I assume you can
give it chunks of 1 byte, but I haven't tried with less
than 256 bytes yet). When this function returns, you may
want to display any rows that were generated in the row
callback, if you aren't already displaying them there. */
/* This one's new also. Simply give it chunks of data as
* they arrive from the data stream (in order, of course).
* On Segmented machines, don't give it any more than 64K.
* The library seems to run fine with sizes of 4K, although
* you can give it much less if necessary (I assume you can
* give it chunks of 1 byte, but I haven't tried with less
* than 256 bytes yet). When this function returns, you may
* want to display any rows that were generated in the row
* callback, if you aren't already displaying them there.
*/
png_process_data(*png_ptr, *info_ptr, buffer, length);
return OK;
}
@ -326,52 +412,56 @@ process_data(png_structp *png_ptr, png_infop *info_ptr,
info_callback(png_structp png_ptr, png_infop info)
{
/* do any setup here, including setting any of the transformations
mentioned in the Reading PNG files section. For now, you _must_
call either png_start_read_image() or png_read_update_info()
after all the transformations are set (even if you don't set
any). You may start getting rows before png_process_data()
returns, so this is your last chance to prepare for that. */
* mentioned in the Reading PNG files section. For now, you _must_
* call either png_start_read_image() or png_read_update_info()
* after all the transformations are set (even if you don't set
* any). You may start getting rows before png_process_data()
* returns, so this is your last chance to prepare for that.
*/
}
row_callback(png_structp png_ptr, png_bytep new_row,
png_uint_32 row_num, int pass)
{
/* this function is called for every row in the image. If the
image is interlacing, and you turned on the interlace handler,
this function will be called for every row in every pass.
Some of these rows will not be changed from the previous pass.
When the row is not changed, the new_row variable will be NULL.
The rows and passes are called in order, so you don't really
need the row_num and pass, but I'm supplying them because it
may make your life easier.
For the non-NULL rows of interlaced images, you must call
png_progressive_combine_row() passing in the row and the
old row. You can call this function for NULL rows (it will
just return) and for non-interlaced images (it just does the
memcpy for you) if it will make the code easier. Thus, you
can just do this for all cases: */
* image is interlacing, and you turned on the interlace handler,
* this function will be called for every row in every pass.
* Some of these rows will not be changed from the previous pass.
* When the row is not changed, the new_row variable will be NULL.
* The rows and passes are called in order, so you don't really
* need the row_num and pass, but I'm supplying them because it
* may make your life easier.
*
* For the non-NULL rows of interlaced images, you must call
* png_progressive_combine_row() passing in the row and the
* old row. You can call this function for NULL rows (it will
* just return) and for non-interlaced images (it just does the
* memcpy for you) if it will make the code easier. Thus, you
* can just do this for all cases:
*/
png_progressive_combine_row(png_ptr, old_row, new_row);
/* where old_row is what was displayed for previous rows. Note
that the first pass (pass == 0 really) will completely cover
the old row, so the rows do not have to be initialized. After
the first pass (and only for interlaced images), you will have
to pass the current row, and the function will combine the
old row and the new row. */
* that the first pass (pass == 0 really) will completely cover
* the old row, so the rows do not have to be initialized. After
* the first pass (and only for interlaced images), you will have
* to pass the current row, and the function will combine the
* old row and the new row.
*/
}
end_callback(png_structp png_ptr, png_infop info)
{
/* this function is called when the whole image has been read,
including any chunks after the image (up to and including
the IEND). You will usually have the same info chunk as you
had in the header, although some data may have been added
to the comments and time fields.
Most people won't do much here, perhaps setting a flag that
marks the image as finished. */
* including any chunks after the image (up to and including
* the IEND). You will usually have the same info chunk as you
* had in the header, although some data may have been added
* to the comments and time fields.
*
* Most people won't do much here, perhaps setting a flag that
* marks the image as finished.
*/
}
/* write a png file */
@ -383,33 +473,36 @@ void write_png(char *file_name, ... other image information ...)
/* open the file */
fp = fopen(file_name, "wb");
if (!fp)
if (fp == NULL)
return;
/* Create and initialize the png_struct with the desired error handler
functions. If you want to use the default stderr and longjump method,
you can supply NULL for the last three parameters. We also check that
the library version is compatible in case we are using dynamically
linked libraries.
* functions. If you want to use the default stderr and longjump method,
* you can supply NULL for the last three parameters. We also check that
* the library version is compatible with the one used at compile time,
* in case we are using dynamically linked libraries. REQUIRED.
*/
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
(void *)user_error_ptr, user_error_fn, user_warning_fn);
if (!png_ptr)
if (png_ptr == NULL)
{
fclose(fp);
return;
}
/* Allocate/initialize the image information data. REQUIRED */
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
return;
}
/* set error handling */
/* Set error handling. REQUIRED if you aren't supplying your own
* error hadnling functions in the png_create_write_struct() call.
*/
if (setjmp(png_ptr->jmpbuf))
{
/* If we get here, we had a problem reading the file */
@ -418,63 +511,101 @@ void write_png(char *file_name, ... other image information ...)
return;
}
/* One of the following I/O initialization functions is REQUIRED */
**** I/O initialization method 1 ****
/* set up the output control if you are using standard C streams */
png_init_io(png_ptr, fp);
**** I/O initialization method 2 ****
/* If you are using replacement read functions, instead of calling
* png_init_io() here you would call */
png_set_write_fn(png_ptr, (void *)user_io_ptr, user_write_fn,
user_IO_flush_function);
/* where user_io_ptr is a structure you want available to the callbacks */
**** only use 1 initialization method ****
/* set the file information here */
info_ptr->width = ;
info_ptr->height = ;
etc.
/* Set the image information here. Width and height are up to 2^31,
* bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on
* the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY,
* PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB,
* or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or
* PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST
* currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. REQUIRED
*/
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, PNG_COLOR_TYPE_???,
PNG_INTERLACE_????, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
/* set the palette if there is one */
info_ptr->valid |= PNG_INFO_PLTE;
info_ptr->palette = malloc(256 * sizeof (png_color));
info_ptr->num_palette = 256;
/* set the palette if there is one. REQUIRED for indexed-color images */
palette = png_malloc(png_ptr, 256 * sizeof (png_color));
... set palette colors ...
png_set_PLTE(png_ptr, info_ptr, palette, 256);
/* optional significant bit chunk */
info_ptr->valid |= PNG_INFO_sBIT;
/* if we are dealing with a grayscale image then */
info_ptr->sig_bit.gray = true_bit_depth;
sig_bit.gray = true_bit_depth;
/* otherwise, if we are dealing with a color image then */
info_ptr->sig_bit.red = true_red_bit_depth;
info_ptr->sig_bit.green = true_green_bit_depth;
info_ptr->sig_bit.blue = true_blue_bit_depth;
sig_bit.red = true_red_bit_depth;
sig_bit.green = true_green_bit_depth;
sig_bit.blue = true_blue_bit_depth;
/* if the image has an alpha channel then */
info_ptr->sig_bit.alpha = true_alpha_bit_depth;
sig_bit.alpha = true_alpha_bit_depth;
png_set_sBIT(png_ptr, info_ptr, sig_bit);
/* optional gamma chunk is strongly suggested if you have any guess
as to the correct gamma of the image */
info_ptr->valid |= PNG_INFO_gAMA;
info_ptr->gamma = gamma;
/* Optional gamma chunk is strongly suggested if you have any guess
* as to the correct gamma of the image. */
png_set_gAMA(png_ptr, info_ptr, gamma);
/* other optional chunks like cHRM, bKGD, tRNS, tEXt, tIME, oFFs, pHYs, */
/* Optionally write comments into the image */
text_ptr[0].key = "Title";
text_ptr[0].text = "Mona Lisa";
text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[1].key = "Author";
text_ptr[1].text = "Leonardo DaVinci";
text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr[2].key = "Description";
text_ptr[2].text = "<long text>";
text_ptr[2].compression = PNG_TEXT_COMPRESSION_zTXt;
png_set_text(png_ptr, info_ptr, text_ptr, 2);
/* write the file header information */
/* other optional chunks like cHRM, bKGD, tRNS, tIME, oFFs, pHYs, */
/* Write the file header information. REQUIRED */
png_write_info(png_ptr, info_ptr);
/* Once we write out the header, the compression type on the text
* chunks gets changed to PNG_TEXT_COMPRESSION_NONE_WR or
* PNG_TEXT_COMPRESSION_zTXt_WR, so it doesn't get written out again
* at the end.
*/
/* set up the transformations you want. Note that these are
all optional. Only call them if you want them */
* all optional. Only call them if you want them. */
/* invert monocrome pixels */
png_set_invert(png_ptr);
/* shift the pixels up to a legal bit depth and fill in
as appropriate to correctly scale the image */
png_set_shift(png_ptr, &(info_ptr->sig_bit));
/* Shift the pixels up to a legal bit depth and fill in
* as appropriate to correctly scale the image */
png_set_shift(png_ptr, &sig_bit);
/* pack pixels into bytes */
png_set_packing(png_ptr);
/* flip bgr pixels to rgb */
/* swap location of alpha bytes from ARGB to RGBA */
png_set_swap_alpha(png_ptr);
/* Get rid of filler (OR ALPHA) bytes, pack XRGB/RGBX/ARGB/RGBA into
* RGB (4 channels -> 3 channels). The second parameter is not used. */
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
/* flip BGR pixels to RGB */
png_set_bgr(png_ptr);
/* swap bytes of 16 bit files to most significant bit first */
/* swap bytes of 16-bit files to most significant byte first */
png_set_swap(png_ptr);
/* get rid of filler bytes, pack rgb into 3 bytes. The
filler number is not used. */
png_set_filler(png_ptr, 0, PNG_FILLER_BEFORE);
/* swap bits of 1, 2, 4 bit packed pixel formats */
png_set_packswap(png_ptr);
/* turn on interlace handling if you are not using png_write_image() */
if (interlacing)
@ -482,14 +613,22 @@ void write_png(char *file_name, ... other image information ...)
else
number_passes = 1;
/* the easiest way to write the image (you may choose to allocate the
memory differently, however) */
/* The easiest way to write the image (you may have a different memory
* layout, however, so choose what fits your needs best). You need to
* use the first method if you aren't handling interlacing yourself.
*/
png_byte row_pointers[height][width];
/* One of the following output methods is REQUIRED */
**** write out the entire image data in one call ***
png_write_image(png_ptr, row_pointers);
/* the other way to write the image - deal with interlacing */
**** write out the image data by one or more scanlines ****
/* The number of passes is either 1 for non-interlaced images,
* or 7 for interlaced images.
*/
for (pass = 0; pass < number_passes; pass++)
{
/* Write a few rows at a time. */
@ -502,24 +641,22 @@ void write_png(char *file_name, ... other image information ...)
png_write_rows(png_ptr, &row_pointers, 1);
}
}
**** use only one output method ****
/* You can write optional chunks like tEXt, tIME at the end as well.
* Note that if you wrote tEXt or zTXt chunks before the image, and
* you aren't writing out more at the end, you have to set
* info_ptr->num_text = 0 or they will be written out again.
/* You can write optional chunks like tEXt, zTXt, and tIME at the end
* as well.
*/
/* write the rest of the file */
/* It is REQUIRED to call this to finish writing the rest of the file */
png_write_end(png_ptr, info_ptr);
/* if you malloced the palette, free it here */
if (info_ptr->palette)
free(info_ptr->palette);
free(info_ptr->palette);
/* if you allocated any text comments, free them here */
/* clean up after the write, and free any memory allocated */
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
/* close the file */
fclose(fp);

View File

@ -1,16 +1,19 @@
libpng.txt - a description on how to use and modify libpng
libpng 1.0 beta 3 - version 0.89
Updated and distributed by Andreas Dilger <adilger@enel.ucalgary.ca>,
based on:
libpng 1.0 beta 5 - version 0.95
Updated and distributed by Andreas Dilger <adilger@enel.ucalgary.ca>,
Copyright (c) 1996, 1997 Andreas Dilger
March 15, 1997
based on:
libpng 1.0 beta 2 - version 0.88
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
May 24, 1996
Updated/rewritten per request in the libpng FAQ
Copyright (c) 1995 Frank J. T. Wojcik
December 18, 1995 && January 20, 1996
libpng 1.0 beta 2 - version 0.88
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 26, 1996
Updated/rewritten per request in the libpng FAQ
Copyright (c) 1995 Frank J. T. Wojcik
December 18, 1995 && January 20, 1996
I. Introduction
@ -32,10 +35,10 @@ only supports C. Support for other languages is being considered.
Libpng has been designed to handle multiple sessions at one time,
to be easily modifiable, to be portable to the vast majority of
machines (ANSI, K&R, 16 bit, 32 bit) available, and to be easy to
use. The ultimate goal of libpng is to promote the acceptance of
machines (ANSI, K&R, 16-, 32-, and 64-bit) available, and to be easy
to use. The ultimate goal of libpng is to promote the acceptance of
the PNG file format in whatever way possible. While there is still
work to be done (see the pngtodo.txt file), libpng should cover the
work to be done (see the TODO file), libpng should cover the
majority of the needs of it's users.
Libpng uses zlib for its compression and decompression of PNG files.
@ -59,10 +62,14 @@ will not, for the most part, be used by a user except as the first
variable passed to every libpng function call.
The png_info structure is designed to provide information about the
png file. All of its fields are intended to be examined or modified
by the user. See png.h for a good description of the png_info fields.
png.h is also an invaluable reference for programming with libpng.
PNG file. At one time, the fields of png_info were intended to be
directly accessible to the user. However, this tended to cause problems
with applications using dynamically loaded libraries, and as a result
a set of interface functions for png_info were delevoped. The fields
of png_info are still available for older applications, but it is
suggested that applications use the new interfaces if at all possible.
The png.h header file is an invaluable reference for programming with libpng.
And while I'm on the topic, make sure you include the libpng header file:
#include <png.h>
@ -110,24 +117,27 @@ Customizing libpng.
return;
}
Next, png_struct and png_info need to be allocated and initialized.
In order to ensure that the size of these structures is correct even
with a dynamically linked libpng, there are functions to initialize
and allocate the structures. We also pass the library version, and
optionally pointers to error handling functions (these can be NULL
if the default error handlers are to be used). See the section on
Changes to Libpng below regarding the old initialization functions.
Next, png_struct and png_info need to be allocated and initialized. In
order to ensure that the size of these structures is correct even with a
dynamically linked libpng, there are functions to initialize and
allocate the structures. We also pass the library version, optional
pointers to error handling functions, and a pointer to a data struct for
use by the error functions, if necessary (the pointer and functions can
be NULL if the default error handlers are to be used). See the section
on Changes to Libpng below regarding the old initialization functions.
png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
(void *)user_error_ptr, user_error_fn, user_warning_fn);
if (!png_ptr)
return;
png_infop info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr)
{
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return;
}
png_infop end_info = png_create_info_struct(png_ptr);
if (!end_info)
{
@ -160,9 +170,10 @@ free any memory.
Now you need to set up the input code. The default for libpng is to
use the C function fread(). If you use this, you will need to pass a
valid FILE * in the function png_init_io(). Be sure that the file is
opened in binary mode. Again, if you wish to handle reading data in
another way, see the discussion on libpng I/O handling in the Customizing
Libpng section below.
opened in binary mode. If you wish to handle reading data in another
way, you need not call the png_init_io() function, but you must then
implement the libpng I/O methods discussed in the Customizing Libpng
section below.
png_init_io(png_ptr, fp);
@ -177,76 +188,127 @@ image data. You do this with a call to png_read_info().
png_read_info(png_ptr, info_ptr);
The png_info structure is now filled in with all the data necessary
to read the file. Some of the more important parts of the info_ptr are:
Functions are used to get the information from the info_ptr:
width - holds the width of the file
height - holds the height of the file
bit_depth - holds the bit depth of one of the image channels
color_type - describes the channels and what they mean
(see the PNG_COLOR_TYPE_ macros for more information)
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, &compression_type, &filter_type);
width - holds the width of the image in pixels (up to 2^31).
height - holds the height of the image in pixels (up to 2^31).
bit_depth - holds the bit depth of one of the image channels.
(valid values are 1, 2, 4, 8, 16 and depend also on the
color_type. See also significant bits (sBIT) below).
color_type - describes which color/alpha channels are present.
PNG_COLOR_TYPE_GRAY (bit depths 1, 2, 4, 8, 16)
PNG_COLOR_TYPE_GRAY_ALPHA (bit depths 8, 16)
PNG_COLOR_TYPE_PALETTE (bit depths 1, 2, 4, 8)
PNG_COLOR_TYPE_RGB (bit_depths 8, 16)
PNG_COLOR_TYPE_RGB_ALPHA (bit_depths 8, 16)
PNG_COLOR_MASK_PALETTE
PNG_COLOR_MASK_COLOR
PNG_COLOR_MASK_ALPHA
interlace_type - PNG_INTERLACE_TYPE_NONE or PNG_INTERLACE_TYPE_ADAM7
compression_type - (must be PNG_COMPRESSION_TYPE_BASE for PNG 1.0)
filter_type - (must be PNG_FILTER_TYPE_BASE for PNG 1.0)
channels = png_get_channels(png_ptr, info_ptr);
channels - number of channels of info for the color type
pixel_depth - bits per pixel, the result of multiplying the
bit_depth times the channels
(valid values are 1 (GRAY, PALETTE), 2 (GRAY_ALPHA),
3 (RGB), 4 (RGB_ALPHA or RGB + filler byte))
rowbytes = png_get_rowbytes(png_ptr, info_ptr);
rowbytes - number of bytes needed to hold a row
interlace_type - currently 0 for none, 1 for interlaced
signature = png_get_signature(png_ptr, info_ptr);
signature - holds the signature read from the file (if any). The
data is kept in the same offset it would be if the
whole signature were read (ie if you had already read
in 4 bytes of signature, the remaining 4 bytes would
be in signature[4] through signature[7]).
valid - this details which optional chunks were found in the
file. To see if a chunk was present, AND '&' valid with
the appropriate PNG_INFO_<chunk name> define.
whole signature were read (ie if an application had
already read in 4 bytes of signature before staring
libpng, the remaining 4 bytes would be in signature[4]
through signature[7] (see png_set_sig_bytes())).
These are also important, but their validity depends on whether a
corresponding chunk exists. Use valid (see above) to ensure that what
you're doing with these values makes sense.
These are also important, but their validity depends on whether the chunk
has been read. The png_get_valid(png_ptr, info_ptr, PNG_INFO_<chunk>) and
png_get_<chunk>(png_ptr, info_ptr, ...) functions return non-zero if the
data has been read, or zero if it is missing. The parameters to the
png_get_<chunk> are set directly if they are simple data types, or a pointer
into the info_ptr is returned for any complex types.
palette - the palette for the file (PNG_INFO_PLTE)
png_get_PLTE(png_ptr, info_ptr, &palette, &num_palette);
palette - the palette for the file (array of png_color)
num_palette - number of entries in the palette
png_get_gAMA(png_ptr, info_ptr, &gamma);
gamma - the gamma the file is written at (PNG_INFO_gAMA)
sig_bit - the number of significant bits (PNG_INFO_sBIT)
for the gray, red, green, and blue channels, whichever
are appropriate for the given color type.
png_get_sBIT(png_ptr, info_ptr, &sig_bit);
sig_bit - the number of significant bits for (PNG_INFO_sBIT)
the gray, red, green, and blue channels, whichever
are appropriate for the given color type (png_color_16)
png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, &trans_values);
trans - array of transparent entries for palette (PNG_INFO_tRNS)
trans_values - transparent pixel for non-paletted images (PNG_INFO_tRNS)
trans - array of transparent entries for paletted images
num_trans - number of transparent entries
hist - histogram of palette (PNG_INFO_hIST)
num_trans - number of transparent entries (PNG_INFO_tRNS)
png_get_hIST(png_ptr, info_ptr, &hist); (PNG_INFO_hIST)
hist - histogram of palette (array of png_color_16)
png_get_tIME(png_ptr, info_ptr, &mod_time);
mod_time - time image was last modified (PNG_VALID_tIME)
png_get_bKGD(png_ptr, info_ptr, &background);
background - background color (PNG_VALID_bKGD)
text - text comments in the file.
num_text = png_get_text(png_ptr, info_ptr, &text_ptr);
text_ptr - array of png_text holding image comments
text_ptr[i]->key - keyword for comment.
text_ptr[i]->text - text comments for current keyword.
text_ptr[i]->compression - type of compression used on "text"
PNG_TEXT_COMPRESSION_NONE or
PNG_TEXT_COMPRESSION_zTXt
num_text - number of comments
for more information, see the png_info definition in png.h and the
png_get_oFFs(png_ptr, info_ptr, &offset_x, &offset_y, &unit_type);
offset_x - positive offset from the left edge of the screen
offset_y - positive offset from the top edge of the screen
unit_type - PNG_OFFSET_PIXEL, PNG_OFFSET_MICROMETER
png_get_pHYs(png_ptr, info_ptr, &res_x, &res_y, &unit_type);
res_x - pixels/unit physical resolution in x direction
res_y - pixels/unit physical resolution in x direction
unit_type - PNG_RESOLUTION_UNKOWN, PNG_RESOLUTION_METER
For more information, see the png_info definition in png.h and the
PNG specification for chunk contents. Be careful with trusting
rowbytes, as some of the transformations could increase the space
needed to hold a row (expand, RGBX, XRGB, gray_to_rgb, etc.).
See png_update_info(), below.
needed to hold a row (expand, filler, gray_to_rgb, etc.).
See png_read_update_info(), below.
A quick word about text and num_text. PNG stores comments in
keyword/text pairs, one pair per chunk. While there are suggested
keywords, there is no requirement to restrict the use to these
strings. There is a requirement to have at least one character for a
keyword. It is strongly suggested that keywords be sensible to humans
(that's the point), so don't use abbreviations. See the PNG
specification for more details. There is also no requirement to have
text after the keyword.
A quick word about text_ptr and num_text. PNG stores comments in
keyword/text pairs, one pair per chunk, with no limit on the number
of text chunks, and a 2^31 byte limit on their size. While there are
suggested keywords, there is no requirement to restrict the use to these
strings. It is strongly suggested that keywords and text be sensible
to humans (that's the point), so don't use abbreviations or non-printing
symbols. See the PNG specification for more details. There is also
no requirement to have text after the keyword.
Keywords should be limited to 80 characters without leading or trailing
spaces, but non-consecutive spaces are allowed within the keyword. It is
possible to have the same keyword any number of times. The text field
is an array of png_text structures, each holding pointer to a keyword
and a pointer to a text string. Only the text string may be null.
The keyword/text pairs are put into the array in the order that
they are received. However, some or all of the text chunks may be
Keywords should be limited to 79 Latin-1 characters without leading or
trailing spaces, but non-consecutive spaces are allowed within the
keyword. It is possible to have the same keyword any number of times.
The text_ptr is an array of png_text structures, each holding pointer
to a keyword and a pointer to a text string. Only the text string may
be null. The keyword/text pairs are put into the array in the order
that they are received. However, some or all of the text chunks may be
after the image, so, to make sure you have read all the text chunks,
don't mess with these until after you read the stuff after the image.
This will be mentioned again below in the discussion that goes with
png_read_end().
After you've read the file information, you can set up the library to
handle any special transformations of the image data. The various
After you've read the header information, you can set up the library
to handle any special transformations of the image data. The various
ways to transform the data will be described in the order that they
should occur. This is important, as some of these change the color
type and/or bit depth of the data, and some others only work on
@ -260,7 +322,7 @@ supplied in the same format/depth as the current image data. They
are stored in the same format/depth as the image data in a bKGD or tRNS
chunk, so this is what libpng expects for this data. The colors are
transformed to keep in sync with the image data when an application
calls the png_update_info() routine (see below).
calls the png_read_update_info() routine (see below).
Data will be decoded into the supplied row buffers packed into bytes
unless the library has been told to transform it into another format.
@ -279,97 +341,141 @@ transparency information in a tRNS chunk. This is most useful on
grayscale images with bit depths of 2 or 4 or if there is a multiple-image
viewing application that wishes to treat all images in the same