update to png version 1.0.2. -pnunn.

git-svn-id: svn://10.0.0.236/trunk@15985 18797224-902f-48f8-a5cc-f745e15eee43
This commit is contained in:
pnunn%netscape.com 1998-12-08 19:44:02 +00:00
parent 927f043691
commit 7c942df448
18 changed files with 4316 additions and 1930 deletions

View File

@ -1,22 +1,35 @@
README for libpng 0.95
README for libpng 1.0.2 - June 14, 1998 (shared library 2.1)
See the note about version numbers near the top of png.h
This is the fifth (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.
See INSTALL for instructions on how to install libpng.
This is the first official release of libpng. Don't let the fact that
it's the first release fool you. The libpng library has been in
extensive use and testing for about two and a half years. However, it's
finally gotten to the stage where there haven't been significant
changes to the API in some time, and people have a bad feeling about
libraries with versions < 1.0.
****
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. Also, 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
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 that use
this function.
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.
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.
It is important to note that the APIs do not make current programs
that access the info struct directly incompatible with the new
library. However, it is strongly suggested that new programs use
the new APIs (as shown in example.c), and older programs be converted
to the new format, to facilitate upgrades in the future.
****
Additions since 0.90 include the ability to compile libpng as a
@ -63,7 +76,7 @@ If not, it should be at ftp.uu.net in /graphics/png
Eventually, it will be at ftp.uu.net in /pub/archiving/zip/zlib
You may also want a copy of the PNG specification. It is available
as an Internet Draft, and RFC, and a W3C Recommendation. Failing
as an RFC and a W3C Recommendation. Failing
these resources you can try ftp.uu.net in the /graphics/png directory.
This code is currently being archived at ftp.uu.net in the
@ -83,19 +96,19 @@ Finally, if you get any warning messages when compiling libpng
fix. Please mention "libpng" somewhere in the subject line. Thanks.
This release was created and will be supported by myself (of course
based in a large way on Guy's earlier work), and the PNG group.
based in a large way on Guy's and Andreas' earlier work), and the PNG group.
adilger@enel.ucalgary.ca
randeg@alumni.rpi.edu
png-implement@dworkin.wustl.edu
You can reach Guy, the original libpng author, at (internet preferred):
internet: schalnat@group42.com
CompuServe: 75501,1625
You can't reach Guy, the original libpng author, at the addresses
given in previous versions of this document. He and Andreas will read mail
addressed to the png-implement list, however.
Please do not send general questions about PNG. Send them to
the address in the specification. At the same time, please do
not send libpng questions to that address, send them to me. I'll
the address in the specification (png-group@w3.org). At the same
time, please do not send libpng questions to that address, send them to me
or to png-implement@dworkin.wustl.edu. I'll
get them in the end anyway. If you have a question about something
in the PNG specification that is related to using libpng, send it
to me. Send me any questions that start with "I was using libpng,
@ -103,7 +116,7 @@ and ...". If in doubt, send questions to me. I'll bounce them
to others, if necessary.
Please do not send suggestions on how to change PNG. We have
been discussing PNG for a couple years now, and it is official and
been discussing PNG for three years now, and it is official and
finished. If you have suggestions for libpng, however, I'll
gladly listen. Even if your suggestion is not used for version
1.0, it may be used later.
@ -113,28 +126,20 @@ Files in this distribution:
CHANGES => Description of changes between libpng versions
README => This file
TODO => Things not implemented in the current library
ansi2knr.1 => Manual page for ansi2knr
ansi2knr.c => Converts files to K&R style function declarations
build.bat => MS-DOS batch file for Borland compiler
descrip.mms => VMS project file
example.c => Example code for using libpng functions
libpng.3 => manual page for libpng
libpng.txt => Description of libpng and its functions
makefile => Default Unixish makefile
makefile.aco => ACORN makefile
makefile.ama => Amiga makefile
makefile.atr => Atari makefile
makefile.bor => Borland makefile
makefile.dj2 => DJGPP 2 makefile
makefile.elf => Unix ELF makefile
makefile.knr => Makefile which calls ansi2knr to convert files
makefile.mip => MIPS makefile
makefile.msc => Microsoft C makefile
makefile.std => Standard Unix makefile
makefile.tc => Turbo C makefile
makevms.com => VMS make program
libpngpf.3 => manual page for libpng's private functions
png.5 => manual page for the PNG format
png.c => Basic interface functions common to library
png.h => Library function and interface declarations
pngconf.h => System specific library configuration
pngerror.c => Error/warning message I/O functions
pngget.c => Functions for retrieving info from struct
pngmem.c => Memory handling functions
pngpread.c => Progressive reading functions
pngread.c => Read data/helper high-level functions
@ -149,16 +154,44 @@ Files in this distribution:
pngwrite.c => High-level write functions
pngwtran.c => Write data transformations
pngwutil.c => Write utility functions
scripts => Directory containing scripts for building libpng:
descrip.mms => VMS makefile for MMS or MMK
makefile.std => Generic UNIX makefile
makefile.knr => Archaic UNIX Makefile that converts files with ansi2knr
makefile.dec => DEC Alpha UNIX makefile
makefile.sgi => Silicon Graphics IRIX makefile
makefile.sun => Sun makefile
makefile.s2x => Solaris 2.X makefile (gcc, creates libpng.so.2.1.0)
makefile.lnx => Linux/ELF makefile (gcc, creates libpng.so.2.1.0)
makefile.mip => MIPS makefile
makefile.aco => Acorn makefile
makefile.ama => Amiga makefile
smakefile.ppc => AMIGA smakefile for SAS C V6.58/7.00 PPC compiler
(Requires SCOPTIONS, copied from scripts/SCOPTIONS.ppc)
makefile.atr => Atari makefile
makefile.bor => Borland makefile
build.bat => MS-DOS batch file for Borland compiler
makefile.dj2 => DJGPP 2 makefile
makefile.msc => Microsoft C makefile
makefile.w32 => makefile for Microsoft Visual C++ 4.0 and later
makefile.tc3 => Turbo C 3.0 makefile
makefile.os2 => OS/2 Makefile (gcc and emx, requires pngos2.def)
makefile.wat => Watcom 10a+ Makefile, 32-bit flat memory model
pngos2.def => OS/2 module definition file used by makefile.os2
makevms.com => VMS build script
pngdll.mak => To make a png32bd.dll with Borland C++ 4.5
pngdef.pas => Defines for a png32bd.dll with Borland C++ 4.5
Good luck, and happy coding.
-Glenn Randers-Pehrson
Internet: randeg@alumni.rpi.edu
Web: http://www.rpi.edu/~randeg/index.html
-Andreas Eric Dilger
Internet: adilger@enel.ucalgary.ca
Web: http://www-mddsp.enel.ucalgary.ca/People/adilger/
-Guy Eric Schalnat
Group 42, Inc.
Internet: schalnat@group42.com
CompuServe: 75501,1625
Web: http://www.group42.com/
(formerly of Group 42, Inc)
Internet: gschal@infinet.com

View File

@ -1,27 +1,29 @@
/* png.c - location for general purpose png functions
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
/* png.c - location for general purpose libpng functions
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
#define PNG_INTERNAL
#define PNG_NO_EXTERN
#include "png.h"
/* Version information for C files. This had better match the version
string defined in png.h */
char png_libpng_ver[] = "0.95";
* string defined in png.h.
*/
char png_libpng_ver[12] = "1.0.2";
/* Place to hold the signiture string for a PNG file. */
/* Place to hold the signature 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. */
/* 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[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'};
@ -34,6 +36,7 @@ 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_sRGB[5] = {115, 82, 71, 66, '\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'};
@ -53,22 +56,20 @@ int FARDATA png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1};
/* offset to next interlace block in the y direction */
int FARDATA png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2};
/* width of interlace block */
/* this is not currently used - if you need it, uncomment it here and
in png.h
/* Width of interlace block. This is not currently used - if you need
* it, uncomment it here and in png.h
int FARDATA png_pass_width[] = {8, 4, 4, 2, 2, 1, 1};
*/
/* height of interlace block */
/* this is not currently used - if you need it, uncomment it here and
in png.h
/* Height of interlace block. This is not currently used - if you need
* it, uncomment it here and in png.h
int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1};
*/
/* mask to determine which pixels are valid in a pass */
/* Mask to determine which pixels are valid in a pass */
int FARDATA png_pass_mask[] = {0x80, 0x08, 0x88, 0x22, 0xaa, 0x55, 0xff};
/* mask to determine which pixels to overwrite while displaying */
/* Mask to determine which pixels to overwrite while displaying */
int FARDATA png_pass_dsp_mask[] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff};
@ -101,36 +102,35 @@ 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;
return (0);
if (start > 7)
return 0;
return (0);
if (start + num_to_check > 8)
num_to_check = 8 - start;
return (png_memcmp(&sig[start], &png_sig[start], num_to_check));
return ((int)(png_memcmp(&sig[start], &png_sig[start], num_to_check)));
}
/* (Obsolete) function to check signature bytes. It does not allow one
to check a partial signature. This function will be removed in the
future - use png_sig_cmp(). */
* to check a partial signature. This function will be removed in the
* future - use png_sig_cmp().
*/
int
png_check_sig(png_bytep sig, int num)
{
return !png_sig_cmp(sig, (png_size_t)0, (png_size_t)num);
return ((int)!png_sig_cmp(sig, (png_size_t)0, (png_size_t)num));
}
/* Function to allocate memory for zlib. */
voidpf
png_zalloc(voidpf png_ptr, uInt items, uInt size)
{
png_voidp ptr;
png_uint_32 num_bytes;
png_uint_32 num_bytes = (png_uint_32)items * size;
png_voidp ptr = (png_voidp)png_malloc((png_structp)png_ptr, num_bytes);
num_bytes = (png_uint_32)items * size;
ptr = png_malloc((png_structp)png_ptr, num_bytes);
if (num_bytes > (png_uint_32)0x8000)
if (num_bytes > (png_uint_32)0x8000L)
{
png_memset(ptr, 0, (png_size_t)0x8000L);
png_memset((png_bytep)ptr + (png_size_t)0x8000L, 0,
@ -140,7 +140,7 @@ png_zalloc(voidpf png_ptr, uInt items, uInt size)
{
png_memset(ptr, 0, (png_size_t)num_bytes);
}
return (voidpf)(ptr);
return ((voidpf)ptr);
}
/* function to free memory for zlib */
@ -151,78 +151,19 @@ png_zfree(voidpf png_ptr, voidpf ptr)
}
/* Reset the CRC variable to 32 bits of 1's. Care must be taken
in case CRC is > 32 bits to leave the top bits 0. */
* in case CRC is > 32 bits to leave the top bits 0.
*/
void
png_reset_crc(png_structp png_ptr)
{
/* set CRC to all 1's */
#ifdef PNG_USE_OWN_CRC
png_ptr->crc = 0xffffffffL;
#else
png_ptr->crc = crc32(0, Z_NULL, 0);
#endif
}
#ifdef PNG_USE_OWN_CRC
/* 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. */
static png_uint_32 crc_table[256];
/* Flag: has the table been computed? Initially false. */
static int crc_table_computed = 0;
/* make the table for a fast crc */
static void
make_crc_table(void)
{
png_uint_32 c;
int n, k;
for (n = 0; n < 256; n++)
{
c = (png_uint_32)n;
for (k = 0; k < 8; k++)
c = c & 1 ? 0xedb88320L ^ (c >> 1) : c >> 1;
crc_table[n] = c;
}
crc_table_computed = 1;
}
/* 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_size_t len)
{
png_uint_32 c;
png_bytep p;
png_uint_32 n;
c = crc;
p = buf;
n = len;
if (!crc_table_computed)
{
make_crc_table();
}
if (n > 0) do
{
c = crc_table[(png_byte)((c ^ (*p++)) & 0xff)] ^ (c >> 8);
} while (--n);
return c;
}
#endif /* PNG_USE_OWN_CRC */
/* 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. */
* 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_size_t length)
{
@ -241,36 +182,40 @@ png_calculate_crc(png_structp png_ptr, png_bytep ptr, png_size_t length)
}
if (need_crc)
#ifdef PNG_USE_OWN_CRC
png_ptr->crc = update_crc(png_ptr->crc, ptr, length);
#else
png_ptr->crc = crc32(png_ptr->crc, ptr, length);
#endif
png_ptr->crc = crc32(png_ptr->crc, ptr, (uInt)length);
}
/* Allocate the memory for an info_struct for the application. We don't
really need the png_ptr, but it could potentially be useful in the
future. This should be used in favour of malloc(sizeof(png_info))
and png_info_init() so that applications that want to use a shared
libpng don't have to be recompiled if png_info changes size. */
* really need the png_ptr, but it could potentially be useful in the
* future. This should be used in favour of malloc(sizeof(png_info))
* and png_info_init() so that applications that want to use a shared
* libpng don't have to be recompiled if png_info changes size.
*/
png_infop
png_create_info_struct(png_structp png_ptr)
{
png_infop info_ptr;
png_debug(1, "in png_create_info_struct\n");
if(png_ptr == NULL) return (NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if ((info_ptr = (png_infop)png_create_struct_2(PNG_STRUCT_INFO,
png_ptr->malloc_fn)) != NULL)
#else
if ((info_ptr = (png_infop)png_create_struct(PNG_STRUCT_INFO)) != NULL)
#endif
{
png_info_init(info_ptr);
}
return info_ptr;
return (info_ptr);
}
/* This function frees the memory associated with a single info struct.
Normally, one would use either png_destroy_read_struct() or
png_destroy_write_struct() to free an info struct, but this may be
useful for some applications. */
* Normally, one would use either png_destroy_read_struct() or
* png_destroy_write_struct() to free an info struct, but this may be
* useful for some applications.
*/
void
png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
@ -284,14 +229,19 @@ png_destroy_info_struct(png_structp png_ptr, png_infopp info_ptr_ptr)
{
png_info_destroy(png_ptr, info_ptr);
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)info_ptr, png_ptr->free_fn);
#else
png_destroy_struct((png_voidp)info_ptr);
#endif
*info_ptr_ptr = (png_infop)NULL;
}
}
/* Initialize the info structure. This is now an internal function (0.89)
and applications using it are urged to use png_create_info_struct()
instead. */
* and applications using it are urged to use png_create_info_struct()
* instead.
*/
void
png_info_init(png_infop info_ptr)
{
@ -308,11 +258,10 @@ 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)
{
int i;
for (i = 0; i < info_ptr->num_text; i++)
{
png_free(png_ptr, info_ptr->text[i].key);
@ -325,7 +274,8 @@ png_info_destroy(png_structp png_ptr, png_infop info_ptr)
png_free(png_ptr, info_ptr->pcal_units);
if (info_ptr->pcal_params != NULL)
{
for (i = 0; i < info_ptr->pcal_nparams; i++)
int i;
for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
{
png_free(png_ptr, info_ptr->pcal_params[i]);
}
@ -337,18 +287,20 @@ png_info_destroy(png_structp png_ptr, png_infop info_ptr)
}
/* This function returns a pointer to the io_ptr associated with the user
functions. The application should free any memory associated with this
pointer before png_write_destroy() or png_read_destroy() are called. */
* functions. The application should free any memory associated with this
* pointer before png_write_destroy() or png_read_destroy() are called.
*/
png_voidp
png_get_io_ptr(png_structp png_ptr)
{
return png_ptr->io_ptr;
return (png_ptr->io_ptr);
}
#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(). */
* 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)
{
@ -356,3 +308,40 @@ png_init_io(png_structp png_ptr, FILE *fp)
png_ptr->io_ptr = (png_voidp)fp;
}
#endif
#if defined(PNG_TIME_RFC1123_SUPPORTED)
/* Convert the supplied time into an RFC 1123 string suitable for use in
* a "Creation Time" or other text-based time string.
*/
png_charp
png_convert_to_rfc1123(png_structp png_ptr, png_timep ptime)
{
static PNG_CONST char short_months[12][4] =
{"Jan", "Feb", "Mar", "Apr", "May", "Jun",
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
if (png_ptr->time_buffer == NULL)
{
png_ptr->time_buffer = (png_charp)png_malloc(png_ptr, (png_uint_32)(29*
sizeof(char)));
}
#ifdef USE_FAR_KEYWORD
{
char near_time_buf[29];
sprintf(near_time_buf, "%d %s %d %02d:%02d:%02d +0000",
ptime->day % 32, short_months[(ptime->month - 1) % 12],
ptime->year, ptime->hour % 24, ptime->minute % 60,
ptime->second % 61);
png_memcpy(png_ptr->time_buffer, near_time_buf,
29*sizeof(char));
}
#else
sprintf(png_ptr->time_buffer, "%d %s %d %02d:%02d:%02d +0000",
ptime->day % 32, short_months[(ptime->month - 1) % 12],
ptime->year, ptime->hour % 24, ptime->minute % 60,
ptime->second % 61);
#endif
return ((png_charp)png_ptr->time_buffer);
}
#endif /* PNG_TIME_RFC1123_SUPPORTED */

File diff suppressed because it is too large Load Diff

View File

@ -212,13 +212,16 @@
#define PNG_READ_PACKSWAP_SUPPORTED
#define PNG_READ_INVERT_SUPPORTED
#define PNG_READ_DITHER_SUPPORTED
/*#define PNG_READ_BACKGROUND_SUPPORTED*/
#define PNG_READ_BACKGROUND_SUPPORTED
#define PNG_READ_16_TO_8_SUPPORTED
#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*/
#undef PNG_READ_STRIP_ALPHA_SUPPORTED
#define PNG_WRITE_INTERLACING_SUPPORTED
#define PNG_WRITE_SHIFT_SUPPORTED

View File

@ -1,16 +1,17 @@
/* pngerror.c - stub functions for i/o and memory allocation
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
This file provides a location for all error handling. Users which
need special error handling are expected to write replacement functions
and use png_set_error_fn() to use those functions. See the instructions
at each function. */
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* This file provides a location for all error handling. Users who
* need special error handling are expected to write replacement functions
* and use png_set_error_fn() to use those functions. See the instructions
* at each function.
*/
#define PNG_INTERNAL
#include "png.h"
@ -21,9 +22,10 @@ static void png_default_warning PNGARG((png_structp png_ptr,
png_const_charp message));
/* This function is called whenever there is a fatal error. This function
should not be changed. If there is a need to handle errors differently,
you should supply a replacement error function and use png_set_error_fn()
to replace the error function at run-time. */
* should not be changed. If there is a need to handle errors differently,
* you should supply a replacement error function and use png_set_error_fn()
* to replace the error function at run-time.
*/
void
png_error(png_structp png_ptr, png_const_charp message)
{
@ -36,9 +38,10 @@ png_error(png_structp png_ptr, png_const_charp message)
}
/* This function is called whenever there is a non-fatal error. This function
should not be changed. If there is a need to handle warnings differently,
you should supply a replacement warning function and use
png_set_error_fn() to replace the warning function at run-time. */
* should not be changed. If there is a need to handle warnings differently,
* you should supply a replacement warning function and use
* png_set_error_fn() to replace the warning function at run-time.
*/
void
png_warning(png_structp png_ptr, png_const_charp message)
{
@ -48,10 +51,65 @@ png_warning(png_structp png_ptr, png_const_charp message)
png_default_warning(png_ptr, message);
}
/* These utilities are used internally to build an error message that relates
* to the current chunk. The chunk name comes from png_ptr->chunk_name,
* this is used to prefix the message. The message is limited in length
* to 63 bytes, the name characters are output as hex digits wrapped in []
* if the character is invalid.
*/
#define isnonalpha(c) ((c) < 41 || (c) > 122 || ((c) > 90 && (c) < 97))
static PNG_CONST char png_digit[16] = {
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
};
static void
png_format_buffer(png_structp png_ptr, png_charp buffer, png_const_charp message)
{
int iout = 0, iin = 0;
while (iin < 4) {
int c = png_ptr->chunk_name[iin++];
if (isnonalpha(c)) {
buffer[iout++] = '[';
buffer[iout++] = png_digit[(c & 0xf0) >> 4];
buffer[iout++] = png_digit[c & 0xf];
buffer[iout++] = ']';
} else {
buffer[iout++] = c;
}
}
if (message == NULL)
buffer[iout] = 0;
else {
buffer[iout++] = ':';
buffer[iout++] = ' ';
png_memcpy(buffer+iout, message, 64);
buffer[iout+63] = 0;
}
}
void
png_chunk_error(png_structp png_ptr, png_const_charp message)
{
char msg[16+64];
png_format_buffer(png_ptr, msg, message);
png_error(png_ptr, msg);
}
void
png_chunk_warning(png_structp png_ptr, png_const_charp message)
{
char msg[16+64];
png_format_buffer(png_ptr, msg, message);
png_warning(png_ptr, msg);
}
/* This is the default error handling function. Note that replacements for
this function MUST NOT RETURN, or the program will likely crash. This
function is used by default, or if the program supplies NULL for the
error function pointer in png_set_error_fn(). */
* this function MUST NOT RETURN, or the program will likely crash. This
* function is used by default, or if the program supplies NULL for the
* error function pointer in png_set_error_fn().
*/
static void
png_default_error(png_structp png_ptr, png_const_charp message)
{
@ -71,9 +129,10 @@ png_default_error(png_structp png_ptr, png_const_charp message)
}
/* This function is called when there is a warning, but the library thinks
it can continue anyway. Replacement functions don't have to do anything
here if you don't want to. In the default configuration, png_ptr is
not used, but it is passed in case it may be useful. */
* it can continue anyway. Replacement functions don't have to do anything
* here if you don't want them to. In the default configuration, png_ptr is
* not used, but it is passed in case it may be useful.
*/
static void
png_default_warning(png_structp png_ptr, png_const_charp message)
{
@ -86,9 +145,10 @@ png_default_warning(png_structp png_ptr, png_const_charp message)
}
/* This function is called when the application wants to use another method
of handling errors and warnings. Note that the error function MUST NOT
return to the calling routine or serious problems will occur. The return
method used in the default routine calls longjmp(png_ptr->jmpbuf, 1) */
* of handling errors and warnings. Note that the error function MUST NOT
* return to the calling routine or serious problems will occur. The return
* method used in the default routine calls longjmp(png_ptr->jmpbuf, 1)
*/
void
png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warning_fn)
@ -100,12 +160,14 @@ png_set_error_fn(png_structp png_ptr, png_voidp error_ptr,
/* This function returns a pointer to the error_ptr associated with the user
functions. The application should free any memory associated with this
pointer before png_write_destroy and png_read_destroy are called. */
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp
png_get_error_ptr(png_structp png_ptr)
{
return png_ptr->error_ptr;
return ((png_voidp)png_ptr->error_ptr);
}

View File

@ -1,11 +1,12 @@
/* pngget.c - retrieval of values from info struct
libpng 1.0 beta 5 - version 0.95
For conditions of distribution and use, see copyright notice in png.h
Copyright (c) 1996, 1997 Andreas Dilger
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
#define PNG_INTERNAL
#include "png.h"
@ -13,7 +14,7 @@
png_uint_32
png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
{
if (info_ptr != NULL)
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->valid & flag);
else
return(0);
@ -22,28 +23,307 @@ png_get_valid(png_structp png_ptr, png_infop info_ptr, png_uint_32 flag)
png_uint_32
png_get_rowbytes(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->rowbytes);
else
return(0);
}
#ifdef PNG_EASY_ACCESS_SUPPORTED
/* easy access to info, added in libpng-0.99 */
png_uint_32
png_get_image_width(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->width;
}
return (0);
}
png_uint_32
png_get_image_height(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->height;
}
return (0);
}
png_byte
png_get_bit_depth(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->bit_depth;
}
return (0);
}
png_byte
png_get_color_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->color_type;
}
return (0);
}
png_byte
png_get_filter_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->filter_type;
}
return (0);
}
png_byte
png_get_interlace_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->interlace_type;
}
return (0);
}
png_byte
png_get_compression_type(png_structp png_ptr, png_infop info_ptr)
{
if (png_ptr != NULL && info_ptr != NULL)
{
return info_ptr->compression_type;
}
return (0);
}
png_uint_32
png_get_x_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_x_pixels_per_meter");
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
return (0);
else return (info_ptr->x_pixels_per_unit);
}
else
#endif
return (0);
}
png_uint_32
png_get_y_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_y_pixels_per_meter");
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER)
return (0);
else return (info_ptr->y_pixels_per_unit);
}
else
#endif
return (0);
}
png_uint_32
png_get_pixels_per_meter(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_pixels_per_meter");
if(info_ptr->phys_unit_type != PNG_RESOLUTION_METER ||
info_ptr->x_pixels_per_unit != info_ptr->y_pixels_per_unit)
return (0);
else return (info_ptr->x_pixels_per_unit);
}
else
#endif
return (0);
}
float
png_get_pixel_aspect_ratio(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_pHYs_SUPPORTED) || defined(PNG_WRITE_pHYs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_aspect_ratio");
if (info_ptr->x_pixels_per_unit == 0)
return ((float)0.0);
else
return ((float)info_ptr->y_pixels_per_unit
/(float)info_ptr->x_pixels_per_unit);
}
else
#endif
return ((float)0.0);
}
png_uint_32
png_get_x_offset_microns(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
return (0);
else return (info_ptr->x_offset);
}
else
#endif
return (0);
}
png_uint_32
png_get_y_offset_microns(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
if(info_ptr->offset_unit_type != PNG_OFFSET_MICROMETER)
return (0);
else return (info_ptr->y_offset);
}
else
#endif
return (0);
}
png_uint_32
png_get_x_offset_pixels(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_x_offset_microns");
if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
return (0);
else return (info_ptr->x_offset);
}
else
#endif
return (0);
}
png_uint_32
png_get_y_offset_pixels(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
{
png_debug1(1, "in %s retrieval function\n", "png_get_y_offset_microns");
if(info_ptr->offset_unit_type != PNG_OFFSET_PIXEL)
return (0);
else return (info_ptr->y_offset);
}
else
#endif
return (0);
}
#ifdef PNG_INCH_CONVERSIONS
png_uint_32
png_get_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_pixels_per_meter(png_ptr, info_ptr)
*.03937 +.5)
}
png_uint_32
png_get_x_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_x_pixels_per_meter(png_ptr, info_ptr)
*.03937 +.5)
}
png_uint_32
png_get_y_pixels_per_inch(png_structp png_ptr, png_infop info_ptr)
{
return ((png_uint_32)((float)png_get_y_pixels_per_meter(png_ptr, info_ptr)
*.03937 +.5)
}
float
png_get_x_offset_inches(png_structp png_ptr, png_infop info_ptr)
{
return ((float)png_get_x_offset_microns(png_ptr, info_ptr)
*.03937/1000000. +.5)
}
float
png_get_y_offset_inches(png_structp png_ptr, png_infop info_ptr)
{
return ((float)png_get_y_offset_microns(png_ptr, info_ptr)
*.03937/1000000. +.5)
}
#if defined(PNG_READ_pHYs_SUPPORTED)
png_uint_32
png_get_pHYs_dpi(png_structp png_ptr, png_infop info_ptr,
png_uint_32 *res_x, png_uint_32 *res_y, int *unit_type)
{
png_uint_32 retval = 0;
if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
{
png_debug1(1, "in %s retrieval function\n", "pHYs");
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (res_y != NULL)
{
*res_y = info_ptr->y_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (unit_type != NULL)
{
*unit_type = (int)info_ptr->phys_unit_type;
retval |= PNG_INFO_pHYs;
if(unit_type == 1)
{
if (res_x != NULL) *res_x = (png_uint_32)(*res_x * 39.37 + .50);
if (res_y != NULL) *res_y = (png_uint_32)(*res_y * 39.37 + .50);
}
}
}
return (retval);
}
#endif /* PNG_READ_pHYs_SUPPORTED */
#endif /* PNG_INCH_CONVERSIONS */
/* png_get_channels really belongs in here, too, but it's been around longer */
#endif /* PNG_EASY_ACCESS_SUPPORTED */
png_byte
png_get_channels(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->channels);
else
return(0);
return (0);
}
png_bytep
png_get_signature(png_structp png_ptr, png_infop info_ptr)
{
if (info_ptr != NULL)
if (png_ptr != NULL && info_ptr != NULL)
return(info_ptr->signature);
else
return(NULL);
return (NULL);
}
#if defined(PNG_READ_bKGD_SUPPORTED)
@ -51,8 +331,8 @@ 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)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)
&& background != NULL)
{
png_debug1(1, "in %s retrieval function\n", "bKGD");
*background = &(info_ptr->background);
@ -68,7 +348,7 @@ 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)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
{
png_debug1(1, "in %s retrieval function\n", "cHRM");
if (white_x != NULL)
@ -97,8 +377,8 @@ png_get_cHRM(png_structp png_ptr, png_infop info_ptr,
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)
if (png_ptr != NULL && 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;
@ -108,11 +388,27 @@ png_get_gAMA(png_structp png_ptr, png_infop info_ptr, double *file_gamma)
}
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
png_uint_32
png_get_sRGB(png_structp png_ptr, png_infop info_ptr, int *file_srgb_intent)
{
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)
&& file_srgb_intent != NULL)
{
png_debug1(1, "in %s retrieval function\n", "sRGB");
*file_srgb_intent = (int)info_ptr->srgb_intent;
return (PNG_INFO_sRGB);
}
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)
if (png_ptr != NULL && info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)
&& hist != NULL)
{
png_debug1(1, "in %s retrieval function\n", "hIST");
*hist = info_ptr->hist;
@ -129,9 +425,12 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
int *filter_type)
{
if (info_ptr != NULL && width != NULL && height != NULL &&
if (png_ptr != NULL && info_ptr != NULL && width != NULL && height != NULL &&
bit_depth != NULL && color_type != NULL)
{
int pixel_depth, channels;
png_uint_32 rowbytes_per_pixel;
png_debug1(1, "in %s retrieval function\n", "IHDR");
*width = info_ptr->width;
*height = info_ptr->height;
@ -143,6 +442,23 @@ png_get_IHDR(png_structp png_ptr, png_infop info_ptr,
*filter_type = info_ptr->filter_type;
if (interlace_type != NULL)
*interlace_type = info_ptr->interlace_type;
/* check for potential overflow of rowbytes */
if (*color_type == PNG_COLOR_TYPE_PALETTE)
channels = 1;
else if (*color_type & PNG_COLOR_MASK_COLOR)
channels = 3;
else
channels = 1;
if (*color_type & PNG_COLOR_MASK_ALPHA)
channels++;
pixel_depth = *bit_depth * channels;
rowbytes_per_pixel = (pixel_depth + 7) >> 3;
if ((*width > (png_uint_32)2147483647L/rowbytes_per_pixel))
{
png_warning(png_ptr,
"Width too large for libpng to process image data.");
}
return (1);
}
return (0);
@ -153,8 +469,8 @@ 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)
if (png_ptr != NULL && 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;
@ -172,7 +488,7 @@ 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 &&
if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pCAL &&
purpose != NULL && X0 != NULL && X1 != NULL && type != NULL &&
nparams != NULL && units != NULL && params != NULL)
{
@ -195,16 +511,28 @@ 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_uint_32 retval = 0;
if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_pHYs)
{
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);
if (res_x != NULL)
{
*res_x = info_ptr->x_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (res_y != NULL)
{
*res_y = info_ptr->y_pixels_per_unit;
retval |= PNG_INFO_pHYs;
}
if (unit_type != NULL)
{
*unit_type = (int)info_ptr->phys_unit_type;
retval |= PNG_INFO_pHYs;
}
}
return (0);
return (retval);
}
#endif
@ -212,7 +540,8 @@ 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)
if (png_ptr != NULL && info_ptr != NULL && info_ptr->valid & PNG_INFO_PLTE &&
palette != NULL)
{
png_debug1(1, "in %s retrieval function\n", "PLTE");
*palette = info_ptr->palette;
@ -227,7 +556,8 @@ png_get_PLTE(png_structp png_ptr, png_infop info_ptr, png_colorp *palette,
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)
if (png_ptr != NULL && 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);
@ -242,15 +572,16 @@ 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))
if (png_ptr != NULL && 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));
(png_ptr->chunk_name[0] == '\0' ? "text"
: (png_const_charp)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 ((png_uint_32)info_ptr->num_text);
}
return(0);
}
@ -260,7 +591,8 @@ png_get_text(png_structp png_ptr, png_infop info_ptr, png_textp *text_ptr,
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)
if (png_ptr != NULL && 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);
@ -275,25 +607,37 @@ 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_uint_32 retval = 0;
if (png_ptr != NULL && 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)
if (info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
*trans = info_ptr->trans;
if (trans != NULL)
{
*trans = info_ptr->trans;
retval |= PNG_INFO_tRNS;
}
if (trans_values != NULL)
*trans_values = &(info_ptr->trans_values);
}
else if (trans_values != NULL)
else /* if (info_ptr->color_type != PNG_COLOR_TYPE_PALETTE) */
{
*trans_values = &(info_ptr->trans_values);
if (trans_values != NULL)
{
*trans_values = &(info_ptr->trans_values);
retval |= PNG_INFO_tRNS;
}
if(trans != NULL)
*trans = NULL;
}
else
if(num_trans != NULL)
{
return (0);
*num_trans = info_ptr->num_trans;
retval |= PNG_INFO_tRNS;
}
*num_trans = info_ptr->num_trans;
return (PNG_INFO_tRNS);
}
return (0);
return (retval);
}
#endif

