Imported from libpng-0.96.tar
This commit is contained in:
parent
02ad0efbc8
commit
47a0c422ca
69
CHANGES
69
CHANGES
@ -37,7 +37,7 @@ version 0.7
|
||||
finished dithering and other stuff
|
||||
added test program
|
||||
changed name from pnglib to libpng
|
||||
version 0.71
|
||||
version 0.71 [June, 1995]
|
||||
changed pngtest.png for zlib 0.93
|
||||
fixed error in libpng.txt and example.c
|
||||
version 0.8
|
||||
@ -56,26 +56,28 @@ version 0.8
|
||||
enabled png_set_shift to work with paletted images on read
|
||||
added png_read_update_info() - updates info structure with
|
||||
transformations
|
||||
version 0.81
|
||||
version 0.81 [August, 1995]
|
||||
incorporated Tim Wegner's medium model code (thanks, Tim)
|
||||
version 0.85
|
||||
added more medium model code (almost everythings a far)
|
||||
version 0.82 [September, 1995]
|
||||
[unspecified changes]
|
||||
version 0.85 [December, 1995]
|
||||
added more medium model code (almost everything's a far)
|
||||
added i/o, error, and memory callback functions
|
||||
fixed some bugs (16 bit, 4 bit interlaced, etc.)
|
||||
added first run progressive reader (barely tested)
|
||||
version 0.86
|
||||
version 0.86 [January, 1996]
|
||||
fixed bugs
|
||||
improved documentation
|
||||
version 0.87
|
||||
version 0.87 [January, 1996]
|
||||
fixed medium model bugs
|
||||
fixed other bugs introduced in 0.85 and 0.86
|
||||
added some minor documentation
|
||||
version 0.88
|
||||
version 0.88 [January, 1996]
|
||||
fixed progressive bugs
|
||||
replaced tabs with spaces
|
||||
cleaned up documentation
|
||||
added callbacks for read/write and warning/error functions
|
||||
version 0.89
|
||||
version 0.89 [July, 1996]
|
||||
added new initialization API to make libpng work better with shared libs
|
||||
we now have png_create_read_struct(), png_create_write_struct(),
|
||||
png_create_info_struct(), png_destroy_read_struct(), and
|
||||
@ -101,14 +103,14 @@ version 0.89
|
||||
into a binary when only reading or writing functionality is used
|
||||
new pngtest image also has interlacing and zTXt
|
||||
updated documentation to reflect new API
|
||||
version 0.90
|
||||
version 0.90 [January, 1997]
|
||||
made CRC errors/warnings on critical and ancillary chunks configurable
|
||||
libpng will use the zlib CRC routines by (compile-time) default
|
||||
changed DOS small/medium model memory support - needs zlib 1.04 (Tim Wegner)
|
||||
added external C++ wrapper statements to png.h (Gilles Dauphin)
|
||||
allow PNG file to be read when some or all of file signature has already
|
||||
been read from the beginning of the stream (this affects the size of
|
||||
info_struct and invalidates all programs that use a shared libpng)
|
||||
been read from the beginning of the stream. ****This affects the size
|
||||
of info_struct and invalidates all programs that use a shared libpng****
|
||||
fixed png_filler() declarations
|
||||
fixed? background color conversions
|
||||
fixed order of error function pointers to match documentation
|
||||
@ -120,3 +122,48 @@ version 0.90
|
||||
routines can determine if the chunk is in the right place
|
||||
- all chunk handling routines have the same prototypes, so we will
|
||||
be able to handle all chunks via a callback mechanism
|
||||
try to fix Linux "setjmp" buffer size problems
|
||||
version 0.95 [March, 1997]
|
||||
fixed bug in pngwutil.c allocating "up_row" twice and "avg_row" never
|
||||
fixed bug in PNG file signature compares when start != 0
|
||||
changed parameter type of png_set_filler(...filler...) from png_byte
|
||||
to png_uint_32
|
||||
added test for MACOS to ensure that both math.h and fp.h are not #included
|
||||
added macros for libpng to be compiled as a Windows DLL (Andreas Kupries)
|
||||
added "packswap" transformation, which changes the endianness of
|
||||
packed-pixel bytes (Kevin Bracey)
|
||||
added "strip_alpha" transformation, which removes the alpha channel of
|
||||
input images without using it (not neccesarily a good idea)
|
||||
added "swap_alpha" transformation, which puts the alpha channel in front
|
||||
of the color bytes instead of after
|
||||
removed all implicit variable tests which assume NULL == 0 (I think)
|
||||
changed several variables to "png_size_t" to show 16/32-bit limitations
|
||||
added new pCAL chunk read/write support
|
||||
added experimental filter selection weighting (Greg Roelofs)
|
||||
removed old png_set_rgbx() and png_set_xrgb() functions that have been
|
||||
obsolete for about 2 years now (use png_set_filler() instead)
|
||||
added macros to read 16- and 32-bit ints directly from buffer, to be
|
||||
used only on those systems that support it (namely PowerPC and 680x0)
|
||||
With some testing, this may become the default for MACOS/PPC systems.
|
||||
only calculate CRC on data if we are going to use it
|
||||
added macros for zTXt compression type PNG_zTXt_COMPRESSION_???
|
||||
added macros for simple libpng debugging output selectable at compile time
|
||||
removed PNG_READ_END_MODE in progressive reader (Smarasderagd)
|
||||
more description of info_struct in libpng.txt and png.h
|
||||
more instructions in example.c
|
||||
more chunk types tested in pngtest.c
|
||||
renamed pngrcb.c to pngset.c, and all png_read_<chunk> functions to be
|
||||
png_set_<chunk>. We now have corresponding png_get_<chunk>
|
||||
functions in pngget.c to get infomation in info_ptr. This isolates
|
||||
the application from the internal organization of png_info_struct
|
||||
(good for shared library implementations).
|
||||
version 0.96 [May, 1997]
|
||||
fixed serious bug with < 8bpp images introduced in 0.95
|
||||
fixed 256-color transparency bug (Greg Roelofs)
|
||||
fixed up documentation (Greg Roelofs, Laszlo Nyul)
|
||||
fixed "error" in pngconf.h for Linux setjmp() behaviour
|
||||
fixed DOS medium model support (Tim Wegner)
|
||||
fixed png_check_keyword() for case with error in static string text
|
||||
added read of CRC after IEND chunk for embedded PNGs (Laszlo Nyul)
|
||||
added typecasts to quiet compiler errors
|
||||
added more debugging info
|
||||
|
90
README
90
README
@ -1,55 +1,54 @@
|
||||
readme.txt - for libpng 0.90
|
||||
README for libpng 0.96
|
||||
|
||||
This is the fourth beta version of libpng 1.0. The changes from
|
||||
libpng-0.89 include bug fixes, a C++ wrapper for png.h, some
|
||||
additions to the API, as well as internal changes to the library.
|
||||
This is the sixth (and hopefully last) beta release of libpng 1.0.
|
||||
The changes from libpng-0.90 include bug fixes, a C++ wrapper for
|
||||
png.h, some additions to the API, as well as internal changes to
|
||||
the library. See "CHANGES" for a detailed list of differences.
|
||||
|
||||
**
|
||||
Note that some of the changes to the png_info structure render
|
||||
this version of the library binary incompatible with libpng-0.89
|
||||
if you are using a shared library. Re-compiling the application
|
||||
should be enough to remove this problem.
|
||||
**
|
||||
****
|
||||
Note that some of the changes to the png_info structure render this
|
||||
version of the library binary incompatible with libpng-0.89 or
|
||||
earlier versions if you are using a shared library. The type of the
|
||||
"filler" parameter for png_set_filler() has changed from png_byte to
|
||||
png_uint_32, which will affect shared-library applications which use
|
||||
this function.
|
||||
|
||||
The additions to 0.89 include the ability to read from a PNG stream
|
||||
which has had some (or all) of the signature bytes read by the
|
||||
calling application. This also allows the reading of embedded PNG
|
||||
streams that do not have the PNG file signature. As well, it is
|
||||
now possible to set the library action on the detection of chunk
|
||||
CRC errors. It is possible to set different actions based on
|
||||
whether the error occurred in a critical or an ancillary chunk.
|
||||
To avoid problems with changes to the internals of png_info_struct,
|
||||
new APIs have been made available in 0.95 to avoid direct application
|
||||
access to info_ptr. These functions are the png_set_<chunk> and
|
||||
png_get_<chunk> functions. These functions should be used when
|
||||
accessing/storing the info_struct data, rather than manipulating it
|
||||
directly, to avoid such problems in the future.
|
||||
****
|
||||
|
||||
The callback functions for the error/warning messages have changed
|
||||
since the 0.88 release because their implementation was broken,
|
||||
and it was thought best to change the API itself (which was only
|
||||
introduced in libpng-0.88 itself) to alert the user to the change,
|
||||
rather than mislead the user into thinking their application was
|
||||
OK after re-compiling. This means that calls to png_set_message_fn()
|
||||
no longer exist, because the previously suggested method of calling
|
||||
them before png_read_init() or png_write_init() is now ineffective.
|
||||
Additions since 0.90 include the ability to compile libpng as a
|
||||
Windows DLL, and new APIs for accessing data in the info struct.
|
||||
Experimental functions include the ability to set weighting and cost
|
||||
factors for row filter selection, direct reads of integers from buffers
|
||||
on big-endian processors that support misaligned data access, faster
|
||||
methods of doing alpha composition, and more accurate 16->8 bit color
|
||||
conversion.
|
||||
|
||||
The preferred method of setting the error and warning callbacks
|
||||
has been incorporated into the allocation of the png_struct and
|
||||
info_struct itself, which allow them to be safely used during the
|
||||
initialization of the structure, as well as to keep the size of
|
||||
the png_struct internal to the library, rather than at compile time
|
||||
of the application. This will hopefully remove any problems with
|
||||
dynamically linked libraries, and should be considered the preferred
|
||||
method of creating these structures, although the previous
|
||||
initialization API is still available for compatibility. See libpng.txt
|
||||
for more information on the new API.
|
||||
The additions since 0.89 include the ability to read from a PNG stream
|
||||
which has had some (or all) of the signature bytes read by the calling
|
||||
application. This also allows the reading of embedded PNG streams that
|
||||
do not have the PNG file signature. As well, it is now possible to set
|
||||
the library action on the detection of chunk CRC errors. It is possible
|
||||
to set different actions based on whether the CRC error occurred in a
|
||||
critical or an ancillary chunk.
|
||||
|
||||
The changes made to the library, and bugs fixed are based on discussions
|
||||
on the PNG implementation mailing list <png-implement@dworking.wustl.edu>
|
||||
and not on material submitted to Guy.
|
||||
|
||||
For a detailed description on using libpng, read libpng.txt. For
|
||||
usage information and restrictions (what little they are) on libpng,
|
||||
see png.h. For a description on using zlib (the compression library
|
||||
used by libpng) and zlib's restrictions, see zlib.h
|
||||
examples of libpng in a program, see example.c and pngtest.c. For usage
|
||||
information and restrictions (what little they are) on libpng, see
|
||||
png.h. For a description on using zlib (the compression library used by
|
||||
libpng) and zlib's restrictions, see zlib.h
|
||||
|
||||
I have included a general makefile, as well as several machine and compiler
|
||||
specific ones, but you may have to modify one for your own needs.
|
||||
I have included a general makefile, as well as several machine and
|
||||
compiler specific ones, but you may have to modify one for your own needs.
|
||||
|
||||
You should use zlib 1.0.4 or later to run this, but it MAY work with
|
||||
versions as old as zlib 0.95. Even so, there are bugs in older zlib
|
||||
@ -113,7 +112,7 @@ gladly listen. Even if your suggestion is not used for version
|
||||
|
||||
Files in this distribution:
|
||||
|
||||
CHANGES.txt => Description of changes between libpng versions
|
||||
CHANGES => Description of changes between libpng versions
|
||||
README => This file
|
||||
TODO => Things not implemented in the current library
|
||||
ansi2knr.c => Converts files to K&R style function declarations
|
||||
@ -121,7 +120,7 @@ Files in this distribution:
|
||||
descrip.mms => VMS project file
|
||||
example.c => Example code for using libpng functions
|
||||
libpng.txt => Description of libpng and its functions
|
||||
makefile => Defualt makefile
|
||||
makefile => Default Unixish makefile
|
||||
makefile.aco => ACORN makefile
|
||||
makefile.ama => Amiga makefile
|
||||
makefile.atr => Atari makefile
|
||||
@ -140,11 +139,11 @@ Files in this distribution:
|
||||
pngerror.c => Error/warning message I/O functions
|
||||
pngmem.c => Memory handling functions
|
||||
pngpread.c => Progressive reading functions
|
||||
pngrcb.c => Read callback (data handling) low-level functions
|
||||
pngread.c => Read data/helper high-level functions
|
||||
pngrio.c => Lowest-level data read I/O functions
|
||||
pngrtran.c => Read data transformation functions
|
||||
pngrutil.c => Read data utility functions
|
||||
pngset.c => Functions for storing data into the info_struct
|
||||
pngtest.c => Library test program
|
||||
pngtest.png => Library test sample image
|
||||
pngtrans.c => Common data transformation functions
|
||||
@ -156,13 +155,12 @@ Files in this distribution:
|
||||
Good luck, and happy coding.
|
||||
|
||||
-Andreas Eric Dilger
|
||||
University of Calgary
|
||||
Internet: adilger@enel.ucalgary.ca
|
||||
Web: www-mddsp.enel.ucalgary.ca/People/adilger/
|
||||
Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
|
||||
|
||||
-Guy Eric Schalnat
|
||||
Group 42, Inc.
|
||||
Internet: schalnat@group42.com
|
||||
CompuServe: 75501,1625
|
||||
Web: www.group42.com
|
||||
Web: http://www.group42.com/
|
||||
|
||||
|
24
TODO
24
TODO
@ -1,23 +1,19 @@
|
||||
pngtodo.txt - list of things to do for libpng
|
||||
|
||||
for 0.9
|
||||
add "grayscale->palette" transformation and "palette->grayscale" detection
|
||||
improved dithering
|
||||
final bug fixes
|
||||
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
|
||||
multi-lingual message support
|
||||
|
||||
after 1.0
|
||||
overlaying one image on top of another
|
||||
better filter selection
|
||||
(counting huffman bits/precompression? filter inertia? filter costs?)
|
||||
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
|
||||
better C++ wrapper/full C++ implementation?
|
||||
text conversion between different code pages (Latin-1 -> Mac and DOS)
|
||||
|
@ -8,9 +8,9 @@ pref = /prefix=all
|
||||
|
||||
|
||||
|
||||
OBJS = png.obj, pngrcb.obj, pngrutil.obj, pngtrans.obj, pngwutil.obj,\
|
||||
pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj, pngwtran.obj,\
|
||||
pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
|
||||
OBJS = png.obj, pngset.obj, pngget.obj, pngrutil.obj, pngtrans.obj,\
|
||||
pngwutil.obj, pngread.obj, pngmem.obj, pngwrite.obj, pngrtran.obj,\
|
||||
pngwtran.obj, pngrio.obj, pngwio.obj, pngerror.obj, pngpread.obj
|
||||
|
||||
|
||||
CFLAGS= $(C_DEB) $(CC_DEFS) $(PREF)
|
||||
@ -35,7 +35,8 @@ clean :
|
||||
# Other dependencies.
|
||||
png.obj : png.h, pngconf.h
|
||||
pngpread.obj : png.h, pngconf.h
|
||||
pngrcb.obj : png.h, pngconf.h
|
||||
pngset.obj : png.h, pngconf.h
|
||||
pngget.obj : png.h, pngconf.h
|
||||
pngread.obj : png.h, pngconf.h
|
||||
pngrtran.obj : png.h, pngconf.h
|
||||
pngrutil.obj : png.h, pngconf.h
|
||||
|
545
example.c
545
example.c
@ -1,92 +1,107 @@
|
||||
/* example.c - an example of using libpng */
|
||||
|
||||
/* this is an example of how to use libpng to read and write
|
||||
png files. The file libpng.txt is much more verbose then
|
||||
this. If you have not read it, do so first. This was
|
||||
designed to be a starting point of an implementation.
|
||||
This is not officially part of libpng, and therefore
|
||||
/* This is an example of how to use libpng to read and write PNG files.
|
||||
The file libpng.txt is much more verbose then this. If you have not
|
||||
read it, do so first. This was designed to be a starting point of an
|
||||
implementation. This is not officially part of libpng, and therefore
|
||||
does not require a copyright notice.
|
||||
|
||||
This file does not currently compile, because it is missing
|
||||
certain parts, like allocating memory to hold an image.
|
||||
You will have to supply these parts to get it to compile.
|
||||
This file does not currently compile, because it is missing certain
|
||||
parts, like allocating memory to hold an image. You will have to
|
||||
supply these parts to get it to compile. For an example of a minimal
|
||||
working PNG reader/writer, see pngtest.c, included in this distribution.
|
||||
*/
|
||||
|
||||
#include <png.h>
|
||||
|
||||
/* Check to see if a file is a png file using png_check_sig().
|
||||
/* Check to see if a file is a PNG file using png_check_sig(). Returns
|
||||
non-zero if the image is a PNG, and 0 if it isn't a PNG.
|
||||
|
||||
If this call is successful, and you are going to keep the file
|
||||
open, you should call png_set_sig_bytes_read(png_ptr, 8);
|
||||
once you have created the png_ptr, so that libpng knows it
|
||||
doesn't have to read the signature again. Make sure you don't
|
||||
call png_set_sig_bytes_read() with more than 8 bytes read or
|
||||
give it an incorrect number of bytes read, or you will either
|
||||
have read too many bytes (your fault), or you are telling libpng
|
||||
to read the wrong number of magic bytes (also your fault). */
|
||||
int check_png(char *file_name, FILE **fp)
|
||||
If this call is successful, and you are going to keep the file open,
|
||||
you should call png_set_sig_bytes(png_ptr, PNG_BYTES_TO_CHECK); once
|
||||
you have created the png_ptr, so that libpng knows your application
|
||||
has read that many bytes from the start of the file. Make sure you
|
||||
don't call png_set_sig_bytes() with more than 8 bytes read or give it
|
||||
an incorrect number of bytes read, or you will either have read too
|
||||
many bytes (your fault), or you are telling libpng to read the wrong
|
||||
number of magic bytes (also your fault).
|
||||
|
||||
Many applications already read the first 2 or 4 bytes from the start
|
||||
of the image to determine the file type, so it would be easiest just
|
||||
to pass the bytes to png_check_sig() or even skip that if you know
|
||||
you have a PNG file, and call png_set_sig_bytes().
|
||||
*/
|
||||
#define PNG_BYTES_TO_CHECK 4
|
||||
int check_if_png(char *file_name, FILE **fp)
|
||||
{
|
||||
char buf[8];
|
||||
int ret;
|
||||
char buf[PNG_BYTES_TO_CHECK];
|
||||
|
||||
*fp = fopen(file_name, "rb");
|
||||
if (!fp)
|
||||
return 0;
|
||||
ret = fread(buf, 1, 8, *fp);
|
||||
|
||||
if (ret != 8)
|
||||
/* Open the prospective PNG file. */
|
||||
if ((*fp = fopen(file_name, "rb")) != NULL);
|
||||
return 0;
|
||||
|
||||
/* Check the signature starting at byte 0, and check all 8 bytes */
|
||||
ret = png_check_sig(buf, 0, 8);
|
||||
/* Read in the signature bytes */
|
||||
if (fread(buf, 1, PNG_BYTES_TO_CHECK, *fp) != PNG_BYTES_TO_CHECK)
|
||||
return 0;
|
||||
|
||||
return (ret);
|
||||
/* Compare the first PNG_BYTES_TO_CHECK bytes of the signature. */
|
||||
return(png_check_sig(buf, PNG_BYTES_TO_CHECK));
|
||||
}
|
||||
|
||||
/* read a png file. You may want to return an error code if the read
|
||||
/* Read a PNG file. You may want to return an error code if the read
|
||||
fails (depending upon the failure). There are two "prototypes" given
|
||||
here - one where we are given the filename, and we need to open the
|
||||
file, and the other where we are given an open file (possibly with
|
||||
some or all of the magic bytes read - see above) and an opened file
|
||||
for reading. */
|
||||
------- prototype 1 ----------
|
||||
some or all of the magic bytes read - see comments above). */
|
||||
**** prototype 1 ****
|
||||
void read_png(char *file_name) /* We need to open the file */
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
unsigned int sig_read = 0;
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
FILE *fp;
|
||||
|
||||
if ((fp = fopen(file_name, "rb")) == NULL)
|
||||
return;
|
||||
------- prototype 2 ----------
|
||||
**** prototype 2 ****
|
||||
void read_png(FILE *fp, unsigned int sig_read) /* file is already open */
|
||||
{
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
------- only use one! --------
|
||||
png_uint_32 width, height;
|
||||
int bit_depth, color_type, interlace_type;
|
||||
**** only use one prototype! ****
|
||||
|
||||
/* Create and initialize the png_struct with the desired error handler
|
||||
functions. If you want to use the default stderr and longjump method,
|
||||
you can supply NULL for the last three parameters. We also check that
|
||||
the header file is compatible with the library version. */
|
||||
* functions. If you want to use the default stderr and longjump method,
|
||||
* you can supply NULL for the last three parameters. We also supply the
|
||||
* the compiler header file version, so that we know if the application
|
||||
* was compiled with a compatible version of the library. REQUIRED
|
||||
*/
|
||||
png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
|
||||
(void *)user_error_ptr, user_error_fn, user_warning_fn);
|
||||
|
||||
if (!png_ptr)
|
||||
if (png_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Allocate/initialize the memory for image information. REQUIRED. */
|
||||
info_ptr = png_create_info_struct();
|
||||
if (!info_ptr)
|
||||
if (info_ptr == NULL)
|
||||
{
|
||||
fclose(fp);
|
||||
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
|
||||
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 */
|
||||
|
659
libpng.txt
659
libpng.txt
@ -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.
|
||||
|
21
makefile
21
makefile
@ -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
|
||||
|
196
makefile.aco
196
makefile.aco
@ -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
|
||||
|
@ -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
|
||||
|
@ -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)\
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
43
makefile.elf
43
makefile.elf
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
13
makefile.msc
13
makefile.msc
@ -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 ;
|
||||
|
21
makefile.std
21
makefile.std
@ -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
72
makefile.sun
Normal 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
|
||||
|
18
makefile.tc
18
makefile.tc
@ -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
|
||||
|
@ -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
128
png.c
@ -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
|
||||
|
201
pngconf.h
201
pngconf.h
@ -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 */
|
||||
|
||||
|
11
pngerror.c
11
pngerror.c
@ -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
300
pngget.c
Normal 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
|
||||
|
91
pngmem.c
91
pngmem.c
@ -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,15 +190,14 @@ 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
|
||||
@ -307,8 +306,6 @@ png_free(png_structp png_ptr, png_voidp ptr)
|
||||
# endif
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* FORTIFY */
|
||||
#endif /* Not Borland DOS special memory handler */
|
||||
|
||||
|
276
pngpread.c
276
pngpread.c
@ -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");
|
||||
|
||||
#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[(png_size_t)length] = '\0';
|
||||
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");
|
||||
|
||||
#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[(png_size_t)length] = '\0';
|
||||
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
243
pngrcb.c
@ -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
301
pngread.c
@ -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++)
|
||||
{
|
||||
|
36
pngrio.c
36
pngrio.c
@ -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;
|
||||
|
1190
pngrtran.c
1190
pngrtran.c
File diff suppressed because it is too large
Load Diff
722
pngrutil.c
722
pngrutil.c
File diff suppressed because it is too large
Load Diff
312
pngset.c
Normal file
312
pngset.c
Normal 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
|
||||
|
264
pngtest.c
264
pngtest.c
@ -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, ¶ms))
|
||||
{
|
||||
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);
|
||||
|
BIN
pngtest.png
BIN
pngtest.png
Binary file not shown.
Before Width: | Height: | Size: 8.3 KiB After Width: | Height: | Size: 8.4 KiB |
477
pngtrans.c
477
pngtrans.c
@ -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;
|
||||
}
|
||||
|
||||
/* 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). */
|
||||
void
|
||||
png_set_rgbx(png_structp png_ptr)
|
||||
{
|
||||
png_set_filler(png_ptr, (png_byte)0xff, PNG_FILLER_AFTER);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(PNG_READ_SWAP_ALPHA_SUPPORTED) || \
|
||||
defined(PNG_WRITE_SWAP_ALPHA_SUPPORTED)
|
||||
void
|
||||
png_set_xrgb(png_structp png_ptr)
|
||||
png_set_swap_alpha(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_bytep rp;
|
||||
png_byte t;
|
||||
png_debug(1, "in png_do_strip_filler\n");
|
||||
#if defined(PNG_USELESS_TESTS_SUPPORTED)
|
||||
if (row != NULL && row_info != NULL)
|
||||
#endif
|
||||
{
|
||||
/*
|
||||
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 */
|
||||
|
||||
|
36
pngwio.c
36
pngwio.c
@ -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;
|
||||
|
363
pngwrite.c
363
pngwrite.c
@ -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->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->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;
|
||||
|
181
pngwtran.c
181
pngwtran.c
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
1008
pngwutil.c
1008
pngwutil.c
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user