[libpng16] Deflate/inflate was reworked to move common zlib calls into single

functions [rw]util.c.  A new shared keyword check routine was also added
and the 'zbuf' is no longer allocated on progressive read.  It is now
possible to call png_inflate() incrementally.
This commit is contained in:
John Bowler 2012-03-09 09:15:18 -06:00 committed by Glenn Randers-Pehrson
parent 6038b80277
commit b5d0051dcb
15 changed files with 1579 additions and 1475 deletions

View File

@ -1,5 +1,5 @@
Libpng 1.6.0beta17 - March 8, 2012
Libpng 1.6.0beta17 - March 9, 2012
This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version.
@ -286,9 +286,13 @@ Version 1.6.0beta16 [March 6, 2012]
If the call to deflateInit2() is wrong a png_warning will be issued
(in fact this is harmless, but the PNG data produced may be sub-optimal).
Version 1.6.0beta17 [March 8, 2012]
Version 1.6.0beta17 [March 9, 2012]
Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
Reject iCCP chunk after the first, even if the first one is invalid.
Reject all iCCP chunks after the first, even if the first one is invalid.
Deflate/inflate was reworked to move common zlib calls into single
functions [rw]util.c. A new shared keyword check routine was also added
and the 'zbuf' is no longer allocated on progressive read. It is now
possible to call png_inflate() incrementally.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

View File

@ -4037,9 +4037,13 @@ Version 1.6.0beta16 [March 6, 2012]
If the call to deflateInit2() is wrong a png_warning will be issued
(in fact this is harmless, but the PNG data produced may be sub-optimal).
Version 1.6.0beta17 [March 8, 2012]
Version 1.6.0beta17 [March 9, 2012]
Fixed PNG_LIBPNG_BUILD_BASE_TYPE definition.
Reject iCCP chunk after the first, even if the first one is invalid.
Reject all iCCP chunks after the first, even if the first one is invalid.
Deflate/inflate was reworked to move common zlib calls into single
functions [rw]util.c. A new shared keyword check routine was also added
and the 'zbuf' is no longer allocated on progressive read. It is now
possible to call png_inflate() incrementally.
Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit

132
png.c
View File

