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

547
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);
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);
/* 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)
/* 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)
/* swap the RGBA or GA data to ARGB or AG (or BGRA to ABGR) */
png_set_swap_alpha(png_ptr);
/* swap bytes of 16 bit files to least significant byte first */
png_set_swap(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)
/* Add filler (or alpha) byte (before/after each RGB triplet) */
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
/* turn on interlace handling if you are not using png_read_image() */
/* 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 */
[[[[[[[ 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;
/* other optional chunks like cHRM, bKGD, tRNS, tEXt, tIME, oFFs, pHYs, */
/* 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);
/* write the file header information */
/* 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);
/* 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,18 +641,16 @@ 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);
/* if you allocated any text comments, free them here */

View File

@ -1,13 +1,16 @@
libpng.txt - a description on how to use and modify libpng
libpng 1.0 beta 3 - version 0.89
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
January 26, 1996
Updated/rewritten per request in the libpng FAQ
Copyright (c) 1995 Frank J. T. Wojcik
December 18, 1995 && January 20, 1996
@ -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 way.
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
info_ptr->bit_depth < 8)
if (color_type == PNG_COLOR_TYPE_PALETTE && bit_depth < 8)
png_set_expand(png_ptr);
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY &&
info_ptr->bit_depth < 8)
if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
png_set_expand(png_ptr);
if (info_ptr->valid & PNG_INFO_tRNS)
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
png_set_expand(png_ptr);
PNG can have files with 16 bits per channel. If you only can handle
8 bits per channel, this will strip the pixels down to 8 bit.
if (info_ptr->bit_depth == 16)
if (bit_depth == 16)
png_set_strip_16(png_ptr);
If, for some reason, you don't need the alpha channel on an image,
and you want to remove it rather than combining it with the background:
if (color_type & PNG_COLOR_MASK_ALPHA)
png_set_strip_alpha(png_ptr);
PNG files pack pixels of bit depths 1, 2, and 4 into bytes as small as
they can, resulting in, for example, 8 pixels per byte for 1 bit
files. This code expands to 1 pixel per byte without changing the
values of the pixels:
if (info_ptr->bit_depth < 8)
if (bit_depth < 8)
png_set_packing(png_ptr);
PNG files have possible bit depths of 1, 2, 4, 8, and 16. It is then
required that values be "scaled" or "shifted" up to the bit depth used
in the file (ie from 5 bits/sample in the range [0,31] to 8 bits/sample
in the range [0, 255]). However, they also provide a way to describe
the true bit depth of the image. See the PNG specification for details.
This call reduces the pixels back down to the true bit depth:
PNG files have possible bit depths of 1, 2, 4, 8, and 16. All pixels
stored in a PNG image whave been "scaled" or "shifted" up to the next
higher possible bit depth (eg from 5 bits/sample in the range [0,31] to
8 bits/sample in the range [0, 255]). However, it is also possible to
convert the PNG pixel data back to the original bit depth of the image.
This call reduces the pixels back down to the original bit depth:
if (info_ptr->valid & PNG_INFO_sBIT)
png_set_shift(png_ptr, &(info_ptr->sig_bit));
png_color_16p sig_bit;
PNG files store 3 color pixels in red, green, blue order. This code
if (png_get_sBIT(png_ptr, info_ptr, &sig_bit))
png_set_shift(png_ptr, sig_bit);
PNG files store 3-color pixels in red, green, blue order. This code
changes the storage of the pixels to blue, green, red:
if (info_ptr->color_type == PNG_COLOR_TYPE_RGB ||
info_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
if (color_type == PNG_COLOR_TYPE_RGB ||
color_type == PNG_COLOR_TYPE_RGB_ALPHA)
png_set_bgr(png_ptr);
PNG files store RGB pixels packed into 3 bytes. This code expands them
into 4 bytes for windowing systems that need them in this format:
if (info_ptr->bit_depth == 8 &&
info_ptr->color_type == PNG_COLOR_TYPE_RGB)
png_set_filler(png_ptr, filler_byte, PNG_FILLER_BEFORE);
if (bit_depth == 8 && color_type == PNG_COLOR_TYPE_RGB)
png_set_filler(png_ptr, filler, PNG_FILLER_BEFORE);
where filler_byte is the number to fill with, and the location is
where "filler" is the number to fill with, and the location is
either PNG_FILLER_BEFORE or PNG_FILLER_AFTER, depending upon whether
you want the filler before the RGB or after.
you want the filler before the RGB or after. This transformation
does not affect images that already have full alpha channels.
For some uses, you may want a gray-scale image to be represented as
If you are reading an image with an alpha channel, and you need the
data as ARGB instead of the normal PNG format RGBA:
if (color_type == PNG_COLOR_TYPE_RGB_ALPHA)
png_set_swap_alpha(png_ptr);
For some uses, you may want a grayscale image to be represented as
RGB. This code will do that conversion:
if (info_ptr->color_type == PNG_COLOR_TYPE_GRAY ||
info_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
if (color_type == PNG_COLOR_TYPE_GRAY ||
color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
png_set_gray_to_rgb(png_ptr);
The following code handles alpha and transparency by replacing it with
a background value. If there was a valid bKGD in the file, you can use
it if you want. However, you can replace it with your own if you want
also. If there wasn't one in the file, you must supply a color. If
libpng is doing gamma correction, you will need to tell libpng where
the background came from so it can do the appropriate gamma
correction. If you have a grayscale and you are using png_set_expand()
to change to a higher bit-depth you must indicate if the background gray
needs to be expanded to the new bit-depth. Similarly, if you are reading
The png_set_background() function tells libpng to composite images
with alpha or simple transparency against the supplied background
color. If the PNG file contains a bKGD chunk (PNG_INFO_bKGD valid),
you may use this color, or supply another color more suitable for
the current display (e.g., the background color from a web page). You
need to tell libpng whether the color is in the gamma space of the
dispay (PNG_BACKGROUND_GAMMA_SCREEN for colors you supply), the file
(PNG_BACKGROUND_GAMMA_FILE for colors from the bKGD chunk), or one
that is neither of these gammas (PNG_BACKGROUND_GAMMA_UNIQUE - I don't
know why anyone would use this, but it's here).
If you have a grayscale and you are using png_set_expand() to change to
a higher bit-depth you must indicate if the supplied background gray
is supplied in the original file bit depth (need_expand = 1) or in the
expanded bit depth (need_expand = 0). Similarly, if you are reading
a paletted image, you must indicate if you have supplied the background
index that needs to be expanded to RGB values. You can always specify
RGB color values directly when setting your background for paletted images.
as a palette index that needs to be expanded (need_expand = 1). You can
also specify an RGB triplet that isn't in the palette when setting your
background for a paletted image.
png_color_16 my_background;
png_color_16p image_background;
if (info_ptr->valid & PNG_INFO_bKGD)
png_set_backgrond(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);
The following code handles gamma transformations of the data. Pass
both the file gamma and the desired screen gamma. If the file does
not have a gamma value, you can pass one anyway if you wish. Note
that file gammas are inverted from screen gammas. See the discussions
on gamma in the PNG specification for more information. It is
strongly recommended that viewers support gamma correction.
To properly display PNG images on any kind of system, the application needs
to know what the display gamma is. Ideally, the user will know this, and
the application will allow them to set it. One method of allowing the user
to set the display gamma separately for each system is to check for the
DISPLAY_GAMMA environment variable, which will hopefully be correctly set.
if (info_ptr->valid & PNG_INFO_gAMA)
png_set_gamma(png_ptr, screen_gamma, info_ptr->gamma);
if (/* We have a user-defined screen gamma value */)
{
screen_gamma = user_defined_screen_gamma;
}
/* One way that applications can 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 */
}
The png_set_gamma() function handles gamma transformations of the data.
Pass both the file gamma and the current screen_gamma. If the file does
not have a gamma value, you can pass one anyway if you have an idea what
it is (usually 0.45 is a good guess for GIF images on PCs). Note
that file gammas are inverted from screen gammas. See the discussions
on gamma in the PNG specification for an excellent description of what
gamma is, and why all applications should support it. It is strongly
recommended that PNG viewers support gamma correction.
if (png_get_gAMA(png_ptr, info_ptr, &gamma))
png_set_gamma(png_ptr, screen_gamma, gamma);
else
png_set_gamma(png_ptr, screen_gamma, 0.45);
@ -384,13 +490,15 @@ maximum_colors. If there is a histogram, it will use it to make
more intelligent choices when reducing the palette. If there is no
histogram, it may not do as good a job.
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
if (color_type & PNG_COLOR_MASK_COLOR)
{
if (info_ptr->valid & PNG_INFO_PLTE)
if (png_get_valid(png_ptr, info_ptr, PNG_INFO_PLTE))
{
png_set_dither(png_ptr, info_ptr->palette,
info_ptr->num_palette, max_screen_colors,
info_ptr->histogram, 1);
png_color_16p histogram;
png_get_hIST(png_ptr, info_ptr, &histogram);
png_set_dither(png_ptr, palette, num_palette, max_screen_colors,
histogram, 1);
}
else
{
@ -406,8 +514,7 @@ PNG files describe monochrome as black being zero and white being one.
The following code will reverse this (make black be one and white be
zero):
if (info_ptr->bit_depth == 1 &&
info_ptr->color_type == PNG_COLOR_GRAY)
if (bit_depth == 1 && color_type == PNG_COLOR_GRAY)
png_set_invert_mono(png_ptr);
PNG files store 16 bit pixels in network byte order (big-endian,
@ -415,19 +522,24 @@ ie. most significant bits first). This code chages the storage to the
other way (little-endian, ie. least significant bits first, eg. the
way PCs store them):
if (info_ptr->bit_depth == 16)
if (bit_depth == 16)
png_set_swap(png_ptr);
If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
need to change the order the pixels are packed into bytes, you can use:
if (bit_depth < 8)
png_set_packswap(png_ptr);
The last thing to handle is interlacing; this is covered in detail below,
but you must call the function here.
if (info_ptr->interlace_type)
number_passes = png_set_interlace_handling(png_ptr);
After setting the transformations, libpng can update your png_info
structure to reflect any transformations you've requested with this
call. This is most useful to update the info structures rowbytes
field, so you can use it to allocate your image memory. This function
call. This is most useful to update the info structure's rowbytes
field so you can use it to allocate your image memory. This function
will also update your palette with the correct display gamma and
background if these have been given with the calls above.
@ -462,7 +574,7 @@ You can point to void or char or whatever you use for pixels.
If you don't want to read int the whole image at once, you can
use png_read_rows() instead. If there is no interlacing (check
info_ptr->interlace_type), this is simple:
interlace_type == PNG_INTERLACE_TYPE_NONE), this is simple:
png_read_rows(png_ptr, row_pointers, NULL, number_of_rows);
@ -475,11 +587,11 @@ row_pointers:
png_read_row(png_ptr, &row_pointers, NULL);
If the file is interlaced (info_ptr->interlace_type != 0), things get
somewhat harder. The only currently (as of 6/96 -- PNG
Specification version 1.0) defined interlacing scheme for PNG files
(info_ptr->interlace_type == 1) is a someewhat complicated 2D interlace
scheme, known as Adam7, that breaks down an image into seven smaller
images of varying size, based on an 8x8 grid.
somewhat harder. The only current (PNG Specification version 1.0)
interlacing type for PNG is (interlace_type == PNG_INTERLACE_TYPE_ADAM7)
is a someewhat complicated 2D interlace scheme, known as Adam7, that
breaks down an image into seven smaller images of varying size, based
on an 8x8 grid.
libpng can fill out those images or it can give them to you "as is".
If you want them filled out, there are two ways to do that. The one
@ -515,7 +627,7 @@ numbered scanlines. Phew!
If you want libpng to expand the images, call this before calling
png_start_read_image() or png_read_update_info():
if (info_ptr->interlace_type)
if (interlace_type == PNG_INTERLACE_TYPE_ADAM7)
number_passes = png_set_interlace_handling(png_ptr);
This will return the number of passes needed. Currently, this
@ -755,7 +867,7 @@ section below for more information on the libpng error handling.
return;
}
Now you need to set up the input code. The default for libpng is to
Now you need to set up the output code. The default for libpng is to
use the C function fwrite(). 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 writing data in
@ -810,32 +922,74 @@ contain, see the PNG specification.
Some of the more important parts of the png_info are:
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_ defines for more information
interlace_type - allowed values are 0 for none, 1 for interlaced
valid - this describes which optional chunks to write to the
file. Note that if you are writing a
PNG_COLOR_TYPE_PALETTE file, the PLTE chunk is not
optional, but must still be marked for writing. To
mark chunks for writing, logical OR '|' valid with
the appropriate PNG_INFO_<chunk name> define.
palette - the palette for the file (PNG_INFO_PLTE)
png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type,
interlace_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_INTER_LACE_TYPE_ADAM7
compression_type - (must be PNG_COMPRESSION_TYPE_DEFAULT for PNG 1.0)
filter_type - (must be PNG_FILTER_TYPE_DEFAULT for PNG 1.0)
Any or all of interlace_type, compression_type, of filter_type can be
NULL if you are not interested in their values.
png_set_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
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_set_gAMA(png_ptr, info_ptr, gamma);
gamma - the gamma the image was created at (PNG_INFO_gAMA)
png_set_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_set_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_set_hIST(png_ptr, info_ptr, hist); (PNG_INFO_hIST)
hist - histogram of palette (array of png_color_16)
png_set_tIME(png_ptr, info_ptr, mod_time);
mod_time - time image was last modified (PNG_VALID_tIME)
png_set_bKGD(png_ptr, info_ptr, background);
background - background color (PNG_VALID_bKGD)
text - text comments in the file.
num_text - number of comments
png_set_text(png_ptr, info_ptr, text_ptr, num_text);
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 in text_ptr
png_set_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
A quick word about text and num_text. text is an array of png_text
structures. num_text is the number of valid structures in the array.
@ -846,8 +1000,12 @@ The compression types have the same valid numbers as the compression
types of the image data. Currently, the only valid number is zero.
However, you can store text either compressed or uncompressed, unlike
images which always have to be compressed. So if you don't want the
text compressed, set the compression type to -1. Until text gets
around 1000 bytes, it is not worth compressing it.
text compressed, set the compression type to PNG_TEXT_COMPRESSION_NONE.
Until text gets around 1000 bytes, it is not worth compressing it.
After the text has been written out to the file, the compression type
is set to PNG_TEXT_COMPRESSION_NONE_WR or PNG_TEXT_COMPRESSION_zTXt_WR,
so that it isn't written out again at the end (in case you are calling
png_write_end() with the same struct.
The keywords that are given in the PNG Specification are:
@ -889,7 +1047,8 @@ time_t routine uses gmtime(). You don't have to use either of
these, but if you wish to fill in the png_time structure directly,
you should provide the time in universal time (GMT) if possible
instead of your local time. Note that the year number is the full
year (ie 1996, rather than 96), and that months start with 1.
year (ie 1996, rather than 96 - PNG is year 2000 compliant!), and
that months start with 1.
You are now ready to write all the file information up to the actual
image data. You do this with a call to png_write_info().
@ -926,40 +1085,45 @@ PNG files reduce possible bit depths to 1, 2, 4, 8, and 16. If your
data is of another bit depth, you can write an sBIT chunk into the
file so that decoders can get the original data if desired.
/* Do this before png_write_info() */
info_ptr->valid |= PNG_INFO_sBIT;
/* Set the true bit depth of the image data */
if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
if (color_type & PNG_COLOR_MASK_COLOR)
{
info_ptr->sig_bit.red = true_bit_depth;
info_ptr->sig_bit.green = true_bit_depth;
info_ptr->sig_bit.blue = true_bit_depth;
sig_bit.red = true_bit_depth;
sig_bit.green = true_bit_depth;
sig_bit.blue = true_bit_depth;
}
else
{
info_ptr->sig_bit.gray = true_bit_depth;
sig_bit.gray = true_bit_depth;
}
if (color_type & PNG_COLOR_MASK_ALPHA)
{
sig_bit.alpha = true_bit_depth;
}
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
{
info_ptr->sig_bit.alpha = true_bit_depth;
}
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
If the data is stored in the row buffer in a bit depth other than
one supported by PNG (ie 3 bit data in the range 0-7 for a 4-bit PNG),
this will scale the values to appear to be the correct bit depth as
is required by PNG.
png_set_shift(png_ptr, &(info_ptr->sig_bit));
png_set_shift(png_ptr, &sig_bit);
PNG files store 16 bit pixels in network byte order (big-endian,
ie. most significant bits first). This code would be used if they are
supplied the other way (little-endian, ie. least significant bits
first, eg. the way PCs store them):
if (bit_depth > 8)
png_set_swap(png_ptr);
If you are using packed-pixel images (1, 2, or 4 bits/pixel), and you
need to change the order the pixels are packed into bytes, you can use:
if (bit_depth < 8)
png_set_packswap(png_ptr);
PNG files store 3 color pixels in red, green, blue order. This code
would be used if they are supplied as blue, green, red:
@ -1056,9 +1220,7 @@ and only update the rows that are actually used.
After you are finished writing the image, you should finish writing
the file. If you are interested in writing comments or time, you should
pass the an appropriately filled png_info pointer. If you
are not interested, you can pass NULL. If you have written text at
the beginning and are not writing more at the end, you should set
info_ptr->num_text = 0, or the text will be written again here.
are not interested, you can pass NULL.
png_write_end(png_ptr, info_ptr);
@ -1079,26 +1241,27 @@ standard things like memory allocation, input/output, and error handling.
The second deals with more complicated things like adding new chunks,
adding new transformations, and generally changing how libpng works.
All of the memory allocation, input/output, and error handling in
libpng goes through callbacks which are user setable. The default
routines are in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively.
To change these functions, call the approprate png_set_???_fn() function.
All of the memory allocation, input/output, and error handling in libpng
goes through callbacks which are user setable. The default routines are
in pngmem.c, pngrio.c, pngwio.c, and pngerror.c respectively. To change
these functions, call the approprate png_set_???_fn() function.
Memory allocation is done through the functions png_large_malloc(),
png_malloc(), png_realloc(), png_large_free(), and png_free(). These
currently just call the standard C functions. The large functions must
handle exactly 64K, but they don't have to handle more than that. If
your pointers can't access more then 64K at a time, you will want to
set MAXSEG_64K in zlib.h. Since it is unlikely that the method of
handling memory allocation on a platform will change between applications,
these functions must be modified in the library at compile time.
your pointers can't access more then 64K at a time, you will want to set
MAXSEG_64K in zlib.h. Since it is unlikely that the method of handling
memory allocation on a platform will change between applications, these
functions must be modified in the library at compile time.
Input/Output in libpng is done throught png_read() and png_write(), which
currently just call fread() and fwrite(). The FILE * is stored in
png_struct, and is initialized via png_init_io(). If you wish to change
the method of I/O, the library supplies callbacks that you can set through
the function png_set_read_fn() and png_set_write_fn() at run time. These
functions also provide a void pointer that can be retrieved via the function
Input/Output in libpng is done throught png_read() and png_write(),
which currently just call fread() and fwrite(). The FILE * is stored in
png_struct and is initialized via png_init_io(). If you wish to change
the method of I/O, the library supplies callbacks that you can set
through the function png_set_read_fn() and png_set_write_fn() at run
time, instead of calling the png_init_io() function. These functions
also provide a void pointer that can be retrieved via the function
png_get_io_ptr(). For example:
png_set_read_fn(png_structp png_ptr, voidp io_ptr,
@ -1123,7 +1286,7 @@ a write stream, and vice versa.
Error handling in libpng is done through png_error() and png_warning().
Errors handled through png_error() are fatal, meaning that png_error()
should never return to it's caller. Currently, this is handled via
should never return to its caller. Currently, this is handled via
setjmp() and longjmp(), but you could change this to do things like
exit() if you should wish. On non-fatal errors, png_warning() is called
to print a warning message, and then control returns to the calling code.
@ -1152,7 +1315,7 @@ catch exception handling methods. This makes the code much easier to write,
as there is no need to check every return code of every function call.
However, there are some uncertainties about the status of local variables
after a longjmp, so the user may want to be careful about doing anything after
setjmp returns non zero besides returning itself. Consult your compiler
setjmp returns non-zero besides returning itself. Consult your compiler
documentation for more details.
If you need to read or write custom chunks, you will need to get deeper
@ -1220,16 +1383,16 @@ Configuring zlib:
There are special functions to configure the compression. Perhaps the
most useful one changes the compression level, which currently uses
input compression values in the range 0 - 9. The library normally
uses the default compression level (Z_DEFAULT_COMPRESSION = 6), but if
speed is not critical it is possible to configure it for maximum
compression (Z_BEST_COMPRESSION = 9) to generate smaller PNG files.
uses the default compression level (Z_DEFAULT_COMPRESSION = 6). Tests
have shown that for a large majority of images, compression values in
the range 3-6 compress as well as higher levels, and do so much faster.
For online applications it may be desirable to have maximum speed
(Z_BEST_SPEED = 1). With versions of zlib after v0.99, you can also
specify no compression (Z_NO_COMPRESSION = 0), but this would create
files larger than just storing the raw bitmap. You can specify the
compression level by calling:
png_set_compression_mem_level(png_ptr, level);
png_set_compression_level(png_ptr, level);
Another useful one is to reduce the memory level used by the library.
The memory level defaults to 8, but it can be lowered if you are
@ -1237,9 +1400,20 @@ short on memory (running DOS, for example, where you only have 640K).
png_set_compression_mem_level(png_ptr, level);
If you want to control whether libpng uses filtering or not, you
can call this function. Filtering is enabled by default for RGB
and grayscale images (with and without alpha), and for 8-bit
The other functions are for configuring zlib. They are not recommended
for normal use and may result in writing an invalid PNG file. See
zlib.h for more information on what these mean.
png_set_compression_strategy(png_ptr, strategy);
png_set_compression_window_bits(png_ptr, window_bits);
png_set_compression_method(png_ptr, method);
Controlling row filtering:
If you want to control whether libpng uses filtering or not, which
filters are used, and how it goes about picking row filters, you
can call one of these functions. Filtering is enabled by default for
RGB and grayscale images (with and without alpha), and for 8-bit
paletted images, but not for paletted images with bit depths less
than 8 bits/pixel. The 'method' parameter sets the main filtering
method, which is currently only '0' in the PNG 1.0 specification.
@ -1255,23 +1429,46 @@ the image, you should start with flags set for all of the filters
you intend to use so that libpng can initialize its internal
structures appropriately for all of the filter types.
png_set_filter(png_ptr, method, filters);
filters = PNG_FILTER_NONE | PNG_FILTER_SUB | PNG_FILTER_UP;
png_set_filter(png_ptr, PNG_FILTER_TYPE_BASE, filters);
The other functions are for configuring zlib. They are not recommended
for normal use and may result in writing an invalid PNG file. See
zlib.h for more information on what these mean.
It is also possible to influence how libpng chooses from among the
available filters. This is done in two ways - by telling it how
important it is to keep the same filter for successive rows, and
by telling it the relative computational costs of the filters.
png_set_compression_strategy(png_ptr, strategy);
png_set_compression_window_bits(png_ptr, window_bits);
png_set_compression_method(png_ptr, method);
double weights[3] = {1.5, 1.3, 1.1},
costs[PNG_FILTER_VALUE_LAST] = {1.0, 1.3, 1.3, 1.5, 1.7};
Except for png_set_filter(), all of these are just controlling zlib,
so see the zlib documentation (zlib.h and zconf.h) for more information.
png_set_filter_selection(png_ptr, PNG_FILTER_SELECTION_WEIGHTED,
3, weights, costs);
The weights are multiplying factors which indicate to libpng that row
should be the same for successive rows unless another row filter is that
many times better than the previous filter. In the above example, if
the previous 3 filters were SUB, SUB, NONE, the SUB filter could have a
"sum of absolute differences" 1.5 x 1.3 times higher than other filters
and still be chosen, while the NONE filter could have a sum 1.1 times
higher than other filters and still be chosen. Unspecified weights are
taken to be 1.0, and the specified weights should probably be declining
like those above in order to emphasize recent filters over older filters.
The filter costs specify for each filter type a relative decoding cost
to be considered when selecting row filters. This means that filters
with higher costs are less likely to be chosen over filters with lower
costs, unless their "sum of absolute differences" is that much smaller.
The costs do not necessarily reflect the exact computational speeds of
the various filters, since this would unduely influence the final image
size.
Note that the numbers above were invented purely for this example and
are given only to help explain the function usage. Little testing has
been done to find optimum values for either the costs or the weights.
Removing unwanted object code:
There are a bunch of #define's in pngconf.h that control what parts of
libpng are compiled. All the defines end in _SUPPORT. If you are
libpng are compiled. All the defines end in _SUPPORTED. If you are
never going to use an ability, you can change the #define to #undef
before recompiling libpng and save yourself code and data space. All
the reading and writing specific code are in seperate files, so the
@ -1283,32 +1480,34 @@ are used for both reading and writing, and always need to be included.
The progressive reader is in pngpread.c
If you are creating or distributing a dynamically linked library (a .so
or DLL file), you should not remove or disable any parts of the
library, as this will cause applications linked with different versions
of the library to fail if they call functions not available in your
library. The size of the library itself should not be an issue, because
only those sections which are actually used will be loaded into memory.
or DLL file), you should not remove or disable any parts of the library,
as this will cause applications linked with different versions of the
library to fail if they call functions not available in your library.
The size of the library itself should not be an issue, because only
those sections which are actually used will be loaded into memory.
Changes to Libpng from version 0.88 to version 0.89
It should be noted that version 0.89 of libpng is not distributed by
the original author, Guy Schalnat, but rather Andreas Dilger, although
all of the copyright messages have been left in Guy's name.
Changes to Libpng from version 0.88
The old libpng functions png_read_init(), png_write_init() and
png_info_init() still exist in the 0.89 version of the library, as
do png_read_destroy() and png_write_destroy(). The preferred method
of creating and initializing the libpng structures is via the
png_create_read_struct(), png_create_write_struct(), and
It should be noted that versions of libpng later than 0.88 are not
distributed by the original libpng author, Guy Schalnat, but rather
another member of the original PNG Group, Andreas Dilger. Guy is still
alive and well, but he has moved on to other things.
The old libpng functions png_read_init(), png_write_init(),
png_info_init(), png_read_destroy(), and png_write_destory() have been
moved to PNG_INTERNAL in version 0.95 to discourage their use. The
preferred method of creating and initializing the libpng structures is
via the png_create_read_struct(), png_create_write_struct(), and
png_create_info_struct() because they isolate the size of the structures
from the application, allow version error checking, and also allow
the use of custom error handling routines during the initialization,
which the old functions do not. The functions png_read_destroy() and
png_write_destroy() do not actually free the memory that libpng allocated
for these structs, but just reset the data structures, so they can be
used instead of png_destroy_read_struct() and png_destroy_write_struct()
if you feel there is too much system overhead allocating and freeing the
png_struct for each image read.
from the application, allow version error checking, and also allow the
use of custom error handling routines during the initialization, which
the old functions do not. The functions png_read_destroy() and
png_write_destroy() do not actually free the memory that libpng
allocated for these structs, but just reset the data structures, so they
can be used instead of png_destroy_read_struct() and
png_destroy_write_struct() if you feel there is too much system overhead
allocating and freeing the png_struct for each image read.
Setting the error callbacks via png_set_message_fn() before
png_read_init() as was suggested in libpng-0.88 is no longer supported
@ -1316,5 +1515,5 @@ because this caused applications which do not use custom error functions
to fail if the png_ptr was not initialized to zero. It is still possible
to set the error callbacks AFTER png_read_init(), or to change them with
png_set_error_fn(), which is essentially the same function, but with a
new name to force compilation errors with the new library.
new name to force compilation errors with applications that try to use
the old method.

View File

@ -2,17 +2,23 @@
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
# For conditions of distribution and use, see copyright notice in png.h
CC=cc
CFLAGS=-I../zlib -O
LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=../zlib
ZLIBINC=../zlib
#RANLIB=ranlib
RANLIB=echo
CC=cc
CFLAGS=-I$(ZLIBINC) -O # -g -DPNG_DEBUG=1
LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
#RANLIB=echo
RANLIB=ranlib
# where make install puts libpng.a and png.h
prefix=/usr/local
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
@ -48,7 +54,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h
pngrutil.o: png.h pngconf.h

View File

@ -13,23 +13,25 @@ Squeezeflags = -o $@
# Final targets:
@.libpng-lib: @.o.png @.o.pngerror @.o.pngrio @.o.pngwio @.o.pngmem \
@.o.pngpread @.o.pngrcb @.o.pngread @.o.pngrtran @.o.pngrutil @.o.pngtrans @.o.pngwrite \
@.o.pngwtran @.o.pngwutil
LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngwio \
@.o.pngmem @.o.pngpread @.o.pngrcb @.o.pngread @.o.pngrtran @.o.pngrutil @.o.pngtrans \
@.o.pngwrite @.o.pngwtran @.o.pngwutil
@.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngrtran \
@.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil
LibFile $(LibFileflags) @.o.png @.o.pngerror @.o.pngrio @.o.pngrtran \
@.o.pngmem @.o.pngpread @.o.pngset @.o.pngget @.o.pngread @.o.pngwio \
@.o.pngrutil @.o.pngtrans @.o.pngwrite @.o.pngwtran @.o.pngwutil
@.mm-libpng-lib: @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio @.mm.pngmem \
@.mm.pngpread @.mm.pngrcb @.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans \
@.mm.pngwrite @.mm.pngwtran @.mm.pngwutil
LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio @.mm.pngwio \
@.mm.pngmem @.mm.pngpread @.mm.pngrcb @.mm.pngread @.mm.pngrtran @.mm.pngrutil \
@.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil
@.mm.pngpread @.mm.pngset @.mm.pngget @.mm.pngread @.mm.pngrtran \
@.mm.pngrutil @.mm.pngtrans @.mm.pngwrite @.mm.pngwtran @.mm.pngwutil
LibFile $(LibFileflags) @.mm.png @.mm.pngerror @.mm.pngrio \
@.mm.pngwio @.mm.pngmem @.mm.pngpread @.mm.pngset @.mm.pngget \
@.mm.pngread @.mm.pngrtran @.mm.pngrutil @.mm.pngtrans @.mm.pngwrite \
@.mm.pngwtran @.mm.pngwutil
# User-editable dependencies:
# (C) Copyright 1997 Tom Tanner
Test: @.pngtest
<Prefix$Dir>.PngTest
@remove <Prefix$Dir>.pngout_png
<Prefix$Dir>.pngtest
@remove <Prefix$Dir>.pngtest
#It would be nice if you could stop "make" listing from here on!
@.pngtest: @.o.pngtest @.libpng-lib C:o.Stubs Zlib:zlib_lib
@ -47,3 +49,173 @@ Test: @.pngtest
# Dynamic dependencies:
o.pngtest: c.pngtest
o.pngtest: h.png
o.pngtest: Zlib:h.zlib
o.pngtest: Zlib:h.zconf
o.pngtest: h.pngconf
mm.png: LibPng:c.png
mm.png: LibPng:h.png
mm.png: Zlib:h.zlib
mm.png: Zlib:h.zconf
mm.png: LibPng:h.pngconf
mm.png: MemCheck:ANSI.h.stdio
mm.pngerror: LibPng:c.pngerror
mm.pngerror: LibPng:h.png
mm.pngerror: Zlib:h.zlib
mm.pngerror: Zlib:h.zconf
mm.pngerror: LibPng:h.pngconf
mm.pngerror: MemCheck:ANSI.h.stdio
mm.pngrio: LibPng:c.pngrio
mm.pngrio: LibPng:h.png
mm.pngrio: Zlib:h.zlib
mm.pngrio: Zlib:h.zconf
mm.pngrio: LibPng:h.pngconf
mm.pngrio: MemCheck:ANSI.h.stdio
mm.pngwio: LibPng:c.pngwio
mm.pngwio: LibPng:h.png
mm.pngwio: Zlib:h.zlib
mm.pngwio: Zlib:h.zconf
mm.pngwio: LibPng:h.pngconf
mm.pngwio: MemCheck:ANSI.h.stdio
mm.pngmem: LibPng:c.pngmem
mm.pngmem: LibPng:h.png
mm.pngmem: Zlib:h.zlib
mm.pngmem: Zlib:h.zconf
mm.pngmem: LibPng:h.pngconf
mm.pngmem: MemCheck:ANSI.h.stdio
mm.pngpread: LibPng:c.pngpread
mm.pngpread: LibPng:h.png
mm.pngpread: Zlib:h.zlib
mm.pngpread: Zlib:h.zconf
mm.pngpread: LibPng:h.pngconf
mm.pngpread: MemCheck:ANSI.h.stdio
mm.pngset: LibPng:c.pngset
mm.pngset: LibPng:h.png
mm.pngset: Zlib:h.zlib
mm.pngset: Zlib:h.zconf
mm.pngset: LibPng:h.pngconf
mm.pngset: MemCheck:ANSI.h.stdio
mm.pngget: LibPng:c.pngget
mm.pngget: LibPng:h.png
mm.pngget: Zlib:h.zlib
mm.pngget: Zlib:h.zconf
mm.pngget: LibPng:h.pngconf
mm.pngget: MemCheck:ANSI.h.stdio
mm.pngread: LibPng:c.pngread
mm.pngread: LibPng:h.png
mm.pngread: Zlib:h.zlib
mm.pngread: Zlib:h.zconf
mm.pngread: LibPng:h.pngconf
mm.pngread: MemCheck:ANSI.h.stdio
mm.pngrtran: LibPng:c.pngrtran
mm.pngrtran: LibPng:h.png
mm.pngrtran: Zlib:h.zlib
mm.pngrtran: Zlib:h.zconf
mm.pngrtran: LibPng:h.pngconf
mm.pngrtran: MemCheck:ANSI.h.stdio
mm.pngrutil: LibPng:c.pngrutil
mm.pngrutil: LibPng:h.png
mm.pngrutil: Zlib:h.zlib
mm.pngrutil: Zlib:h.zconf
mm.pngrutil: LibPng:h.pngconf
mm.pngrutil: MemCheck:ANSI.h.stdio
mm.pngtrans: LibPng:c.pngtrans
mm.pngtrans: LibPng:h.png
mm.pngtrans: Zlib:h.zlib
mm.pngtrans: Zlib:h.zconf
mm.pngtrans: LibPng:h.pngconf
mm.pngtrans: MemCheck:ANSI.h.stdio
mm.pngwrite: LibPng:c.pngwrite
mm.pngwrite: LibPng:h.png
mm.pngwrite: Zlib:h.zlib
mm.pngwrite: Zlib:h.zconf
mm.pngwrite: LibPng:h.pngconf
mm.pngwrite: MemCheck:ANSI.h.stdio
mm.pngwtran: LibPng:c.pngwtran
mm.pngwtran: LibPng:h.png
mm.pngwtran: Zlib:h.zlib
mm.pngwtran: Zlib:h.zconf
mm.pngwtran: LibPng:h.pngconf
mm.pngwtran: MemCheck:ANSI.h.stdio
mm.pngwutil: LibPng:c.pngwutil
mm.pngwutil: LibPng:h.png
mm.pngwutil: Zlib:h.zlib
mm.pngwutil: Zlib:h.zconf
mm.pngwutil: LibPng:h.pngconf
mm.pngwutil: MemCheck:ANSI.h.stdio
o.png: c.png
o.png: h.png
o.png: Zlib:h.zlib
o.png: Zlib:h.zconf
o.png: h.pngconf
o.pngerror: c.pngerror
o.pngerror: h.png
o.pngerror: Zlib:h.zlib
o.pngerror: Zlib:h.zconf
o.pngerror: h.pngconf
o.pngrio: c.pngrio
o.pngrio: h.png
o.pngrio: Zlib:h.zlib
o.pngrio: Zlib:h.zconf
o.pngrio: h.pngconf
o.pngwio: c.pngwio
o.pngwio: h.png
o.pngwio: Zlib:h.zlib
o.pngwio: Zlib:h.zconf
o.pngwio: h.pngconf
o.pngmem: c.pngmem
o.pngmem: h.png
o.pngmem: Zlib:h.zlib
o.pngmem: Zlib:h.zconf
o.pngmem: h.pngconf
o.pngpread: c.pngpread
o.pngpread: h.png
o.pngpread: Zlib:h.zlib
o.pngpread: Zlib:h.zconf
o.pngpread: h.pngconf
o.pngset: c.pngset
o.pngset: h.png
o.pngset: Zlib:h.zlib
o.pngset: Zlib:h.zconf
o.pngset: h.pngconf
o.pngget: c.pngget
o.pngget: h.png
o.pngget: Zlib:h.zlib
o.pngget: Zlib:h.zconf
o.pngget: h.pngconf
o.pngread: c.pngread
o.pngread: h.png
o.pngread: Zlib:h.zlib
o.pngread: Zlib:h.zconf
o.pngread: h.pngconf
o.pngrtran: c.pngrtran
o.pngrtran: h.png
o.pngrtran: Zlib:h.zlib
o.pngrtran: Zlib:h.zconf
o.pngrtran: h.pngconf
o.pngrutil: c.pngrutil
o.pngrutil: h.png
o.pngrutil: Zlib:h.zlib
o.pngrutil: Zlib:h.zconf
o.pngrutil: h.pngconf
o.pngtrans: c.pngtrans
o.pngtrans: h.png
o.pngtrans: Zlib:h.zlib
o.pngtrans: Zlib:h.zconf
o.pngtrans: h.pngconf
o.pngwrite: c.pngwrite
o.pngwrite: h.png
o.pngwrite: Zlib:h.zlib
o.pngwrite: Zlib:h.zconf
o.pngwrite: h.pngconf
o.pngwtran: c.pngwtran
o.pngwtran: h.png
o.pngwtran: Zlib:h.zlib
o.pngwtran: Zlib:h.zconf
o.pngwtran: h.pngconf
o.pngwutil: c.pngwutil
o.pngwutil: h.png
o.pngwutil: Zlib:h.zlib
o.pngwutil: Zlib:h.zconf
o.pngwutil: h.pngconf

View File

@ -22,7 +22,7 @@ AR= oml
# make directory command
MKDIR= makedir
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o pngpread.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o pngpread.o \
pngread.o pngerror.o pngwrite.o pngrtran.o pngwtran.o pngrio.o pngwio.o pngmem.o
all: libpng.lib pngtest

View File

@ -10,7 +10,7 @@ LDFLAGS=-lpng -lz -lm
# where make install puts libpng.a and png.h
OBJS = $(LBR)(png.o) $(LBR)(pngrcb.o) $(LBR)(pngrutil.o)\
OBJS = $(LBR)(png.o) $(LBR)(pngset.o) $(LBR)(pngget.o) $(LBR)(pngrutil.o)\
$(LBR)(pngtrans.o) $(LBR)(pngwutil.o)\
$(LBR)(pngread.o) $(LBR)(pngerror.o) $(LBR)(pngwrite.o)\
$(LBR)(pngrtran.o) $(LBR)(pngwtran.o)\

View File

@ -74,7 +74,8 @@ OBJS = \
pngerror.$(O) \
pngmem.$(O) \
pngpread.$(O) \
pngrcb.$(O) \
pngset.$(O) \
pngget.$(O) \
pngread.$(O) \
pngrio.$(O) \
pngrtran.$(O) \
@ -91,7 +92,8 @@ LIBOBJS = \
+pngmem.$(O) \
+pngpread.$(O) \
+pngread.$(O) \
+pngrcb.$(O) \
+pngset.$(O) \
+pngget.$(O) \
+pngrio.$(O) \
+pngrtran.$(O) \
+pngrutil.$(O) \
@ -126,7 +128,8 @@ test:
## Minor Targets
png.obj: png.c
pngrcb.obj: pngrcb.c
pngset.obj: pngset.c
pngget.obj: pngget.c
pngread.obj: pngread.c
pngpread.obj: pngpread.c
pngrtran.obj: pngrtran.c

View File

@ -12,7 +12,7 @@ RANLIB=ranlib
#prefix=/usr/local
prefix=.
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o pngwtran.o \
pngmem.o pngerror.o pngpread.o
@ -38,7 +38,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngpread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h

View File

@ -3,21 +3,32 @@
# For conditions of distribution and use, see copyright notice in png.h
CC=gcc
CFLAGS=-I../zlib -Wall -Wwrite-strings -Wpointer-arith \
-Wstrict-prototypes -Wmissing-prototypes -O2 -fPIC
LDFLAGS=-L. -Wl,-rpath,. -L../zlib/ -Wl,-rpath,../zlib/ -lpng -lz -lm
# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=../zlib
ZLIBINC=../zlib
WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow \
-Wmissing-declarations -Wtraditional -Wcast-align \
-Wstrict-prototypes -Wmissing-prototypes #-Wconversion
CFLAGS=-I$(ZLIBINC) -Wall -O2 -fPIC # $(WARNMORE) # -g -DPNG_DEBUG=3
LDFLAGS=-L. -Wl,-rpath,. -L$(ZLIBLIB) -Wl,-rpath,$(ZLIBLIB) -lpng -lz -lm
RANLIB=ranlib
#RANLIB=echo
PNGMAJ = 0
PNGMIN = 90
PNGMIN = 96
PNGVER = $(PNGMAJ).$(PNGMIN)
# where make install puts libpng.a, libpng.so*, and png.h
prefix=/usr/local
INCPATH=$(prefix)/include
LIBPATH=$(prefix)/lib
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
@ -37,22 +48,19 @@ libpng.so.$(PNGVER): $(OBJS)
gcc -shared -Wl,-soname,libpng.so.$(PNGMAJ) -o libpng.so.$(PNGVER) $(OBJS)
pngtest: pngtest.o libpng.so
$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
$(CC) -o pngtest pngtest.o $(LDFLAGS)
test: pngtest
./pngtest
install: libpng.so.$(PNGVER)
-@mkdir $(prefix)/include
-@mkdir $(prefix)/lib
cp png.h $(prefix)/include
cp pngconf.h $(prefix)/include
chmod 644 $(prefix)/include/png.h
chmod 644 $(prefix)/include/pngconf.h
cp libpng.so.$(PNGVER) $(prefix)/lib
chmod 755 $(prefix)/lib/libpng.so.$(PNGVER)
-@/bin/rm $(prefix)/lib/libpng.so.$(PNGMAJ) $(prefix)/lib/libpng.so
(cd $(prefix)/lib; ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
-@mkdir $(INCPATH) $(LIBPATH)
cp png.h pngconf.h $(INCPATH)
chmod 644 $(INCPATH)/png.h $(INCPATH)/pngconf.h
cp libpng.so.$(PNGVER) $(LIBPATH)
chmod 755 $(LIBPATH)/libpng.so.$(PNGVER)
-@/bin/rm $(LIBPATH)/libpng.so.$(PNGMAJ) $(LIBPATH)/libpng.so
(cd $(LIBPATH); ln -sf libpng.so.$(PNGVER) libpng.so.$(PNGMAJ); \
ln -sf libpng.so.$(PNGMAJ) libpng.so)
clean:
@ -65,7 +73,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h
pngrutil.o: png.h pngconf.h

View File

@ -14,7 +14,7 @@ RANLIB=ranlib
# where make install puts libpng.a and png.h
prefix=/usr/local
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
@ -60,7 +60,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngpread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h

View File

@ -13,7 +13,7 @@ RANLIB=echo
# where make install puts libpng.a and png.h
prefix=/usr/local
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
@ -49,7 +49,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngpread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h

View File

@ -16,15 +16,19 @@ O=.obj
ERRFILE= >> pngerrs
# variables
OBJS1 = png$(O) pngrcb$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) pngmem$(O) pngpread$(O)
OBJS2 = pngread$(O) pngerror$(O) pngwrite$(O) pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
all: libpng.lib
png$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
pngrcb$(O): png.h pngconf.h
pngset$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
pngget$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
pngread$(O): png.h pngconf.h
@ -66,10 +70,11 @@ pngwtran$(O): png.h pngconf.h
pngwutil$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c $(ERRFILE)
libpng.lib: $(OBJS1) $(OBJS2)
libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
del libpng.lib
lib libpng $(OBJS1);
lib libpng $(OBJS2);
lib libpng $(OBJS3);
pngtest.exe: pngtest.obj libpng.lib
$(LD) $(LDFLAGS) pngtest.obj,,,libpng.lib ..\zlib\zlib.lib ;

View File

@ -2,17 +2,23 @@
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
# For conditions of distribution and use, see copyright notice in png.h
CC=cc
CFLAGS=-I../zlib -O
LDFLAGS=-L. -L../zlib/ -lpng -lz -lm
# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=../zlib
ZLIBINC=../zlib
#RANLIB=ranlib
RANLIB=echo
CC=cc
CFLAGS=-I$(ZLIBINC) -O # -g -DPNG_DEBUG=1
LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
#RANLIB=echo
RANLIB=ranlib
# where make install puts libpng.a and png.h
prefix=/usr/local
OBJS = png.o pngrcb.o pngrutil.o pngtrans.o pngwutil.o \
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
@ -48,7 +54,8 @@ pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngrcb.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h
pngrutil.o: png.h pngconf.h

72
makefile.sun Normal file
View File

@ -0,0 +1,72 @@
# makefile for libpng
# Copyright (C) 1995 Guy Eric Schalnat, Group 42, Inc.
# For conditions of distribution and use, see copyright notice in png.h
# Where the zlib library and include files are located
#ZLIBLIB=/usr/local/lib
#ZLIBINC=/usr/local/include
ZLIBLIB=../zlib
ZLIBINC=../zlib
WARNMORE=-Wwrite-strings -Wpointer-arith -Wshadow -Wconversion \
-Wmissing-declarations -Wtraditional -Wcast-align \
-Wstrict-prototypes -Wmissing-prototypes
CC=gcc
CFLAGS=-I$(ZLIBINC) -O $(WARNMORE) -DPNG_DEBUG=4
LDFLAGS=-L. -L$(ZLIBLIB) -lpng -lz -lm
RANLIB=ranlib
#RANLIB=echo
# where make install puts libpng.a and png.h
prefix=/usr/local
OBJS = png.o pngset.o pngget.o pngrutil.o pngtrans.o pngwutil.o \
pngread.o pngrio.o pngwio.o pngwrite.o pngrtran.o \
pngwtran.o pngmem.o pngerror.o pngpread.o
all: libpng.a pngtest
libpng.a: $(OBJS)
ar rc $@ $(OBJS)
$(RANLIB) $@
pngtest: pngtest.o libpng.a
$(CC) -o pngtest $(CCFLAGS) pngtest.o $(LDFLAGS)
test: pngtest
./pngtest
install: libpng.a
-@mkdir $(prefix)/include
-@mkdir $(prefix)/lib
cp png.h $(prefix)/include
cp pngconf.h $(prefix)/include
chmod 644 $(prefix)/include/png.h
chmod 644 $(prefix)/include/pngconf.h
cp libpng.a $(prefix)/lib
chmod 644 $(prefix)/lib/libpng.a
clean:
rm -f *.o libpng.a pngtest pngout.png
# DO NOT DELETE THIS LINE -- make depend depends on it.
png.o: png.h pngconf.h
pngerror.o: png.h pngconf.h
pngrio.o: png.h pngconf.h
pngwio.o: png.h pngconf.h
pngmem.o: png.h pngconf.h
pngset.o: png.h pngconf.h
pngget.o: png.h pngconf.h
pngread.o: png.h pngconf.h
pngrtran.o: png.h pngconf.h
pngrutil.o: png.h pngconf.h
pngtest.o: png.h pngconf.h
pngtrans.o: png.h pngconf.h
pngwrite.o: png.h pngconf.h
pngwtran.o: png.h pngconf.h
pngwutil.o: png.h pngconf.h
pngpread.o: png.h pngconf.h

View File

@ -13,17 +13,22 @@ LDFLAGS=$(MODEL)
O=.obj
# variables
OBJS1 = png$(O) pngrcb$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O) pngmem$(O) pngpread$(O)
OBJS2 = pngread$(O) pngerror$(O) pngwrite$(O) pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
OBJSL1 = +png$(O) +pngrcb$(O) +pngrutil$(O) +pngtrans$(O) +pngwutil$(O) +pngmem$(O) +pngpread$(O)
OBJSL2 = +pngread$(O) +pngerror$(O) +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)
OBJS1 = png$(O) pngset$(O) pngget$(O) pngrutil$(O) pngtrans$(O) pngwutil$(O)
OBJS2 = pngmem$(O) pngpread$(O) pngread$(O) pngerror$(O) pngwrite$(O)
OBJS3 = pngrtran$(O) pngwtran$(O) pngrio$(O) pngwio$(O)
OBJSL1 = +png$(O) +pngset$(O) +pngget$(O) +pngrutil$(O) +pngtrans$(O)
OBJSL2 = +pngwutil$(O) +pngmem$(O) +pngpread$(O) +pngread$(O) +pngerror$(O)
OBJSL3 = +pngwrite$(O) +pngrtran$(O) +pngwtran$(O) +pngrio$(O) +pngwio$(O)
all: libpng.lib
png$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c
pngrcb$(O): png.h pngconf.h
pngset$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c
pngget$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c
pngread$(O): png.h pngconf.h
@ -65,8 +70,9 @@ pngwtran$(O): png.h pngconf.h
pngwutil$(O): png.h pngconf.h
$(CC) -c $(CFLAGS) $*.c
libpng.lib: $(OBJS1) $(OBJS2)
libpng.lib: $(OBJS1) $(OBJS2) $(OBJS3)
$(LIB) libpng +$(OBJSL1)
$(LIB) libpng +$(OBJSL2)
$(LIB) libpng +$(OBJSL3)
# End of makefile for libpng

View File

@ -38,8 +38,10 @@ $ CALL MAKE png.OBJ "cc ''CCOPT' png" -
png.c png.h pngconf.h
$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -
pngpread.c png.h pngconf.h
$ CALL MAKE pngrcb.OBJ "cc ''CCOPT' pngrcb" -
pngrcb.c png.h pngconf.h
$ CALL MAKE pngset.OBJ "cc ''CCOPT' pngset" -
pngset.c png.h pngconf.h
$ CALL MAKE pngget.OBJ "cc ''CCOPT' pngget" -
pngget.c png.h pngconf.h
$ CALL MAKE pngread.OBJ "cc ''CCOPT' pngread" -
pngread.c png.h pngconf.h
$ CALL MAKE pngpread.OBJ "cc ''CCOPT' pngpread" -

128
png.c
View File

@ -1,41 +1,43 @@
/* png.c - location for general purpose png functions
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
#define PNG_NO_EXTERN
#include "png.h"
/* version information for c files. This better match the version
/* Version information for C files. This had better match the version
string defined in png.h */
char png_libpng_ver[] = "0.90";
char png_libpng_ver[] = "0.95";
/* place to hold the signiture string for a png file. */
/* Place to hold the signiture string for a PNG file. */
png_byte FARDATA png_sig[8] = {137, 80, 78, 71, 13, 10, 26, 10};
/* constant strings for known chunk types. If you need to add a chunk,
add a string holding the name here. If you want to make the code
portable to EBCDIC machines, use ASCII numbers, not characters. */
png_byte FARDATA png_IHDR[4] = { 73, 72, 68, 82};
png_byte FARDATA png_IDAT[4] = { 73, 68, 65, 84};
png_byte FARDATA png_IEND[4] = { 73, 69, 78, 68};
png_byte FARDATA png_PLTE[4] = { 80, 76, 84, 69};
png_byte FARDATA png_gAMA[4] = {103, 65, 77, 65};
png_byte FARDATA png_sBIT[4] = {115, 66, 73, 84};
png_byte FARDATA png_cHRM[4] = { 99, 72, 82, 77};
png_byte FARDATA png_tRNS[4] = {116, 82, 78, 83};
png_byte FARDATA png_bKGD[4] = { 98, 75, 71, 68};
png_byte FARDATA png_hIST[4] = {104, 73, 83, 84};
png_byte FARDATA png_tEXt[4] = {116, 69, 88, 116};
png_byte FARDATA png_zTXt[4] = {122, 84, 88, 116};
png_byte FARDATA png_pHYs[4] = {112, 72, 89, 115};
png_byte FARDATA png_oFFs[4] = {111, 70, 70, 115};
png_byte FARDATA png_tIME[4] = {116, 73, 77, 69};
png_byte FARDATA png_IHDR[5] = { 73, 72, 68, 82, '\0'};
png_byte FARDATA png_IDAT[5] = { 73, 68, 65, 84, '\0'};
png_byte FARDATA png_IEND[5] = { 73, 69, 78, 68, '\0'};
png_byte FARDATA png_PLTE[5] = { 80, 76, 84, 69, '\0'};
png_byte FARDATA png_bKGD[5] = { 98, 75, 71, 68, '\0'};
png_byte FARDATA png_cHRM[5] = { 99, 72, 82, 77, '\0'};
png_byte FARDATA png_gAMA[5] = {103, 65, 77, 65, '\0'};
png_byte FARDATA png_hIST[5] = {104, 73, 83, 84, '\0'};
png_byte FARDATA png_oFFs[5] = {111, 70, 70, 115, '\0'};
png_byte FARDATA png_pCAL[5] = {112, 67, 65, 76, '\0'};
png_byte FARDATA png_pHYs[5] = {112, 72, 89, 115, '\0'};
png_byte FARDATA png_sBIT[5] = {115, 66, 73, 84, '\0'};
png_byte FARDATA png_tEXt[5] = {116, 69, 88, 116, '\0'};
png_byte FARDATA png_tIME[5] = {116, 73, 77, 69, '\0'};
png_byte FARDATA png_tRNS[5] = {116, 82, 78, 83, '\0'};
png_byte FARDATA png_zTXt[5] = {122, 84, 88, 116, '\0'};
/* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
@ -78,6 +80,7 @@ int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
void
png_set_sig_bytes(png_structp png_ptr, int num_bytes)
{
png_debug(1, "in png_set_sig_bytes\n");
if (num_bytes > 8)
png_error(png_ptr, "Too many bytes for PNG signature.");
@ -93,20 +96,20 @@ png_set_sig_bytes(png_structp png_ptr, int num_bytes)
* PNG signature (this is the same behaviour as strcmp, memcmp, etc).
*/
int
png_sig_cmp(png_bytep sig, int start, int num_to_check)
png_sig_cmp(png_bytep sig, png_size_t start, png_size_t num_to_check)
{
if (num_to_check > 8)
num_to_check = 8;
else if (num_to_check < 1)
return 0;
if (start > 7 || start < 0)
if (start > 7)
return 0;
if (start + num_to_check > 8)
num_to_check = 8 - start;
return (png_memcmp(sig, &png_sig[start], (unsigned int)num_to_check));
return (png_memcmp(&sig[start], &png_sig[start], num_to_check));
}
/* (Obsolete) function to check signature bytes. It does not allow one
@ -115,7 +118,7 @@ png_sig_cmp(png_bytep sig, int start, int num_to_check)
int
png_check_sig(png_bytep sig, int num)
{
return !png_sig_cmp(sig, 0, num);
return !png_sig_cmp(sig, (png_size_t)0, (png_size_t)num);
}
/* Function to allocate memory for zlib. */
@ -125,10 +128,9 @@ png_zalloc(voidpf png_ptr, uInt items, uInt size)
png_voidp ptr;
png_uint_32 num_bytes;
ptr = png_malloc((png_structp)png_ptr,
(png_uint_32)items * (png_uint_32)size);
num_bytes = (png_uint_32)items * (png_uint_32)size;
if (num_bytes > (png_uint_32)0x7fff)
num_bytes = (png_uint_32)items * size;
ptr = png_malloc((png_structp)png_ptr, num_bytes);
if (num_bytes > (png_uint_32)0x8000)
{
png_memset(ptr, 0, (png_size_t)0x8000L);
png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
@ -153,7 +155,7 @@ png_zfree(voidpf png_ptr, voidpf ptr)
void
png_reset_crc(png_structp png_ptr)
{
/* set crc to all 1's */
/* set CRC to all 1's */
#ifdef PNG_USE_OWN_CRC
png_ptr->crc = 0xffffffffL;
#else
@ -162,7 +164,8 @@ png_reset_crc(png_structp png_ptr)
}
#ifdef PNG_USE_OWN_CRC
/* Table of CRC's of all 8-bit messages. If you wish to png_malloc this
/* Table of CRCs of all 8-bit messages. By default, we use the tables made
by zlib, to save some memory. If you wish to png_malloc() this
table, turn this into a pointer, and png_malloc() it in make_crc_table().
You may then want to hook it into png_struct and free it with the
destroy functions. Another alternative is to pre-fill the table. */
@ -188,11 +191,11 @@ make_crc_table(void)
crc_table_computed = 1;
}
/* Update a running CRC with the bytes buf[0..len-1]--the crc should be
/* Update a running CRC with the bytes buf[0..len-1] - the CRC should be
initialized to all 1's, and the transmitted value is the 1's complement
of the final running CRC. */
static png_uint_32
update_crc(png_uint_32 crc, png_bytep buf, png_uint_32 len)
update_crc(png_uint_32 crc, png_bytep buf, png_size_t len)
{
png_uint_32 c;
png_bytep p;
@ -216,14 +219,28 @@ update_crc(png_uint_32 crc, png_bytep buf, png_uint_32 len)
}
#endif /* PNG_USE_OWN_CRC */
/* Calculate the crc over a section of data. Note that while we
are passing in a 32 bit value for length, on 16 bit machines, you
would need to use huge pointers to access all that data. If you
need this, put huge here and above. */
/* Calculate the CRC over a section of data. We can only pass as
much data to this routine as the largest single buffer size. We
also check that this data will actually be used before going to the
trouble of calculating it. */
void
png_calculate_crc(png_structp png_ptr, png_bytep ptr,
png_uint_32 length)
png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
{
int need_crc = 1;
if (png_ptr->chunk_name[0] & 0x20) /* ancillary */
{
if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
(PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
need_crc = 0;
}
else /* critical */
{
if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
need_crc = 0;
}
if (need_crc)
#ifdef PNG_USE_OWN_CRC
png_ptr->crc = update_crc(png_ptr->crc, ptr, length);
#else
@ -241,6 +258,7 @@ png_create_info_struct(png_structp png_ptr)
{
png_infop info_ptr;
png_debug(1, "in png_create_info_struct\n");
if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
{
png_info_init(info_ptr);
@ -258,10 +276,11 @@ png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
png_infop info_ptr = NULL;
if (info_ptr_ptr)
png_debug(1, "in png_destroy_info_struct\n");
if (info_ptr_ptr != NULL)
info_ptr = *info_ptr_ptr;
if (info_ptr)
if (info_ptr != NULL)
{
png_info_destroy(png_ptr, info_ptr);
@ -276,24 +295,42 @@ png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
void
png_info_init(png_infop info_ptr)
{
png_debug(1, "in png_info_init\n");
/* set everything to 0 */
png_memset(info_ptr, 0, sizeof (png_info));
}
/* This is an internal routine to free any memory that the info struct is
pointing to before re-using it or freeing the struct itself. */
* pointing to before re-using it or freeing the struct itself. Recall
* that png_free() checks for NULL pointers for us.
*/
void
png_info_destroy(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
int i;
png_debug(1, "in png_info_destroy\n");
if (info_ptr->text != NULL)
{
for (i = 0; i < info_ptr->num_text; i++)
{
png_free(png_ptr, info_ptr->text[i].key);
}
png_free(png_ptr, info_ptr->text);
}
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
png_free(png_ptr, info_ptr->pcal_purpose);
png_free(png_ptr, info_ptr->pcal_units);
if (info_ptr->pcal_params != NULL)
{
for (i = 0; i < info_ptr->pcal_nparams; i++)
{
png_free(png_ptr, info_ptr->pcal_params[i]);
}
png_free(png_ptr, info_ptr->pcal_params);
}
#endif
png_info_init(info_ptr);
@ -308,11 +345,14 @@ png_get_io_ptr(png_structp png_ptr)
return png_ptr->io_ptr;
}
/* Initialize the default input/output functions for the png file. If you
change the read, or write routines, you can call either png_set_read_fn()
#if !defined(PNG_NO_STDIO)
/* Initialize the default input/output functions for the PNG file. If you
use your own read or write routines, you can call either png_set_read_fn()
or png_set_write_fn() instead of png_init_io(). */
void
png_init_io(png_structp png_ptr, FILE *fp)
{
png_debug(1, "in png_init_io\n");
png_ptr->io_ptr = (png_voidp)fp;
}
#endif

1737
png.h

File diff suppressed because it is too large Load Diff

203
pngconf.h
View File

@ -1,10 +1,11 @@
/* pngconf.c - machine configurable file for libpng
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
December 3, 1996
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
/* Any machine specific code is near the front of this file, so if you
@ -29,16 +30,16 @@
#define PNG_ZBUF_SIZE 8192
/* If you are running on a machine where you cannot allocate more then
64K of memory, uncomment this. While libpng will not normally need
that much memory in a chunk (unless you load up a very large file),
zlib needs to know how big of a chunk it can use, and libpng thus
makes sure to check any memory allocation to verify it will fit
into memory.
#define PNG_MAX_ALLOC_64K
/* If you are running on a machine where you cannot allocate more
than 64K of memory at once, uncomment this. While libpng will not
normally need that much memory in a chunk (unless you load up a very
large file), zlib needs to know how big of a chunk it can use, and
libpng thus makes sure to check any memory allocation to verify it
will fit into memory.
#define PNG_MAX_MALLOC_64K
*/
#ifdef MAXSEG_64K
#define PNG_MAX_ALLOC_64K
#if defined(MAXSEG_64K) && !defined(PNG_MAX_MALLOC_64K)
#define PNG_MAX_MALLOC_64K
#endif
/* This protects us against compilers which run on a windowing system
@ -56,12 +57,13 @@
/* This macro protects us against machines that don't have function
prototypes (ie K&R style headers). If your compiler does not handle
function prototypes, define this macro. I've always been able to use
_NO_PROTO as the indicator, but you may need to drag the empty declaration
out in front of here, or change the ifdef to suit your own needs. */
function prototypes, define this macro and use the included ansi2knr.
I've always been able to use _NO_PROTO as the indicator, but you may
need to drag the empty declaration out in front of here, or change the
ifdef to suit your own needs. */
#ifndef PNGARG
#ifdef OF /* Zlib prototype munger */
#ifdef OF /* zlib prototype munger */
#define PNGARG(arglist) OF(arglist)
#else
@ -85,17 +87,16 @@
#include <sys/types.h>
#endif
/* need the time information for reading tIME chunks */
#include <time.h>
/* This is an attempt to force a single setjmp behaviour on Linux */
/* This is an attempt to force a single setjmp behaviour on Linux. If
the X config stuff didn't define _BSD_SOURCE we wouldn't need this. */
#ifdef linux
#ifdef _BSD_SOURCE
#define _PNG_SAVE_BSD_SOURCE
#undef _BSD_SOURCE
#endif
#ifdef _SETJMP_H
error: png.h already includes setjmp.h
#error __png_h_already_includes_setjmp_h__
#error __dont_include_it_again__
#endif
#endif /* linux */
@ -115,25 +116,39 @@ error: png.h already includes setjmp.h
#include <string.h>
#endif
/* Other defines for things like memory and the like can go here. These
are the only files included in libpng, so if you need to change them,
change them here. They are only included if PNG_INTERNAL is defined. */
/* Other defines for things like memory and the like can go here. */
#ifdef PNG_INTERNAL
#include <stdlib.h>
/* Where do we need this???
#include <ctype.h>
*/
/* The functions exported by PNG_EXTERN are PNG_INTERNAL functions, which
* aren't usually used outside the library (as far as I know), so it is
* debatable if they should be exported at all. In the future, when it is
* possible to have run-time registry of chunk-handling functions, some of
* these will be made available again.
#define PNG_EXTERN extern
*/
#define PNG_EXTERN
/* Other defines specific to compilers can go here. Try to keep
them inside an appropriate ifdef/endif pair for portability */
#ifdef MACOS
#if defined(MACOS)
/* We need to check that <math.h> hasn't already been included earlier
as it seems it doesn't agree with <fp.h>, yet we should really use
<fp.h> if possible. */
#if !defined(__MATH_H__) && !defined(__MATH_H) && !defined(__cmath__)
#include <fp.h>
#endif
#else
#include <math.h>
#endif
/* For some reason, Borland C++ defines memcmp, etc. in mem.h, not
stdlib.h like it should (I think). Or perhaps this is a C++
feature? */
"feature"? */
#ifdef __TURBOC__
#include <mem.h>
#include "alloc.h"
@ -159,6 +174,10 @@ error: png.h already includes setjmp.h
#define PNG_MAX_GAMMA_8 11
/* This controls how much a difference in gamma we can tolerate before
we actually start doing gamma conversion. */
#define PNG_GAMMA_THRESHOLD 0.05
#endif /* PNG_INTERNAL */
/* The following uses const char * instead of char * for error
@ -167,8 +186,7 @@ error: png.h already includes setjmp.h
normally defined to make configuration easier, as it is not a
critical part of the code.
*/
#define PNG_USE_CONST
#undef PNG_USE_CONST
#ifdef PNG_USE_CONST
# define PNG_CONST const
@ -191,12 +209,14 @@ error: png.h already includes setjmp.h
/* Any transformations you will not be using can be undef'ed here */
#define PNG_PROGRESSIVE_READ_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_READ_INTERLACING_SUPPORTED
#define PNG_READ_EXPAND_SUPPORTED
#define PNG_READ_SHIFT_SUPPORTED
#define PNG_READ_PACK_SUPPORTED
#define PNG_READ_BGR_SUPPORTED
#define PNG_READ_SWAP_SUPPORTED
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_DITHER_SUPPORTED
#define PNG_READ_BACKGROUND_SUPPORTED
@ -204,55 +224,79 @@ error: png.h already includes setjmp.h
#define PNG_READ_FILLER_SUPPORTED
#define PNG_READ_GAMMA_SUPPORTED
#define PNG_READ_GRAY_TO_RGB_SUPPORTED
#define PNG_READ_SWAP_ALPHA_SUPPORTED
#define PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED
#define PNG_WRITE_PACK_SUPPORTED
#define PNG_WRITE_BGR_SUPPORTED
#define PNG_WRITE_SWAP_SUPPORTED
#define PNG_WRITE_PACKSWAP_SUPPORTED
#define PNG_WRITE_INVERT_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED
#define PNG_WRITE_FILLER_SUPPORTED /* This is the same as WRITE_STRIP_ALPHA */
#define PNG_WRITE_FLUSH_SUPPORTED
#define PNG_WRITE_SWAP_ALPHA_SUPPORTED
#define PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
/* These are currently experimental features */
#undef PNG_READ_16_TO_8_ACCURATE_SHIFT_SUPPORTED /* very little testing */
#undef PNG_READ_COMPOSITE_NODIV_SUPPORTED /* very little testing */
/* This is only for PowerPC big-endian and 680x0 systems */
#undef PNG_READ_BIG_ENDIAN_SUPPORTED /* some testing */
/* These functions are turned off by default, as they will be phased out. */
#undef PNG_USE_OWN_CRC
#undef PNG_USELESS_TESTS_SUPPORTED
#undef PNG_CORRECT_PALETTE_SUPPORTED
/* any chunks you are not interested in, you can undef here. The
ones that allocate memory may be expecially important (hIST,
tEXt, zTXt, tRNS) Others will just save time and make png_info
smaller. OPT_PLTE only disables the optional palette in RGB
and RGB Alpha images. */
/* Any chunks you are not interested in, you can undef here. The
* ones that allocate memory may be expecially important (hIST,
* tEXt, zTXt, tRNS, pCAL). Others will just save time and make png_info
* a bit smaller. OPT_PLTE only disables the optional palette in RGB
* and RGBA images.
*/
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_bKGD_SUPPORTED
#define PNG_READ_cHRM_SUPPORTED
#define PNG_READ_gAMA_SUPPORTED
#define PNG_READ_hIST_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_READ_oFFs_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_pCAL_SUPPORTED
#define PNG_READ_pHYs_SUPPORTED
#define PNG_READ_sBIT_SUPPORTED
#define PNG_READ_tEXt_SUPPORTED
#define PNG_READ_tIME_SUPPORTED
#define PNG_READ_tRNS_SUPPORTED
#define PNG_READ_zTXt_SUPPORTED
#define PNG_READ_OPT_PLTE_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_WRITE_bKGD_SUPPORTED
#define PNG_WRITE_cHRM_SUPPORTED
#define PNG_WRITE_gAMA_SUPPORTED
#define PNG_WRITE_hIST_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_oFFs_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_WRITE_pCAL_SUPPORTED
#define PNG_WRITE_pHYs_SUPPORTED
#define PNG_WRITE_sBIT_SUPPORTED
#define PNG_WRITE_tEXt_SUPPORTED
#define PNG_WRITE_tIME_SUPPORTED
#define PNG_WRITE_tRNS_SUPPORTED
#define PNG_WRITE_zTXt_SUPPORTED
/* need the time information for reading tIME chunks */
#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
#include <time.h>
#endif
/* Some typedefs to get us started. These should be safe on most of the
common platforms. The typedefs should be at least as large as the
numbers suggest (a png_uint_32 must be at least 32 bits long), but they
don't have to be exactly that size. */
* common platforms. The typedefs should be at least as large as the
* numbers suggest (a png_uint_32 must be at least 32 bits long), but they
* don't have to be exactly that size. Some compilers dislike passing
* unsigned shorts as function parameters, so you may be better off using
* unsigned int for png_uint_16. Likewise, for 64-bit systems, you may
* want to have unsigned int for png_uint_32 instead of unsigned long.
*/
typedef unsigned long png_uint_32;
typedef long png_int_32;
@ -265,13 +309,13 @@ typedef unsigned char png_byte;
typedef size_t png_size_t;
/* The following is needed for medium model support. It cannot be in the
PNG_INTERNAL section. Needs modification for other compilers besides
MSC. Model independent support declares all arrays that might be very
large using the far keyword. The Zlib version used must also support
model independent data. As of version Zlib .95, the necessary changes
have been made in Zlib. The USE_FAR_KEYWORD define triggers other
changes that are needed. Most of the far keyword changes are hidden
inside typedefs with suffix "f". (Tim Wegner) */
* PNG_INTERNAL section. Needs modification for other compilers besides
* MSC. Model independent support declares all arrays and pointers to be
* large using the far keyword. The zlib version used must also support
* model independent data. As of version zlib 1.0.4, the necessary changes
* have been made in zlib. The USE_FAR_KEYWORD define triggers other
* changes that are needed. (Tim Wegner)
*/
/* Separate compiler dependencies (problem here is that zlib.h always
defines FAR. (SJT) */
@ -319,17 +363,12 @@ typedef size_t png_size_t;
# define FAR
#endif
/* SJT: At this point FAR is always defined */
/* SJT: */
/* At this point FAR is always defined */
#ifndef FARDATA
#define FARDATA
#endif
/* Not used anymore (as of 0.88), but kept for compatability (for now). */
typedef unsigned char FAR png_bytef;
/* SJT: Add typedefs for pointers */
/* Add typedefs for pointers */
typedef void FAR * png_voidp;
typedef png_byte FAR * png_bytep;
typedef png_uint_32 FAR * png_uint_32p;
@ -338,8 +377,9 @@ typedef png_uint_16 FAR * png_uint_16p;
typedef png_int_16 FAR * png_int_16p;
typedef PNG_CONST char FAR * png_const_charp;
typedef char FAR * png_charp;
typedef double FAR * png_doublep;
/* SJT: Pointers to pointers; i.e. arrays */
/* Pointers to pointers; i.e. arrays */
typedef png_byte FAR * FAR * png_bytepp;
typedef png_uint_32 FAR * FAR * png_uint_32pp;
typedef png_int_32 FAR * FAR * png_int_32pp;
@ -347,16 +387,29 @@ typedef png_uint_16 FAR * FAR * png_uint_16pp;
typedef png_int_16 FAR * FAR * png_int_16pp;
typedef PNG_CONST char FAR * FAR * png_const_charpp;
typedef char FAR * FAR * png_charpp;
typedef double FAR * FAR * png_doublepp;
/* Pointers to pointers to pointers; i.e. pointer to array */
typedef char FAR * FAR * FAR * png_charppp;
/* SJT: libpng typedefs for types in zlib. If Zlib changes
or another compression library is used, then change these.
Eliminates need to change all the source files.
*/
/* libpng typedefs for types in zlib. If zlib changes
* or another compression library is used, then change these.
* Eliminates need to change all the source files.
*/
typedef charf * png_zcharp;
typedef charf * FAR * png_zcharpp;
typedef z_stream FAR * png_zstreamp;
/* allow for compilation as dll under windows */
#ifdef __WIN32DLL__
#define PNG_EXPORT(type,symbol) __declspec(dllexport) type symbol
#endif
#ifndef PNG_EXPORT
#define PNG_EXPORT(t,s) t s
#endif
/* User may want to use these so not in PNG_INTERNAL. Any library functions
that are passed far data must be model independent. */
@ -366,25 +419,27 @@ typedef z_stream FAR * png_zstreamp;
# define NOCHECK 0
# define CVT_PTR(ptr) (far_to_near(png_ptr,ptr,CHECK))
# define CVT_PTR_NOCHECK(ptr) (far_to_near(png_ptr,ptr,NOCHECK))
# define png_strcpy _fstrcpy
# define png_strcat _fstrcat
# define png_strlen _fstrlen
# define png_strcmp _fstrcmp
# define png_memcmp _fmemcmp /* SJT: added */
# define png_memcpy _fmemcpy
# define png_memset _fmemset
#else /* use the usual functions */
# define CVT_PTR(ptr) (ptr)
# define CVT_PTR_NOCHECK(ptr) (ptr)
# define png_strcpy strcpy
# define png_strcat strcat
# define png_strlen strlen
# define png_strcmp strcmp
# define png_memcmp memcmp /* SJT: added */
# define png_memcpy memcpy
# define png_memset memset
#endif
/* End of memory model independent support */
/* Just a double check that someone hasn't tried to define something
* contradictory.
*/
#if (PNG_ZBUF_SIZE > 65536) && defined(PNG_MAX_MALLOC_64K)
#undef PNG_ZBUF_SIZE
#define PNG_ZBUF_SIZE 65536
#endif
#endif /* PNGCONF_H */

View File

@ -1,10 +1,11 @@
/* pngerror.c - stub functions for i/o and memory allocation
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
This file provides a location for all error handling. Users which
need special error handling are expected to write replacement functions
@ -26,7 +27,7 @@ static void png_default_warning PNGARG((png_structp png_ptr,
void
png_error(png_structp png_ptr, png_const_charp message)
{
if (png_ptr->error_fn)
if (png_ptr->error_fn != NULL)
(*(png_ptr->error_fn))(png_ptr, message);
/* if the following returns or doesn't exist, use the default function,
@ -41,7 +42,7 @@ png_error(png_structp png_ptr, png_const_charp message)
void
png_warning(png_structp png_ptr, png_const_charp message)
{
if (png_ptr->warning_fn)
if (png_ptr->warning_fn != NULL)
(*(png_ptr->warning_fn))(png_ptr, message);
else
png_default_warning(png_ptr, message);
@ -76,7 +77,7 @@ png_default_error(png_structp png_ptr, png_const_charp message)
static void
png_default_warning(png_structp png_ptr, png_const_charp message)
{
if (!png_ptr)
if (png_ptr == NULL)
return;
#ifndef PNG_NO_STDIO

300
pngget.c Normal file
View File

@ -0,0 +1,300 @@
/* pngget.c - retrieval of values from info struct
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
#include "png.h"
png_uint_32
png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
{
if (info_ptr != NULL)
return(info_ptr->valid & flag);
else
return(0);
}
png_uint_32
png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
return(info_ptr->rowbytes);
else
return(0);
}
png_byte
png_get_channels(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
return(info_ptr->channels);
else
return(0);
}
png_bytep
png_get_signature(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
return(info_ptr->signature);
else
return(NULL);
}
#if defined(PNG_READ_bKGD_SUPPORTED)
png_uint_32
png_get_bKGD(png_structp png_ptr, png_infop info_ptr,
png_color_16p *background)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_bKGD &&
background != NULL)
{
png_debug1(1, "in %s retrieval function\n", "bKGD");
*background = &(info_ptr->background);
return (PNG_INFO_bKGD);
}
return (0);
}
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
png_uint_32
png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
double *white_x, double *white_y, double *red_x, double *red_y,
double *green_x, double *green_y, double *blue_x, double *blue_y)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_cHRM)
{
png_debug1(1, "in %s retrieval function\n", "cHRM");
if (white_x != NULL)
*white_x = (double)info_ptr->x_white;
if (white_y != NULL)
*white_y = (double)info_ptr->y_white;
if (red_x != NULL)
*red_x = (double)info_ptr->x_red;
if (red_y != NULL)
*red_y = (double)info_ptr->y_red;
if (green_x != NULL)
*green_x = (double)info_ptr->x_green;
if (green_y != NULL)
*green_y = (double)info_ptr->y_green;
if (blue_x != NULL)
*blue_x = (double)info_ptr->x_blue;
if (blue_y != NULL)
*blue_y = (double)info_ptr->y_blue;
return (PNG_INFO_cHRM);
}
return (0);
}
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
png_uint_32
png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_gAMA &&
file_gamma != NULL)
{
png_debug1(1, "in %s retrieval function\n", "gAMA");
*file_gamma = (double)info_ptr->gamma;
return (PNG_INFO_gAMA);
}
return (0);
}
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
png_uint_32
png_get_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p *hist)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_hIST && hist != NULL)
{
png_debug1(1, "in %s retrieval function\n", "hIST");
*hist = info_ptr->hist;
return (PNG_INFO_hIST);
}
return (0);
}
#endif
png_uint_32
png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *width, png_uint_32 *height, int *bit_depth,
int *color_type, int *interlace_type, int *compression_type,
int *filter_type)
{
if (info_ptr != NULL && width != NULL && height != NULL &&
bit_depth != NULL && color_type != NULL)
{
png_debug1(1, "in %s retrieval function\n", "IHDR");
*width = info_ptr->width;
*height = info_ptr->height;
*bit_depth = info_ptr->bit_depth;
*color_type = info_ptr->color_type;
if (compression_type != NULL)
*compression_type = info_ptr->compression_type;
if (filter_type != NULL)
*filter_type = info_ptr->filter_type;
if (interlace_type != NULL)
*interlace_type = info_ptr->interlace_type;
return (1);
}
return (0);
}
#if defined(PNG_READ_oFFs_SUPPORTED)
png_uint_32
png_get_oFFs(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *offset_x, png_uint_32 *offset_y, int *unit_type)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_oFFs &&
offset_x != NULL && offset_y != NULL && unit_type != NULL)
{
png_debug1(1, "in %s retrieval function\n", "oFFs");
*offset_x = info_ptr->x_offset;
*offset_y = info_ptr->y_offset;
*unit_type = (int)info_ptr->offset_unit_type;
return (PNG_INFO_oFFs);
}
return (0);
}
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
png_uint_32
png_get_pCAL(png_structp png_ptr, png_infop info_ptr,
png_charp *purpose, png_int_32 *X0, png_int_32 *X1, int *type, int *nparams,
png_charp *units, png_charpp *params)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL &&
purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
nparams != NULL && units != NULL && params != NULL)
{
png_debug1(1, "in %s retrieval function\n", "pCAL");
*purpose = info_ptr->pcal_purpose;
*X0 = info_ptr->pcal_X0;
*X1 = info_ptr->pcal_X1;
*type = (int)info_ptr->pcal_type;
*nparams = (int)info_ptr->pcal_nparams;
*units = info_ptr->pcal_units;
*params = info_ptr->pcal_params;
return (PNG_INFO_pCAL);
}
return (0);
}
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
png_uint_32
png_get_pHYs(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs &&
res_x != NULL && res_y != NULL && unit_type != NULL)
{
png_debug1(1, "in %s retrieval function\n", "pHYs");
*res_x = info_ptr->x_pixels_per_unit;
*res_y = info_ptr->y_pixels_per_unit;
*unit_type = (int)info_ptr->phys_unit_type;
return (PNG_INFO_pHYs);
}
return (0);
}
#endif
png_uint_32
png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
int *num_palette)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_PLTE && palette != NULL)
{
png_debug1(1, "in %s retrieval function\n", "PLTE");
*palette = info_ptr->palette;
*num_palette = info_ptr->num_palette;
png_debug1(3, "num_palette = %d\n", *num_palette);
return (PNG_INFO_PLTE);
}
return (0);
}
#if defined(PNG_READ_sBIT_SUPPORTED)
png_uint_32
png_get_sBIT(png_structp png_ptr, png_infop info_ptr, png_color_8p *sig_bit)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_sBIT && sig_bit != NULL)
{
png_debug1(1, "in %s retrieval function\n", "sBIT");
*sig_bit = &(info_ptr->sig_bit);
return (PNG_INFO_sBIT);
}
return (0);
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
png_uint_32
png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
int *num_text)
{
if ((info_ptr != NULL) || (info_ptr->num_text > 0))
{
png_debug1(1, "in %s retrieval function\n",
(png_ptr->chunk_name[0] == '\0' ? "text" : png_ptr->chunk_name));
if (text_ptr != NULL)
*text_ptr = info_ptr->text;
if (num_text != NULL)
*num_text = info_ptr->num_text;
return (info_ptr->num_text);
}
return(0);
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
png_uint_32
png_get_tIME(png_structp png_ptr, png_infop info_ptr, png_timep *mod_time)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tIME && mod_time != NULL)
{
png_debug1(1, "in %s retrieval function\n", "tIME");
*mod_time = &(info_ptr->mod_time);
return (PNG_INFO_tIME);
}
return (0);
}
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
png_uint_32
png_get_tRNS(png_structp png_ptr, png_infop info_ptr,
png_bytep *trans, int *num_trans, png_color_16p *trans_values)
{
if (info_ptr != NULL && info_ptr->valid & PNG_INFO_tRNS)
{
png_debug1(1, "in %s retrieval function\n", "tRNS");
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE && trans != NULL)
{
*trans = info_ptr->trans;
}
else if (trans_values != NULL)
{
*trans_values = &(info_ptr->trans_values);
}
else
{
return (0);
}
*num_trans = info_ptr->num_trans;
return (PNG_INFO_tRNS);
}
return (0);
}
#endif

View File

@ -1,10 +1,11 @@
/* pngmem.c - stub functions for memory allocation
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
This file provides a location for all memory allocation. Users which
need special memory handling are expected to modify the code in this file
@ -45,30 +46,34 @@ png_create_struct(int type)
void
png_destroy_struct(png_voidp struct_ptr)
{
if (struct_ptr)
if (struct_ptr != NULL)
farfree (struct_ptr);
}
/* Allocate memory. For reasonable files, size should never exceed
64K. However, zlib may allocate more then 64K if you don't tell
it not to. See zconf.h and png.h for more information. zlib does
need to allocate exactly 64K, so whatever you call here must
have the ability to do that. */
/* Borland seems to have a problem in DOS mode for exactly 64K.
It gives you a segment with an offset of 8 (perhaps to store it's
memory stuff). zlib doesn't like this at all, so we have to
detect and deal with it. This code should not be needed in
Windows or OS/2 modes, and only in 16 bit mode. This code has
been updated by Alexander Lehmann for version 0.89 to waste less
memory.
*/
* 64K. However, zlib may allocate more then 64K if you don't tell
* it not to. See zconf.h and png.h for more information. zlib does
* need to allocate exactly 64K, so whatever you call here must
* have the ability to do that.
*
* Borland seems to have a problem in DOS mode for exactly 64K.
* It gives you a segment with an offset of 8 (perhaps to store it's
* memory stuff). zlib doesn't like this at all, so we have to
* detect and deal with it. This code should not be needed in
* Windows or OS/2 modes, and only in 16 bit mode. This code has
* been updated by Alexander Lehmann for version 0.89 to waste less
* memory.
*
* Note that we can't use png_size_t for the "size" declaration,
* since on some systems a png_size_t is a 16-bit quantity, and as a
* result, we would be truncating potentially larger memory requests
* (which should cause a fatal error) and introducing major problems.
*/
png_voidp
png_malloc(png_structp png_ptr, png_uint_32 size)
{
png_voidp ret;
if (!png_ptr || !size)
if (png_ptr == NULL || size == 0)
return ((voidp)NULL);
#ifdef PNG_MAX_MALLOC_64K
@ -78,11 +83,11 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
if (size == (png_uint_32)(65536L))
{
if (!png_ptr->offset_table)
if (png_ptr->offset_table == NULL)
{
/* try to see if we need to do any of this fancy stuff */
ret = farmalloc(size);
if (!ret || ((long)ret & 0xffff))
if (ret == NULL || ((png_size_t)ret & 0xffff))
{
int num_blocks;
png_uint_32 total_size;
@ -90,7 +95,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
int i;
png_byte huge * hptr;
if (ret)
if (ret != NULL)
farfree(ret);
ret = NULL;
@ -106,27 +111,27 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
table = farmalloc(total_size);
if (!table)
if (table == NULL)
{
png_error(png_ptr, "Out of Memory");
}
if ((long)table & 0xfff0)
if ((png_size_t)table & 0xfff0)
{
png_error(png_ptr, "Farmalloc didn't return normalized pointer");
}
png_ptr->offset_table = table;
png_ptr->offset_table_ptr = farmalloc(
num_blocks * sizeof (png_bytep));
png_ptr->offset_table_ptr = farmalloc(num_blocks *
sizeof (png_bytep));
if (!png_ptr->offset_table_ptr)
if (png_ptr->offset_table_ptr == NULL)
{
png_error(png_ptr, "Out of memory");
}
hptr = (png_byte huge *)table;
if ((long)hptr & 0xf)
if ((png_size_t)hptr & 0xf)
{
hptr = (png_byte huge *)((long)(hptr) & 0xfffffff0L);
hptr += 16L;
@ -165,12 +170,10 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
void
png_free(png_structp png_ptr, png_voidp ptr)
{
if (!png_ptr)
if (png_ptr == NULL || ptr == NULL)
return;
if (ptr != NULL)
{
if (png_ptr->offset_table)
if (png_ptr->offset_table != NULL)
{
int i;
@ -178,7 +181,7 @@ png_free(png_structp png_ptr, png_voidp ptr)
{
if (ptr == png_ptr->offset_table_ptr[i])
{
ptr = 0;
ptr = NULL;
png_ptr->offset_table_count_free++;
break;
}
@ -187,14 +190,13 @@ png_free(png_structp png_ptr, png_voidp ptr)
{
farfree(png_ptr->offset_table);
farfree(png_ptr->offset_table_ptr);
png_ptr->offset_table = 0;
png_ptr->offset_table_ptr = 0;
png_ptr->offset_table = NULL;
png_ptr->offset_table_ptr = NULL;
}
}
if (ptr)
if (ptr != NULL)
farfree(ptr);
}
}
#else /* Not the Borland DOS special memory handler */
@ -205,7 +207,7 @@ png_free(png_structp png_ptr, png_voidp ptr)
png_voidp
png_create_struct(int type)
{
size_t size;
png_size_t size;
png_voidp struct_ptr;
if (type == PNG_STRUCT_INFO)
@ -236,7 +238,7 @@ png_create_struct(int type)
void
png_destroy_struct(png_voidp struct_ptr)
{
if (struct_ptr)
if (struct_ptr != NULL)
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(struct_ptr);
#else
@ -255,13 +257,12 @@ png_destroy_struct(png_voidp struct_ptr)
need to allocate exactly 64K, so whatever you call here must
have the ability to do that. */
#ifndef FORTIFY
png_voidp
png_malloc(png_structp png_ptr, png_uint_32 size)
{
png_voidp ret;
if (!png_ptr || !size)
return ((voidp)0);
if (png_ptr == NULL || size == 0)
return (NULL);
#ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
@ -269,7 +270,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
#endif
#if defined(__TURBOC__) && !defined(__FLAT__)
ret = farmalloc(size);
ret = farmalloc((png_size_t)size);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
ret = halloc(size, 1);
@ -286,17 +287,15 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
return ret;
}
/* free a pointer allocated by png_malloc(). In the default
/* Free a pointer allocated by png_malloc(). In the default
configuration, png_ptr is not used, but is passed in case it
is needed. If ptr is NULL, return without taking any action. */
void
png_free(png_structp png_ptr, png_voidp ptr)
{
if (!png_ptr)
if (png_ptr == NULL || ptr == NULL)
return;
if (ptr != NULL)
{
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(ptr);
#else
@ -306,9 +305,7 @@ png_free(png_structp png_ptr, png_voidp ptr)
free(ptr);
# endif
#endif
}
}
#endif /* FORTIFY */
#endif /* Not Borland DOS special memory handler */

View File

@ -1,10 +1,11 @@
/* pngpread.c - read a png file in push mode
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
@ -14,7 +15,7 @@
void
png_process_data(png_structp png_ptr, png_infop info_ptr,
png_bytep buffer, png_uint_32 buffer_size)
png_bytep buffer, png_size_t buffer_size)
{
png_push_restore_buffer(png_ptr, buffer, buffer_size);
@ -61,14 +62,9 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr)
break;
}
#endif
case PNG_READ_END_MODE:
{
png_push_read_chunk(png_ptr, info_ptr);
break;
}
case PNG_SKIP_MODE:
{
png_push_skip(png_ptr);
png_push_crc_finish(png_ptr);
break;
}
default:
@ -87,7 +83,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr)
void
png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
{
int num_checked = png_ptr->sig_bytes,
png_size_t num_checked = png_ptr->sig_bytes,
num_to_check = 8 - num_checked;
if (png_ptr->buffer_size < num_to_check)
@ -96,7 +92,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
}
png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]),
(png_uint_32)num_to_check);
num_to_check);
png_ptr->sig_bytes += num_to_check;
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
@ -137,8 +133,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_push_fill_buffer(png_ptr, chunk_length, 4);
png_ptr->push_length = png_get_uint_32(chunk_length);
png_reset_crc(png_ptr);
png_push_fill_buffer(png_ptr, png_ptr->chunk_name, 4);
png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
}
@ -292,6 +287,18 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
{
if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{
png_push_save_buffer(png_ptr);
return;
}
png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
{
@ -325,21 +332,21 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
}
void
png_push_crc_skip(png_structp png_ptr, png_uint_32 length)
png_push_crc_skip(png_structp png_ptr, png_uint_32 skip)
{
png_ptr->process_mode = PNG_SKIP_MODE;
png_ptr->skip_length = length;
png_ptr->skip_length = skip;
}
void
png_push_skip(png_structp png_ptr)
png_push_crc_finish(png_structp png_ptr)
{
if (png_ptr->skip_length && png_ptr->save_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (png_ptr->skip_length < png_ptr->save_buffer_size)
save_size = png_ptr->skip_length;
if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
save_size = (png_size_t)png_ptr->skip_length;
else
save_size = png_ptr->save_buffer_size;
@ -348,14 +355,14 @@ png_push_skip(png_structp png_ptr)
png_ptr->skip_length -= save_size;
png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += (png_size_t)save_size;
png_ptr->save_buffer_ptr += save_size;
}
if (png_ptr->skip_length && png_ptr->current_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (png_ptr->skip_length < png_ptr->current_buffer_size)
save_size = png_ptr->skip_length;
if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
save_size = (png_size_t)png_ptr->skip_length;
else
save_size = png_ptr->current_buffer_size;
@ -364,7 +371,7 @@ png_push_skip(png_structp png_ptr)
png_ptr->skip_length -= save_size;
png_ptr->buffer_size -= save_size;
png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += (png_size_t)save_size;
png_ptr->current_buffer_ptr += save_size;
}
if (!png_ptr->skip_length)
{
@ -375,50 +382,45 @@ png_push_skip(png_structp png_ptr)
}
png_crc_finish(png_ptr, 0);
if (png_ptr->mode & PNG_AFTER_IDAT)
png_ptr->process_mode = PNG_READ_END_MODE;
else
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
}
}
void
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer,
png_uint_32 length)
png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length)
{
png_bytep ptr;
ptr = buffer;
if (png_ptr->save_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (length < png_ptr->save_buffer_size)
save_size = length;
else
save_size = png_ptr->save_buffer_size;
png_memcpy(ptr, png_ptr->save_buffer_ptr, (png_size_t)save_size);
png_memcpy(ptr, png_ptr->save_buffer_ptr, save_size);
length -= save_size;
ptr += (png_size_t)save_size;
ptr += save_size;
png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += (png_size_t)save_size;
png_ptr->save_buffer_ptr += save_size;
}
if (length && png_ptr->current_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (length < png_ptr->current_buffer_size)
save_size = length;
else
save_size = png_ptr->current_buffer_size;
png_memcpy(ptr, png_ptr->current_buffer_ptr, (png_size_t)save_size);
png_memcpy(ptr, png_ptr->current_buffer_ptr, save_size);
png_ptr->buffer_size -= save_size;
png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += (png_size_t)save_size;
png_ptr->current_buffer_ptr += save_size;
}
}
@ -429,7 +431,7 @@ png_push_save_buffer(png_structp png_ptr)
{
if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
{
int i;
png_size_t i;
png_bytep sp;
png_bytep dp;
@ -444,25 +446,20 @@ png_push_save_buffer(png_structp png_ptr)
if (png_ptr->save_buffer_size + png_ptr->current_buffer_size >
png_ptr->save_buffer_max)
{
png_uint_32 new_max;
png_size_t new_max;
png_bytep old_buffer;
new_max = (int)(png_ptr->save_buffer_size +
png_ptr->current_buffer_size + 256);
new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256;
old_buffer = png_ptr->save_buffer;
png_ptr->save_buffer = (png_bytep)
png_malloc(png_ptr, new_max);
png_memcpy(png_ptr->save_buffer, old_buffer,
(png_size_t)png_ptr->save_buffer_size);
png_ptr->save_buffer = (png_bytep)png_malloc(png_ptr, new_max);
png_memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size);
png_free(png_ptr, old_buffer);
png_ptr->save_buffer_max = new_max;
}
if (png_ptr->current_buffer_size)
{
png_memcpy(png_ptr->save_buffer +
(png_size_t)png_ptr->save_buffer_size,
png_ptr->current_buffer_ptr,
(png_size_t)png_ptr->current_buffer_size);
png_memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size,
png_ptr->current_buffer_ptr, png_ptr->current_buffer_size);
png_ptr->save_buffer_size += png_ptr->current_buffer_size;
png_ptr->current_buffer_size = 0;
}
@ -472,7 +469,7 @@ png_push_save_buffer(png_structp png_ptr)
void
png_push_restore_buffer(png_structp png_ptr, png_bytep buffer,
png_uint_32 buffer_length)
png_size_t buffer_length)
{
png_ptr->current_buffer = buffer;
png_ptr->current_buffer_size = buffer_length;
@ -497,13 +494,12 @@ png_push_read_IDAT(png_structp png_ptr)
png_ptr->push_length = png_get_uint_32(chunk_length);
png_reset_crc(png_ptr);
png_push_fill_buffer(png_ptr, png_ptr->chunk_name, 4);
png_calculate_crc(png_ptr, chunk_length, 4);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_ptr->flags |= PNG_FLAG_HAVE_CHUNK_HEADER;
if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
{
png_ptr->process_mode = PNG_READ_END_MODE;
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
png_error(png_ptr, "Not enough compressed data");
return;
@ -513,9 +509,9 @@ png_push_read_IDAT(png_structp png_ptr)
}
if (png_ptr->idat_size && png_ptr->save_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (png_ptr->idat_size < png_ptr->save_buffer_size)
if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
save_size = png_ptr->idat_size;
else
save_size = png_ptr->save_buffer_size;
@ -526,13 +522,13 @@ png_push_read_IDAT(png_structp png_ptr)
png_ptr->idat_size -= save_size;
png_ptr->buffer_size -= save_size;
png_ptr->save_buffer_size -= save_size;
png_ptr->save_buffer_ptr += (png_size_t)save_size;
png_ptr->save_buffer_ptr += save_size;
}
if (png_ptr->idat_size && png_ptr->current_buffer_size)
{
png_uint_32 save_size;
png_size_t save_size;
if (png_ptr->idat_size < png_ptr->current_buffer_size)
if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
save_size = png_ptr->idat_size;
else
save_size = png_ptr->current_buffer_size;
@ -543,7 +539,7 @@ png_push_read_IDAT(png_structp png_ptr)
png_ptr->idat_size -= save_size;
png_ptr->buffer_size -= save_size;
png_ptr->current_buffer_size -= save_size;
png_ptr->current_buffer_ptr += (png_size_t)save_size;
png_ptr->current_buffer_ptr += save_size;
}
if (!png_ptr->idat_size)
{
@ -560,7 +556,7 @@ png_push_read_IDAT(png_structp png_ptr)
void
png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
png_uint_32 buffer_length)
png_size_t buffer_length)
{
int ret;
@ -569,22 +565,25 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
png_ptr->zstream.next_in = buffer;
png_ptr->zstream.avail_in = (uInt)buffer_length;
do
while(1)
{
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret == Z_STREAM_END)
{
if (png_ptr->zstream.avail_in)
png_error(png_ptr, "Extra compressed data");
if (!png_ptr->zstream.avail_out)
if (!(png_ptr->zstream.avail_out))
{
png_push_process_row(png_ptr);
}
png_ptr->mode = PNG_AFTER_IDAT;
png_ptr->mode |= PNG_AFTER_IDAT;
png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
break;
}
if (ret != Z_OK)
else if (ret == Z_BUF_ERROR)
break;
else if (ret != Z_OK)
png_error(png_ptr, "Decompression Error");
if (!(png_ptr->zstream.avail_out))
{
@ -592,8 +591,9 @@ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
png_ptr->zstream.next_out = png_ptr->row_buf;
}
} while (png_ptr->zstream.avail_in);
else
break;
}
}
void
@ -611,19 +611,18 @@ png_push_process_row(png_structp png_ptr)
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
(int)(png_ptr->row_buf[0]));
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
#if defined(PNG_READ_INTERLACING_SUPPORTED)
/* blow up interlaced rows to full size */
if (png_ptr->interlaced &&
(png_ptr->transformations & PNG_INTERLACE))
if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE))
{
if (png_ptr->pass < 6)
png_do_read_interlace(&(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->pass);
png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
switch (png_ptr->pass)
{
@ -747,7 +746,7 @@ png_read_push_finish_row(png_structp png_ptr)
if (png_ptr->interlaced)
{
png_ptr->row_number = 0;
png_memset(png_ptr->prev_row, 0, (png_size_t)png_ptr->rowbytes + 1);
png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
do
{
png_ptr->pass++;
@ -781,8 +780,19 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length
if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
png_error(png_ptr, "Out of place tEXt");
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
png_ptr->current_text[(png_size_t)length] = '\0';
#ifdef PNG_MAX_MALLOC_64K
png_ptr->skip_length = 0; /* This may not be necessary */
if (length > 65535L) /* We can't hold the entire string in memory */
{
png_warning(png_ptr, "tEXt chunk too large to fit in memory");
png_ptr->skip_length = length - 65535L;
length = 65535L;
}
#endif
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
png_ptr->current_text[length] = '\0';
png_ptr->current_text_ptr = png_ptr->current_text;
png_ptr->current_text_size = length;
png_ptr->current_text_left = length;
@ -794,21 +804,19 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr->buffer_size && png_ptr->current_text_left)
{
png_uint_32 text_size;
png_size_t text_size;
if (png_ptr->buffer_size < png_ptr->current_text_left)
text_size = png_ptr->buffer_size;
else
text_size = png_ptr->current_text_left;
png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
text_size);
png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
text_size);
png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
png_ptr->current_text_left -= text_size;
png_ptr->current_text_ptr += (png_size_t)text_size;
png_ptr->current_text_ptr += text_size;
}
if (!(png_ptr->current_text_left))
{
png_textp text_ptr;
png_charp text;
png_charp key;
@ -818,7 +826,12 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
return;
}
png_crc_finish(png_ptr, 0);
png_push_crc_finish(png_ptr);
#if defined(PNG_MAX_MALLOC_64K)
if (png_ptr->skip_length)
return;
#endif
key = png_ptr->current_text;
png_ptr->current_text = 0;
@ -826,20 +839,17 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
for (text = key; *text; text++)
/* empty loop */ ;
if (text != key + (png_size_t)png_ptr->current_text_size)
if (text != key + png_ptr->current_text_size)
text++;
png_read_tEXt(png_ptr, info_ptr, key, text,
png_ptr->current_text_size - (text - key));
text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr->key = key;
text_ptr->text = text;
if (png_ptr->mode == PNG_AFTER_IDAT)
{
png_ptr->process_mode = PNG_READ_END_MODE;
}
else
{
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
}
png_set_text(png_ptr, info_ptr, text_ptr, 1);
png_free(png_ptr, text_ptr);
}
}
#endif
@ -851,8 +861,21 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length
if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
png_error(png_ptr, "Out of place zTXt");
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length + 1);
png_ptr->current_text[(png_size_t)length] = '\0';
#ifdef PNG_MAX_MALLOC_64K
/* We can't handle zTXt chunks > 64K, since we don't have enough space
* to be able to store the uncompressed data. Actually, the threshold
* is probably around 32K, but it isn't as definite as 64K is.
*/
if (length > 65535L)
{
png_warning(png_ptr, "zTXt chunk too large to fit in memory");
png_push_crc_skip(png_ptr, length);
return;
}
#endif
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
png_ptr->current_text[length] = '\0';
png_ptr->current_text_ptr = png_ptr->current_text;
png_ptr->current_text_size = length;
png_ptr->current_text_left = length;
@ -864,25 +887,23 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr->buffer_size && png_ptr->current_text_left)
{
png_uint_32 text_size;
png_size_t text_size;
if (png_ptr->buffer_size < png_ptr->current_text_left)
if (png_ptr->buffer_size < (png_uint_32)png_ptr->current_text_left)
text_size = png_ptr->buffer_size;
else
text_size = png_ptr->current_text_left;
png_push_fill_buffer(png_ptr, (png_bytep)png_ptr->current_text_ptr,
text_size);
png_calculate_crc(png_ptr, (png_bytep)png_ptr->current_text_ptr,
text_size);
png_crc_read(png_ptr, (png_bytep)png_ptr->current_text_ptr, text_size);
png_ptr->current_text_left -= text_size;
png_ptr->current_text_ptr += (png_size_t)text_size;
png_ptr->current_text_ptr += text_size;
}
if (!(png_ptr->current_text_left))
{
png_textp text_ptr;
png_charp text;
png_charp key;
int ret;
png_uint_32 text_size, key_size;
png_size_t text_size, key_size;
if (png_ptr->buffer_size < 4)
{
@ -890,7 +911,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
return;
}
png_crc_finish(png_ptr, 0);
png_push_crc_finish(png_ptr);
key = png_ptr->current_text;
png_ptr->current_text = 0;
@ -899,7 +920,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
/* empty loop */ ;
/* zTXt can't have zero text */
if (text == key + (png_size_t)png_ptr->current_text_size)
if (text == key + png_ptr->current_text_size)
{
png_free(png_ptr, key);
return;
@ -907,7 +928,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
text++;
if (*text) /* check compression byte */
if (*text != PNG_TEXT_COMPRESSION_zTXt) /* check compression byte */
{
png_free(png_ptr, key);
return;
@ -919,7 +940,7 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size -
(text - key));
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = (png_size_t)png_ptr->zbuf_size;
png_ptr->zstream.avail_out = png_ptr->zbuf_size;
key_size = text - key;
text_size = 0;
@ -937,19 +958,19 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_free(png_ptr, text);
return;
}
if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END)
{
if (!text)
if (text == NULL)
{
text = (png_charp)png_malloc(png_ptr,
png_ptr->zbuf_size - png_ptr->zstream.avail_out +
key_size + 1);
png_memcpy(text + (png_size_t)key_size, png_ptr->zbuf,
(png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
png_memcpy(text, key, (png_size_t)key_size);
text_size = key_size + (png_size_t)png_ptr->zbuf_size -
png_memcpy(text + key_size, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);
png_memcpy(text, key, key_size);
text_size = key_size + png_ptr->zbuf_size -
png_ptr->zstream.avail_out;
*(text + (png_size_t)text_size) = '\0';
*(text + text_size) = '\0';
}
else
{
@ -958,12 +979,12 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
tmp = text;
text = png_malloc(png_ptr, text_size +
png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1);
png_memcpy(text, tmp, (png_size_t)text_size);
png_memcpy(text, tmp, text_size);
png_free(png_ptr, tmp);
png_memcpy(text + (png_size_t)text_size, png_ptr->zbuf,
(png_size_t)(png_ptr->zbuf_size - png_ptr->zstream.avail_out));
png_memcpy(text + text_size, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);
text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
*(text + (png_size_t)text_size) = '\0';
*(text + text_size) = '\0';
}
if (ret != Z_STREAM_END)
{
@ -992,18 +1013,17 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_free(png_ptr, key);
key = text;
text += (png_size_t)key_size;
text += key_size;
text_size -= key_size;
png_read_zTXt(png_ptr, info_ptr, key, text, text_size, 0);
if (png_ptr->mode == PNG_AFTER_IDAT)
{
png_ptr->process_mode = PNG_READ_END_MODE;
}
else
{
png_ptr->process_mode = PNG_READ_CHUNK_MODE;
}
text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
text_ptr->key = key;
text_ptr->text = text;
png_set_text(png_ptr, info_ptr, text_ptr, 1);
png_free(png_ptr, text_ptr);
}
}
#endif
@ -1033,21 +1053,21 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 len
void
png_push_have_info(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr->info_fn)
if (png_ptr->info_fn != NULL)
(*(png_ptr->info_fn))(png_ptr, info_ptr);
}
void
png_push_have_end(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr->end_fn)
if (png_ptr->end_fn != NULL)
(*(png_ptr->end_fn))(png_ptr, info_ptr);
}
void
png_push_have_row(png_structp png_ptr, png_bytep row)
{
if (png_ptr->row_fn)
if (png_ptr->row_fn != NULL)
(*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number,
(int)png_ptr->pass);
}
@ -1056,7 +1076,7 @@ void
png_progressive_combine_row (png_structp png_ptr,
png_bytep old_row, png_bytep new_row)
{
if (new_row)
if (new_row != NULL)
png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
}

243
pngrcb.c
View File

@ -1,243 +0,0 @@
/* pngrcb.c - callbacks while reading a png file
libpng 1.0 beta 4 - version 0.90
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
*/
#define PNG_INTERNAL
#include "png.h"
void
png_read_IHDR(png_structp png_ptr, png_infop info,
png_uint_32 width, png_uint_32 height, int bit_depth,
int color_type, int compression_type, int filter_type,
int interlace_type)
{
if (!info)
return;
info->width = width;
info->height = height;
info->bit_depth = (png_byte)bit_depth;
info->color_type =(png_byte) color_type;
info->compression_type = (png_byte)compression_type;
info->filter_type = (png_byte)filter_type;
info->interlace_type = (png_byte)interlace_type;
if (info->color_type == PNG_COLOR_TYPE_PALETTE)
info->channels = 1;
else if (info->color_type & PNG_COLOR_MASK_COLOR)
info->channels = 3;
else
info->channels = 1;
if (info->color_type & PNG_COLOR_MASK_ALPHA)
info->channels++;
info->pixel_depth = (png_byte)(info->channels * info->bit_depth);
info->rowbytes = ((info->width * info->pixel_depth + 7) >> 3);
}
void
png_read_PLTE(png_structp png_ptr, png_infop info,
png_colorp palette, int num)
{
if (!info)
return;
info->palette = palette;
info->num_palette = (png_uint_16)num;
info->valid |= PNG_INFO_PLTE;
}
#if defined(PNG_READ_gAMA_SUPPORTED)
void
png_read_gAMA(png_structp png_ptr, png_infop info, double gamma)
{
if (!info)
return;
info->gamma = (float)gamma;
info->valid |= PNG_INFO_gAMA;
}
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
void
png_read_sBIT(png_structp png_ptr, png_infop info,
png_color_8p sig_bit)
{
if (!info)
return;
png_memcpy(&(info->sig_bit), sig_bit, sizeof (png_color_8));
info->valid |= PNG_INFO_sBIT;
}
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
void
png_read_cHRM(png_structp png_ptr, png_infop info,
double white_x, double white_y, double red_x, double red_y,
double green_x, double green_y, double blue_x, double blue_y)
{
if (!info)
return;
info->x_white = (float)white_x;
info->y_white = (float)white_y;
info->x_red = (float)red_x;
info->y_red = (float)red_y;
info->x_green = (float)green_x;
info->y_green = (float)green_y;
info->x_blue = (float)blue_x;
info->y_blue = (float)blue_y;
info->valid |= PNG_INFO_cHRM;
}
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
void
png_read_tRNS(png_structp png_ptr, png_infop info,
png_bytep trans, int num_trans, png_color_16p trans_values)
{
if (!info)
return;
if (trans)
{
info->trans = trans;
}
else
{
png_memcpy(&(info->trans_values), trans_values,
sizeof(png_color_16));
}
info->num_trans = (png_uint_16)num_trans;
info->valid |= PNG_INFO_tRNS;
}
#endif
#if defined(PNG_READ_bKGD_SUPPORTED)
void
png_read_bKGD(png_structp png_ptr, png_infop info,
png_color_16p background)
{
if (!info)
return;
png_memcpy(&(info->background), background, sizeof(png_color_16));
info->valid |= PNG_INFO_bKGD;
}
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
void
png_read_hIST(png_structp png_ptr, png_infop info, png_uint_16p hist)
{
if (!info)
return;
info->hist = hist;
info->valid |= PNG_INFO_hIST;
}
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
void
png_read_pHYs(png_structp png_ptr, png_infop info,
png_uint_32 res_x, png_uint_32 res_y, int unit_type)
{
if (!info)
return;
info->x_pixels_per_unit = res_x;
info->y_pixels_per_unit = res_y;
info->phys_unit_type = (png_byte)unit_type;
info->valid |= PNG_INFO_pHYs;
}
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
void
png_read_oFFs(png_structp png_ptr, png_infop info,
png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
{
if (!info)
return;
info->x_offset = offset_x;
info->y_offset = offset_y;
info->offset_unit_type = (png_byte)unit_type;
info->valid |= PNG_INFO_oFFs;
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
void
png_read_tIME(png_structp png_ptr, png_infop info,
png_timep mod_time)
{
if (!info)
return;
png_memcpy(&(info->mod_time), mod_time, sizeof (png_time));
info->valid |= PNG_INFO_tIME;
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
void
png_read_zTXt(png_structp png_ptr, png_infop info,
png_charp key, png_charp text, png_uint_32 text_len, int compression)
{
if (!info)
return;
if (info->max_text <= info->num_text)
{
if (info->text)
{
png_uint_32 old_max;
old_max = info->max_text;
info->max_text = info->num_text + 16;
{
png_textp old_text;
old_text = info->text;
info->text = (png_textp)png_malloc(png_ptr,
info->max_text * sizeof (png_text));
png_memcpy(info->text, old_text,
(png_size_t)(old_max * sizeof (png_text)));
png_free(png_ptr, old_text);
}
}
else
{
info->max_text = 16;
info->num_text = 0;
info->text = (png_textp)png_malloc(png_ptr,
info->max_text * sizeof (png_text));
}
}
info->text[info->num_text].key = key;
info->text[info->num_text].text = text;
info->text[info->num_text].text_length = text_len;
info->text[info->num_text].compression = compression;
info->num_text++;
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
void
png_read_tEXt(png_structp png_ptr, png_infop info,
png_charp key, png_charp text, png_uint_32 text_len)
{
if (!info)
return;
png_read_zTXt(png_ptr, info, key, text, text_len, -1);
}
#endif

301
pngread.c
View File

@ -1,24 +1,26 @@
/* pngread.c - read a png file
/* pngread.c - read a PNG file
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
#include "png.h"
/* Create a png structure for reading, and allocate any memory needed. */
/* Create a PNG structure for reading, and allocate any memory needed. */
png_structp
png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
png_create_read_struct(png_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn)
{
png_structp png_ptr;
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
#endif
png_debug(1, "in png_create_read_struct\n");
if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
{
return (png_structp)NULL;
@ -38,14 +40,13 @@ png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
#endif
png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
/* This is what will be used for the final version. For the
(ongoing) development library, we know that ALL of the
older library versions are out of date because of the
change in the info_struct size. */
/*
if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0])
/* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
* we must recompile any applications that use any older library version.
* For versions after libpng 1.0, we will be compatible, so we need
* only check the first digit.
*/
if (user_png_ver == NULL || atof(user_png_ver) < atof(png_libpng_ver))
if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
(user_png_ver[0] == '0' && user_png_ver[2] < '9'))
{
png_error(png_ptr,
"Incompatible libpng version in application and library");
@ -76,7 +77,7 @@ png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
}
/* Initialize png structure for reading, and allocate any memory needed.
/* Initialize PNG structure for reading, and allocate any memory needed.
This interface is depreciated in favour of the png_create_read_struct(),
and it will eventually disappear. */
void
@ -84,6 +85,7 @@ png_read_init(png_structp png_ptr)
{
jmp_buf tmp_jmp; /* to save current jump buffer */
png_debug(1, "in png_read_init\n");
/* save jump buffer and error functions */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
@ -126,14 +128,15 @@ png_read_init(png_structp png_ptr)
void
png_read_info(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_read_info\n");
/* save jump buffer and error functions */
/* If we haven't checked all of the PNG signature bytes, do so now. */
if (png_ptr->sig_bytes < 8)
{
int num_checked = png_ptr->sig_bytes,
png_size_t num_checked = png_ptr->sig_bytes,
num_to_check = 8 - num_checked;
png_read_data(png_ptr, &(info_ptr->signature[num_checked]),
(png_uint_32)num_to_check);
png_read_data(png_ptr, &(info_ptr->signature[num_checked]), num_to_check);
png_ptr->sig_bytes = 8;
if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check))
@ -157,56 +160,17 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
/* This should be a binary subdivision search or a hash for
* matching the chunk name rather than a linear search.
*/
if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
png_handle_PLTE(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
png_handle_IEND(png_ptr, info_ptr, length);
#if defined(PNG_READ_gAMA_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_bKGD_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
png_handle_tEXt(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
png_handle_zTXt(png_ptr, info_ptr, length);
#endif
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
{
if (!(png_ptr->mode & PNG_HAVE_IHDR))
@ -219,6 +183,54 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
png_ptr->mode |= PNG_HAVE_IDAT;
break;
}
#if defined(PNG_READ_bKGD_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
png_handle_pCAL(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
png_handle_tEXt(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
png_handle_zTXt(png_ptr, info_ptr, length);
#endif
else
png_handle_unknown(png_ptr, info_ptr, length);
}
@ -228,6 +240,8 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
void
png_read_update_info(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_read_update_info\n");
/* save jump buffer and error functions */
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
png_read_transform_info(png_ptr, info_ptr);
@ -240,6 +254,8 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
void
png_start_read_image(png_structp png_ptr)
{
png_debug(1, "in png_start_read_image\n");
/* save jump buffer and error functions */
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
}
@ -248,6 +264,9 @@ void
png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{
int ret;
png_debug2(1, "in png_read_row (row %d, pass %d)\n",
png_ptr->row_number, png_ptr->pass);
/* save jump buffer and error functions */
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
@ -260,7 +279,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 0:
if (png_ptr->row_number & 7)
{
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -270,7 +289,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 1:
if ((png_ptr->row_number & 7) || png_ptr->width < 5)
{
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -280,7 +299,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 2:
if ((png_ptr->row_number & 7) != 4)
{
if (dsp_row && (png_ptr->row_number & 4))
if (dsp_row != NULL && (png_ptr->row_number & 4))
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -290,7 +309,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 3:
if ((png_ptr->row_number & 3) || png_ptr->width < 3)
{
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -300,7 +319,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 4:
if ((png_ptr->row_number & 3) != 2)
{
if (dsp_row && (png_ptr->row_number & 2))
if (dsp_row != NULL && (png_ptr->row_number & 2))
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -310,7 +329,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
case 5:
if ((png_ptr->row_number & 1) || png_ptr->width < 2)
{
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
png_read_finish_row(png_ptr);
@ -355,7 +374,8 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->zstream.next_in = png_ptr->zbuf;
if (png_ptr->zbuf_size > png_ptr->idat_size)
png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
png_crc_read(png_ptr, png_ptr->zbuf,
(png_size_t)png_ptr->zstream.avail_in);
png_ptr->idat_size -= png_ptr->zstream.avail_in;
}
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
@ -386,7 +406,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->row_buf + 1, png_ptr->prev_row + 1,
(int)(png_ptr->row_buf[0]));
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, (png_size_t)png_ptr->rowbytes + 1);
png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1);
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
@ -398,41 +418,41 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
{
if (png_ptr->pass < 6)
png_do_read_interlace(&(png_ptr->row_info),
png_ptr->row_buf + 1, png_ptr->pass);
png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations);
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row,
png_pass_dsp_mask[png_ptr->pass]);
if (row)
if (row != NULL)
png_combine_row(png_ptr, row,
png_pass_mask[png_ptr->pass]);
}
else
#endif
{
if (row)
if (row != NULL)
png_combine_row(png_ptr, row, 0xff);
if (dsp_row)
if (dsp_row != NULL)
png_combine_row(png_ptr, dsp_row, 0xff);
}
png_read_finish_row(png_ptr);
}
/* read a one or more rows of image data. If the image is interlaced,
/* Read one or more rows of image data. If the image is interlaced,
and png_set_interlace_handling() has been called, the rows need to
to contain the contents of the rows from the previous pass. If
the image has alpha or transparency, and png_handle_alpha() has been
called, the rows contents must be initialized to the contents of the
screen. row holds the actual image, and pixels are placed in it
screen. "row" holds the actual image, and pixels are placed in it
as they arrive. If the image is displayed after each pass, it will
appear to "sparkle" in. display_row can be used to display a
appear to "sparkle" in. "display_row" can be used to display a
"chunky" progressive image, with finer detail added as it becomes
available. If you do not want this "chunky" display, you may pass
NULL for display_rows. If you do not want the sparkle display, and
NULL for display_row. If you do not want the sparkle display, and
you have not called png_handle_alpha(), you may pass NULL for rows.
If you have called png_handle_alpha(), and the image has either an
alpha channel or a transparency chunk, you must provide a buffer for
rows. In this case, you do not have to provide a display_rows buffer
rows. In this case, you do not have to provide a display_row buffer
also, but you may. If the image is not interlaced, or if you have
not called png_set_interlace_handling(), the display_row buffer will
be ignored, so pass NULL to it. */
@ -445,6 +465,8 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
png_bytepp rp;
png_bytepp dp;
png_debug(1, "in png_read_rows\n");
/* save jump buffer and error functions */
rp = row;
dp = display_row;
for (i = 0; i < num_rows; i++)
@ -452,30 +474,30 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
png_bytep rptr;
png_bytep dptr;
if (rp)
if (rp != NULL)
rptr = *rp;
else
rptr = NULL;
if (dp)
if (dp != NULL)
dptr = *dp;
else
dptr = NULL;
png_read_row(png_ptr, rptr, dptr);
if (row)
if (row != NULL)
rp++;
if (display_row)
if (display_row != NULL)
dp++;
}
}
/* read the image. If the image has an alpha channel or a transparency
/* Read the entire image. If the image has an alpha channel or a tRNS
chunk, and you have called png_handle_alpha(), you will need to
initialize the image to the current image that png will be overlaying.
initialize the image to the current image that PNG will be overlaying.
We set the num_rows again here, in case it was incorrectly set in
png_read_start_row() by a call to png_read_update_info() or
png_start_read_image() if png_set_interlace_handling() wasn't called
prior to either of these functions like it should have been. You only
need to call this function once. If you desire to have an image for
prior to either of these functions like it should have been. You can
only call this function once. If you desire to have an image for
each pass of a interlaced image, use png_read_rows() instead */
void
png_read_image(png_structp png_ptr, png_bytepp image)
@ -484,6 +506,8 @@ png_read_image(png_structp png_ptr, png_bytepp image)
int pass, j;
png_bytepp rp;
png_debug(1, "in png_read_image\n");
/* save jump buffer and error functions */
pass = png_set_interlace_handling(png_ptr);
png_ptr->num_rows = png_ptr->height; /* Make sure this is set correctly */
@ -499,7 +523,7 @@ png_read_image(png_structp png_ptr, png_bytepp image)
}
}
/* read the end of the png file. Will not read past the end of the
/* Read the end of the PNG file. Will not read past the end of the
file, will verify the end is accurate, and will read any comments
or time information at the end of the file, if info is not NULL. */
void
@ -508,7 +532,9 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
png_byte chunk_length[4];
png_uint_32 length;
png_crc_finish(png_ptr, 0);
png_debug(1, "in png_read_end\n");
/* save jump buffer and error functions */
png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
do
{
@ -518,45 +544,72 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
png_reset_crc(png_ptr);
png_crc_read(png_ptr, png_ptr->chunk_name, 4);
png_debug1(0, "Reading %s chunk.\n", png_ptr->chunk_name);
if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4))
png_handle_IHDR(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
png_handle_PLTE(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
{
/* Zero length IDATs are legal after the last IDAT has been
* read, but not after other chunks have been read.
*/
if (length > 0 || png_ptr->mode & PNG_AFTER_IDAT)
png_error(png_ptr, "Too many IDAT's found");
else
png_crc_finish(png_ptr, 0);
}
#if defined(PNG_READ_tIME_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_PLTE, 4))
png_handle_PLTE(png_ptr, info_ptr, length);
else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
png_handle_IEND(png_ptr, info_ptr, length);
#if defined(PNG_READ_bKGD_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4))
png_handle_bKGD(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_cHRM_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4))
png_handle_cHRM(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_gAMA_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4))
png_handle_gAMA(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4))
png_handle_hIST(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_oFFs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4))
png_handle_oFFs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pCAL_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4))
png_handle_pCAL(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_pHYs_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4))
png_handle_pHYs(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sBIT_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tEXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4))
png_handle_tEXt(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tIME_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4))
png_handle_tIME(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
png_handle_tRNS(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_zTXt_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4))
png_handle_zTXt(png_ptr, info_ptr, length);
#endif
else if (!png_memcmp(png_ptr->chunk_name, png_IEND, 4))
png_handle_IEND(png_ptr, info_ptr, length);
else
png_handle_unknown(png_ptr, info_ptr, length);
} while (!(png_ptr->mode & PNG_HAVE_IEND));
@ -570,30 +623,32 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
png_structp png_ptr = NULL;
png_infop info_ptr = NULL, end_info_ptr = NULL;
if (png_ptr_ptr)
png_debug(1, "in png_destroy_read_struct\n");
/* save jump buffer and error functions */
if (png_ptr_ptr != NULL)
png_ptr = *png_ptr_ptr;
if (info_ptr_ptr)
if (info_ptr_ptr != NULL)
info_ptr = *info_ptr_ptr;
if (end_info_ptr_ptr)
if (end_info_ptr_ptr != NULL)
end_info_ptr = *end_info_ptr_ptr;
png_read_destroy(png_ptr, info_ptr, end_info_ptr);
if (info_ptr)
if (info_ptr != NULL)
{
png_destroy_struct((png_voidp)info_ptr);
*info_ptr_ptr = (png_infop)NULL;
}
if (end_info_ptr)
if (end_info_ptr != NULL)
{
png_destroy_struct((png_voidp)end_info_ptr);
*end_info_ptr_ptr = (png_infop)NULL;
}
if (png_ptr)
if (png_ptr != NULL)
{
png_destroy_struct((png_voidp)png_ptr);
*png_ptr_ptr = (png_structp)NULL;
@ -610,10 +665,12 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
png_error_ptr warning_fn;
png_voidp error_ptr;
if (info_ptr)
png_debug(1, "in png_read_destroy\n");
/* save jump buffer and error functions */
if (info_ptr != NULL)
png_info_destroy(png_ptr, info_ptr);
if (end_info_ptr)
if (end_info_ptr != NULL)
png_info_destroy(png_ptr, end_info_ptr);
png_free(png_ptr, png_ptr->zbuf);
@ -641,7 +698,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
png_free(png_ptr, png_ptr->hist);
#endif
#if defined(PNG_READ_GAMMA_SUPPORTED)
if (png_ptr->gamma_16_table)
if (png_ptr->gamma_16_table != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
{
@ -651,7 +708,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
#endif
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
png_free(png_ptr, png_ptr->gamma_16_table);
if (png_ptr->gamma_16_from_1)
if (png_ptr->gamma_16_from_1 != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
{
@ -659,7 +716,7 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
}
}
png_free(png_ptr, png_ptr->gamma_16_from_1);
if (png_ptr->gamma_16_to_1)
if (png_ptr->gamma_16_to_1 != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
{

View File

@ -1,10 +1,11 @@
/* pngrio.c - functions for data input
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
This file provides a location for all input. Users which need
special handling are expected to write a function which has the same
@ -20,12 +21,12 @@
reads from a file pointer. Note that this routine sometimes gets called
with very small lengths, so you should implement some kind of simple
buffering if you are using unbuffered reads. This should never be asked
to read more then 64K on a 16 bit machine. The cast to png_size_t is
there to quiet some compilers */
to read more then 64K on a 16 bit machine. */
void
png_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
if (png_ptr->read_data_fn)
png_debug1(4,"reading %d bytes\n", length);
if (png_ptr->read_data_fn != NULL)
(*(png_ptr->read_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL read function");
@ -37,11 +38,16 @@ png_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
than changing the library. */
#ifndef USE_FAR_KEYWORD
static void
png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
png_size_t check;
/* fread() returns 0 on error, so it is OK to store this in a png_size_t
* instead of an int, which is what fread() actually returns.
*/
check = (png_size_t)fread(data, (png_size_t)1, length,
(FILE *)png_ptr->io_ptr);
check = fread(data, 1, (size_t)length, (FILE *)png_ptr->io_ptr);
if (check != length)
{
png_error(png_ptr, "Read Error");
@ -57,9 +63,9 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
#define MIN(a,b) (a <= b ? a : b)
static void
png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
int check;
png_byte *n_data;
FILE *io_ptr;
@ -68,18 +74,18 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
{
check = fread(n_data, 1, (size_t)length, io_ptr);
check = fread(n_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t read, remaining, err;
check = 0;
remaining = (png_size_t)length;
remaining = length;
do
{
read = MIN(NEAR_BUF_SIZE, remaining);
err = fread(buf, 1, read, io_ptr);
err = fread(buf, (png_size_t)1, read, io_ptr);
png_memcpy(data, buf, read); /* copy far buffer to near buffer */
if(err != read)
break;
@ -116,7 +122,7 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
{
png_ptr->io_ptr = io_ptr;
if (read_data_fn)
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;

1194
pngrtran.c

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

312
pngset.c Normal file
View File

@ -0,0 +1,312 @@
/* pngset.c - storage of image information into info struct
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
#include "png.h"
#if defined(PNG_READ_bKGD_SUPPORTED) || defined(PNG_WRITE_bKGD_SUPPORTED)
void
png_set_bKGD(png_structp png_ptr, png_infop info_ptr, png_color_16p background)
{
png_debug1(1, "in %s storage function\n", "bKGD");
if (info_ptr == NULL)
return;
png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
info_ptr->valid |= PNG_INFO_bKGD;
}
#endif
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
void
png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
double white_x, double white_y, double red_x, double red_y,
double green_x, double green_y, double blue_x, double blue_y)
{
png_debug1(1, "in %s storage function\n", "cHRM");
if (info_ptr == NULL)
return;
info_ptr->x_white = (float)white_x;
info_ptr->y_white = (float)white_y;
info_ptr->x_red = (float)red_x;
info_ptr->y_red = (float)red_y;
info_ptr->x_green = (float)green_x;
info_ptr->y_green = (float)green_y;
info_ptr->x_blue = (float)blue_x;
info_ptr->y_blue = (float)blue_y;
info_ptr->valid |= PNG_INFO_cHRM;
}
#endif
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
void
png_set_gAMA(png_structp png_ptr, png_infop info_ptr, double file_gamma)
{
png_debug1(1, "in %s storage function\n", "gAMA");
if (info_ptr == NULL)
return;
info_ptr->gamma = (float)file_gamma;
info_ptr->valid |= PNG_INFO_gAMA;
}
#endif
#if defined(PNG_READ_hIST_SUPPORTED) || defined(PNG_WRITE_hIST_SUPPORTED)
void
png_set_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_16p hist)
{
png_debug1(1, "in %s storage function\n", "hIST");
if (info_ptr == NULL)
return;
info_ptr->hist = hist;
info_ptr->valid |= PNG_INFO_hIST;
}
#endif
void
png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth,
int color_type, int interlace_type, int compression_type,
int filter_type)
{
png_debug1(1, "in %s storage function\n", "IHDR");
if (info_ptr == NULL)
return;
info_ptr->width = width;
info_ptr->height = height;
info_ptr->bit_depth = (png_byte)bit_depth;
info_ptr->color_type =(png_byte) color_type;
info_ptr->compression_type = (png_byte)compression_type;
info_ptr->filter_type = (png_byte)filter_type;
info_ptr->interlace_type = (png_byte)interlace_type;
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
info_ptr->channels = 1;
else if (info_ptr->color_type & PNG_COLOR_MASK_COLOR)
info_ptr->channels = 3;
else
info_ptr->channels = 1;
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
info_ptr->channels++;
info_ptr->pixel_depth = (png_byte)(info_ptr->channels * info_ptr->bit_depth);
info_ptr->rowbytes = ((info_ptr->width * info_ptr->pixel_depth + 7) >> 3);
}
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
void
png_set_oFFs(png_structp png_ptr, png_infop info_ptr,
png_uint_32 offset_x, png_uint_32 offset_y, int unit_type)
{
png_debug1(1, "in %s storage function\n", "oFFs");
if (info_ptr == NULL)
return;
info_ptr->x_offset = offset_x;
info_ptr->y_offset = offset_y;
info_ptr->offset_unit_type = (png_byte)unit_type;
info_ptr->valid |= PNG_INFO_oFFs;
}
#endif
#if defined(PNG_READ_pCAL_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED)
void
png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
png_charp purpose, png_int_32 X0, png_int_32 X1, int type, int nparams,
png_charp units, png_charpp params)
{
png_size_t length;
int i;
png_debug1(1, "in %s storage function\n", "pCAL");
if (info_ptr == NULL)
return;
length = png_strlen(purpose) + 1;
png_debug1(3, "allocating purpose for info (%d bytes)\n", length);
info_ptr->pcal_purpose = (png_charp)png_malloc(png_ptr, length);
png_memcpy(info_ptr->pcal_purpose, purpose, length);
png_debug(3, "storing X0, X1, type, and nparams in info\n");
info_ptr->pcal_X0 = X0;
info_ptr->pcal_X1 = X1;
info_ptr->pcal_type = (png_byte)type;
info_ptr->pcal_nparams = (png_byte)nparams;
length = png_strlen(units) + 1;
png_debug1(3, "allocating units for info (%d bytes)\n", length);
info_ptr->pcal_units = (png_charp)png_malloc(png_ptr, length);
png_memcpy(info_ptr->pcal_units, units, length);
info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
(nparams + 1) * sizeof(png_charp));
info_ptr->pcal_params[nparams] = NULL;
for (i = 0; i < nparams; i++)
{
length = png_strlen(params[i]) + 1;
png_debug2(3, "allocating parameter %d for info (%d bytes)\n", i, length);
info_ptr->pcal_params[i] = (png_charp)png_malloc(png_ptr, length);
png_memcpy(info_ptr->pcal_params[i], params[i], length);
}
info_ptr->valid |= PNG_INFO_pCAL;
}
#endif
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
void
png_set_pHYs(png_structp png_ptr, png_infop info_ptr,
png_uint_32 res_x, png_uint_32 res_y, int unit_type)
{
png_debug1(1, "in %s storage function\n", "pHYs");
if (info_ptr == NULL)
return;
info_ptr->x_pixels_per_unit = res_x;
info_ptr->y_pixels_per_unit = res_y;
info_ptr->phys_unit_type = (png_byte)unit_type;
info_ptr->valid |= PNG_INFO_pHYs;
}
#endif
void
png_set_PLTE(png_structp png_ptr, png_infop info_ptr,
png_colorp palette, int num_palette)
{
png_debug1(1, "in %s storage function\n", "PLTE");
if (info_ptr == NULL)
return;
info_ptr->palette = palette;
info_ptr->num_palette = (png_uint_16)num_palette;
info_ptr->valid |= PNG_INFO_PLTE;
}
#if defined(PNG_READ_sBIT_SUPPORTED) || defined(PNG_WRITE_sBIT_SUPPORTED)
void
png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
png_color_8p sig_bit)
{
png_debug1(1, "in %s storage function\n", "sBIT");
if (info_ptr == NULL)
return;
png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
info_ptr->valid |= PNG_INFO_sBIT;
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
void
png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
int num_text)
{
int i;
png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
"text" : png_ptr->chunk_name));
if (info_ptr == NULL || num_text == 0)
return;
/* Make sure we have enough space in the "text" array in info_struct
* to hold all of the incoming text_ptr objects.
*/
if (info_ptr->num_text + num_text > info_ptr->max_text)
{
if (info_ptr->text != NULL)
{
png_textp old_text;
int old_max;
old_max = info_ptr->max_text;
info_ptr->max_text = info_ptr->num_text + num_text + 8;
old_text = info_ptr->text;
info_ptr->text = (png_textp)png_malloc(png_ptr,
info_ptr->max_text * sizeof (png_text));
png_memcpy(info_ptr->text, old_text, old_max * sizeof(png_text));
png_free(png_ptr, old_text);
}
else
{
info_ptr->max_text = num_text + 8;
info_ptr->num_text = 0;
info_ptr->text = (png_textp)png_malloc(png_ptr,
info_ptr->max_text * sizeof (png_text));
}
png_debug1(3, "allocated %d entries for info_ptr->text\n",
info_ptr->max_text);
}
for (i = 0; i < num_text; i++)
{
png_textp textp = &(info_ptr->text[info_ptr->num_text]);
if (text_ptr[i].text == NULL)
text_ptr[i].text = "";
if (text_ptr[i].text[0] == '\0')
{
textp->text_length = 0;
textp->compression = PNG_TEXT_COMPRESSION_NONE;
}
else
{
textp->text_length = png_strlen(text_ptr[i].text);
textp->compression = text_ptr[i].compression;
}
textp->text = text_ptr[i].text;
textp->key = text_ptr[i].key;
info_ptr->num_text++;
png_debug1(3, "transferred text chunk %d\n", info_ptr->num_text);
}
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED) || defined(PNG_WRITE_tIME_SUPPORTED)
void
png_set_tIME(png_structp png_ptr, png_infop info_ptr, png_timep mod_time)
{
png_debug1(1, "in %s storage function\n", "tIME");
if (info_ptr == NULL)
return;
png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
info_ptr->valid |= PNG_INFO_tIME;
}
#endif
#if defined(PNG_READ_tRNS_SUPPORTED) || defined(PNG_WRITE_tRNS_SUPPORTED)
void
png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
png_bytep trans, int num_trans, png_color_16p trans_values)
{
png_debug1(1, "in %s storage function\n", "tRNS");
if (info_ptr == NULL)
return;
if (trans != NULL)
{
info_ptr->trans = trans;
}
if (trans_values != NULL)
{
png_memcpy(&(info_ptr->trans_values), trans_values,
sizeof(png_color_16));
}
info_ptr->num_trans = (png_uint_16)num_trans;
info_ptr->valid |= PNG_INFO_tRNS;
}
#endif

266
pngtest.c
View File

@ -1,14 +1,21 @@
/* pngtest.c - a simple test program to test libpng
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
*/
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#include <stdio.h>
#include <stdlib.h>
/* Makes pngtest verbose so we can find problems (needs to be before png.h) */
#ifndef PNG_DEBUG
#define PNG_DEBUG 0
#endif
#include "png.h"
#ifdef __TURBOC__
@ -30,23 +37,21 @@ char *outname = "pngout.png";
char inbuf[256], outbuf[256];
int main(int argc, char *argv[])
int
main(int argc, char *argv[])
{
FILE *fpin, *fpout;
png_structp read_ptr;
png_structp write_ptr;
png_infop info_ptr;
png_infop end_info;
png_structp read_ptr, write_ptr;
png_infop read_info_ptr, write_info_ptr, end_info_ptr;
png_bytep row_buf;
png_byte *near_row_buf;
png_uint_32 rowbytes;
png_uint_32 y;
int channels, num_pass, pass;
png_uint_32 width, height;
int num_pass, pass;
int bit_depth, color_type;
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
#endif
row_buf = (png_bytep)NULL;
near_row_buf = (png_byte *)NULL;
fprintf(STDERR, "Testing libpng version %s\n", PNG_LIBPNG_VER_STRING);
@ -70,28 +75,30 @@ int main(int argc, char *argv[])
exit(1);
}
fpin = fopen(inname, "rb");
if (!fpin)
if ((fpin = fopen(inname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find input file %s\n", inname);
return 1;
}
fpout = fopen(outname, "wb");
if (!fpout)
if ((fpout = fopen(outname, "wb")) == NULL)
{
fprintf(STDERR, "Could not open output file %s\n", outname);
fclose(fpin);
return 1;
}
png_debug(0, "Allocating read and write structures\n");
read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
(png_error_ptr)NULL, (png_error_ptr)NULL);
write_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, (png_voidp)NULL,
(png_error_ptr)NULL, (png_error_ptr)NULL);
info_ptr = png_create_info_struct(read_ptr);
end_info = png_create_info_struct(read_ptr);
png_debug(0, "Allocating read_info, write_info and end_info structures\n");
read_info_ptr = png_create_info_struct(read_ptr);
write_info_ptr = png_create_info_struct(read_ptr);
end_info_ptr = png_create_info_struct(read_ptr);
png_debug(0, "Setting jmpbuf for read struct\n");
#ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf))
#else
@ -99,12 +106,14 @@ int main(int argc, char *argv[])
#endif
{
fprintf(STDERR, "libpng read error\n");
png_destroy_read_struct(&read_ptr, &info_ptr, &end_info);
png_destroy_write_struct(&write_ptr, (png_infopp)NULL);
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
fclose(fpin);
fclose(fpout);
return 1;
}
png_debug(0, "Setting jmpbuf for write struct\n");
#ifdef USE_FAR_KEYWORD
png_memcpy(read_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
if (setjmp(jmpbuf))
@ -113,92 +122,227 @@ int main(int argc, char *argv[])
#endif
{
fprintf(STDERR, "libpng write error\n");
png_destroy_read_struct(&read_ptr, &info_ptr, &end_info);
png_destroy_write_struct(&write_ptr, (png_infopp)NULL);
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
fclose(fpin);
fclose(fpout);
return 1;
}
#ifdef USE_FAR_KEYWORD
png_memcpy(write_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
png_debug(0, "Initializing input and output streams\n");
png_init_io(read_ptr, fpin);
png_init_io(write_ptr, fpout);
png_read_info(read_ptr, info_ptr);
png_write_info(write_ptr, info_ptr);
png_debug(0, "Reading info struct\n");
png_read_info(read_ptr, read_info_ptr);
if ((info_ptr->color_type & PNG_COLOR_TYPE_PALETTE)==PNG_COLOR_TYPE_PALETTE)
channels = 1;
else
channels = 3;
if (info_ptr->color_type & PNG_COLOR_MASK_ALPHA)
channels++;
png_debug(0, "Transferring info struct\n");
{
int interlace_type, compression_type, filter_type;
rowbytes = ((info_ptr->width * info_ptr->bit_depth * channels + 7) >> 3);
near_row_buf = (png_byte *)malloc((size_t)rowbytes);
row_buf = (png_bytep)near_row_buf;
if (!row_buf)
if (png_get_IHDR(read_ptr, read_info_ptr, &width, &height, &bit_depth,
&color_type, &interlace_type, &compression_type, &filter_type))
{
png_set_IHDR(write_ptr, write_info_ptr, width, height, bit_depth,
color_type, interlace_type, compression_type, filter_type);
}
}
#if defined(PNG_READ_bKGD_SUPPORTED) && defined(PNG_WRITE_bKGD_SUPPORTED)
{
png_color_16p background;
if (png_get_bKGD(read_ptr, read_info_ptr, &background))
{
png_set_bKGD(write_ptr, write_info_ptr, background);
}
}
#endif
#if defined(PNG_READ_cHRM_SUPPORTED) && defined(PNG_WRITE_cHRM_SUPPORTED)
{
double white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
if (png_get_cHRM(read_ptr, read_info_ptr, &white_x, &white_y, &red_x,
&red_y, &green_x, &green_y, &blue_x, &blue_y))
{
png_set_cHRM(write_ptr, write_info_ptr, white_x, white_y, red_x,
red_y, green_x, green_y, blue_x, blue_y);
}
}
#endif
#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_WRITE_gAMA_SUPPORTED)
{
double gamma;
if (png_get_gAMA(read_ptr, read_info_ptr, &gamma))
{
png_set_gAMA(write_ptr, write_info_ptr, gamma);
}
}
#endif
#if defined(PNG_READ_hIST_SUPPORTED) && defined(PNG_WRITE_hIST_SUPPORTED)
{
png_uint_16p hist;
if (png_get_hIST(read_ptr, read_info_ptr, &hist))
{
png_set_hIST(write_ptr, write_info_ptr, hist);
}
}
#endif
#if defined(PNG_READ_oFFs_SUPPORTED) && defined(PNG_WRITE_oFFs_SUPPORTED)
{
png_uint_32 offset_x, offset_y;
int unit_type;
if (png_get_oFFs(read_ptr, read_info_ptr,&offset_x,&offset_y,&unit_type))
{
png_set_oFFs(write_ptr, write_info_ptr, offset_x, offset_y, unit_type);
}
}
#endif
#if defined(PNG_READ_pCAL_SUPPORTED) && defined(PNG_WRITE_pCAL_SUPPORTED)
{
png_charp purpose, units;
png_charpp params;
png_int_32 X0, X1;
int type, nparams;
if (png_get_pCAL(read_ptr, read_info_ptr, &purpose, &X0, &X1, &type,
&nparams, &units, &params))
{
png_set_pCAL(write_ptr, write_info_ptr, purpose, X0, X1, type,
nparams, units, params);
}
}
#endif
#if defined(PNG_READ_pHYs_SUPPORTED) && defined(PNG_WRITE_pHYs_SUPPORTED)
{
png_uint_32 res_x, res_y;
int unit_type;
if (png_get_pHYs(read_ptr, read_info_ptr, &res_x, &res_y, &unit_type))
{
png_set_pHYs(write_ptr, write_info_ptr, res_x, res_y, unit_type);
}
}
#endif
{
png_colorp palette;
int num_palette;
if (png_get_PLTE(read_ptr, read_info_ptr, &palette, &num_palette))
{
png_set_PLTE(write_ptr, write_info_ptr, palette, num_palette);
}
}
#if defined(PNG_READ_sBIT_SUPPORTED) && defined(PNG_WRITE_sBIT_SUPPORTED)
{
png_color_8p sig_bit;
if (png_get_sBIT(read_ptr, read_info_ptr, &sig_bit))
{
png_set_sBIT(write_ptr, write_info_ptr, sig_bit);
}
}
#endif
#if (defined(PNG_READ_tEXt_SUPPORTED) && defined(PNG_WRITE_tEXt_SUPPORTED)) || \
(defined(PNG_READ_zTXt_SUPPORTED) && defined(PNG_WRITE_zTXt_SUPPORTED))
{
png_textp text_ptr;
int num_text;
if (png_get_text(read_ptr, read_info_ptr, &text_ptr, &num_text) > 0)
{
png_debug1(0, "Handling %d tEXt/zTXt chunks\n", num_text);
png_set_text(write_ptr, write_info_ptr, text_ptr, num_text);
}
}
#endif
#if defined(PNG_READ_tIME_SUPPORTED) && defined(PNG_WRITE_tIME_SUPPORTED)
{
png_timep mod_time;
if (png_get_tIME(read_ptr, read_info_ptr, &mod_time))
{
png_set_tIME(write_ptr, write_info_ptr, mod_time);
}
}
#endif
#if defined(PNG_READ_tRNS_SUPPORTED) && defined(PNG_WRITE_tRNS_SUPPORTED)
{
png_bytep trans;
int num_trans;
png_color_16p trans_values;
if (png_get_tRNS(read_ptr, read_info_ptr, &trans, &num_trans,
&trans_values))
{
png_set_tRNS(write_ptr, write_info_ptr, trans, num_trans,
trans_values);
}
}
#endif
png_debug(0, "\nWriting info struct\n");
png_write_info(write_ptr, write_info_ptr);
row_buf = (png_bytep)png_malloc(read_ptr,
png_get_rowbytes(read_ptr, read_info_ptr));
if (row_buf == NULL)
{
fprintf(STDERR, "No memory to allocate row buffer\n");
png_destroy_read_struct(&read_ptr, &info_ptr, &end_info);
png_destroy_write_struct(&write_ptr, (png_infopp)NULL);
png_destroy_read_struct(&read_ptr, &read_info_ptr, (png_infopp)NULL);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
fclose(fpin);
fclose(fpout);
return 1;
}
if (info_ptr->interlace_type)
{
num_pass = png_set_interlace_handling(read_ptr);
num_pass = png_set_interlace_handling(write_ptr);
}
else
{
num_pass = 1;
}
png_set_interlace_handling(write_ptr);
for (pass = 0; pass < num_pass; pass++)
{
for (y = 0; y < info_ptr->height; y++)
for (y = 0; y < height; y++)
{
#ifdef TESTING
fprintf(STDERR, "Processing line #%ld\n", y);
#endif
png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)0, 1);
png_read_rows(read_ptr, (png_bytepp)&row_buf, (png_bytepp)NULL, 1);
png_write_rows(write_ptr, (png_bytepp)&row_buf, 1);
}
}
png_read_end(read_ptr, end_info);
png_write_end(write_ptr, end_info);
png_debug(0, "Reading and writing end_info data\n");
png_read_end(read_ptr, end_info_ptr);
png_write_end(write_ptr, end_info_ptr);
png_destroy_read_struct(&read_ptr, &info_ptr, &end_info);
png_destroy_write_struct(&write_ptr, (png_infopp)NULL);
png_debug(0, "Destroying data structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr);
fclose(fpin);
fclose(fpout);
free((png_byte *)near_row_buf);
png_free(read_ptr, row_buf);
fpin = fopen(inname, "rb");
if (!fpin)
png_debug(0, "Opening files for comparison\n");
if ((fpin = fopen(inname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find file %s\n", inname);
return 1;
}
fpout = fopen(outname, "rb");
if (!fpout)
if ((fpout = fopen(outname, "rb")) == NULL)
{
fprintf(STDERR, "Could not find file %s\n", outname);
fclose(fpin);
return 1;
}
while (1)
{
int num_in, num_out;
png_size_t num_in, num_out;
num_in = fread(inbuf, 1, 1, fpin);
num_out = fread(outbuf, 1, 1, fpout);
@ -215,7 +359,7 @@ int main(int argc, char *argv[])
if (!num_in)
break;
if (memcmp(inbuf, outbuf, num_in))
if (png_memcmp(inbuf, outbuf, num_in))
{
fprintf(STDERR, "Files %s and %s are different\n", inname, outname);
fclose(fpin);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.3 KiB

After

Width:  |  Height:  |  Size: 8.4 KiB

View File

@ -1,11 +1,11 @@
/* pngtrans.c - transforms the data in a row
routines used by both readers and writers
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
@ -16,6 +16,7 @@
void
png_set_bgr(png_structp png_ptr)
{
png_debug(1, "in png_set_bgr\n");
png_ptr->transformations |= PNG_BGR;
}
#endif
@ -25,6 +26,7 @@ png_set_bgr(png_structp png_ptr)
void
png_set_swap(png_structp png_ptr)
{
png_debug(1, "in png_set_swap\n");
if (png_ptr->bit_depth == 16)
png_ptr->transformations |= PNG_SWAP_BYTES;
}
@ -35,6 +37,7 @@ png_set_swap(png_structp png_ptr)
void
png_set_packing(png_structp png_ptr)
{
png_debug(1, "in png_set_packing\n");
if (png_ptr->bit_depth < 8)
{
png_ptr->transformations |= PNG_PACK;
@ -43,10 +46,22 @@ png_set_packing(png_structp png_ptr)
}
#endif
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
/* turn on packed pixel swapping */
void
png_set_packswap(png_structp png_ptr)
{
png_debug(1, "in png_set_packswap\n");
if (png_ptr->bit_depth < 8)
png_ptr->transformations |= PNG_PACKSWAP;
}
#endif
#if defined(PNG_READ_SHIFT_SUPPORTED) || defined(PNG_WRITE_SHIFT_SUPPORTED)
void
png_set_shift(png_structp png_ptr, png_color_8p true_bits)
{
png_debug(1, "in png_set_shift\n");
png_ptr->transformations |= PNG_SHIFT;
png_ptr->shift = *true_bits;
}
@ -56,6 +71,7 @@ png_set_shift(png_structp png_ptr, png_color_8p true_bits)
int
png_set_interlace_handling(png_structp png_ptr)
{
png_debug(1, "in png_set_interlace handling\n");
if (png_ptr->interlaced)
{
png_ptr->transformations |= PNG_INTERLACE;
@ -67,35 +83,37 @@ png_set_interlace_handling(png_structp png_ptr)
#endif
#if defined(PNG_READ_FILLER_SUPPORTED) || defined(PNG_WRITE_FILLER_SUPPORTED)
/* Add a filler byte on read, or remove a filler or alpha byte on write.
* The filler type has changed in v0.95 to allow future 2-byte fillers
* for 48-bit input data, as well as avoiding problems with some compilers
* which don't like bytes as parameters.
*/
void
png_set_filler(png_structp png_ptr, png_byte filler, int filler_loc)
png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
{
png_debug(1, "in png_set_filler\n");
png_ptr->transformations |= PNG_FILLER;
png_ptr->filler = filler;
png_ptr->filler = (png_byte)filler;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB &&
png_ptr->bit_depth == 8)
/* This should probably go in the "do_filler" routine */
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && png_ptr->bit_depth == 8)
{
png_ptr->usr_channels = 4;
}
}
#endif
/* Old functions kept around for compatability purposes. They will be
* removed at some time in the future, so don't use them. You should
* use png_set_filler() above instead. We set filler bytes to 0xff in
* case they are mistakenly used as PNG alpha (0xff is fully opaque). */
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void
png_set_rgbx(png_structp png_ptr)
png_set_swap_alpha(png_structp png_ptr)
{
png_set_filler(png_ptr, (png_byte)0xff, PNG_FILLER_AFTER);
}
void
png_set_xrgb(png_structp png_ptr)
{
png_set_filler(png_ptr, (png_byte)0xff, PNG_FILLER_BEFORE);
png_debug(1, "in png_set_swap_alpha\n");
png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif
@ -103,6 +121,7 @@ png_set_xrgb(png_structp png_ptr)
void
png_set_invert_mono(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_mono\n");
png_ptr->transformations |= PNG_INVERT_MONO;
}
@ -110,15 +129,17 @@ png_set_invert_mono(png_structp png_ptr)
void
png_do_invert(png_row_infop row_info, png_bytep row)
{
if (row && row_info && row_info->bit_depth == 1 &&
png_debug(1, "in png_do_invert\n");
if (row_info->bit_depth == 1 &&
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp;
png_uint_32 i;
for (i = 0, rp = row;
i < row_info->rowbytes;
i++, rp++)
for (i = 0, rp = row; i < row_info->rowbytes; i++, rp++)
{
*rp = (png_byte)(~(*rp));
}
@ -131,7 +152,12 @@ png_do_invert(png_row_infop row_info, png_bytep row)
void
png_do_swap(png_row_infop row_info, png_bytep row)
{
if (row && row_info && row_info->bit_depth == 16)
png_debug(1, "in png_do_swap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->bit_depth == 16)
{
png_bytep rp;
png_byte t;
@ -149,80 +175,391 @@ png_do_swap(png_row_infop row_info, png_bytep row)
}
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* swaps red and blue */
#if defined(PNG_READ_PACKSWAP_SUPPORTED)||defined(PNG_WRITE_PACKSWAP_SUPPORTED)
static png_byte onebppswaptable[256] = {
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
};
static png_byte twobppswaptable[256] = {
0x00, 0x40, 0x80, 0xC0, 0x10, 0x50, 0x90, 0xD0,
0x20, 0x60, 0xA0, 0xE0, 0x30, 0x70, 0xB0, 0xF0,
0x04, 0x44, 0x84, 0xC4, 0x14, 0x54, 0x94, 0xD4,
0x24, 0x64, 0xA4, 0xE4, 0x34, 0x74, 0xB4, 0xF4,
0x08, 0x48, 0x88, 0xC8, 0x18, 0x58, 0x98, 0xD8,
0x28, 0x68, 0xA8, 0xE8, 0x38, 0x78, 0xB8, 0xF8,
0x0C, 0x4C, 0x8C, 0xCC, 0x1C, 0x5C, 0x9C, 0xDC,
0x2C, 0x6C, 0xAC, 0xEC, 0x3C, 0x7C, 0xBC, 0xFC,
0x01, 0x41, 0x81, 0xC1, 0x11, 0x51, 0x91, 0xD1,
0x21, 0x61, 0xA1, 0xE1, 0x31, 0x71, 0xB1, 0xF1,
0x05, 0x45, 0x85, 0xC5, 0x15, 0x55, 0x95, 0xD5,
0x25, 0x65, 0xA5, 0xE5, 0x35, 0x75, 0xB5, 0xF5,
0x09, 0x49, 0x89, 0xC9, 0x19, 0x59, 0x99, 0xD9,
0x29, 0x69, 0xA9, 0xE9, 0x39, 0x79, 0xB9, 0xF9,
0x0D, 0x4D, 0x8D, 0xCD, 0x1D, 0x5D, 0x9D, 0xDD,
0x2D, 0x6D, 0xAD, 0xED, 0x3D, 0x7D, 0xBD, 0xFD,
0x02, 0x42, 0x82, 0xC2, 0x12, 0x52, 0x92, 0xD2,
0x22, 0x62, 0xA2, 0xE2, 0x32, 0x72, 0xB2, 0xF2,
0x06, 0x46, 0x86, 0xC6, 0x16, 0x56, 0x96, 0xD6,
0x26, 0x66, 0xA6, 0xE6, 0x36, 0x76, 0xB6, 0xF6,
0x0A, 0x4A, 0x8A, 0xCA, 0x1A, 0x5A, 0x9A, 0xDA,
0x2A, 0x6A, 0xAA, 0xEA, 0x3A, 0x7A, 0xBA, 0xFA,
0x0E, 0x4E, 0x8E, 0xCE, 0x1E, 0x5E, 0x9E, 0xDE,
0x2E, 0x6E, 0xAE, 0xEE, 0x3E, 0x7E, 0xBE, 0xFE,
0x03, 0x43, 0x83, 0xC3, 0x13, 0x53, 0x93, 0xD3,
0x23, 0x63, 0xA3, 0xE3, 0x33, 0x73, 0xB3, 0xF3,
0x07, 0x47, 0x87, 0xC7, 0x17, 0x57, 0x97, 0xD7,
0x27, 0x67, 0xA7, 0xE7, 0x37, 0x77, 0xB7, 0xF7,
0x0B, 0x4B, 0x8B, 0xCB, 0x1B, 0x5B, 0x9B, 0xDB,
0x2B, 0x6B, 0xAB, 0xEB, 0x3B, 0x7B, 0xBB, 0xFB,
0x0F, 0x4F, 0x8F, 0xCF, 0x1F, 0x5F, 0x9F, 0xDF,
0x2F, 0x6F, 0xAF, 0xEF, 0x3F, 0x7F, 0xBF, 0xFF
};
static png_byte fourbppswaptable[256] = {
0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70,
0x80, 0x90, 0xA0, 0xB0, 0xC0, 0xD0, 0xE0, 0xF0,
0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71,
0x81, 0x91, 0xA1, 0xB1, 0xC1, 0xD1, 0xE1, 0xF1,
0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72,
0x82, 0x92, 0xA2, 0xB2, 0xC2, 0xD2, 0xE2, 0xF2,
0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73,
0x83, 0x93, 0xA3, 0xB3, 0xC3, 0xD3, 0xE3, 0xF3,
0x04, 0x14, 0x24, 0x34, 0x44, 0x54, 0x64, 0x74,
0x84, 0x94, 0xA4, 0xB4, 0xC4, 0xD4, 0xE4, 0xF4,
0x05, 0x15, 0x25, 0x35, 0x45, 0x55, 0x65, 0x75,
0x85, 0x95, 0xA5, 0xB5, 0xC5, 0xD5, 0xE5, 0xF5,
0x06, 0x16, 0x26, 0x36, 0x46, 0x56, 0x66, 0x76,
0x86, 0x96, 0xA6, 0xB6, 0xC6, 0xD6, 0xE6, 0xF6,
0x07, 0x17, 0x27, 0x37, 0x47, 0x57, 0x67, 0x77,
0x87, 0x97, 0xA7, 0xB7, 0xC7, 0xD7, 0xE7, 0xF7,
0x08, 0x18, 0x28, 0x38, 0x48, 0x58, 0x68, 0x78,
0x88, 0x98, 0xA8, 0xB8, 0xC8, 0xD8, 0xE8, 0xF8,
0x09, 0x19, 0x29, 0x39, 0x49, 0x59, 0x69, 0x79,
0x89, 0x99, 0xA9, 0xB9, 0xC9, 0xD9, 0xE9, 0xF9,
0x0A, 0x1A, 0x2A, 0x3A, 0x4A, 0x5A, 0x6A, 0x7A,
0x8A, 0x9A, 0xAA, 0xBA, 0xCA, 0xDA, 0xEA, 0xFA,
0x0B, 0x1B, 0x2B, 0x3B, 0x4B, 0x5B, 0x6B, 0x7B,
0x8B, 0x9B, 0xAB, 0xBB, 0xCB, 0xDB, 0xEB, 0xFB,
0x0C, 0x1C, 0x2C, 0x3C, 0x4C, 0x5C, 0x6C, 0x7C,
0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC,
0x0D, 0x1D, 0x2D, 0x3D, 0x4D, 0x5D, 0x6D, 0x7D,
0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD,
0x0E, 0x1E, 0x2E, 0x3E, 0x4E, 0x5E, 0x6E, 0x7E,
0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE,
0x0F, 0x1F, 0x2F, 0x3F, 0x4F, 0x5F, 0x6F, 0x7F,
0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF
};
/* swaps pixel packing order within bytes */
void
png_do_bgr(png_row_infop row_info, png_bytep row)
png_do_packswap(png_row_infop row_info, png_bytep row)
{
if (row && row_info && (row_info->color_type & 2))
png_debug(1, "in png_do_packswap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL
#endif
row_info->bit_depth < 8)
{
if (row_info->color_type == 2 && row_info->bit_depth == 8)
png_bytep rp, end, table;
end = row + row_info->rowbytes;
if (row_info->bit_depth == 1)
table = onebppswaptable;
else if (row_info->bit_depth == 2)
table = twobppswaptable;
else if (row_info->bit_depth == 4)
table = fourbppswaptable;
else
return;
for (rp = row; rp < end; rp++)
*rp = table[*rp];
}
}
#endif /* PNG_READ_PACKSWAP_SUPPORTED or PNG_WRITE_PACKSWAP_SUPPORTED */
#if defined(PNG_WRITE_FILLER_SUPPORTED) || \
defined(PNG_READ_STRIP_ALPHA_SUPPORTED)
/* remove filler or alpha byte(s) */
void
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
{
png_debug(1, "in png_do_strip_filler\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
png_bytep rp;
png_byte t;
/*
if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
*/
if (row_info->channels == 4)
{
if (row_info->bit_depth == 8)
{
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, rp = row;
i < row_info->width;
i++, rp += 3)
for (i = 1, sp = row + 4, dp = row + 3; i < row_info->width; i++)
{
t = *rp;
*rp = *(rp + 2);
*(rp + 2) = t;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
}
}
else if (row_info->color_type == 6 && row_info->bit_depth == 8)
/* This converts from XRGB or ARGB to RGB */
else
{
png_bytep rp;
png_byte t;
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, rp = row;
i < row_info->width;
i++, rp += 4)
for (i = 0, sp = row, dp = row; i < row_info->width; i++)
{
t = *rp;
*rp = *(rp + 2);
*(rp + 2) = t;
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
else if (row_info->color_type == 2 && row_info->bit_depth == 16)
row_info->pixel_depth = 24;
row_info->rowbytes = row_info->width * 3;
}
else /* if (row_info->bit_depth == 16) */
{
png_bytep rp;
png_byte t[2];
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, rp = row;
i < row_info->width;
i++, rp += 6)
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
for (i = 1, sp = row + 8, dp = row + 6; i < row_info->width; i++)
{
t[0] = *rp;
t[1] = *(rp + 1);
*rp = *(rp + 4);
*(rp + 1) = *(rp + 5);
*(rp + 4) = t[0];
*(rp + 5) = t[1];
/* This could be (although memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else if (row_info->color_type == 6 && row_info->bit_depth == 16)
else
{
png_bytep rp;
png_byte t[2];
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, rp = row;
i < row_info->width;
i++, rp += 8)
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0, sp = row + 2, dp = row; i < row_info->width; i++)
{
t[0] = *rp;
t[1] = *(rp + 1);
*rp = *(rp + 4);
*(rp + 1) = *(rp + 5);
*(rp + 4) = t[0];
*(rp + 5) = t[1];
/* This could be (although memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_info->width * 6;
}
row_info->channels = 3;
}
/*
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
*/
else if (row_info->channels == 2)
{
if (row_info->bit_depth == 8)
{
/* This converts from GX or GA to G */
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 1, sp = row + 2, dp = row + 1; i < row_info->width; i++)
{
*dp++ = *sp++;
sp++;
}
}
/* This converts from XG or AG to G */
else
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, sp = row, dp = row; i < row_info->width; i++)
{
sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 8;
row_info->rowbytes = row_info->width;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
/* This converts from GGXX or GGAA to GG */
for (i = 1, sp = row + 4, dp = row + 2; i < row_info->width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
sp += 2;
}
}
else
{
png_bytep sp, dp;
png_uint_32 i;
/* This converts from XXGG or AAGG to GG */
for (i = 0, sp = row, dp = row; i < row_info->width; i++)
{
sp += 2;
*dp++ = *sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_info->width * 2;
}
row_info->channels = 1;
}
}
}
#endif
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* swaps red and blue bytes within a pixel */
void
png_do_bgr(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_bgr\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
(row_info->color_type & PNG_COLOR_MASK_COLOR))
{
if (row_info->bit_depth == 8)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_byte save;
png_uint_32 i;
for (i = 0, rp = row; i < row_info->width; i++, rp += 3)
{
save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_byte save;
png_uint_32 i;
for (i = 0, rp = row; i < row_info->width; i++, rp += 4)
{
save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
}
}
else if (row_info->bit_depth == 16)
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB)
{
png_bytep rp;
png_byte save[2];
png_uint_32 i;
for (i = 0, rp = row; i < row_info->width; i++, rp += 6)
{
save[0] = *rp;
save[1] = *(rp + 1);
*rp = *(rp + 4);
*(rp + 1) = *(rp + 5);
*(rp + 4) = save[0];
*(rp + 5) = save[1];
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
png_bytep rp;
png_byte save[2];
png_uint_32 i;
for (i = 0, rp = row; i < row_info->width; i++, rp += 8)
{
save[0] = *rp;
save[1] = *(rp + 1);
*rp = *(rp + 4);
*(rp + 1) = *(rp + 5);
*(rp + 4) = save[0];
*(rp + 5) = save[1];
}
}
}
}
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */

View File

@ -1,10 +1,11 @@
/* pngwio.c - functions for data output
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
This file provides a location for all output. Users which need
special handling are expected to write functions which have the same
@ -20,13 +21,12 @@
writes to a file pointer. Note that this routine sometimes gets called
with very small lengths, so you should implement some kind of simple
buffering if you are using unbuffered writes. This should never be asked
to write more then 64K on a 16 bit machine. The cast to png_size_t is
there to quiet warnings of certain compilers. */
to write more then 64K on a 16 bit machine. */
void
png_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
if (png_ptr->write_data_fn)
if (png_ptr->write_data_fn != NULL )
(*(png_ptr->write_data_fn))(png_ptr, data, length);
else
png_error(png_ptr, "Call to NULL write function");
@ -38,11 +38,11 @@ png_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
than changing the library. */
#ifndef USE_FAR_KEYWORD
static void
png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
check = fwrite(data, 1, (png_size_t)length, (FILE *)(png_ptr->io_ptr));
check = fwrite(data, 1, length, (FILE *)(png_ptr->io_ptr));
if (check != length)
{
png_error(png_ptr, "Write Error");
@ -58,25 +58,25 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
#define MIN(a,b) (a <= b ? a : b)
static void
png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_uint_32 check;
png_byte *n_data;
png_byte *near_data; /* Needs to be "png_byte *" instead of "png_bytep" */
FILE *io_ptr;
/* Check if data really is near. If so, use usual code. */
n_data = (png_byte *)CVT_PTR_NOCHECK(data);
near_data = (png_byte *)CVT_PTR_NOCHECK(data);
io_ptr = (FILE *)CVT_PTR(png_ptr->io_ptr);
if ((png_bytep)n_data == data)
if ((png_bytep)near_data == data)
{
check = fwrite(n_data, 1, (png_size_t)length, io_ptr);
check = fwrite(near_data, 1, length, io_ptr);
}
else
{
png_byte buf[NEAR_BUF_SIZE];
png_size_t written, remaining, err;
check = 0;
remaining = (png_size_t)length;
remaining = length;
do
{
written = MIN(NEAR_BUF_SIZE, remaining);
@ -106,7 +106,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_uint_32 length)
void
png_flush(png_structp png_ptr)
{
if (png_ptr->output_flush_fn)
if (png_ptr->output_flush_fn != NULL)
(*(png_ptr->output_flush_fn))(png_ptr);
}
@ -115,7 +115,7 @@ png_default_flush(png_structp png_ptr)
{
FILE *io_ptr;
io_ptr = (FILE *)CVT_PTR((png_ptr->io_ptr));
if (io_ptr)
if (io_ptr != NULL)
fflush(io_ptr);
}
#endif
@ -148,13 +148,13 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
{
png_ptr->io_ptr = io_ptr;
if (write_data_fn)
if (write_data_fn != NULL)
png_ptr->write_data_fn = write_data_fn;
else
png_ptr->write_data_fn = png_default_write_data;
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
if (output_flush_fn)
if (output_flush_fn != NULL)
png_ptr->output_flush_fn = output_flush_fn;
else
png_ptr->output_flush_fn = png_default_flush;

View File

@ -1,28 +1,32 @@
/* pngwrite.c - general routines to write a png file
/* pngwrite.c - general routines to write a PNG file
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
/* get internal access to png.h */
#define PNG_INTERNAL
#include "png.h"
/* Writes all the png information. This is the suggested way to use
the library. If you have a new chunk to add, make a function to
write it, and put it in the correct location here. If you want
the chunk written after the image data, put it in png_write_end().
I strongly encurage you to supply a PNG_INFO_ flag, and check
info_ptr->valid before writing the chunk, as that will keep the code
from breaking if you want to just write a plain png file.
If you have long comments, I suggest writing them in png_write_end(),
and compressing them. */
/* Writes all the PNG information. This is the suggested way to use the
* library. If you have a new chunk to add, make a function to write it,
* and put it in the correct location here. If you want the chunk written
* after the image data, put it in png_write_end(). I strongly encurage
* you to supply a PNG_INFO_ flag, and check info_ptr->valid before writing
* the chunk, as that will keep the code from breaking if you want to just
* write a plain PNG file. If you have long comments, I suggest writing
* them in png_write_end(), and compressing them.
*/
void
png_write_info(png_structp png_ptr, png_infop info_ptr)
{
int i;
png_debug(1, "in png_write_info\n");
png_write_sig(png_ptr); /* write PNG signature */
/* write IHDR information. */
png_write_IHDR(png_ptr, info_ptr->width, info_ptr->height,
@ -47,7 +51,8 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
info_ptr->x_blue, info_ptr->y_blue);
#endif
if (info_ptr->valid & PNG_INFO_PLTE)
png_write_PLTE(png_ptr, info_ptr->palette, info_ptr->num_palette);
png_write_PLTE(png_ptr, info_ptr->palette,
(png_uint_32)info_ptr->num_palette);
else if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
png_error(png_ptr, "Valid palette required for paletted images\n");
#if defined(PNG_WRITE_tRNS_SUPPORTED)
@ -63,16 +68,22 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
if (info_ptr->valid & PNG_INFO_hIST)
png_write_hIST(png_ptr, info_ptr->hist, info_ptr->num_palette);
#endif
#if defined(PNG_WRITE_pHYs_SUPPORTED)
if (info_ptr->valid & PNG_INFO_pHYs)
png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
#endif
#if defined(PNG_WRITE_oFFs_SUPPORTED)
if (info_ptr->valid & PNG_INFO_oFFs)
png_write_oFFs(png_ptr, info_ptr->x_offset, info_ptr->y_offset,
info_ptr->offset_unit_type);
#endif
#if defined(PNG_WRITE_pCAL_SUPPORTED)
if (info_ptr->valid & PNG_INFO_pCAL)
png_write_pCAL(png_ptr, info_ptr->pcal_purpose, info_ptr->pcal_X0,
info_ptr->pcal_X1, info_ptr->pcal_type, info_ptr->pcal_nparams,
info_ptr->pcal_units, info_ptr->pcal_params);
#endif
#if defined(PNG_WRITE_pHYs_SUPPORTED)
if (info_ptr->valid & PNG_INFO_pHYs)
png_write_pHYs(png_ptr, info_ptr->x_pixels_per_unit,
info_ptr->y_pixels_per_unit, info_ptr->phys_unit_type);
#endif
#if defined(PNG_WRITE_tIME_SUPPORTED)
if (info_ptr->valid & PNG_INFO_tIME)
{
@ -82,15 +93,12 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
#endif
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
/* Check to see if we need to write text chunks */
if (info_ptr->num_text)
{
int i; /* local counter */
/* loop through the text chunks */
for (i = 0; i < info_ptr->num_text; i++)
{
/* if chunk is compressed */
if (info_ptr->text[i].compression >= 0)
png_debug2(2, "Writing header text chunk %d, type %d\n", i,
info_ptr->text[i].compression);
/* If we want a compressed text chunk */
if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
{
#if defined(PNG_WRITE_zTXt_SUPPORTED)
/* write compressed chunk */
@ -100,8 +108,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
#else
png_warning(png_ptr, "Unable to write compressed text\n");
#endif
/* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
}
else
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
{
#if defined(PNG_WRITE_tEXt_SUPPORTED)
/* write uncompressed chunk */
@ -110,25 +120,28 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
#else
png_warning(png_ptr, "Unable to write uncompressed text\n");
#endif
}
/* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
}
}
#endif
}
/* writes the end of the png file. If you don't want to write comments or
/* Writes the end of the PNG file. If you don't want to write comments or
time information, you can pass NULL for info. If you already wrote these
in png_write_info(), do not write them again here. If you have long
comments, I suggest writing them here, and compressing them. */
void
png_write_end(png_structp png_ptr, png_infop info_ptr)
{
png_debug(1, "in png_write_end\n");
if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "No IDATs written into file");
/* see if user wants us to write information chunks */
if (info_ptr)
if (info_ptr != NULL)
{
int i; /* local index variable */
#if defined(PNG_WRITE_tIME_SUPPORTED)
/* check to see if user has supplied a time chunk */
if (info_ptr->valid & PNG_INFO_tIME &&
@ -136,34 +149,36 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
png_write_tIME(png_ptr, &(info_ptr->mod_time));
#endif
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
/* check to see if we need to write comment chunks */
if (info_ptr->num_text)
{
int i; /* local index variable */
/* loop through comment chunks */
for (i = 0; i < info_ptr->num_text; i++)
{
#if defined(PNG_WRITE_zTXt_SUPPORTED)
/* check to see if comment is to be compressed */
if (info_ptr->text[i].compression >= 0)
png_debug2(2, "Writing trailer text chunk %d, type %d\n", i,
info_ptr->text[i].compression);
if (info_ptr->text[i].compression >= PNG_TEXT_COMPRESSION_zTXt)
{
#if defined(PNG_WRITE_zTXt_SUPPORTED)
/* write compressed chunk */
png_write_zTXt(png_ptr, info_ptr->text[i].key,
info_ptr->text[i].text, info_ptr->text[i].text_length,
info_ptr->text[i].compression);
#else
png_warning(png_ptr, "Unable to write compressed text\n");
#endif
/* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_zTXt_WR;
}
#if defined(PNG_WRITE_tEXt_SUPPORTED)
else
#endif
#endif
#if defined(PNG_WRITE_tEXt_SUPPORTED)
else if (info_ptr->text[i].compression == PNG_TEXT_COMPRESSION_NONE)
{
#if defined(PNG_WRITE_tEXt_SUPPORTED)
/* write uncompressed chunk */
png_write_tEXt(png_ptr, info_ptr->text[i].key,
info_ptr->text[i].text, info_ptr->text[i].text_length);
}
#else
png_warning(png_ptr, "Unable to write uncompressed text\n");
#endif
/* Mark this chunk as written */
info_ptr->text[i].compression = PNG_TEXT_COMPRESSION_NONE_WR;
}
}
#endif
@ -171,7 +186,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
png_ptr->mode |= PNG_AFTER_IDAT;
/* write end of png file */
/* write end of PNG file */
png_write_IEND(png_ptr);
}
@ -179,6 +194,7 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
void
png_convert_from_struct_tm(png_timep ptime, struct tm FAR * ttime)
{
png_debug(1, "in png_convert_from_struct_tm\n");
ptime->year = (png_uint_16)(1900 + ttime->tm_year);
ptime->month = (png_byte)(ttime->tm_mon + 1);
ptime->day = (png_byte)ttime->tm_mday;
@ -192,12 +208,13 @@ png_convert_from_time_t(png_timep ptime, time_t ttime)
{
struct tm *tbuf;
png_debug(1, "in png_convert_from_time_t\n");
tbuf = gmtime(&ttime);
png_convert_from_struct_tm(ptime, tbuf);
}
#endif
/* initialize png structure, and allocate any memory needed */
/* Initialize png_ptr structure, and allocate any memory needed */
png_structp
png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn)
@ -206,6 +223,7 @@ png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
#endif
png_debug(1, "in png_create_write_struct\n");
if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
{
return (png_structp)NULL;
@ -225,16 +243,16 @@ png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
#endif
png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
if (user_png_ver == NULL || png_strcmp(user_png_ver, png_libpng_ver))
/* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
* we must recompile any applications that use any older library version.
* For versions after libpng 1.0, we will be compatible, so we need
* only check the first digit.
*/
if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0] ||
(png_libpng_ver[0] == '0' && user_png_ver[2] < '9'))
{
if (user_png_ver == NULL || user_png_ver[0] != png_libpng_ver[0])
{
png_error(png_ptr, "Incompatible libpng versions");
}
else
{
png_warning(png_ptr, "Different libpng versions");
}
png_error(png_ptr,
"Incompatible libpng version in application and library");
}
/* initialize zbuf - compression buffer */
@ -247,12 +265,13 @@ png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
}
/* initialize png structure, and allocate any memory needed */
/* Initialize png_ptr structure, and allocate any memory needed */
void
png_write_init(png_structp png_ptr)
{
jmp_buf tmp_jmp; /* to save current jump buffer */
png_debug(1, "in png_write_init\n");
/* save jump buffer and error functions */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
@ -266,6 +285,11 @@ png_write_init(png_structp png_ptr)
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);
png_set_write_fn(png_ptr, NULL, NULL, NULL);
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
1, NULL, NULL);
#endif
}
/* write a few rows of image data. If the image is interlaced,
@ -279,6 +303,7 @@ png_write_rows(png_structp png_ptr, png_bytepp row,
png_uint_32 i; /* row counter */
png_bytepp rp; /* row pointer */
png_debug(1, "in png_write_rows\n");
/* loop through the rows */
for (i = 0, rp = row; i < num_rows; i++, rp++)
{
@ -295,6 +320,7 @@ png_write_image(png_structp png_ptr, png_bytepp image)
int pass, num_pass; /* pass variables */
png_bytepp rp; /* points to current row */
png_debug(1, "in png_write_image\n");
/* intialize interlace handling. If image is not interlaced,
this will set pass to 1 */
num_pass = png_set_interlace_handling(png_ptr);
@ -313,6 +339,7 @@ png_write_image(png_structp png_ptr, png_bytepp image)
void
png_write_row(png_structp png_ptr, png_bytep row)
{
png_debug(1, "in png_write_row\n");
/* initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
@ -388,8 +415,15 @@ png_write_row(png_structp png_ptr, png_bytep row)
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
/* copy users row into buffer, leaving room for filter byte */
png_memcpy(png_ptr->row_buf + 1, row, (png_size_t)png_ptr->row_info.rowbytes);
png_debug1(4, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
png_debug1(4, "row_info->width = %d\n", png_ptr->row_info.width);
png_debug1(4, "row_info->channels = %d\n", png_ptr->row_info.channels);
png_debug1(4, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
png_debug1(4, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
png_debug1(4, "row_info->rowbytes = %d\n", png_ptr->row_info.rowbytes);
/* Copy user's row into buffer, leaving room for filter byte. */
png_memcpy(png_ptr->row_buf + 1, row, png_ptr->row_info.rowbytes);
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
/* handle interlacing */
@ -411,7 +445,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
if (png_ptr->transformations)
png_do_write_transformations(png_ptr);
/* find a filter if necessary, filter the row and write it out */
/* Find a filter if necessary, filter the row and write it out. */
png_write_find_filter(png_ptr, &(png_ptr->row_info));
}
@ -420,6 +454,7 @@ png_write_row(png_structp png_ptr, png_bytep row)
void
png_set_flush(png_structp png_ptr, int nrows)
{
png_debug(1, "in png_set_flush\n");
png_ptr->flush_dist = (nrows < 0 ? 0 : nrows);
}
@ -429,6 +464,7 @@ png_write_flush(png_structp png_ptr)
{
int wrote_IDAT;
png_debug(1, "in png_write_flush\n");
/* We have already written out all of the data */
if (png_ptr->row_number >= png_ptr->num_rows)
return;
@ -444,13 +480,13 @@ png_write_flush(png_structp png_ptr)
/* check for compression errors */
if (ret != Z_OK)
{
if (png_ptr->zstream.msg)
if (png_ptr->zstream.msg != NULL)
png_error(png_ptr, png_ptr->zstream.msg);
else
png_error(png_ptr, "zlib error");
}
if (!png_ptr->zstream.avail_out)
if (!(png_ptr->zstream.avail_out))
{
/* write the IDAT and reset the zlib output buffer */
png_write_IDAT(png_ptr, png_ptr->zbuf,
@ -482,19 +518,20 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
if (png_ptr_ptr)
png_debug(1, "in png_destroy_write_struct\n");
if (png_ptr_ptr != NULL)
png_ptr = *png_ptr_ptr;
if (info_ptr_ptr)
if (info_ptr_ptr != NULL)
info_ptr = *info_ptr_ptr;
if (info_ptr)
if (info_ptr != NULL)
{
png_destroy_struct((png_voidp)info_ptr);
*info_ptr_ptr = (png_infop)NULL;
}
if (png_ptr)
if (png_ptr != NULL)
{
png_write_destroy(png_ptr);
png_destroy_struct((png_voidp)png_ptr);
@ -503,7 +540,7 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
}
/* free any memory used in png struct (old method) */
/* Free any memory used in png_ptr struct (old method) */
void
png_write_destroy(png_structp png_ptr)
{
@ -512,6 +549,7 @@ png_write_destroy(png_structp png_ptr)
png_error_ptr warning_fn;
png_voidp error_ptr;
png_debug(1, "in png_write_destroy\n");
/* free any memory zlib uses */
deflateEnd(&png_ptr->zstream);
@ -523,6 +561,13 @@ png_write_destroy(png_structp png_ptr)
png_free(png_ptr, png_ptr->up_row);
png_free(png_ptr, png_ptr->avg_row);
png_free(png_ptr, png_ptr->paeth_row);
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
png_free(png_ptr, png_ptr->prev_filters);
png_free(png_ptr, png_ptr->filter_weights);
png_free(png_ptr, png_ptr->inv_filter_weights);
png_free(png_ptr, png_ptr->filter_costs);
png_free(png_ptr, png_ptr->inv_filter_costs);
#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
/* reset structure */
png_memcpy(tmp_jmp, png_ptr->jmpbuf, sizeof (jmp_buf));
@ -540,71 +585,79 @@ png_write_destroy(png_structp png_ptr)
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
}
/* Allow the application to select one or more filters to use */
/* Allow the application to select one or more row filters to use. */
void
png_set_filter(png_structp png_ptr, int method, int filters)
{
/* We allow 'method' only for future expansion of the base filter method */
if (method == 0)
png_debug(1, "in png_set_filter\n");
/* We allow 'method' only for future expansion of the base filter method. */
if (method == PNG_FILTER_TYPE_BASE)
{
switch (filters & (PNG_ALL_FILTERS | 0x07))
{
case 5:
case 6:
case 7: png_warning(png_ptr, "Unknown custom row filter for method 0");
case 0: png_ptr->do_filter = PNG_FILTER_NONE; break;
case 1: png_ptr->do_filter = PNG_FILTER_SUB; break;
case 2: png_ptr->do_filter = PNG_FILTER_UP; break;
case 3: png_ptr->do_filter = PNG_FILTER_AVG; break;
case 4: png_ptr->do_filter = PNG_FILTER_PAETH; break;
case 7: png_warning(png_ptr, "Unknown row filter for method 0");
case PNG_FILTER_VALUE_NONE: png_ptr->do_filter=PNG_FILTER_NONE; break;
case PNG_FILTER_VALUE_SUB: png_ptr->do_filter=PNG_FILTER_SUB; break;
case PNG_FILTER_VALUE_UP: png_ptr->do_filter=PNG_FILTER_UP; break;
case PNG_FILTER_VALUE_AVG: png_ptr->do_filter=PNG_FILTER_AVG; break;
case PNG_FILTER_VALUE_PAETH: png_ptr->do_filter=PNG_FILTER_PAETH;break;
default: png_ptr->do_filter = (png_byte)filters; break;
}
/* If we have allocated the row_buf, then we should have also allocated
* all of the filter buffers that have been selected.
/* If we have allocated the row_buf, this means we have already started
* with the image and we should have allocated all of the filter buffers
* that have been selected. If prev_row isn't already allocated, then
* it is too late to start using the filters that need it, since we
* will be missing the data in the previous row. If an application
* wants to start and stop using particular filters during compression,
* it should start out with all of the filters, and then add and
* remove them after the start of compression.
*/
if (png_ptr->row_buf)
if (png_ptr->row_buf != NULL)
{
if (png_ptr->do_filter & PNG_FILTER_SUB && !(png_ptr->sub_row))
if (png_ptr->do_filter & PNG_FILTER_SUB && png_ptr->sub_row == NULL)
{
png_ptr->sub_row = (png_bytep )png_malloc(png_ptr,
png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
png_ptr->rowbytes + 1);
png_ptr->sub_row[0] = 1; /* Set the row filter type */
png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
}
if (png_ptr->do_filter & PNG_FILTER_UP && !(png_ptr->up_row))
if (png_ptr->do_filter & PNG_FILTER_UP && png_ptr->up_row == NULL)
{
if (!(png_ptr->prev_row))
if (png_ptr->prev_row == NULL)
{
png_warning(png_ptr, "Can't to add up filter after starting");
png_warning(png_ptr, "Can't add Up filter after starting");
png_ptr->do_filter &= ~PNG_FILTER_UP;
}
else
{
png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
png_ptr->rowbytes + 1);
png_ptr->up_row[0] = 2; /* Set the row filter type */
png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
}
}
if (png_ptr->do_filter & PNG_FILTER_AVG && !(png_ptr->avg_row))
if (png_ptr->do_filter & PNG_FILTER_AVG && png_ptr->avg_row == NULL)
{
if (!(png_ptr->prev_row))
if (png_ptr->prev_row == NULL)
{
png_warning(png_ptr, "Can't add average filter after starting");
png_warning(png_ptr, "Can't add Average filter after starting");
png_ptr->do_filter &= ~PNG_FILTER_AVG;
}
else
{
png_ptr->up_row = (png_bytep )png_malloc(png_ptr,
png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
png_ptr->rowbytes + 1);
png_ptr->up_row[0] = 3; /* Set the row filter type */
png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
}
}
if (png_ptr->do_filter & PNG_FILTER_PAETH && !(png_ptr->paeth_row))
if (png_ptr->do_filter & PNG_FILTER_PAETH &&
png_ptr->paeth_row == NULL)
{
if (!(png_ptr->prev_row))
if (png_ptr->prev_row == NULL)
{
png_warning(png_ptr, "Can't add Paeth filter after starting");
png_ptr->do_filter &= ~PNG_FILTER_PAETH;
@ -613,7 +666,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
{
png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
png_ptr->rowbytes + 1);
png_ptr->paeth_row[0] = 4; /* Set the row filter type */
png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
}
}
@ -625,9 +678,134 @@ png_set_filter(png_structp png_ptr, int method, int filters)
png_error(png_ptr, "Unknown custom filter method");
}
/* This allows us to influence the way in which libpng chooses the "best"
* filter for the current scanline. While the "minimum-sum-of-absolute-
* differences metric is relatively fast and effective, there is some
* question as to whether it can be improved upon by trying to keep the
* filtered data going to zlib more consistent, hopefully resulting in
* better compression. */
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
void
png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
int num_weights, png_doublep filter_weights,
png_doublep filter_costs)
{
int i;
png_debug(1, "in png_set_filter_heuristics\n");
if (heuristic_method >= PNG_FILTER_HEURISTIC_LAST)
{
png_warning(png_ptr, "Unknown filter heuristic method");
return;
}
if (heuristic_method == PNG_FILTER_HEURISTIC_DEFAULT)
{
heuristic_method = PNG_FILTER_HEURISTIC_UNWEIGHTED;
}
if (num_weights < 0 || filter_weights == NULL ||
heuristic_method == PNG_FILTER_HEURISTIC_UNWEIGHTED)
{
num_weights = 0;
}
png_ptr->num_prev_filters = num_weights;
png_ptr->heuristic_method = heuristic_method;
if (num_weights > 0)
{
if (png_ptr->prev_filters == NULL)
{
png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
sizeof(png_byte) * num_weights);
/* To make sure that the weighting starts out fairly */
for (i = 0; i < num_weights; i++)
{
png_ptr->prev_filters[i] = 255;
}
}
if (png_ptr->filter_weights == NULL)
{
png_ptr->filter_weights = (png_uint_16p)png_malloc(png_ptr,
sizeof(png_uint_16) * num_weights);
png_ptr->inv_filter_weights = (png_uint_16p)png_malloc(png_ptr,
sizeof(png_uint_16) * num_weights);
for (i = 0; i < num_weights; i++)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
}
for (i = 0; i < num_weights; i++)
{
if (filter_weights[i] < 0.0)
{
png_ptr->inv_filter_weights[i] =
png_ptr->filter_weights[i] = PNG_WEIGHT_FACTOR;
}
else
{
png_ptr->inv_filter_weights[i] =
(png_uint_16)((double)PNG_WEIGHT_FACTOR*filter_weights[i]+0.5);
png_ptr->filter_weights[i] =
(png_uint_16)((double)PNG_WEIGHT_FACTOR/filter_weights[i]+0.5);
}
}
}
/* If, in the future, there are other filter methods, this would
* need to be based on png_ptr->filter.
*/
if (png_ptr->filter_costs == NULL)
{
png_ptr->filter_costs = (png_uint_16p)png_malloc(png_ptr,
sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST);
png_ptr->inv_filter_costs = (png_uint_16p)png_malloc(png_ptr,
sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST);
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{
png_ptr->inv_filter_costs[i] =
png_ptr->filter_costs[i] = PNG_COST_FACTOR;
}
}
/* Here is where we set the relative costs of the different filters. We
* should take the desired compression level into account when setting
* the costs, so that Paeth, for instance, has a high relative cost at low
* compression levels, while it has a lower relative cost at higher
* compression settings. The filter types are in order of increasing
* relative cost, so it would be possible to do this with an algorithm.
*/
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{
if (filter_costs == NULL || filter_costs[i] < 0.0)
{
png_ptr->inv_filter_costs[i] =
png_ptr->filter_costs[i] = PNG_COST_FACTOR;
}
else if (filter_costs[i] >= 1.0)
{
png_ptr->inv_filter_costs[i] =
(png_uint_16)((double)PNG_COST_FACTOR / filter_costs[i] + 0.5);
png_ptr->filter_costs[i] =
(png_uint_16)((double)PNG_COST_FACTOR * filter_costs[i] + 0.5);
}
}
}
#endif /* PNG_WRITE_WEIGHTED_FILTER_SUPPORTED */
void
png_set_compression_level(png_structp png_ptr, int level)
{
png_debug(1, "in png_set_compression_level\n");
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_LEVEL;
png_ptr->zlib_level = level;
}
@ -635,6 +813,7 @@ png_set_compression_level(png_structp png_ptr, int level)
void
png_set_compression_mem_level(png_structp png_ptr, int mem_level)
{
png_debug(1, "in png_set_compression_mem_level\n");
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_MEM_LEVEL;
png_ptr->zlib_mem_level = mem_level;
}
@ -642,6 +821,7 @@ png_set_compression_mem_level(png_structp png_ptr, int mem_level)
void
png_set_compression_strategy(png_structp png_ptr, int strategy)
{
png_debug(1, "in png_set_compression_strategy\n");
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_STRATEGY;
png_ptr->zlib_strategy = strategy;
}
@ -658,6 +838,7 @@ png_set_compression_window_bits(png_structp png_ptr, int window_bits)
void
png_set_compression_method(png_structp png_ptr, int method)
{
png_debug(1, "in png_set_compression_method\n");
if (method != 8)
png_warning(png_ptr, "Only compression method 8 is supported by PNG");
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;

View File

@ -1,10 +1,11 @@
/* pngwtran.c - transforms the data in a row for png writers
/* pngwtran.c - transforms the data in a row for PNG writers
libpng 1.0 beta 4 - version 0.90
libpng 1.0 beta 6 - version 0.96
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.
January 10, 1997
Copyright (c) 1996, 1997 Andreas Dilger
May 12, 1997
*/
#define PNG_INTERNAL
@ -15,15 +16,16 @@
void
png_do_write_transformations(png_structp png_ptr)
{
png_debug(1, "in png_do_write_transformations\n");
#if defined(PNG_WRITE_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_do_write_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK)
png_do_pack(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->bit_depth);
(png_uint_32)png_ptr->bit_depth);
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT)
@ -34,6 +36,10 @@ png_do_write_transformations(png_structp png_ptr)
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_do_swap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_ALPHA)
png_do_write_swap_alpha(&(png_ptr->row_info), png_ptr->row_buf + 1);
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR)
png_do_bgr(&(png_ptr->row_info), png_ptr->row_buf + 1);
@ -49,20 +55,22 @@ png_do_write_transformations(png_structp png_ptr)
row_info bit depth should be 8 (one pixel per byte). The channels
should be 1 (this only happens on grayscale and paletted images) */
void
png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
{
if (row_info && row && row_info->bit_depth == 8 &&
png_debug(1, "in png_do_pack\n");
if (row_info->bit_depth == 8 &&
#if defined(PNG_USELESS_TESTS_SUPPORTED)
row != NULL && row_info != NULL &&
#endif
row_info->channels == 1)
{
switch (bit_depth)
switch ((int)bit_depth)
{
case 1:
{
png_bytep sp;
png_bytep dp;
int mask;
png_int_32 i;
int v;
png_bytep sp, dp;
int mask, v;
png_uint_32 i;
sp = row;
dp = row;
@ -70,7 +78,7 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
v = 0;
for (i = 0; i < row_info->width; i++)
{
if (*sp)
if (*sp != 0)
v |= mask;
sp++;
if (mask > 1)
@ -89,12 +97,9 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
}
case 2:
{
png_bytep sp;
png_bytep dp;
int shift;
png_int_32 i;
int v;
png_byte value;
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
sp = row;
dp = row;
@ -102,6 +107,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
v = 0;
for (i = 0; i < row_info->width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0x3);
v |= (value << shift);
if (shift == 0)
@ -121,12 +128,9 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
}
case 4:
{
png_bytep sp;
png_bytep dp;
int shift;
png_int_32 i;
int v;
png_byte value;
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
sp = row;
dp = row;
@ -134,6 +138,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
v = 0;
for (i = 0; i < row_info->width; i++)
{
png_byte value;
value = (png_byte)(*sp & 0xf);
v |= (value << shift);
@ -154,8 +160,8 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
break;
}
}
row_info->bit_depth = bit_depth;
row_info->pixel_depth = (png_uint_16)(bit_depth * row_info->channels);
row_info->bit_depth = (png_byte)bit_depth;
row_info->pixel_depth = (png_byte)(bit_depth * row_info->channels);
row_info->rowbytes =
((row_info->width * row_info->pixel_depth + 7) >> 3);
}
@ -172,11 +178,16 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_byte bit_depth)
void
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
if (row && row_info &&
png_debug(1, "in png_do_shift\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL &&
#else
if (
#endif
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
int channels;
png_uint_32 channels;
channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
@ -209,7 +220,6 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_bytep bp;
png_uint_32 i;
int j;
png_byte mask;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
@ -221,7 +231,8 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
{
int v;
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
@ -238,7 +249,6 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_bytep bp;
png_uint_32 i;
int j;
for (bp = row, i = 0; i < row_info->width; i++)
{
@ -246,7 +256,8 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
for (c = 0; c < channels; c++, bp++)
{
int v;
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
@ -264,20 +275,17 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_bytep bp;
png_uint_32 i;
int j;
for (bp = row, i = 0;
i < row_info->width * row_info->channels;
i++)
for (bp = row, i = 0; i < row_info->width * row_info->channels; i++)
{
int c;
for (c = 0; c < channels; c++, bp += 2)
{
png_uint_16 value, v;
int j;
v = (png_uint_16)(((png_uint_16)(*bp) << 8) +
(png_uint_16)(*(bp + 1)));
v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
@ -295,51 +303,88 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
}
#endif
#ifdef PNG_WRITE_FILLER_SUPPORTED
/* remove filler byte */
#if defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
void
png_do_write_filler(png_row_infop row_info, png_bytep row,
png_uint_32 flags)
png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
{
if (row && row_info && row_info->color_type == PNG_COLOR_TYPE_RGB &&
row_info->bit_depth == 8)
png_debug(1, "in png_do_write_swap_alpha\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
if (flags & PNG_FLAG_FILLER_AFTER)
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This converts from ARGB to RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_byte save;
png_uint_32 i;
for (i = 1, sp = row + 4, dp = row + 3;
i < row_info->width;
i++)
for (i = 0, sp = dp = row; i < row_info->width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
sp++;
save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
row_info->channels = 3;
row_info->pixel_depth = 24;
row_info->rowbytes = row_info->width * 3;
}
/* This converts from AARRGGBB to RRGGBBAA */
else
{
png_bytep sp, dp;
png_byte save[2];
png_uint_32 i;
for (i = 0, sp = row, dp = row;
i < row_info->width;
i++)
for (i = 0, sp = dp = row; i < row_info->width; i++)
{
sp++;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This converts from AG to GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_byte save;
png_uint_32 i;
for (i = 0, sp = dp = row; i < row_info->width; i++)
{
save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
}
/* This converts from AAGG to GGAA */
else
{
png_bytep sp, dp;
png_byte save[2];
png_uint_32 i;
for (i = 0, sp = dp = row; i < row_info->width; i++)
{
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save[0];
*(dp++) = save[1];
}
}
row_info->channels = 3;
row_info->pixel_depth = 24;
row_info->rowbytes = row_info->width * 3;
}
}
}

1016
pngwutil.c

File diff suppressed because it is too large Load Diff