View File

@ -1,15 +1,18 @@
/* pngmem.c - stub functions for memory allocation
libpng 1.0 beta 5 - version 0.95
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
March 30, 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
to meet their needs. See the instructions at each function. */
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* This file provides a location for all memory allocation. Users who
* need special memory handling are expected to supply replacement
* functions for png_malloc() and png_free(), and to use
* png_create_read_struct_2() and png_create_write_struct_2() to
* identify the replacement functions.
*/
#define PNG_INTERNAL
#include "png.h"
@ -23,6 +26,15 @@
png_voidp
png_create_struct(int type)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL));
}
/* Alternate version of png_create_struct, for use with user-defined malloc. */
png_voidp
png_create_struct_2(int type, png_malloc_ptr malloc_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
@ -31,13 +43,20 @@ png_create_struct(int type)
else if (type == PNG_STRUCT_PNG)
size = sizeof(png_struct);
else
return (png_voidp)NULL;
return ((png_voidp)NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if(malloc_fn != NULL)
{
if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */
if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
{
png_memset(struct_ptr, 0, size);
}
return (struct_ptr);
}
@ -46,8 +65,30 @@ png_create_struct(int type)
void
png_destroy_struct(png_voidp struct_ptr)
{
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
}
/* Free memory allocated by a png_create_struct() call */
void
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
{
#endif
if (struct_ptr != NULL)
{
#ifdef PNG_USER_MEM_SUPPORTED
if(free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
(*(free_fn))(png_ptr, struct_ptr);
struct_ptr = NULL;
return;
}
#endif /* PNG_USER_MEM_SUPPORTED */
farfree (struct_ptr);
struct_ptr = NULL;
}
}
/* Allocate memory. For reasonable files, size should never exceed
@ -57,7 +98,7 @@ png_destroy_struct(png_voidp struct_ptr)
* 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
* It gives you a segment with an offset of 8 (perhaps to store its
* 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
@ -72,16 +113,31 @@ png_destroy_struct(png_voidp struct_ptr)
png_voidp
png_malloc(png_structp png_ptr, png_uint_32 size)
{
#ifndef PNG_USER_MEM_SUPPORTED
png_voidp ret;
#endif
if (png_ptr == NULL || size == 0)
return ((voidp)NULL);
return ((png_voidp)NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if(png_ptr->malloc_fn != NULL)
return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
else
return png_malloc_default(png_ptr, size);
}
png_voidp
png_malloc_default(png_structp png_ptr, png_uint_32 size)
{
png_voidp ret;
#endif PNG_USER_MEM_SUPPORTED
#ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
png_error(png_ptr, "Cannot Allocate > 64K");
#endif
if (size == (png_uint_32)(65536L))
if (size == (png_uint_32)65536L)
{
if (png_ptr->offset_table == NULL)
{
@ -96,8 +152,10 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
png_byte huge * hptr;
if (ret != NULL)
{
farfree(ret);
ret = NULL;
ret = NULL;
}
num_blocks = (int)(1 << (png_ptr->zlib_window_bits - 14));
if (num_blocks < 1)
@ -113,7 +171,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
if (table == NULL)
{
png_error(png_ptr, "Out of Memory");
png_error(png_ptr, "Out Of Memory."); /* Note "O" and "M" */
}
if ((png_size_t)table & 0xfff0)
@ -127,7 +185,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
if (png_ptr->offset_table_ptr == NULL)
{
png_error(png_ptr, "Out of memory");
png_error(png_ptr, "Out Of memory.");
}
hptr = (png_byte huge *)table;
@ -139,7 +197,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
for (i = 0; i < num_blocks; i++)
{
png_ptr->offset_table_ptr[i] = (png_bytep)hptr;
hptr += 65536L;
hptr += (png_uint_32)65536L;
}
png_ptr->offset_table_number = num_blocks;
@ -149,7 +207,7 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
}
if (png_ptr->offset_table_count >= png_ptr->offset_table_number)
png_error(png_ptr, "Out of Memory");
png_error(png_ptr, "Out of Memory.");
ret = png_ptr->offset_table_ptr[png_ptr->offset_table_count++];
}
@ -158,10 +216,10 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
if (ret == NULL)
{
png_error(png_ptr, "Out of Memory");
png_error(png_ptr, "Out of memory."); /* Note "o" and "m" */
}
return ret;
return (ret);
}
/* free a pointer allocated by png_malloc(). In the default
@ -173,6 +231,21 @@ png_free(png_structp png_ptr, png_voidp ptr)
if (png_ptr == NULL || ptr == NULL)
return;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
ptr = NULL;
return;
}
else png_free_default(png_ptr, ptr);
}
void
png_free_default(png_structp png_ptr, png_voidp ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
if (png_ptr->offset_table != NULL)
{
int i;
@ -196,7 +269,10 @@ png_free(png_structp png_ptr, png_voidp ptr)
}
if (ptr != NULL)
{
farfree(ptr);
ptr = NULL;
}
}
#else /* Not the Borland DOS special memory handler */
@ -207,6 +283,17 @@ png_free(png_structp png_ptr, png_voidp ptr)
png_voidp
png_create_struct(int type)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_struct_2(type, NULL));
}
/* Allocate memory for a png_struct or a png_info. The malloc and
memset can be replaced by a single call to calloc() if this is thought
to improve performance noticably.*/
png_voidp
png_create_struct_2(int type, png_malloc_ptr malloc_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_size_t size;
png_voidp struct_ptr;
@ -215,7 +302,16 @@ png_create_struct(int type)
else if (type == PNG_STRUCT_PNG)
size = sizeof(png_struct);
else
return (png_voidp)NULL;
return ((png_voidp)NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if(malloc_fn != NULL)
{
if ((struct_ptr = (*(malloc_fn))(NULL, size)) != NULL)
png_memset(struct_ptr, 0, size);
return (struct_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
if ((struct_ptr = (png_voidp)farmalloc(size)) != NULL)
@ -238,16 +334,40 @@ png_create_struct(int type)
void
png_destroy_struct(png_voidp struct_ptr)
{
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2(struct_ptr, (png_free_ptr)NULL);
}
/* Free memory allocated by a png_create_struct() call */
void
png_destroy_struct_2(png_voidp struct_ptr, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
if (struct_ptr != NULL)
{
#ifdef PNG_USER_MEM_SUPPORTED
if(free_fn != NULL)
{
png_struct dummy_struct;
png_structp png_ptr = &dummy_struct;
(*(free_fn))(png_ptr, struct_ptr);
struct_ptr = NULL;
return;
}
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(struct_ptr);
struct_ptr = NULL;
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(struct_ptr);
struct_ptr = NULL;
# else
free(struct_ptr);
struct_ptr = NULL;
# endif
#endif
}
}
@ -260,9 +380,23 @@ png_destroy_struct(png_voidp struct_ptr)
png_voidp
png_malloc(png_structp png_ptr, png_uint_32 size)
{
#ifndef PNG_USER_MEM_SUPPORTED
png_voidp ret;
#endif
if (png_ptr == NULL || size == 0)
return (NULL);
return ((png_voidp)NULL);
#ifdef PNG_USER_MEM_SUPPORTED
if(png_ptr->malloc_fn != NULL)
return ((png_voidp)(*(png_ptr->malloc_fn))(png_ptr, size));
else
return (png_malloc_default(png_ptr, size));
}
png_voidp
png_malloc_default(png_structp png_ptr, png_uint_32 size)
{
png_voidp ret;
#endif /* PNG_USER_MEM_SUPPORTED */
#ifdef PNG_MAX_MALLOC_64K
if (size > (png_uint_32)65536L)
@ -270,12 +404,12 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
#endif
#if defined(__TURBOC__) && !defined(__FLAT__)
ret = farmalloc((png_size_t)size);
ret = farmalloc(size);
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
ret = halloc(size, 1);
# else
ret = malloc(size);
ret = malloc((size_t)size);
# endif
#endif
@ -284,28 +418,94 @@ png_malloc(png_structp png_ptr, png_uint_32 size)
png_error(png_ptr, "Out of Memory");
}
return ret;
return (ret);
}
/* 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. */
/* Free a pointer allocated by png_malloc(). If ptr is NULL, return
without taking any action. */
void
png_free(png_structp png_ptr, png_voidp ptr)
{
if (png_ptr == NULL || ptr == NULL)
return;
#ifdef PNG_USER_MEM_SUPPORTED
if (png_ptr->free_fn != NULL)
{
(*(png_ptr->free_fn))(png_ptr, ptr);
ptr = NULL;
return;
}
else png_free_default(png_ptr, ptr);
}
void
png_free_default(png_structp png_ptr, png_voidp ptr)
{
#endif /* PNG_USER_MEM_SUPPORTED */
#if defined(__TURBOC__) && !defined(__FLAT__)
farfree(ptr);
ptr = NULL;
#else
# if defined(_MSC_VER) && defined(MAXSEG_64K)
hfree(ptr);
ptr = NULL;
# else
free(ptr);
ptr = NULL;
# endif
#endif
}
#endif /* Not Borland DOS special memory handler */
png_voidp
png_memcpy_check (png_structp png_ptr, png_voidp s1, png_voidp s2,
png_uint_32 length)
{
png_size_t size;
size = (png_size_t)length;
if ((png_uint_32)size != length)
png_error(png_ptr,"Overflow in png_memcpy_check.");
return(png_memcpy (s1, s2, size));
}
png_voidp
png_memset_check (png_structp png_ptr, png_voidp s1, int value,
png_uint_32 length)
{
png_size_t size;
size = (png_size_t)length;
if ((png_uint_32)size != length)
png_error(png_ptr,"Overflow in png_memset_check.");
return (png_memset (s1, value, size));
}
#ifdef PNG_USER_MEM_SUPPORTED
/* This function is called when the application wants to use another method
* of allocating and freeing memory.
*/
void
png_set_mem_fn(png_structp png_ptr, png_voidp mem_ptr, png_malloc_ptr
malloc_fn, png_free_ptr free_fn)
{
png_ptr->mem_ptr = mem_ptr;
png_ptr->malloc_fn = malloc_fn;
png_ptr->free_fn = free_fn;
}
/* This function returns a pointer to the mem_ptr associated with the user
* functions. The application should free any memory associated with this
* pointer before png_write_destroy and png_read_destroy are called.
*/
png_voidp
png_get_mem_ptr(png_structp png_ptr)
{
return ((png_voidp)png_ptr->mem_ptr);
}
#endif /* PNG_USER_MEM_SUPPORTED */

View File

@ -1,12 +1,12 @@
/* pngpread.c - read a png file in push mode
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
#define PNG_INTERNAL
#include "png.h"
@ -46,7 +46,6 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr)
case PNG_READ_IDAT_MODE:
{
png_push_read_IDAT(png_ptr);
break;
}
#if defined(PNG_READ_tEXt_SUPPORTED)
@ -78,8 +77,9 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr)
/* Read any remaining signature bytes from the stream and compare them with
* the correct PNG signature. It is possible that this routine is called
* with bytes already read from the signature, whether because they have been
* checked by the calling application, or from multiple calls to this routine.
* with bytes already read from the signature, either because they have been
* checked by the calling application, or because of multiple calls to this
* routine.
*/
void
png_push_read_sig(png_structp png_ptr, png_infop info_ptr)
@ -117,10 +117,11 @@ void
png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
{
/* First we make sure we have enough data for the 4 byte chunk name
and the 4 byte chunk length before proceeding with decoding the
chunk data. To fully decode each of these chunks, we also make
sure we have enough data in the buffer for the 4 byte CRC at the
end of every chunk (except IDAT, which is handled separately). */
* and the 4 byte chunk length before proceeding with decoding the
* chunk data. To fully decode each of these chunks, we also make
* sure we have enough data in the buffer for the 4 byte CRC at the
* end of every chunk (except IDAT, which is handled separately).
*/
if (!(png_ptr->flags & PNG_FLAG_HAVE_CHUNK_HEADER))
{
png_byte chunk_length[4];
@ -161,8 +162,9 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
else if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
{
/* If we reach an IDAT chunk, this means we have read all of the
header chunks, and we can start reading the image (or if this
is called after the image has been read - we have an error). */
* header chunks, and we can start reading the image (or if this
* is called after the image has been read - we have an error).
*/
if (png_ptr->mode & PNG_HAVE_IDAT)
{
if (png_ptr->push_length == 0)
@ -228,6 +230,18 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr)
png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
{
if (png_ptr->push_length + 4 > png_ptr->buffer_size)
{
png_push_save_buffer(png_ptr);
return;
}
png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length);
}
#endif
#if defined(PNG_READ_tRNS_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4))
{
@ -432,13 +446,13 @@ png_push_save_buffer(png_structp png_ptr)
{
if (png_ptr->save_buffer_ptr != png_ptr->save_buffer)
{
png_size_t i;
png_size_t i,istop;
png_bytep sp;
png_bytep dp;
istop = png_ptr->save_buffer_size;
for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer;
i < png_ptr->save_buffer_size;
i++, sp++, dp++)
i < istop; i++, sp++, dp++)
{
*dp = *sp;
}
@ -452,7 +466,8 @@ png_push_save_buffer(png_structp png_ptr)
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_ptr->save_buffer = (png_bytep)png_malloc(png_ptr,
(png_uint_32)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;
@ -513,7 +528,12 @@ png_push_read_IDAT(png_structp png_ptr)
png_size_t save_size;
if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
save_size = png_ptr->idat_size;
{
save_size = (png_size_t)png_ptr->idat_size;
/* check for overflow */
if((png_uint_32)save_size != png_ptr->idat_size)
png_error(png_ptr, "save_size overflowed in pngpread");
}
else
save_size = png_ptr->save_buffer_size;
@ -530,7 +550,12 @@ png_push_read_IDAT(png_structp png_ptr)
png_size_t save_size;
if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
save_size = png_ptr->idat_size;
{
save_size = (png_size_t)png_ptr->idat_size;
/* check for overflow */
if((png_uint_32)save_size != png_ptr->idat_size)
png_error(png_ptr, "save_size overflowed in pngpread");
}
else
save_size = png_ptr->current_buffer_size;
@ -566,7 +591,7 @@ 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;
while(1)
for(;;)
{
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret == Z_STREAM_END)
@ -605,6 +630,7 @@ png_push_process_row(png_structp png_ptr)
png_ptr->row_info.channels = png_ptr->channels;
png_ptr->row_info.bit_depth = png_ptr->bit_depth;
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
@ -612,7 +638,8 @@ 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_ptr->rowbytes + 1);
png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
png_ptr->rowbytes + 1);
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
@ -747,7 +774,8 @@ 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_ptr->rowbytes + 1);
png_memset_check(png_ptr, png_ptr->prev_row, 0,
png_ptr->rowbytes + 1);
do
{
png_ptr->pass++;
@ -757,8 +785,10 @@ png_read_push_finish_row(png_structp png_ptr)
png_pass_inc[png_ptr->pass] - 1 -
png_pass_start[png_ptr->pass]) /
png_pass_inc[png_ptr->pass];
png_ptr->irowbytes = ((png_ptr->iwidth *
png_ptr->pixel_depth + 7) >> 3) + 1;
if (!(png_ptr->transformations & PNG_INTERLACE))
{
png_ptr->num_rows = (png_ptr->height +
@ -779,24 +809,29 @@ void
png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
png_error(png_ptr, "Out of place tEXt");
{
png_error(png_ptr, "Out of place tEXt");
/* to quiet some compiler warnings */
if(info_ptr == NULL) return;
}
#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 */
if (length > (png_uint_32)65535L) /* 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;
png_ptr->skip_length = length - (png_uint_32)65535L;
length = (png_uint_32)65535L;
}
#endif
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
png_ptr->current_text = (png_charp)png_malloc(png_ptr,
(png_uint_32)(length+1));
png_ptr->current_text[length] = '\0';
png_ptr->current_text_ptr = png_ptr->current_text;
png_ptr->current_text_size = length;
png_ptr->current_text_left = length;
png_ptr->current_text_size = (png_size_t)length;
png_ptr->current_text_left = (png_size_t)length;
png_ptr->process_mode = PNG_READ_tEXt_MODE;
}
@ -843,7 +878,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr)
if (text != key + png_ptr->current_text_size)
text++;
text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
text_ptr->key = key;
text_ptr->text = text;
@ -860,14 +895,18 @@ void
png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
if (png_ptr->mode == PNG_BEFORE_IHDR || png_ptr->mode & PNG_HAVE_IEND)
png_error(png_ptr, "Out of place zTXt");
{
png_error(png_ptr, "Out of place zTXt");
/* to quiet some compiler warnings */
if(info_ptr == NULL) return;
}
#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)
if (length > (png_uint_32)65535L)
{
png_warning(png_ptr, "zTXt chunk too large to fit in memory");
png_push_crc_skip(png_ptr, length);
@ -875,11 +914,12 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length
}
#endif
png_ptr->current_text = (png_charp)png_malloc(png_ptr, length+1);
png_ptr->current_text = (png_charp)png_malloc(png_ptr,
(png_uint_32)(length+1));
png_ptr->current_text[length] = '\0';
png_ptr->current_text_ptr = png_ptr->current_text;
png_ptr->current_text_size = length;
png_ptr->current_text_left = length;
png_ptr->current_text_size = (png_size_t)length;
png_ptr->current_text_left = (png_size_t)length;
png_ptr->process_mode = PNG_READ_zTXt_MODE;
}
@ -941,7 +981,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_ptr->zbuf_size;
png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
key_size = text - key;
text_size = 0;
@ -964,8 +1004,8 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
if (text == NULL)
{
text = (png_charp)png_malloc(png_ptr,
png_ptr->zbuf_size - png_ptr->zstream.avail_out +
key_size + 1);
(png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out +
key_size + 1));
png_memcpy(text + key_size, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);
png_memcpy(text, key, key_size);
@ -978,8 +1018,9 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_charp tmp;
tmp = text;
text = png_malloc(png_ptr, text_size +
png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1);
text = (png_charp)png_malloc(png_ptr, text_size +
(png_uint_32)(png_ptr->zbuf_size - png_ptr->zstream.avail_out
+ 1));
png_memcpy(text, tmp, text_size);
png_free(png_ptr, tmp);
png_memcpy(text + text_size, png_ptr->zbuf,
@ -1015,9 +1056,8 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
png_free(png_ptr, key);
key = text;
text += key_size;
text_size -= key_size;
text_ptr = (png_textp)png_malloc(png_ptr, sizeof(png_text));
text_ptr = (png_textp)png_malloc(png_ptr, (png_uint_32)sizeof(png_text));
text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt;
text_ptr->key = key;
text_ptr->text = text;
@ -1030,11 +1070,12 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr)
#endif
/* This function is called when we haven't found a handler for this
chunk. In the future we will have code here which can handle
user-defined callback functions for unknown chunks before they are
ignored or cause an error. If there isn't a problem with the
chunk itself (ie a bad chunk name or a critical chunk), the chunk
is (currently) silently ignored. */
* chunk. In the future we will have code here that can handle
* user-defined callback functions for unknown chunks before they are
* ignored or cause an error. If there isn't a problem with the
* chunk itself (ie a bad chunk name or a critical chunk), the chunk
* is (currently) silently ignored.
*/
void
png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
{
@ -1042,10 +1083,9 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 len
if (!(png_ptr->chunk_name[0] & 0x20))
{
char msg[40];
sprintf(msg, "Unknown critical chunk %s", png_ptr->chunk_name);
png_error(png_ptr, msg);
png_chunk_error(png_ptr, "unknown critical chunk");
/* to quiet some compiler warnings */
if(info_ptr == NULL) return;
}
png_push_crc_skip(png_ptr, length);
@ -1077,7 +1117,7 @@ void
png_progressive_combine_row (png_structp png_ptr,
png_bytep old_row, png_bytep new_row)
{
if (new_row != NULL)
if (new_row != NULL) /* new_row must == png_ptr->row_buf here. */
png_combine_row(png_ptr, old_row, png_pass_dsp_mask[png_ptr->pass]);
}
@ -1089,6 +1129,7 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr,
png_ptr->info_fn = info_fn;
png_ptr->row_fn = row_fn;
png_ptr->end_fn = end_fn;
png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer);
}
@ -1099,3 +1140,4 @@ png_get_progressive_ptr(png_structp png_ptr)
}
#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */

View File

@ -1,27 +1,49 @@
/* pngread.c - read a PNG file
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* This file contains routines that an application calls directly to
* read a PNG file or stream.
*/
#define PNG_INTERNAL
#include "png.h"
/* Create a PNG structure for reading, and allocate any memory needed. */
png_structp
png_create_read_struct(png_charp user_png_ver, png_voidp error_ptr,
png_create_read_struct(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_read_struct_2(user_png_ver, error_ptr, error_fn,
warn_fn, NULL, NULL, NULL));
}
/* Alternate create PNG structure for reading, and allocate any memory needed. */
png_structp
png_create_read_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_structp png_ptr;
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
#endif
png_debug(1, "in png_create_read_struct\n");
#ifdef PNG_USER_MEM_SUPPORTED
if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
(png_malloc_ptr)malloc_fn)) == NULL)
#else
if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
#endif
{
return (png_structp)NULL;
}
@ -31,14 +53,18 @@ png_create_read_struct(png_charp user_png_ver, png_voidp error_ptr,
if (setjmp(png_ptr->jmpbuf))
#endif
{
png_free(png_ptr, png_ptr->zbuf);
png_destroy_struct(png_ptr);
png_free(png_ptr, png_ptr->zbuf);
png_destroy_struct(png_ptr);
return (png_structp)NULL;
}
#ifdef USE_FAR_KEYWORD
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
#ifdef PNG_USER_MEM_SUPPORTED
png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif /* PNG_USER_MEM_SUPPORTED */
png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
/* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
@ -55,9 +81,8 @@ png_create_read_struct(png_charp user_png_ver, png_voidp error_ptr,
/* initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);
memset(png_ptr->zbuf, NULL, png_ptr->zbuf_size );
png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = (voidpf)png_ptr;
@ -79,9 +104,8 @@ png_create_read_struct(png_charp user_png_ver, png_voidp error_ptr,
return (png_ptr);
}
/* Initialize PNG structure for reading, and allocate any memory needed.
This interface is depreciated in favour of the png_create_read_struct(),
This interface is deprecated in favour of the png_create_read_struct(),
and it will eventually disappear. */
void
png_read_init(png_structp png_ptr)
@ -100,7 +124,8 @@ png_read_init(png_structp png_ptr)
/* initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);
png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = (voidpf)png_ptr;
@ -121,9 +146,9 @@ png_read_init(png_structp png_ptr)
}
/* Read the information before the actual image data. This has been
* changed in v0.90 to allow reading a file which already has the magic
* changed in v0.90 to allow reading a file that already has the magic
* bytes read from the stream. You can tell libpng how many bytes have
* been read from the beginning of the stream (up to the maxumum of 8)
* been read from the beginning of the stream (up to the maximum of 8)
* via png_set_sig_bytes(), and we will only check the remaining bytes
* here. The application can then have access to the signature bytes we
* read if it is determined that this isn't a valid PNG file.
@ -152,7 +177,7 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
}
}
while (1)
for(;;)
{
png_byte chunk_length[4];
png_uint_32 length;
@ -218,6 +243,10 @@ png_read_info(png_structp png_ptr, png_infop info_ptr)
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
png_handle_sRGB(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);
@ -250,10 +279,11 @@ png_read_update_info(png_structp png_ptr, png_infop info_ptr)
png_read_transform_info(png_ptr, info_ptr);
}
/* initialize palette, background, etc, after transformations
are set, but before any reading takes place. This allows
the user to obtail a gamma corrected palette, for example.
If the user doesn't call this, we will do it ourselves. */
/* Initialize palette, background, etc, after transformations
* are set, but before any reading takes place. This allows
* the user to obtain a gamma-corrected palette, for example.
* If the user doesn't call this, we will do it ourselves.
*/
void
png_start_read_image(png_structp png_ptr)
{
@ -272,6 +302,38 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
/* save jump buffer and error functions */
if (!(png_ptr->flags & PNG_FLAG_ROW_INIT))
png_read_start_row(png_ptr);
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
/* check for transforms that have been set but were defined out */
#if defined(PNG_WRITE_INVERT_SUPPORTED) && !defined(PNG_READ_INVERT_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_READ_INVERT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED) && !defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_READ_FILLER_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED) && !defined(PNG_READ_PACKSWAP_SUPPORTED)
if (png_ptr->transformations & PNG_PACKSWAP)
png_warning(png_ptr, "PNG_READ_PACKSWAP_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_PACK_SUPPORTED) && !defined(PNG_READ_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_READ_PACK_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED) && !defined(PNG_READ_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_READ_SHIFT_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_BGR_SUPPORTED) && !defined(PNG_READ_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_READ_BGR_SUPPORTED is not defined.");
#endif
#if defined(PNG_WRITE_SWAP_SUPPORTED) && !defined(PNG_READ_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_READ_SWAP_SUPPORTED is not defined.");
#endif
}
#if defined(PNG_READ_INTERLACING_SUPPORTED)
/* if interlaced and we do not need a new row, combine row and return */
@ -356,7 +418,7 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->zstream.next_out = png_ptr->row_buf;
png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
do
{
{
if (!(png_ptr->zstream.avail_in))
{
while (!png_ptr->idat_size)
@ -382,7 +444,6 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_ptr->idat_size -= png_ptr->zstream.avail_in;
}
ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
if (ret == Z_STREAM_END)
{
if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
@ -396,21 +457,24 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
"Decompression error");
} while (png_ptr->zstream.avail_out);
} while (png_ptr->zstream.avail_out);
png_ptr->row_info.color_type = png_ptr->color_type;
png_ptr->row_info.width = png_ptr->iwidth;
png_ptr->row_info.channels = png_ptr->channels;
png_ptr->row_info.bit_depth = png_ptr->bit_depth;
png_ptr->row_info.pixel_depth = png_ptr->pixel_depth;
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
{
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
}
png_read_filter_row(png_ptr, &(png_ptr->row_info),
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_ptr->rowbytes + 1);
png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf,
png_ptr->rowbytes + 1);
if (png_ptr->transformations)
png_do_read_transformations(png_ptr);
@ -440,26 +504,34 @@ png_read_row(png_structp png_ptr, png_bytep row, png_bytep dsp_row)
png_combine_row(png_ptr, dsp_row, 0xff);
}
png_read_finish_row(png_ptr);
if (png_ptr->read_row_fn != NULL)
(*(png_ptr->read_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
}
/* 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
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
"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_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_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. */
* and png_set_interlace_handling() has been called, the rows need 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
* 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
* "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_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_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.
*
* [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.2.
*/
void
png_read_rows(png_structp png_ptr, png_bytepp row,
@ -473,40 +545,46 @@ png_read_rows(png_structp png_ptr, png_bytepp row,
/* save jump buffer and error functions */
rp = row;
dp = display_row;
for (i = 0; i < num_rows; i++)
{
png_bytep rptr;
png_bytep dptr;
if (rp != NULL)
rptr = *rp;
else
rptr = NULL;
if (dp != NULL)
dptr = *dp;
else
dptr = NULL;
png_read_row(png_ptr, rptr, dptr);
if (row != NULL)
if (rp != NULL && dp != NULL)
for (i = 0; i < num_rows; i++)
{
png_bytep rptr = *rp++;
png_bytep dptr = *dp++;
png_read_row(png_ptr, rptr, dptr);
}
else if(rp != NULL)
for (i = 0; i < num_rows; i++)
{
png_bytep rptr = *rp;
png_read_row(png_ptr, rptr, NULL);
rp++;
if (display_row != NULL)
}
else if(dp != NULL)
for (i = 0; i < num_rows; i++)
{
png_bytep dptr = *dp;
png_read_row(png_ptr, NULL, dptr);
dp++;
}
}
}
/* 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.
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 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 */
* chunk, and you have called png_handle_alpha()[*], you will need to
* 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 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.
*
* [*] png_handle_alpha() does not exist yet, as of libpng version 1.0.2.
*/
void
png_read_image(png_structp png_ptr, png_bytepp image)
{
png_uint_32 i;
png_uint_32 i,image_height;
int pass, j;
png_bytepp rp;
@ -514,12 +592,13 @@ png_read_image(png_structp png_ptr, png_bytepp image)
/* 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 */
image_height=png_ptr->height;
png_ptr->num_rows = image_height; /* Make sure this is set correctly */
for (j = 0; j < pass; j++)
{
rp = image;
for (i = 0; i < png_ptr->height; i++)
for (i = 0; i < image_height; i++)
{
png_read_row(png_ptr, *rp, NULL);
rp++;
@ -528,8 +607,9 @@ 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
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. */
* 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
png_read_end(png_structp png_ptr, png_infop info_ptr)
{
@ -598,6 +678,10 @@ png_read_end(png_structp png_ptr, png_infop info_ptr)
else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4))
png_handle_sBIT(png_ptr, info_ptr, length);
#endif
#if defined(PNG_READ_sRGB_SUPPORTED)
else if (!png_memcmp(png_ptr->chunk_name, png_sRGB, 4))
png_handle_sRGB(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);
@ -626,6 +710,9 @@ 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;
#ifdef PNG_USER_MEM_SUPPORTED
png_free_ptr free_fn = NULL;
#endif /* PNG_USER_MEM_SUPPORTED */
png_debug(1, "in png_destroy_read_struct\n");
/* save jump buffer and error functions */
@ -638,23 +725,46 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
if (end_info_ptr_ptr != NULL)
end_info_ptr = *end_info_ptr_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
free_fn = png_ptr->free_fn;
#endif
png_read_destroy(png_ptr, info_ptr, end_info_ptr);
if (info_ptr != NULL)
{
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
png_free(png_ptr, info_ptr->text);
#endif
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)info_ptr, free_fn);
#else
png_destroy_struct((png_voidp)info_ptr);
#endif
*info_ptr_ptr = (png_infop)NULL;
}
if (end_info_ptr != NULL)
{
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_READ_zTXt_SUPPORTED)
png_free(png_ptr, end_info_ptr->text);
#endif
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)end_info_ptr, free_fn);
#else
png_destroy_struct((png_voidp)end_info_ptr);
#endif
*end_info_ptr_ptr = (png_infop)NULL;
}
if (png_ptr != NULL)
{
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)png_ptr, free_fn);
#else
png_destroy_struct((png_voidp)png_ptr);
#endif
*png_ptr_ptr = (png_structp)NULL;
}
}
@ -663,11 +773,13 @@ png_destroy_read_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr,
void
png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr)
{
int i;
jmp_buf tmp_jmp;
png_error_ptr error_fn;
png_error_ptr warning_fn;
png_voidp error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
png_free_ptr free_fn;
#endif
png_debug(1, "in png_read_destroy\n");
/* save jump buffer and error functions */
@ -692,11 +804,9 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
png_free(png_ptr, png_ptr->gamma_to_1);
#endif
if (png_ptr->flags & PNG_FLAG_FREE_PALETTE)
png_free(png_ptr, png_ptr->palette);
#if defined(PNG_READ_BACKGROUND_SUPPORTED) && defined(PNG_READ_bKGD_SUPPORTED)
png_zfree(png_ptr, png_ptr->palette);
if (png_ptr->flags & PNG_FLAG_FREE_TRANS)
png_free(png_ptr, png_ptr->trans);
#endif
#if defined(PNG_READ_hIST_SUPPORTED)
if (png_ptr->flags & PNG_FLAG_FREE_HIST)
png_free(png_ptr, png_ptr->hist);
@ -704,17 +814,20 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
#if defined(PNG_READ_GAMMA_SUPPORTED)
if (png_ptr->gamma_16_table != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_table[i]);
}
}
#endif
#if defined(PNG_READ_BACKGROUND_SUPPORTED)
png_free(png_ptr, png_ptr->gamma_16_table);
if (png_ptr->gamma_16_from_1 != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_from_1[i]);
}
@ -722,13 +835,19 @@ 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 != NULL)
{
for (i = 0; i < (1 << (8 - png_ptr->gamma_shift)); i++)
int i;
int istop = (1 << (8 - png_ptr->gamma_shift));
for (i = 0; i < istop; i++)
{
png_free(png_ptr, png_ptr->gamma_16_to_1[i]);
}
}
png_free(png_ptr, png_ptr->gamma_16_to_1);
#endif
#endif
#if defined(PNG_TIME_RFC1123_SUPPORTED)
png_free(png_ptr, png_ptr->time_buffer);
#endif /* PNG_TIME_RFC1123_SUPPORTED */
inflateEnd(&png_ptr->zstream);
#ifdef PNG_PROGRESSIVE_READ_SUPPORTED
@ -743,12 +862,24 @@ png_read_destroy(png_structp png_ptr, png_infop info_ptr, png_infop end_info_ptr
error_fn = png_ptr->error_fn;
warning_fn = png_ptr->warning_fn;
error_ptr = png_ptr->error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
free_fn = png_ptr->free_fn;
#endif
png_memset(png_ptr, 0, sizeof (png_struct));
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
png_ptr->error_ptr = error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
png_ptr->free_fn = free_fn;
#endif
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
}
void
png_set_read_status_fn(png_structp png_ptr, png_read_status_ptr read_row_fn)
{
png_ptr->read_row_fn = read_row_fn;
}