@ -283,41 +283,29 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
*/
if (png_user_version_check(&create_struct, user_png_ver))
{
/* TODO: delay initializing the zlib structure until it really is
* needed.
*/
/* Initialize zbuf - compression/decompression buffer */
create_struct.zbuf_size = PNG_ZBUF_SIZE;
create_struct.zbuf = png_voidcast(png_bytep,
png_malloc_warn(&create_struct, create_struct.zbuf_size));
png_structrp png_ptr = png_voidcast(png_structrp,
png_malloc_warn(&create_struct, sizeof *png_ptr));
/* Finally allocate the png_struct itself. */
if (create_struct.zbuf != NULL)
if (png_ptr != NULL)
{
png_structrp png_ptr = png_voidcast(png_structrp,
png_malloc_warn(&create_struct, sizeof *png_ptr));
/* png_ptr->zstream holds a back-pointer to the png_struct, so
* this can only be done now:
*/
create_struct.zstream.zalloc = png_zalloc;
create_struct.zstream.zfree = png_zfree;
create_struct.zstream.opaque = png_ptr;
if (png_ptr != NULL)
{
# ifdef PNG_SETJMP_SUPPORTED
/* Eliminate the local error handling: */
create_struct.jmp_buf_ptr = NULL;
create_struct.jmp_buf_size = 0;
create_struct.longjmp_fn = 0;
# endif
# ifdef PNG_SETJMP_SUPPORTED
/* Eliminate the local error handling: */
create_struct.jmp_buf_ptr = NULL;
create_struct.jmp_buf_size = 0;
create_struct.longjmp_fn = 0;
# endif
*png_ptr = create_struct;
*png_ptr = create_struct;
/* png_ptr->zstream holds a back-pointer to the png_struct, so
* this can only be done now:
*/
png_ptr->zstream.zalloc = png_zalloc;
png_ptr->zstream.zfree = png_zfree;
png_ptr->zstream.opaque = png_ptr;
/* This is the successful return point */
return png_ptr;
}
/* This is the successful return point */
return png_ptr;
}
}
}
@ -325,15 +313,6 @@ png_create_png_struct,(png_const_charp user_png_ver, png_voidp error_ptr,
/* A longjmp because of a bug in the application storage allocator or a
* simple failure to allocate the png_struct.
*/
if (create_struct.zbuf != NULL)
{
png_bytep zbuf = create_struct.zbuf;
/* Ensure we don't keep on returning to this point: */
create_struct.zbuf = NULL;
png_free(&create_struct, zbuf);
}
return NULL;
}
@ -768,13 +747,13 @@ png_get_copyright(png_const_structrp png_ptr)
#else
# ifdef __STDC__
return PNG_STRING_NEWLINE \
"libpng version 1.6.0beta17 - March 6, 2012" PNG_STRING_NEWLINE \
"libpng version 1.6.0beta17 - March 9, 2012" PNG_STRING_NEWLINE \
"Copyright (c) 1998-2012 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
"Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
"Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
PNG_STRING_NEWLINE;
# else
return "libpng version 1.6.0beta17 - March 6, 2012\
return "libpng version 1.6.0beta17 - March 9, 2012\
Copyright (c) 1998-2012 Glenn Randers-Pehrson\
Copyright (c) 1996-1997 Andreas Dilger\
Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
@ -867,6 +846,7 @@ png_reset_zstream(png_structrp png_ptr)
if (png_ptr == NULL)
return Z_STREAM_ERROR;
/* WARNING: this resets the window bits to the maximum! */
return (inflateReset(&png_ptr->zstream));
}
#endif /* PNG_READ_SUPPORTED */
@ -882,6 +862,76 @@ png_access_version_number(void)
#if defined(PNG_READ_SUPPORTED) || defined(PNG_WRITE_SUPPORTED)
/* Ensure that png_ptr->zstream.msg holds some appropriate error message string.
* If it doesn't 'ret' is used to set it to something appropriate, even in cases
* like Z_OK or Z_STREAM_END where the error code is apparently a success code.
*/
void /* PRIVATE */
png_zstream_error(png_structrp png_ptr, int ret)
{
/* Translate 'ret' into an appropriate error string, priority is given to the
* one in zstream if set. This always returns a string, even in cases like
* Z_OK or Z_STREAM_END where the error code is a success code.
*/
if (png_ptr->zstream.msg == NULL) switch (ret)
{
default:
case Z_OK:
png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return code");
break;
case Z_STREAM_END:
/* Normal exit */
png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected end of LZ stream");
break;
case Z_NEED_DICT:
/* This means the deflate stream did not have a dictionary; this
* indicates a bogus PNG.
*/
png_ptr->zstream.msg = PNGZ_MSG_CAST("missing LZ dictionary");
break;
case Z_ERRNO:
/* gz APIs only: should not happen */
png_ptr->zstream.msg = PNGZ_MSG_CAST("zlib IO error");
break;
case Z_STREAM_ERROR:
/* internal libpng error */
png_ptr->zstream.msg = PNGZ_MSG_CAST("bad parameters to zlib");
break;
case Z_DATA_ERROR:
png_ptr->zstream.msg = PNGZ_MSG_CAST("damaged LZ stream");
break;
case Z_MEM_ERROR:
png_ptr->zstream.msg = PNGZ_MSG_CAST("insufficient memory");
break;
case Z_BUF_ERROR:
/* End of input or output; not a problem if the caller is doing
* incremental read or write.
*/
png_ptr->zstream.msg = PNGZ_MSG_CAST("truncated");
break;
case Z_VERSION_ERROR:
png_ptr->zstream.msg = PNGZ_MSG_CAST("unsupported zlib version");
break;
case PNG_UNEXPECTED_ZLIB_RETURN:
/* Compile errors here mean that zlib now uses the value co-opted in
* pngpriv.h for PNG_UNEXPECTED_ZLIB_RETURN; update the switch above
* and change pngpriv.h. Note that this message is "... return",
* whereas the default/Z_OK one is "... return code".
*/
png_ptr->zstream.msg = PNGZ_MSG_CAST("unexpected zlib return");
break;
}
}
/* png_convert_size: a PNGAPI but no longer in png.h, so deleted
* at libpng 1.5.5!
*/

