Imported from libpng-0.96.tar
This commit is contained in:
parent
02ad0efbc8
commit
47a0c422ca
69
CHANGES
69
CHANGES
@ -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
90
README
@ -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
38
TODO
@ -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)
|
||||
|
@ -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
565
example.c
@ -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);
|
||||
|
693
libpng.txt
693
libpng.txt
@ -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 |