View File

@ -1,18 +1,19 @@
/* pngrio.c - functions for data input
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
This file provides a location for all input. Users which need
special handling are expected to write a function which has the same
arguments as this, and perform a similar function, but possibly has
a different input method. Note that you shouldn't change this
function, but rather write a replacement function and then make
libpng use it at run time with png_set_read_fn(...) */
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* This file provides a location for all input. Users who need
* special handling are expected to write a function that has the same
* arguments as this and performs a similar function, but that possibly
* has a different input method. Note that you shouldn't change this
* function, but rather write a replacement function and then make
* libpng use it at run time with png_set_read_fn(...).
*/
#define PNG_INTERNAL
#include "png.h"
@ -23,7 +24,7 @@
buffering if you are using unbuffered reads. This should never be asked
to read more then 64K on a 16 bit machine. */
void
png_read_data( png_structp png_ptr, png_bytep data, png_size_t length)
png_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
png_debug1(4,"reading %d bytes\n", length);
if (png_ptr->read_data_fn != NULL)
@ -32,11 +33,11 @@ png_read_data( png_structp png_ptr, png_bytep data, png_size_t length)
png_error(png_ptr, "Call to NULL read function");
}
/* This is the function which does the actual reading of data. If you are
#if !defined(PNG_NO_STDIO)
/* This is the function that does the actual reading of data. If you are
not reading from a standard C stream, you should create a replacement
read_data function and use it at run time with png_set_read_fn(), rather
than changing the library. */
#define USE_FAR_KEYWORD
#ifndef USE_FAR_KEYWORD
static void
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
@ -61,9 +62,7 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
*/
#define NEAR_BUF_SIZE 1024
#ifndef MIN
#define MIN(a,b) (a <= b ? a : b)
#endif /* !MIN */
static void
png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
@ -99,13 +98,13 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
}
while (remaining != 0);
}
if (check != length)
if ((png_uint_32)check != (png_uint_32)length)
{
png_error(png_ptr, "read Error");
}
}
#endif
#endif
/* This function allows the application to supply a new input function
for libpng if standard C streams aren't being used.
@ -114,10 +113,10 @@ png_default_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
png_ptr - pointer to a png input data structure
io_ptr - pointer to user supplied structure containing info about
the input functions. May be NULL.
read_data_fn - pointer to a new input function which takes as it's
read_data_fn - pointer to a new input function that takes as its
arguments a pointer to a png_struct, a pointer to
a location where input data can be stored, and a 32-bit
unsigned int which is the number of bytes to be read.
unsigned int that is the number of bytes to be read.
To exit and output any fatal error messages the new write
function should call png_error(png_ptr, "Error msg"). */
void
@ -125,14 +124,25 @@ png_set_read_fn(png_structp png_ptr, png_voidp io_ptr,
png_rw_ptr read_data_fn)
{
png_ptr->io_ptr = io_ptr;
#if !defined(PNG_NO_STDIO)
if (read_data_fn != NULL)
png_ptr->read_data_fn = read_data_fn;
else
png_ptr->read_data_fn = png_default_read_data;
#else
png_ptr->read_data_fn = read_data_fn;
#endif
/* It is an error to write to a read device */
png_ptr->write_data_fn = NULL;
if (png_ptr->write_data_fn != NULL)
{
png_ptr->write_data_fn = NULL;
png_warning(png_ptr,
"It's an error to set both read_data_fn and write_data_fn in the ");
png_warning(png_ptr,
"same structure. Resetting write_data_fn to NULL.");
}
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
png_ptr->output_flush_fn = NULL;

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,12 +1,17 @@
/* pngset.c - storage of image information into info struct
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* The functions here are used during reads to store data from the file
* into the info struct, and during writes to store application data
* into the info struct for writing into the file. This abstracts the
* info struct and allows us to change the structure in the future.
*/
#define PNG_INTERNAL
#include "png.h"
@ -16,7 +21,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
png_memcpy(&(info_ptr->background), background, sizeof(png_color_16));
@ -31,7 +36,7 @@ png_set_cHRM(png_structp png_ptr, png_infop info_ptr,
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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->x_white = (float)white_x;
@ -51,7 +56,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->gamma = (float)file_gamma;
@ -64,7 +69,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->hist = hist;
@ -78,8 +83,9 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
int color_type, int interlace_type, int compression_type,
int filter_type)
{
int rowbytes_per_pixel;
png_debug1(1, "in %s storage function\n", "IHDR");
if (info_ptr == NULL)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->width = width;
@ -98,7 +104,17 @@ png_set_IHDR(png_structp png_ptr, png_infop info_ptr,
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);
/* check for overflow */
rowbytes_per_pixel = (info_ptr->pixel_depth + 7) >> 3;
if (( width > (png_uint_32)2147483647L/rowbytes_per_pixel))
{
png_warning(png_ptr,
"Width too large to process image data; rowbytes will overflow.");
info_ptr->rowbytes = (png_size_t)0;
}
else
info_ptr->rowbytes = (info_ptr->width * info_ptr->pixel_depth + 7) >> 3;
}
#if defined(PNG_READ_oFFs_SUPPORTED) || defined(PNG_WRITE_oFFs_SUPPORTED)
@ -107,7 +123,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->x_offset = offset_x;
@ -123,17 +139,17 @@ 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;
png_uint_32 length;
int i;
png_debug1(1, "in %s storage function\n", "pCAL");
if (info_ptr == NULL)
if (png_ptr == NULL || 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_memcpy(info_ptr->pcal_purpose, purpose, (png_size_t)length);
png_debug(3, "storing X0, X1, type, and nparams in info\n");
info_ptr->pcal_X0 = X0;
@ -144,10 +160,10 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
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);
png_memcpy(info_ptr->pcal_units, units, (png_size_t)length);
info_ptr->pcal_params = (png_charpp)png_malloc(png_ptr,
(nparams + 1) * sizeof(png_charp));
(png_uint_32)((nparams + 1) * sizeof(png_charp)));
info_ptr->pcal_params[nparams] = NULL;
for (i = 0; i < nparams; i++)
@ -155,7 +171,7 @@ png_set_pCAL(png_structp png_ptr, png_infop info_ptr,
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);
png_memcpy(info_ptr->pcal_params[i], params[i], (png_size_t)length);
}
info_ptr->valid |= PNG_INFO_pCAL;
@ -168,7 +184,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->x_pixels_per_unit = res_x;
@ -183,7 +199,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->palette = palette;
@ -197,7 +213,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
png_memcpy(&(info_ptr->sig_bit), sig_bit, sizeof (png_color_8));
@ -205,8 +221,57 @@ png_set_sBIT(png_structp png_ptr, png_infop info_ptr,
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED) || \
defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
#if defined(PNG_READ_sRGB_SUPPORTED) || defined(PNG_WRITE_sRGB_SUPPORTED)
void
png_set_sRGB(png_structp png_ptr, png_infop info_ptr, int intent)
{
png_debug1(1, "in %s storage function\n", "sRGB");
if (png_ptr == NULL || info_ptr == NULL)
return;
info_ptr->srgb_intent = (png_byte)intent;
info_ptr->valid |= PNG_INFO_sRGB;
}
void
png_set_sRGB_gAMA_and_cHRM(png_structp png_ptr, png_infop info_ptr,
int intent)
{
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
float file_gamma;
#endif
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
#endif
png_debug1(1, "in %s storage function\n", "sRGB_gAMA_and_cHRM");
if (png_ptr == NULL || info_ptr == NULL)
return;
png_set_sRGB(png_ptr, info_ptr, intent);
#if defined(PNG_READ_gAMA_SUPPORTED) || defined(PNG_WRITE_gAMA_SUPPORTED)
file_gamma = (float).45;
png_set_gAMA(png_ptr, info_ptr, file_gamma);
#endif
#if defined(PNG_READ_cHRM_SUPPORTED) || defined(PNG_WRITE_cHRM_SUPPORTED)
white_x = (float).3127;
white_y = (float).3290;
red_x = (float).64;
red_y = (float).33;
green_x = (float).30;
green_y = (float).60;
blue_x = (float).15;
blue_y = (float).06;
png_set_cHRM(png_ptr, info_ptr,
white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
#endif
}
#endif
#if defined(PNG_READ_tEXt_SUPPORTED) || defined(PNG_WRITE_tEXt_SUPPORTED) || \
defined(PNG_READ_zTXt_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)
@ -214,9 +279,9 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
int i;
png_debug1(1, "in %s storage function\n", (png_ptr->chunk_name[0] == '\0' ?
"text" : png_ptr->chunk_name));
"text" : (png_const_charp)png_ptr->chunk_name));
if (info_ptr == NULL || num_text == 0)
if (png_ptr == NULL || info_ptr == NULL || num_text == 0)
return;
/* Make sure we have enough space in the "text" array in info_struct
@ -233,8 +298,9 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
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_uint_32)(info_ptr->max_text * sizeof (png_text)));
png_memcpy(info_ptr->text, old_text, (png_size_t)(old_max *
sizeof(png_text)));
png_free(png_ptr, old_text);
}
else
@ -242,7 +308,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
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_uint_32)(info_ptr->max_text * sizeof (png_text)));
}
png_debug1(3, "allocated %d entries for info_ptr->text\n",
info_ptr->max_text);
@ -253,7 +319,7 @@ png_set_text(png_structp png_ptr, png_infop info_ptr, png_textp text_ptr,
png_textp textp = &(info_ptr->text[info_ptr->num_text]);
if (text_ptr[i].text == NULL)
text_ptr[i].text = "";
text_ptr[i].text = (png_charp)"";
if (text_ptr[i].text[0] == '\0')
{
@ -278,7 +344,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
png_memcpy(&(info_ptr->mod_time), mod_time, sizeof (png_time));
@ -292,7 +358,7 @@ 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)
if (png_ptr == NULL || info_ptr == NULL)
return;
if (trans != NULL)
@ -304,6 +370,8 @@ png_set_tRNS(png_structp png_ptr, png_infop info_ptr,
{
png_memcpy(&(info_ptr->trans_values), trans_values,
sizeof(png_color_16));
if (num_trans == 0)
num_trans = 1;
}
info_ptr->num_trans = (png_uint_16)num_trans;
info_ptr->valid |= PNG_INFO_tRNS;

View File

@ -1,22 +1,22 @@
/* pngtrans.c - transforms the data in a row (used by both readers and writers)
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
#define PNG_INTERNAL
#include "png.h"
#include <math.h>
#if defined(PNG_READ_BGR_SUPPORTED) || defined(PNG_WRITE_BGR_SUPPORTED)
/* turn on bgr to rgb mapping */
void
png_set_bgr(png_structp png_ptr)
{
png_debug(1, "in png_set_bgr\n");
png_ptr->transformations |= PNG_BGR;
}
#endif
@ -26,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;
}
@ -36,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;
@ -49,6 +51,7 @@ png_set_packing(png_structp png_ptr)
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;
}
@ -58,46 +61,44 @@ png_set_packswap(png_structp png_ptr)
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;
}
#endif
#if defined(PNG_READ_INTERLACING_SUPPORTED) || defined(PNG_WRITE_INTERLACING_SUPPORTED)
#if defined(PNG_READ_INTERLACING_SUPPORTED) || \
defined(PNG_WRITE_INTERLACING_SUPPORTED)
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;
return 7;
return (7);
}
return 1;
return (1);
}
#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.
* for 48-bit input data, as well as to avoid problems with some compilers
* that don't like bytes as parameters.
*/
void
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 = (png_byte)filler;
if (filler_loc == PNG_FILLER_AFTER)
png_ptr->flags |= PNG_FLAG_FILLER_AFTER;
else
png_ptr->flags &= ~PNG_FLAG_FILLER_AFTER;
/* This should probably go in the "do_filler" routine */
if (png_ptr->color_type == PNG_COLOR_TYPE_RGB && png_ptr->bit_depth == 8)
{
png_ptr->usr_channels = 4;
}
}
#endif
@ -106,34 +107,48 @@ png_set_filler(png_structp png_ptr, png_uint_32 filler, int filler_loc)
void
png_set_swap_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_swap_alpha\n");
png_ptr->transformations |= PNG_SWAP_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_ALPHA_SUPPORTED) || \
defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void
png_set_invert_alpha(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_alpha\n");
png_ptr->transformations |= PNG_INVERT_ALPHA;
}
#endif
#if defined(PNG_READ_INVERT_SUPPORTED) || defined(PNG_WRITE_INVERT_SUPPORTED)
void
png_set_invert_mono(png_structp png_ptr)
{
png_debug(1, "in png_set_invert_mono\n");
png_ptr->transformations |= PNG_INVERT_MONO;
}
/* invert monocrome grayscale data */
/* invert monochrome grayscale data */
void
png_do_invert(png_row_infop row_info, png_bytep row)
{
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL && row_info->bit_depth == 1 &&
#else
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)
row_info->color_type == PNG_COLOR_TYPE_GRAY)
{
png_bytep rp;
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop = row_info->rowbytes;
for (i = 0, rp = row; i < row_info->rowbytes; i++, rp++)
for (i = 0; i < istop; i++)
{
*rp = (png_byte)(~(*rp));
rp++;
}
}
}
@ -144,21 +159,20 @@ png_do_invert(png_row_infop row_info, png_bytep row)
void
png_do_swap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_swap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL && row_info->bit_depth == 16)
#else
if (row_info->bit_depth == 16)
row != NULL && row_info != NULL &&
#endif
row_info->bit_depth == 16)
{
png_bytep rp;
png_byte t;
png_bytep rp = row;
png_uint_32 i;
png_uint_32 istop= row_info->width * row_info->channels;
for (i = 0, rp = row;
i < row_info->width * row_info->channels;
i++, rp += 2)
for (i = 0; i < istop; i++, rp += 2)
{
t = *rp;
png_byte t = *rp;
*rp = *(rp + 1);
*(rp + 1) = t;
}
@ -276,11 +290,12 @@ static png_byte fourbppswaptable[256] = {
void
png_do_packswap(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_packswap\n");
if (
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL && row_info->bit_depth < 8)
#else
if (row_info->bit_depth < 8)
row != NULL && row_info != NULL &&
#endif
row_info->bit_depth < 8)
{
png_bytep rp, end, table;
@ -307,6 +322,7 @@ png_do_packswap(png_row_infop row_info, png_bytep row)
void
png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
{
png_debug(1, "in png_do_strip_filler\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
@ -315,6 +331,11 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
if (row_info->color_type == PNG_COLOR_TYPE_RGB ||
row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
*/
png_bytep sp=row;
png_bytep dp=row;
png_uint_32 row_width=row_info->width;
png_uint_32 i;
if (row_info->channels == 4)
{
if (row_info->bit_depth == 8)
@ -322,10 +343,8 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
/* This converts from RGBX or RGBA to RGB */
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 1, sp = row + 4, dp = row + 3; i < row_info->width; i++)
dp+=3; sp+=4;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
@ -336,10 +355,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
/* This converts from XRGB or ARGB to RGB */
else
{
png_bytep sp, dp;
png_uint_32 i;
for (i = 0, sp = row, dp = row; i < row_info->width; i++)
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
@ -348,17 +364,15 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
}
}
row_info->pixel_depth = 24;
row_info->rowbytes = row_info->width * 3;
row_info->rowbytes = row_width * 3;
}
else /* if (row_info->bit_depth == 16) */
{
if (flags & PNG_FLAG_FILLER_AFTER)
{
png_bytep sp, dp;
png_uint_32 i;
/* This converts from RRGGBBXX or RRGGBBAA to RRGGBB */
for (i = 1, sp = row + 8, dp = row + 6; i < row_info->width; i++)
sp += 8; dp += 6;
for (i = 1; i < row_width; i++)
{
/* This could be (although memcpy is probably slower):
png_memcpy(dp, sp, 6);
@ -376,17 +390,15 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
}
else
{
png_bytep sp, dp;
png_uint_32 i;
/* This converts from XXRRGGBB or AARRGGBB to RRGGBB */
for (i = 0, sp = row + 2, dp = row; i < row_info->width; i++)
for (i = 0; i < row_width; i++)
{
/* This could be (although memcpy is probably slower):
png_memcpy(dp, sp, 6);
sp += 8;
dp += 6;
*/
sp+=2;
*dp++ = *sp++;
*dp++ = *sp++;
*dp++ = *sp++;
@ -396,9 +408,10 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
}
}
row_info->pixel_depth = 48;
row_info->rowbytes = row_info->width * 6;
row_info->rowbytes = row_width * 6;
}
row_info->channels = 3;
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
}
/*
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY ||
@ -411,10 +424,7 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
/* 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++)
for (i = 0; i < row_width; i++)
{
*dp++ = *sp++;
sp++;
@ -423,27 +433,22 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
/* 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++)
for (i = 0; i < row_width; i++)
{
sp++;
*dp++ = *sp++;
}
}
row_info->pixel_depth = 8;
row_info->rowbytes = row_info->width;
row_info->rowbytes = row_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++)
sp += 4; dp += 2;
for (i = 1; i < row_width; i++)
{
*dp++ = *sp++;
*dp++ = *sp++;
@ -452,11 +457,8 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
}
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++)
for (i = 0; i < row_width; i++)
{
sp += 2;
*dp++ = *sp++;
@ -464,9 +466,10 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
}
}
row_info->pixel_depth = 16;
row_info->rowbytes = row_info->width * 2;
row_info->rowbytes = row_width * 2;
}
row_info->channels = 1;
row_info->color_type &= ~PNG_COLOR_MASK_ALPHA;
}
}
}
@ -477,24 +480,24 @@ png_do_strip_filler(png_row_infop row_info, png_bytep row, png_uint_32 flags)
void
png_do_bgr(png_row_infop row_info, png_bytep row)
{
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL &&
#else
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))
{
png_uint_32 row_width = row_info->width;
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)
for (i = 0, rp = row; i < row_width; i++, rp += 3)
{
save = *rp;
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
@ -502,12 +505,11 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
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)
for (i = 0, rp = row; i < row_width; i++, rp += 4)
{
save = *rp;
png_byte save = *rp;
*rp = *(rp + 2);
*(rp + 2) = save;
}
@ -518,36 +520,35 @@ png_do_bgr(png_row_infop row_info, png_bytep row)
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)
for (i = 0, rp = row; i < row_width; i++, rp += 6)
{
save[0] = *rp;
save[1] = *(rp + 1);
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 4) = save[0];
*(rp + 5) = save[1];
*(rp + 5) = save;
}
}
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)
for (i = 0, rp = row; i < row_width; i++, rp += 8)
{
save[0] = *rp;
save[1] = *(rp + 1);
png_byte save = *rp;
*rp = *(rp + 4);
*(rp + 4) = save;
save = *(rp + 1);
*(rp + 1) = *(rp + 5);
*(rp + 4) = save[0];
*(rp + 5) = save[1];
*(rp + 5) = save;
}
}
}
}
}
#endif /* PNG_READ_BGR_SUPPORTED or PNG_WRITE_BGR_SUPPORTED */

View File

@ -1,18 +1,19 @@
/* pngwio.c - functions for data output
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
This file provides a location for all output. Users which need
special handling are expected to write functions which have the same
arguments as these, and perform similar functions, but possibly use
different output methods. Note that you shouldn't change these
functions, but rather write replacement functions and then change
them at run time with png_set_write_fn(...) */
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*
* This file provides a location for all output. Users who need
* special handling are expected to write functions that have the same
* arguments as these and perform similar functions, but that possibly
* use different output methods. Note that you shouldn't change these
* functions, but rather write replacement functions and then change
* them at run time with png_set_write_fn(...).
*/
#define PNG_INTERNAL
#include "png.h"
@ -21,7 +22,7 @@
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. */
to write more than 64K on a 16 bit machine. */
void
png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
@ -32,7 +33,8 @@ png_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
png_error(png_ptr, "Call to NULL write function");
}
/* This is the function which does the actual writing of data. If you are
#if !defined(PNG_NO_STDIO)
/* This is the function that does the actual writing of data. If you are
not writing to a standard C stream, you should create a replacement
write_data function and use it at run time with png_set_write_fn(), rather
than changing the library. */
@ -97,6 +99,7 @@ png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
}
}
#endif
#endif
/* This function is called to output any data pending writing (normally
@ -110,6 +113,7 @@ png_flush(png_structp png_ptr)
(*(png_ptr->output_flush_fn))(png_ptr);
}
#if !defined(PNG_NO_STDIO)
static void
png_default_flush(png_structp png_ptr)
{
@ -119,6 +123,7 @@ png_default_flush(png_structp png_ptr)
fflush(io_ptr);
}
#endif
#endif
/* This function allows the application to supply new output functions for
libpng if standard C streams aren't being used.
@ -127,13 +132,13 @@ png_default_flush(png_structp png_ptr)
png_ptr - pointer to a png output data structure
io_ptr - pointer to user supplied structure containing info about
the output functions. May be NULL.
write_data_fn - pointer to a new output function which takes as its
write_data_fn - pointer to a new output function that takes as its
arguments a pointer to a png_struct, a pointer to
data to be written, and a 32-bit unsigned int which is
data to be written, and a 32-bit unsigned int that is
the number of bytes to be written. The new write
function should call png_error(png_ptr, "Error msg")
to exit and output any fatal error messages.
flush_data_fn - pointer to a new flush function which takes as its
flush_data_fn - pointer to a new flush function that takes as its
arguments a pointer to a png_struct. After a call to
the flush function, there should be no data in any buffers
or pending transmission. If the output method doesn't do
@ -148,25 +153,40 @@ png_set_write_fn(png_structp png_ptr, png_voidp io_ptr,
{
png_ptr->io_ptr = io_ptr;
#if !defined(PNG_NO_STDIO)
if (write_data_fn != NULL)
png_ptr->write_data_fn = write_data_fn;
else
png_ptr->write_data_fn = png_default_write_data;
#else
png_ptr->write_data_fn = write_data_fn;
#endif
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
#if !defined(PNG_NO_STDIO)
if (output_flush_fn != NULL)
png_ptr->output_flush_fn = output_flush_fn;
else
png_ptr->output_flush_fn = png_default_flush;
#else
png_ptr->output_flush_fn = output_flush_fn;
#endif
#endif /* PNG_WRITE_FLUSH_SUPPORTED */
/* It is an error to read while writing a png file */
png_ptr->read_data_fn = NULL;
if (png_ptr->read_data_fn != NULL)
{
png_ptr->read_data_fn = NULL;
png_warning(png_ptr,
"Attempted to set both read_data_fn and write_data_fn in");
png_warning(png_ptr,
"the same structure. Resetting read_data_fn to NULL.");
}
}
#if defined(USE_FAR_KEYWORD)
#if defined(_MSC_VER)
void *far_to_near(png_structp png_ptr,png_voidp ptr, int check)
void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;
@ -178,7 +198,7 @@ void *far_to_near(png_structp png_ptr,png_voidp ptr, int check)
return(near_ptr);
}
# else
void *far_to_near(png_structp png_ptr,png_voidp ptr, int check)
void *png_far_to_near(png_structp png_ptr,png_voidp ptr, int check)
{
void *near_ptr;
void FAR *far_ptr;

View File

@ -1,12 +1,12 @@
/* pngwrite.c - general routines to write a PNG file
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
/* get internal access to png.h */
#define PNG_INTERNAL
@ -15,7 +15,7 @@
/* 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
* after the image data, put it in png_write_end(). I strongly encourage
* 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
@ -24,20 +24,31 @@
void
png_write_info(png_structp png_ptr, png_infop info_ptr)
{
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
int i;
#endif
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,
info_ptr->bit_depth, info_ptr->color_type, info_ptr->compression_type,
info_ptr->filter_type, info_ptr->interlace_type);
info_ptr->filter_type,
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
info_ptr->interlace_type);
#else
0);
#endif
/* the rest of these check to see if the valid field has the appropriate
flag set, and if it does, writes the chunk. */
#if defined(PNG_WRITE_gAMA_SUPPORTED)
if (info_ptr->valid & PNG_INFO_gAMA)
png_write_gAMA(png_ptr, info_ptr->gamma);
#endif
#if defined(PNG_WRITE_sRGB_SUPPORTED)
if (info_ptr->valid & PNG_INFO_sRGB)
png_write_sRGB(png_ptr, (int)info_ptr->srgb_intent);
#endif
#if defined(PNG_WRITE_sBIT_SUPPORTED)
if (info_ptr->valid & PNG_INFO_sBIT)
png_write_sBIT(png_ptr, &(info_ptr->sig_bit), info_ptr->color_type);
@ -55,10 +66,23 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
(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)
if (info_ptr->valid & PNG_INFO_tRNS)
{
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
/* invert the alpha channel (in tRNS) */
if (png_ptr->transformations & PNG_INVERT_ALPHA &&
info_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
{
int j;
for (j=0; j<(int)info_ptr->num_trans; j++)
info_ptr->trans[j] = 255 - info_ptr->trans[j];
}
#endif
png_write_tRNS(png_ptr, info_ptr->trans, &(info_ptr->trans_values),
info_ptr->num_trans, info_ptr->color_type);
}
#endif
#if defined(PNG_WRITE_bKGD_SUPPORTED)
if (info_ptr->valid & PNG_INFO_bKGD)
@ -128,9 +152,10 @@ png_write_info(png_structp png_ptr, png_infop info_ptr)
}
/* 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. */
* 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)
{
@ -141,7 +166,9 @@ png_write_end(png_structp png_ptr, png_infop info_ptr)
/* see if user wants us to write information chunks */
if (info_ptr != NULL)
{
#if defined(PNG_WRITE_tEXt_SUPPORTED) || defined(PNG_WRITE_zTXt_SUPPORTED)
int i; /* local index variable */
#endif
#if defined(PNG_WRITE_tIME_SUPPORTED)
/* check to see if user has supplied a time chunk */
if (info_ptr->valid & PNG_INFO_tIME &&
@ -216,17 +243,34 @@ png_convert_from_time_t(png_timep ptime, time_t ttime)
/* 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_create_write_struct(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn)
{
#ifdef PNG_USER_MEM_SUPPORTED
return (png_create_write_struct_2(user_png_ver, error_ptr, error_fn,
warn_fn, NULL, NULL, NULL));
}
/* Alternate initialize png_ptr structure, and allocate any memory needed */
png_structp
png_create_write_struct_2(png_const_charp user_png_ver, png_voidp error_ptr,
png_error_ptr error_fn, png_error_ptr warn_fn, png_voidp mem_ptr,
png_malloc_ptr malloc_fn, png_free_ptr free_fn)
{
#endif /* PNG_USER_MEM_SUPPORTED */
png_structp png_ptr;
#ifdef USE_FAR_KEYWORD
jmp_buf jmpbuf;
#endif
png_debug(1, "in png_create_write_struct\n");
#ifdef PNG_USER_MEM_SUPPORTED
if ((png_ptr = (png_structp)png_create_struct_2(PNG_STRUCT_PNG,
(png_malloc_ptr)malloc_fn)) == NULL)
#else
if ((png_ptr = (png_structp)png_create_struct(PNG_STRUCT_PNG)) == NULL)
#endif /* PNG_USER_MEM_SUPPORTED */
{
return (png_structp)NULL;
return ((png_structp)NULL);
}
#ifdef USE_FAR_KEYWORD
if (setjmp(jmpbuf))
@ -236,11 +280,14 @@ png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
{
png_free(png_ptr, png_ptr->zbuf);
png_destroy_struct(png_ptr);
return (png_structp)NULL;
return ((png_structp)NULL);
}
#ifdef USE_FAR_KEYWORD
png_memcpy(png_ptr->jmpbuf,jmpbuf,sizeof(jmp_buf));
#endif
#ifdef PNG_USER_MEM_SUPPORTED
png_set_mem_fn(png_ptr, mem_ptr, malloc_fn, free_fn);
#endif /* PNG_USER_MEM_SUPPORTED */
png_set_error_fn(png_ptr, error_ptr, error_fn, warn_fn);
/* Libpng 0.90 and later are binary incompatible with libpng 0.89, so
@ -257,13 +304,18 @@ png_create_write_struct(png_const_charp user_png_ver, voidp error_ptr,
/* initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);
png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
png_set_write_fn(png_ptr, NULL, NULL, NULL);
return (png_ptr);
}
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
png_set_filter_heuristics(png_ptr, PNG_FILTER_HEURISTIC_DEFAULT,
1, NULL, NULL);
#endif
return ((png_structp)png_ptr);
}
/* Initialize png_ptr structure, and allocate any memory needed */
void
@ -283,7 +335,8 @@ png_write_init(png_structp png_ptr)
/* initialize zbuf - compression buffer */
png_ptr->zbuf_size = PNG_ZBUF_SIZE;
png_ptr->zbuf = png_malloc(png_ptr, png_ptr->zbuf_size);
png_ptr->zbuf = (png_bytep)png_malloc(png_ptr,
(png_uint_32)png_ptr->zbuf_size);
png_set_write_fn(png_ptr, NULL, NULL, NULL);
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
@ -292,10 +345,11 @@ png_write_init(png_structp png_ptr)
#endif
}
/* write a few rows of image data. If the image is interlaced,
either you will have to write the 7 sub images, or, if you
have called png_set_interlace_handling(), you will have to
"write" the image seven times */
/* Write a few rows of image data. If the image is interlaced,
* either you will have to write the 7 sub images, or, if you
* have called png_set_interlace_handling(), you will have to
* "write" the image seven times.
*/
void
png_write_rows(png_structp png_ptr, png_bytepp row,
png_uint_32 num_rows)
@ -311,8 +365,9 @@ png_write_rows(png_structp png_ptr, png_bytepp row,
}
}
/* write the image. You only need to call this function once, even
if you are writing an interlaced image. */
/* Write the image. You only need to call this function once, even
* if you are writing an interlaced image.
*/
void
png_write_image(png_structp png_ptr, png_bytepp image)
{
@ -321,9 +376,13 @@ png_write_image(png_structp png_ptr, png_bytepp image)
png_bytepp rp; /* points to current row */
png_debug(1, "in png_write_image\n");
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
/* intialize interlace handling. If image is not interlaced,
this will set pass to 1 */
num_pass = png_set_interlace_handling(png_ptr);
#else
num_pass = 1;
#endif
/* loop through passes */
for (pass = 0; pass < num_pass; pass++)
{
@ -339,10 +398,41 @@ 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");
png_debug2(1, "in png_write_row (row %ld, pass %d)\n",
png_ptr->row_number, png_ptr->pass);
/* initialize transformations and other stuff if first time */
if (png_ptr->row_number == 0 && png_ptr->pass == 0)
{
/* check for transforms that have been set but were defined out */
#if !defined(PNG_WRITE_INVERT_SUPPORTED) && defined(PNG_READ_INVERT_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_MONO)
png_warning(png_ptr, "PNG_WRITE_INVERT_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_FILLER_SUPPORTED) && defined(PNG_READ_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_warning(png_ptr, "PNG_WRITE_FILLER_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_PACKSWAP_SUPPORTED) && defined(PNG_READ_PACKSWAP_SUPPORTED)
if (png_ptr->transformations & PNG_PACKSWAP)
png_warning(png_ptr, "PNG_WRITE_PACKSWAP_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_PACK_SUPPORTED) && defined(PNG_READ_PACK_SUPPORTED)
if (png_ptr->transformations & PNG_PACK)
png_warning(png_ptr, "PNG_WRITE_PACK_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_SHIFT_SUPPORTED) && defined(PNG_READ_SHIFT_SUPPORTED)
if (png_ptr->transformations & PNG_SHIFT)
png_warning(png_ptr, "PNG_WRITE_SHIFT_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_BGR_SUPPORTED) && defined(PNG_READ_BGR_SUPPORTED)
if (png_ptr->transformations & PNG_BGR)
png_warning(png_ptr, "PNG_WRITE_BGR_SUPPORTED is not defined.");
#endif
#if !defined(PNG_WRITE_SWAP_SUPPORTED) && defined(PNG_READ_SWAP_SUPPORTED)
if (png_ptr->transformations & PNG_SWAP_BYTES)
png_warning(png_ptr, "PNG_WRITE_SWAP_SUPPORTED is not defined.");
#endif
png_write_start_row(png_ptr);
}
@ -412,11 +502,20 @@ png_write_row(png_structp png_ptr, png_bytep row)
png_ptr->row_info.bit_depth = png_ptr->usr_bit_depth;
png_ptr->row_info.pixel_depth = (png_byte)(png_ptr->row_info.bit_depth *
png_ptr->row_info.channels);
png_ptr->row_info.rowbytes = ((png_ptr->row_info.width *
(png_uint_32)png_ptr->row_info.pixel_depth + 7) >> 3);
png_debug1(3, "row_info->color_type = %d\n", png_ptr->row_info.color_type);
png_debug1(3, "row_info->width = %d\n", png_ptr->row_info.width);
png_debug1(3, "row_info->channels = %d\n", png_ptr->row_info.channels);
png_debug1(3, "row_info->bit_depth = %d\n", png_ptr->row_info.bit_depth);
png_debug1(3, "row_info->pixel_depth = %d\n", png_ptr->row_info.pixel_depth);
png_debug1(3, "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);
png_memcpy_check(png_ptr, png_ptr->row_buf + 1, row,
png_ptr->row_info.rowbytes);
#if defined(PNG_WRITE_INTERLACING_SUPPORTED)
/* handle interlacing */
@ -440,6 +539,9 @@ png_write_row(png_structp png_ptr, png_bytep row)
/* Find a filter if necessary, filter the row and write it out. */
png_write_find_filter(png_ptr, &(png_ptr->row_info));
if (png_ptr->write_row_fn != NULL)
(*(png_ptr->write_row_fn))(png_ptr, png_ptr->row_number, png_ptr->pass);
}
#if defined(PNG_WRITE_FLUSH_SUPPORTED)
@ -510,24 +612,56 @@ png_destroy_write_struct(png_structpp png_ptr_ptr, png_infopp info_ptr_ptr)
{
png_structp png_ptr = NULL;
png_infop info_ptr = NULL;
#ifdef PNG_USER_MEM_SUPPORTED
png_free_ptr free_fn = NULL;
#endif
png_debug(1, "in png_destroy_write_struct\n");
if (png_ptr_ptr != NULL)
{
png_ptr = *png_ptr_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
free_fn = png_ptr->free_fn;
#endif
}
if (info_ptr_ptr != NULL)
info_ptr = *info_ptr_ptr;
if (info_ptr != NULL)
{
#ifdef PNG_WRITE_tEXt_SUPPORTED
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)
{
int i;
for (i = 0; i < (int)info_ptr->pcal_nparams; i++)
{
png_free(png_ptr, info_ptr->pcal_params[i]);
}
png_free(png_ptr, info_ptr->pcal_params);
}
#endif
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)info_ptr, free_fn);
#else
png_destroy_struct((png_voidp)info_ptr);
#endif
*info_ptr_ptr = (png_infop)NULL;
}
if (png_ptr != NULL)
{
png_write_destroy(png_ptr);
#ifdef PNG_USER_MEM_SUPPORTED
png_destroy_struct_2((png_voidp)png_ptr, free_fn);
#else
png_destroy_struct((png_voidp)png_ptr);
#endif
*png_ptr_ptr = (png_structp)NULL;
}
}
@ -541,6 +675,9 @@ png_write_destroy(png_structp png_ptr)
png_error_ptr error_fn;
png_error_ptr warning_fn;
png_voidp error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
png_free_ptr free_fn;
#endif
png_debug(1, "in png_write_destroy\n");
/* free any memory zlib uses */
@ -554,6 +691,9 @@ 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_TIME_RFC1123_SUPPORTED)
png_free(png_ptr, png_ptr->time_buffer);
#endif /* PNG_TIME_RFC1123_SUPPORTED */
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED)
png_free(png_ptr, png_ptr->prev_filters);
png_free(png_ptr, png_ptr->filter_weights);
@ -568,12 +708,18 @@ png_write_destroy(png_structp png_ptr)
error_fn = png_ptr->error_fn;
warning_fn = png_ptr->warning_fn;
error_ptr = png_ptr->error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
free_fn = png_ptr->free_fn;
#endif
png_memset(png_ptr, 0, sizeof (png_struct));
png_ptr->error_fn = error_fn;
png_ptr->warning_fn = warning_fn;
png_ptr->error_ptr = error_ptr;
#ifdef PNG_USER_MEM_SUPPORTED
png_ptr->free_fn = free_fn;
#endif
png_memcpy(png_ptr->jmpbuf, tmp_jmp, sizeof (jmp_buf));
}
@ -613,7 +759,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
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->rowbytes + 1));
png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
}
@ -627,7 +773,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
else
{
png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
png_ptr->rowbytes + 1);
(png_ptr->rowbytes + 1));
png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
}
}
@ -642,7 +788,7 @@ png_set_filter(png_structp png_ptr, int method, int filters)
else
{
png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
png_ptr->rowbytes + 1);
(png_ptr->rowbytes + 1));
png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
}
}
@ -657,8 +803,8 @@ png_set_filter(png_structp png_ptr, int method, int filters)
}
else
{
png_ptr->paeth_row = (png_bytep )png_malloc(png_ptr,
png_ptr->rowbytes + 1);
png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
(png_ptr->rowbytes + 1));
png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
}
}
@ -676,7 +822,8 @@ png_set_filter(png_structp png_ptr, int method, int filters)
* 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. */
* better compression.
*/
#if defined(PNG_WRITE_WEIGHTED_FILTER_SUPPORTED) /* GRR 970116 */
void
png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
@ -711,7 +858,7 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
if (png_ptr->prev_filters == NULL)
{
png_ptr->prev_filters = (png_bytep)png_malloc(png_ptr,
sizeof(png_byte) * num_weights);
(png_uint_32)(sizeof(png_byte) * num_weights));
/* To make sure that the weighting starts out fairly */
for (i = 0; i < num_weights; i++)
@ -722,11 +869,11 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
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->filter_weights = (png_uint_16p) png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * num_weights));
png_ptr->inv_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,
(png_uint_32)(sizeof(png_uint_16) * num_weights));
for (i = 0; i < num_weights; i++)
{
@ -757,11 +904,11 @@ png_set_filter_heuristics(png_structp png_ptr, int heuristic_method,
*/
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->filter_costs = (png_uint_16p) png_malloc(png_ptr,
(png_uint_32)(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);
png_ptr->inv_filter_costs = (png_uint_16p) png_malloc(png_ptr,
(png_uint_32)(sizeof(png_uint_16) * PNG_FILTER_VALUE_LAST));
for (i = 0; i < PNG_FILTER_VALUE_LAST; i++)
{
@ -837,3 +984,21 @@ png_set_compression_method(png_structp png_ptr, int method)
png_ptr->flags |= PNG_FLAG_ZLIB_CUSTOM_METHOD;
png_ptr->zlib_method = method;
}
void
png_set_write_status_fn(png_structp png_ptr, png_write_status_ptr write_row_fn)
{
png_ptr->write_row_fn = write_row_fn;
}
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
void
png_set_write_user_transform_fn(png_structp png_ptr, png_user_transform_ptr
write_user_transform_fn)
{
png_debug(1, "in png_set_write_user_transform_fn\n");
png_ptr->transformations |= PNG_USER_TRANSFORM;
png_ptr->write_user_transform_fn = write_user_transform_fn;
}
#endif

View File

@ -1,27 +1,47 @@
/* pngwtran.c - transforms the data in a row for PNG writers
libpng 1.0 beta 5 - version 0.95
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
March 30, 1997
*/
*
* libpng 1.0.2 - June 14, 1998
* 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
* Copyright (c) 1998, Glenn Randers-Pehrson
*/
#define PNG_INTERNAL
#include "png.h"
/* transform the data according to the users wishes. The order of
transformations is significant. */
/* Transform the data according to the user's wishes. The order of
* transformations is significant.
*/
void
png_do_write_transformations(png_structp png_ptr)
{
png_debug(1, "in png_do_write_transformations\n");
#if defined(PNG_WRITE_USER_TRANSFORM_SUPPORTED)
if (png_ptr->transformations & PNG_USER_TRANSFORM)
if(png_ptr->write_user_transform_fn != NULL)
(*(png_ptr->write_user_transform_fn)) /* user write transform function */
(png_ptr, /* png_ptr */
&(png_ptr->row_info), /* row_info: */
/* png_uint_32 width; width of row */
/* png_uint_32 rowbytes; number of bytes in row */
/* png_byte color_type; color type of pixels */
/* png_byte bit_depth; bit depth of samples */
/* png_byte channels; number of channels (1-4) */
/* png_byte pixel_depth; bits per pixel (depth*channels) */
png_ptr->row_buf + 1); /* start of pixel data for row */
#endif
#if defined(PNG_WRITE_FILLER_SUPPORTED)
if (png_ptr->transformations & PNG_FILLER)
png_do_strip_filler(&(png_ptr->row_info), png_ptr->row_buf + 1,
png_ptr->flags);
#endif
#if defined(PNG_WRITE_PACKSWAP_SUPPORTED)
if (png_ptr->transformations & PNG_PACKSWAP)
png_do_packswap(&(png_ptr->row_info), png_ptr->row_buf + 1);
#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,
@ -36,6 +56,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_INVERT_ALPHA_SUPPORTED)
if (png_ptr->transformations & PNG_INVERT_ALPHA)
png_do_write_invert_alpha(&(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);
@ -51,17 +75,17 @@ png_do_write_transformations(png_structp png_ptr)
}
#if defined(PNG_WRITE_PACK_SUPPORTED)
/* pack pixels into bytes. Pass the true bit depth in bit_depth. The
row_info bit depth should be 8 (one pixel per byte). The channels
should be 1 (this only happens on grayscale and paletted images) */
/* Pack pixels into bytes. Pass the true bit depth in bit_depth. The
* 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_uint_32 bit_depth)
{
png_debug(1, "in png_do_pack\n");
if (row_info->bit_depth == 8 &&
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL && row_info->bit_depth < 8 &&
#else
if (row_info->bit_depth < 8 &&
row != NULL && row_info != NULL &&
#endif
row_info->channels == 1)
{
@ -72,12 +96,14 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
png_bytep sp, dp;
int mask, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
mask = 0x80;
v = 0;
for (i = 0; i < row_info->width; i++)
for (i = 0; i < row_width; i++)
{
if (*sp != 0)
v |= mask;
@ -101,14 +127,15 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 6;
v = 0;
for (i = 0; i < row_info->width; i++)
for (i = 0; i < row_width; i++)
{
png_byte value;
png_byte value;
value = (png_byte)(*sp & 0x3);
v |= (value << shift);
@ -132,12 +159,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
png_bytep sp, dp;
int shift, v;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
sp = row;
dp = row;
shift = 4;
v = 0;
for (i = 0; i < row_info->width; i++)
for (i = 0; i < row_width; i++)
{
png_byte value;
@ -170,12 +198,13 @@ png_do_pack(png_row_infop row_info, png_bytep row, png_uint_32 bit_depth)
#endif
#if defined(PNG_WRITE_SHIFT_SUPPORTED)
/* shift pixel values to take advantage of whole range. Pass the
true number of bits in bit_depth. The row should be packed
according to row_info->bit_depth. Thus, if you had a row of
bit depth 4, but the pixels only had values from 0 to 7, you
would pass 3 as bit_depth, and this routine would translate the
data to 0 to 15. */
/* Shift pixel values to take advantage of whole range. Pass the
* true number of bits in bit_depth. The row should be packed
* according to row_info->bit_depth. Thus, if you had a row of
* bit depth 4, but the pixels only had values from 0 to 7, you
* would pass 3 as bit_depth, and this routine would translate the
* data to 0 to 15.
*/
void
png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
@ -188,9 +217,8 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
row_info->color_type != PNG_COLOR_TYPE_PALETTE)
{
int shift_start[4], shift_dec[4];
png_uint_32 channels;
int channels = 0;
channels = 0;
if (row_info->color_type & PNG_COLOR_MASK_COLOR)
{
shift_start[channels] = row_info->bit_depth - bit_depth->red;
@ -216,12 +244,13 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
channels++;
}
/* with low row dephts, could only be grayscale, so one channel */
/* with low row depths, could only be grayscale, so one channel */
if (row_info->bit_depth < 8)
{
png_bytep bp;
png_bytep bp = row;
png_uint_32 i;
png_byte mask;
png_uint_32 row_bytes = row_info->rowbytes;
if (bit_depth->gray == 1 && row_info->bit_depth == 2)
mask = 0x55;
@ -230,9 +259,9 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
else
mask = 0xff;
for (bp = row, i = 0; i < row_info->rowbytes; i++, bp++)
for (i = 0; i < row_bytes; i++, bp++)
{
png_uint_16 v;
png_uint_16 v;
int j;
v = *bp;
@ -248,27 +277,25 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
}
else if (row_info->bit_depth == 8)
{
png_bytep bp;
png_bytep bp = row;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (bp = row, i = 0; i < row_info->width; i++)
for (i = 0; i < istop; i++, bp++)
{
int c;
for (c = 0; c < channels; c++, bp++)
png_uint_16 v;
int j;
int c = (int)(i%channels);
v = *bp;
*bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
png_uint_16 v;
int j;
v = *bp;
*bp = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & 0xff);
}
if (j > 0)
*bp |= (png_byte)((v << j) & 0xff);
else
*bp |= (png_byte)((v >> (-j)) & 0xff);
}
}
}
@ -276,28 +303,25 @@ png_do_shift(png_row_infop row_info, png_bytep row, png_color_8p bit_depth)
{
png_bytep bp;
png_uint_32 i;
png_uint_32 istop = channels * row_info->width;
for (bp = row, i = 0; i < row_info->width * row_info->channels; i++)
for (bp = row, i = 0; i < istop; i++)
{
int c;
int c = (int)(i%channels);
png_uint_16 value, v;
int j;
for (c = 0; c < channels; c++, bp += 2)
v = ((png_uint_16)(*bp) << 8) + *(bp + 1);
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
png_uint_16 value, v;
int j;
v = ((png_uint_16)(*bp) << 8) + (png_uint_16)(*(bp + 1));
value = 0;
for (j = shift_start[c]; j > -shift_dec[c]; j -= shift_dec[c])
{
if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
}
*bp = (png_byte)(value >> 8);
*(bp + 1) = (png_byte)(value & 0xff);
if (j > 0)
value |= (png_uint_16)((v << j) & (png_uint_16)0xffff);
else
value |= (png_uint_16)((v >> (-j)) & (png_uint_16)0xffff);
}
*bp++ = (png_byte)(value >> 8);
*bp++ = (png_byte)(value & 0xff);
}
}
}
@ -319,12 +343,11 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
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++)
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
save = *(sp++);
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
@ -335,11 +358,12 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
else
{
png_bytep sp, dp;
png_byte save[2];
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_info->width; i++)
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
@ -359,12 +383,12 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_byte save;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_info->width; i++)
for (i = 0, sp = dp = row; i < row_width; i++)
{
save = *(sp++);
png_byte save = *(sp++);
*(dp++) = *(sp++);
*(dp++) = save;
}
@ -373,11 +397,12 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
else
{
png_bytep sp, dp;
png_byte save[2];
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_info->width; i++)
for (i = 0, sp = dp = row; i < row_width; i++)
{
png_byte save[2];
save[0] = *(sp++);
save[1] = *(sp++);
*(dp++) = *(sp++);
@ -391,3 +416,82 @@ png_do_write_swap_alpha(png_row_infop row_info, png_bytep row)
}
#endif
#if defined(PNG_WRITE_INVERT_ALPHA_SUPPORTED)
void
png_do_write_invert_alpha(png_row_infop row_info, png_bytep row)
{
png_debug(1, "in png_do_write_invert_alpha\n");
#if defined(PNG_USELESS_TESTS_SUPPORTED)
if (row != NULL && row_info != NULL)
#endif
{
if (row_info->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
{
/* This inverts the alpha channel in RGBA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = 255 - *(sp++);
}
}
/* This inverts the alpha channel in RRGGBBAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = 255 - *(sp++);
*(dp++) = 255 - *(sp++);
}
}
}
else if (row_info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
{
/* This inverts the alpha channel in GA */
if (row_info->bit_depth == 8)
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = 255 - *(sp++);
}
}
/* This inverts the alpha channel in GGAA */
else
{
png_bytep sp, dp;
png_uint_32 i;
png_uint_32 row_width = row_info->width;
for (i = 0, sp = dp = row; i < row_width; i++)
{
*(dp++) = *(sp++);
*(dp++) = *(sp++);
*(dp++) = 255 - *(sp++);
*(dp++) = 255 - *(sp++);
}
}
}
}
}
#endif

File diff suppressed because it is too large Load Diff