12
png.h
View File

@ -1,7 +1,7 @@
/* png.h - header file for PNG reference library
*
* libpng version 1.6.0beta17 - March 6, 2012
* libpng version 1.6.0beta17 - March 9, 2012
* Copyright (c) 1998-2012 Glenn Randers-Pehrson
* (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
* (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
@ -11,7 +11,7 @@
* Authors and maintainers:
* libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
* libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
* libpng versions 0.97, January 1998, through 1.6.0beta17 - March 6, 2012: Glenn
* libpng versions 0.97, January 1998, through 1.6.0beta17 - March 9, 2012: Glenn
* See also "Contributing Authors", below.
*
* Note about libpng version numbers:
@ -198,7 +198,7 @@
*
* This code is released under the libpng license.
*
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta17, March 6, 2012, are
* libpng versions 1.2.6, August 15, 2004, through 1.6.0beta17, March 9, 2012, are
* Copyright (c) 2004, 2006-2012 Glenn Randers-Pehrson, and are
* distributed according to the same disclaimer and license as libpng-1.2.5
* with the following individual added to the list of Contributing Authors:
@ -310,7 +310,7 @@
* Y2K compliance in libpng:
* =========================
*
* March 6, 2012
* March 9, 2012
*
* Since the PNG Development group is an ad-hoc body, we can't make
* an official declaration.
@ -376,7 +376,7 @@
/* Version information for png.h - this should match the version in png.c */
#define PNG_LIBPNG_VER_STRING "1.6.0beta17"
#define PNG_HEADER_VERSION_STRING \
" libpng version 1.6.0beta17 - March 6, 2012\n"
" libpng version 1.6.0beta17 - March 9, 2012\n"
#define PNG_LIBPNG_VER_SONUM 16
#define PNG_LIBPNG_VER_DLLNUM 16
@ -1047,7 +1047,7 @@ PNG_EXPORTA(9, void, png_longjmp, (png_const_structrp png_ptr, int val),
#ifdef PNG_READ_SUPPORTED
/* Reset the compression stream */
PNG_EXPORT(10, int, png_reset_zstream, (png_structrp png_ptr));
PNG_EXPORTA(10, int, png_reset_zstream, (png_structrp png_ptr), PNG_DEPRECATED);
#endif
/* New functions added in libpng-1.0.2 (not enabled by default until 1.2.0) */

View File

@ -1070,7 +1070,24 @@ png_get_user_chunk_ptr(png_const_structrp png_ptr)
png_size_t PNGAPI
png_get_compression_buffer_size(png_const_structrp png_ptr)
{
return (png_ptr ? png_ptr->zbuf_size : 0);
if (png_ptr == NULL)
return 0;
# ifdef PNG_WRITE_SUPPORTED
if (png_ptr->mode & PNG_IS_READ_STRUCT)
# endif
{
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
return png_ptr->IDAT_read_size;
# else
return PNG_IDAT_READ_SIZE;
# endif
}
# ifdef PNG_WRITE_SUPPORTED
else
return png_ptr->zbuffer_size;
# endif
}
#ifdef PNG_SET_USER_LIMITS_SUPPORTED

View File

@ -838,7 +838,7 @@ png_push_read_IDAT(png_structrp png_ptr)
png_crc_finish(png_ptr, 0);
png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
png_ptr->mode |= PNG_AFTER_IDAT;
png_ptr->flags &= ~PNG_FLAG_ZSTREAM_IN_USE;
png_ptr->zowner = 0;
}
}
@ -894,7 +894,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
{
/* Terminate the decompression. */
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
png_ptr->flags &= ~PNG_FLAG_ZSTREAM_IN_USE;
png_ptr->zowner = 0;
/* This may be a truncated stream (missing or
* damaged end code). Treat that as a warning.
@ -923,7 +923,7 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
/* Extra data. */
png_warning(png_ptr, "Extra compressed data in IDAT");
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
png_ptr->flags &= ~PNG_FLAG_ZSTREAM_IN_USE;
png_ptr->zowner = 0;
/* Do no more processing; skip the unprocessed
* input check below.

View File

@ -467,6 +467,7 @@ typedef const png_uint_16p * png_const_uint_16pp;
#define PNG_HAVE_PNG_SIGNATURE 0x1000
#define PNG_HAVE_CHUNK_AFTER_IDAT 0x2000 /* Have another chunk after IDAT */
#define PNG_HAVE_iCCP 0x4000
#define PNG_IS_READ_STRUCT 0x8000 /* Else is a write struct */
/* Flags for the transformations the PNG library does on the image data */
#define PNG_BGR 0x0001
@ -512,9 +513,9 @@ typedef const png_uint_16p * png_const_uint_16pp;
/* Flags for the png_ptr->flags rather than declaring a byte for each one */
#define PNG_FLAG_ZLIB_CUSTOM_STRATEGY 0x0001
#define PNG_FLAG_ZSTREAM_INITIALIZED 0x0002 /* Added to libpng-1.6.0 */
#define PNG_FLAG_ZSTREAM_IN_USE 0x0004 /* Added to libpng-1.6.0 */
/* 0x0004 unused */
#define PNG_FLAG_ZSTREAM_ENDED 0x0008 /* Added to libpng-1.6.0 */
#define PNG_FLAG_ZSTREAM_CMF_FIXUP 0x0010 /* Added to libpng-1.6.0 */
/* 0x0010 unused */
/* 0x0020 unused */
#define PNG_FLAG_ROW_INIT 0x0040
#define PNG_FLAG_FILLER_AFTER 0x0080
@ -551,18 +552,6 @@ typedef const png_uint_16p * png_const_uint_16pp;
#define PNG_FLAG_CRC_MASK (PNG_FLAG_CRC_ANCILLARY_MASK | \
PNG_FLAG_CRC_CRITICAL_MASK)
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
* can handle at once. This type need be no larger than 16 bits (so maximum of
* 65535), this define allows us to discover how big it is, but limited by the
* maximuum for png_size_t. The value can be overriden in a library build
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
* lower value (e.g. 255 works). A lower value may help memory usage (slightly)
* and may even improve performance on some systems (and degrade it on others.)
*/
#ifndef ZLIB_IO_MAX
# define ZLIB_IO_MAX ((uInt)-1)
#endif
/* Save typing and make code easier to understand */
#define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
@ -736,7 +725,18 @@ extern "C" {
*/
/* Zlib support */
PNG_INTERNAL_FUNCTION(void,png_inflate_claim,(png_structrp png_ptr),PNG_EMPTY);
#define PNG_UNEXPECTED_ZLIB_RETURN (-7)
PNG_INTERNAL_FUNCTION(void, png_zstream_error,(png_structrp png_ptr, int ret),
PNG_EMPTY);
/* Used by the zlib handling functions to ensure that z_stream::msg is always
* set before they return.
*/
#ifdef PNG_WRITE_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_free_buffer_list,(png_structrp png_ptr,
png_compression_bufferp *list),PNG_EMPTY);
/* Free the buffer list used by the compressed write code. */
#endif
#if defined PNG_FLOATING_POINT_SUPPORTED &&\
!defined PNG_FIXED_POINT_MACRO_SUPPORTED
@ -851,15 +851,16 @@ PNG_INTERNAL_FUNCTION(void,png_flush,(png_structrp png_ptr),PNG_EMPTY);
/* Write the IHDR chunk, and update the png_struct with the necessary
* information.
*/
PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr, png_uint_32 width,
png_uint_32 height, int bit_depth, int color_type, int compression_method,
int filter_method, int interlace_method),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_write_IHDR,(png_structrp png_ptr,
png_uint_32 width, png_uint_32 height, int bit_depth, int color_type,
int compression_method, int filter_method, int interlace_method),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_write_PLTE,(png_structrp png_ptr,
png_const_colorp palette, png_uint_32 num_pal),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_write_IDAT,(png_structrp png_ptr, png_bytep data,
png_size_t length),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_compress_IDAT,(png_structrp png_ptr,
png_const_bytep row_data, png_alloc_size_t row_data_length, int flush),
PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_write_IEND,(png_structrp png_ptr),PNG_EMPTY);
@ -921,15 +922,9 @@ PNG_INTERNAL_FUNCTION(void,png_write_hIST,(png_structrp png_ptr,
#endif
/* Chunks that have keywords */
#if defined(PNG_WRITE_TEXT_SUPPORTED) || defined(PNG_WRITE_pCAL_SUPPORTED) || \
defined(PNG_WRITE_iCCP_SUPPORTED) || defined(PNG_WRITE_sPLT_SUPPORTED)
PNG_INTERNAL_FUNCTION(png_size_t,png_check_keyword,(png_structrp png_ptr,
png_const_charp key, png_charpp new_key),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_tEXt_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr, png_const_charp key,
png_const_charp text, png_size_t text_len),PNG_EMPTY);
PNG_INTERNAL_FUNCTION(void,png_write_tEXt,(png_structrp png_ptr,
png_const_charp key, png_const_charp text, png_size_t text_len),PNG_EMPTY);
#endif
#ifdef PNG_WRITE_zTXt_SUPPORTED
@ -1054,8 +1049,24 @@ PNG_INTERNAL_FUNCTION(void,png_read_filter_row_paeth4_neon,(png_row_infop row_in
PNG_INTERNAL_FUNCTION(void,png_write_find_filter,(png_structrp png_ptr,
png_row_infop row_info),PNG_EMPTY);
/* Finish a row while reading, dealing with interlacing passes, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),PNG_EMPTY);
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
PNG_INTERNAL_FUNCTION(void,png_read_IDAT_data,(png_structrp png_ptr,
png_bytep output, png_alloc_size_t avail_out),PNG_EMPTY);
/* Read 'avail_out' bytes of data from the IDAT stream. If the output buffer
* is NULL the function checks, instead, for the end of the stream. In this
* case a benign error will be issued if the stream end is not found or if
* extra data has to be consumed.
*/
PNG_INTERNAL_FUNCTION(void,png_read_finish_IDAT,(png_structrp png_ptr),
PNG_EMPTY);
/* This cleans up when the IDAT LZ stream does not end when the last image
* byte is read; there is still some pending input.
*/
PNG_INTERNAL_FUNCTION(void,png_read_finish_row,(png_structrp png_ptr),
PNG_EMPTY);
/* Finish a row while reading, dealing with interlacing passes, etc. */
#endif
/* Initialize the row buffers, etc. */
PNG_INTERNAL_FUNCTION(void,png_read_start_row,(png_structrp png_ptr),PNG_EMPTY);

View File

@ -48,6 +48,14 @@ png_create_read_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
if (png_ptr != NULL)
{
png_ptr->mode = PNG_IS_READ_STRUCT;
/* Adding in libpng-1.6.0; this can be used to detect a read structure if
* required (it will be zero in a write structure.)
*/
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
png_ptr->IDAT_read_size = PNG_IDAT_READ_SIZE;
# endif
/* TODO: delay this, it can be done in png_init_io (if the app doesn't
* do it itself) avoiding setting the default function if it is not
* required.
@ -268,8 +276,6 @@ png_start_read_image(png_structrp png_ptr)
void PNGAPI
png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
{
int ret;
png_row_info row_info;
if (png_ptr == NULL)
@ -423,56 +429,8 @@ png_read_row(png_structrp png_ptr, png_bytep row, png_bytep dsp_row)
if (!(png_ptr->mode & PNG_HAVE_IDAT))
png_error(png_ptr, "Invalid attempt to read row data");
png_ptr->zstream.next_out = png_ptr->row_buf;
/* TODO: WARNING: BAD NEWS ALERT: this fails, terminally, if the row width is
* bigger than a uInt.
*/
png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth,
png_ptr->iwidth) + 1);
do
{
if (!(png_ptr->zstream.avail_in))
{
while (png_ptr->idat_size == 0)
{
png_crc_finish(png_ptr, 0);
png_ptr->idat_size = png_read_chunk_header(png_ptr);
if (png_ptr->chunk_name != png_IDAT)
png_error(png_ptr, "Not enough image data");
}
png_ptr->zstream.avail_in = png_ptr->zbuf_size;
png_ptr->zstream.next_in = png_ptr->zbuf;
if (png_ptr->zbuf_size > png_ptr->idat_size)
png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
png_ptr->idat_size -= png_ptr->zstream.avail_in;
}
/* Use NO_FLUSH, not SYNC_FLUSH, here because we keep reading data until
* we have a row to process (so leave it to zlib to decide when to flush
* the output.)
*/
ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
if (ret == Z_STREAM_END)
{
if (png_ptr->zstream.avail_out || png_ptr->zstream.avail_in ||
png_ptr->idat_size)
png_benign_error(png_ptr, "Extra compressed data");
png_ptr->mode |= PNG_AFTER_IDAT;
/* Release the stream */
png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
png_ptr->flags &= ~PNG_FLAG_ZSTREAM_IN_USE;
break;
}
if (ret != Z_OK)
png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
"Decompression error");
} while (png_ptr->zstream.avail_out);
/* Fill the row with IDAT data: */
png_read_IDAT_data(png_ptr, png_ptr->row_buf, row_info.rowbytes + 1);
if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE)
{
@ -702,7 +660,10 @@ png_read_end(png_structrp png_ptr, png_inforp info_ptr)
if (png_ptr == NULL)
return;
png_crc_finish(png_ptr, 0); /* Finish off CRC from last IDAT chunk */
/* If png_read_end is called in the middle of reading the rows there may
* still be pending IDAT data and an owned zstream. Deal with this here.
*/
png_read_finish_IDAT(png_ptr);
#ifdef PNG_READ_CHECK_FOR_INVALID_INDEX_SUPPORTED
/* Report invalid palette index; added at libng-1.5.10 */
@ -851,10 +812,9 @@ png_read_destroy(png_structrp png_ptr)
png_destroy_gamma_table(png_ptr);
#endif
png_free(png_ptr, png_ptr->zbuf);
png_free(png_ptr, png_ptr->big_row_buf);
png_free(png_ptr, png_ptr->big_prev_row);
png_free(png_ptr, png_ptr->chunkdata);
png_free(png_ptr, png_ptr->read_buffer);
#ifdef PNG_READ_QUANTIZE_SUPPORTED
png_free(png_ptr, png_ptr->palette_lookup);

1121
pngrutil.c

File diff suppressed because it is too large Load Diff

View File

@ -1231,26 +1231,51 @@ png_set_compression_buffer_size(png_structrp png_ptr, png_size_t size)
if (png_ptr == NULL)
return;
png_free(png_ptr, png_ptr->zbuf);
if (size == 0 || size > PNG_UINT_31_MAX)
png_error(png_ptr, "invalid compression buffer size");
if (size > ZLIB_IO_MAX)
{
png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
png_ptr->zbuf_size = ZLIB_IO_MAX;
size = ZLIB_IO_MAX; /* must fit */
}
# ifdef PNG_SEQUENTIAL_READ_SUPPORTED
if (png_ptr->mode & PNG_IS_READ_STRUCT)
{
png_ptr->IDAT_read_size = (png_uint_32)size; /* checked above */
return;
}
# endif
else
png_ptr->zbuf_size = (uInt)size;
png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
/* The following ensures a relatively safe failure if this gets called while
* the buffer is actually in use.
*/
png_ptr->zstream.next_out = png_ptr->zbuf;
png_ptr->zstream.avail_out = 0;
png_ptr->zstream.avail_in = 0;
# ifdef PNG_WRITE_SUPPORTED
if (!(png_ptr->mode & PNG_IS_READ_STRUCT))
{
if (png_ptr->zowner != 0)
{
png_warning(png_ptr,
"Compression buffer size cannot be changed because it is in use");
return;
}
if (size > ZLIB_IO_MAX)
{
png_warning(png_ptr,
"Compression buffer size limited to system maximum");
size = ZLIB_IO_MAX; /* must fit */
}
else if (size < 6)
{
/* Deflate will potentially go into an infinite loop on a SYNC_FLUSH
* if this is permitted.
*/
png_warning(png_ptr,
"Compression buffer size cannot be reduced below 6");
return;
}
if (png_ptr->zbuffer_size != size)
{
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_ptr->zbuffer_size = (uInt)size;
}
}
# endif
}
void PNGAPI

View File

@ -24,7 +24,50 @@
* in this structure and is required for decompressing the LZ compressed
* data in PNG files.
*/
#ifndef ZLIB_CONST
/* We must ensure that zlib uses 'const' in declarations. */
# define ZLIB_CONST
#endif
#include "zlib.h"
#ifdef const
/* zlib.h sometimes #defines const to nothing, undo this. */
# undef const
#endif
/* zlib.h has mediocre z_const use before 1.2.6, this stuff is for compatibility
* with older builds.
*/
#if ZLIB_VERNUM < 0x1260
# define PNGZ_MSG_CAST(s) png_constcast(char*,s)
# define PNGZ_INPUT_CAST(b) png_constcast(png_bytep,b)
#else
# define PNGZ_MSG_CAST(s) (s)
# define PNGZ_INPUT_CAST(b) (b)
#endif
/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
* can handle at once. This type need be no larger than 16 bits (so maximum of
* 65535), this define allows us to discover how big it is, but limited by the
* maximuum for png_size_t. The value can be overriden in a library build
* (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
* lower value (e.g. 255 works). A lower value may help memory usage (slightly)
* and may even improve performance on some systems (and degrade it on others.)
*/
#ifndef ZLIB_IO_MAX
# define ZLIB_IO_MAX ((uInt)-1)
#endif
#ifdef PNG_WRITE_SUPPORTED
/* The type of a compression buffer list used by the write code. */
typedef struct png_compression_buffer
{
struct png_compression_buffer *next;
png_byte output[1]; /* actually zbuf_size */
} png_compression_buffer, *png_compression_bufferp;
#define PNG_COMPRESSION_BUFFER_SIZE(pp)\
(offsetof(png_compression_buffer, output) + (pp)->zbuffer_size)
#endif
struct png_struct_def
{
@ -65,11 +108,13 @@ struct png_struct_def
png_uint_32 flags; /* flags indicating various things to libpng */
png_uint_32 transformations; /* which transformations to perform */
z_stream zstream; /* decompression structure */
png_bytep zbuf; /* buffer for zlib */
uInt zbuf_size; /* size of zbuf */
png_uint_32 zowner; /* ID (chunk type) of zstream owner, 0 if none */
z_stream zstream; /* decompression structure */
#ifdef PNG_WRITE_SUPPORTED
png_compression_bufferp zbuffer_list; /* Created on demand during write */
uInt zbuffer_size; /* size of the actual buffer */
int zlib_level; /* holds zlib compression level */
int zlib_method; /* holds zlib compression method */
int zlib_window_bits; /* holds zlib compression window bits */
@ -341,8 +386,14 @@ struct png_struct_def
/* New member added in libpng-1.2.26 */
png_size_t old_big_row_buf_size;
#ifdef PNG_READ_SUPPORTED
/* New member added in libpng-1.2.30 */
png_charp chunkdata; /* buffer for reading chunk data */
png_bytep read_buffer; /* buffer for reading chunk data */
png_alloc_size_t read_buffer_size; /* current size of the buffer */
#endif
#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
uInt IDAT_read_size; /* limit on read buffer size for IDAT */
#endif
#ifdef PNG_IO_STATE_SUPPORTED
/* New member added in libpng-1.4.0 */

View File

@ -475,6 +475,8 @@ png_create_write_struct_2,(png_const_charp user_png_ver, png_voidp error_ptr,
/* Set the zlib control values to defaults; they can be overridden by the
* application after the struct has been created.
*/
png_ptr->zbuffer_size = PNG_ZBUF_SIZE;
png_ptr->zlib_strategy = Z_FILTERED; /* may be overridden if no filters */
png_ptr->zlib_level = Z_DEFAULT_COMPRESSION;
png_ptr->zlib_mem_level = 8;
@ -784,8 +786,6 @@ png_set_flush(png_structrp png_ptr, int nrows)
void PNGAPI
png_write_flush(png_structrp png_ptr)
{
int wrote_IDAT;
png_debug(1, "in png_write_flush");
if (png_ptr == NULL)
@ -795,39 +795,7 @@ png_write_flush(png_structrp png_ptr)
if (png_ptr->row_number >= png_ptr->num_rows)
return;
do
{
int ret;
/* Compress the data */
ret = deflate(&png_ptr->zstream, Z_SYNC_FLUSH);
wrote_IDAT = 0;
/* Check for compression errors */
if (ret != Z_OK)
{
if (png_ptr->zstream.msg != NULL)
png_error(png_ptr, png_ptr->zstream.msg);
else
png_error(png_ptr, "zlib error");
}
if (!(png_ptr->zstream.avail_out))
{
/* Write the IDAT and reset the zlib output buffer */
png_write_IDAT(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
wrote_IDAT = 1;
}
} while (wrote_IDAT == 1);
/* If there is any data left to be output, write it into a new IDAT */
if (png_ptr->zbuf_size != png_ptr->zstream.avail_out)
{
/* Write the IDAT and reset the zlib output buffer */
png_write_IDAT(png_ptr, png_ptr->zbuf,
png_ptr->zbuf_size - png_ptr->zstream.avail_out);
}
png_compress_IDAT(png_ptr, NULL, 0, Z_SYNC_FLUSH);
png_ptr->flush_rows = 0;
png_flush(png_ptr);
}
@ -848,7 +816,7 @@ png_write_destroy(png_structrp png_ptr)
deflateEnd(&png_ptr->zstream);
/* Free our memory. png_free checks NULL for us. */
png_free(png_ptr, png_ptr->zbuf);
png_free_buffer_list(png_ptr, &png_ptr->zbuffer_list);
png_free(png_ptr, png_ptr->row_buf);
#ifdef PNG_WRITE_FILTER_SUPPORTED
png_free(png_ptr, png_ptr->prev_row);

1417
pngwutil.c

File diff suppressed because it is too large Load Diff

View File

@ -516,6 +516,30 @@ setting sCAL_PRECISION default 5
setting ZBUF_SIZE default 8192
# This is the size of the decompression buffer used when counting or checking
# the decompressed size of an LZ stream from a compressed ancilliary chunk; the
# decompressed data is never used so a different size may be optimal. This size
# was determined using contrib/libtests/timepng.c with compressed zTXt data
# around 11MByte in size. Slight speed improvements (up to about 14% in
# timepng) can be achieved by very large increases (to 32kbyte) on regular data,
# but highly compressible data shows only around 2% improvement. The size is
# chosen to minimize the effects of DoS attacks based on using very large
# amounts of highly compressible data.
setting INFLATE_BUF_SIZE default 1024
# This is the maximum amount of IDAT data that the sequential reader will
# process at one time. The setting does not affect the size of IDAT chunks
# read, just the amount read at once. Neither does it affect the progressive
# reader, which processes just the amount of data the application gives it.
# The sequential reader is currently unable to process more than one IDAT at
# once - it has to read and process each one in turn. There is no point setting
# this to a value larger than the IDAT chunks typically encountered (it would
# just waste memory) but there may be some point in reducing it below the value
# of ZBUF_SIZE (the size of IDAT chunks written by libpng.)
setting IDAT_READ_SIZE default PNG_ZBUF_SIZE
# Ancillary chunks
chunk bKGD
chunk cHRM

View File

@ -3,7 +3,7 @@
/* pnglibconf.h - library build configuration */
/* Libpng 1.6.0beta17 - March 6, 2012 */
/* Libpng 1.6.0beta17 - March 9, 2012 */
/* Copyright (c) 1998-2012 Glenn Randers-Pehrson */
@ -26,6 +26,8 @@
#define PNG_COST_SHIFT 3
#define PNG_DEFAULT_READ_MACROS 1
#define PNG_GAMMA_THRESHOLD_FIXED 5000
#define PNG_IDAT_READ_SIZE PNG_ZBUF_SIZE
#define PNG_INFLATE_BUF_SIZE 1024
#define PNG_MAX_GAMMA_8 11
#define PNG_QUANTIZE_BLUE_BITS 5
#define PNG_QUANTIZE_GREEN_BITS 5