diff options
Diffstat (limited to 'src/3rdparty/libpng/pngrutil.c')
-rw-r--r-- | src/3rdparty/libpng/pngrutil.c | 406 |
1 files changed, 245 insertions, 161 deletions
diff --git a/src/3rdparty/libpng/pngrutil.c b/src/3rdparty/libpng/pngrutil.c index f656dfb..d971e8f 100644 --- a/src/3rdparty/libpng/pngrutil.c +++ b/src/3rdparty/libpng/pngrutil.c @@ -1,8 +1,8 @@ /* pngrutil.c - utilities to read a PNG file * - * Last changed in libpng 1.2.38 [July 16, 2009] - * Copyright (c) 1998-2009 Glenn Randers-Pehrson + * Last changed in libpng 1.4.0 [January 3, 2010] + * Copyright (c) 1998-2010 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.) * @@ -14,57 +14,21 @@ * libpng itself during the course of reading an image. */ -#define PNG_INTERNAL +#define PNG_NO_PEDANTIC_WARNINGS #include "png.h" -#if defined(PNG_READ_SUPPORTED) +#ifdef PNG_READ_SUPPORTED +#include "pngpriv.h" -#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) -# define WIN32_WCE_OLD -#endif - -#ifdef PNG_FLOATING_POINT_SUPPORTED -# if defined(WIN32_WCE_OLD) -/* The strtod() function is not supported on WindowsCE */ -__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr) -{ - double result = 0; - int len; - wchar_t *str, *end; - - len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); - str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); - if ( NULL != str ) - { - MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); - result = wcstod(str, &end); - len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); - *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); - png_free(png_ptr, str); - } - return result; -} -# else # define png_strtod(p,a,b) strtod(a,b) -# endif -#endif - png_uint_32 PNGAPI png_get_uint_31(png_structp png_ptr, png_bytep buf) { -#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED png_uint_32 i = png_get_uint_32(buf); -#else - /* Avoid an extra function call by inlining the result. */ - png_uint_32 i = ((png_uint_32)(*buf) << 24) + - ((png_uint_32)(*(buf + 1)) << 16) + - ((png_uint_32)(*(buf + 2)) << 8) + - (png_uint_32)(*(buf + 3)); -#endif if (i > PNG_UINT_31_MAX) - png_error(png_ptr, "PNG unsigned integer out of range."); + png_error(png_ptr, "PNG unsigned integer out of range"); return (i); } -#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED +#ifndef PNG_USE_READ_MACROS /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ png_uint_32 PNGAPI png_get_uint_32(png_bytep buf) @@ -101,7 +65,7 @@ png_get_uint_16(png_bytep buf) return (i); } -#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ +#endif /* PNG_USE_READ_MACROS */ /* Read the chunk header (length + type name). * Put the type name into png_ptr->chunk_name, and return the length. @@ -112,6 +76,13 @@ png_read_chunk_header(png_structp png_ptr) png_byte buf[8]; png_uint_32 length; +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk header is being read. + * PNG_IO_CHUNK_HDR requires a single I/O call. + */ + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR; +#endif + /* Read the length and the chunk name */ png_read_data(png_ptr, buf, 8); length = png_get_uint_31(png_ptr, buf); @@ -129,6 +100,13 @@ png_read_chunk_header(png_structp png_ptr) /* Check to see if chunk name is valid */ png_check_chunk_name(png_ptr, png_ptr->chunk_name); +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that chunk data will (possibly) be read. + * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls. + */ + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA; +#endif + return length; } @@ -173,7 +151,8 @@ png_crc_finish(png_structp png_ptr, png_uint_32 skip) } else { - png_chunk_error(png_ptr, "CRC error"); + png_chunk_benign_error(png_ptr, "CRC error"); + return (0); } return (1); } @@ -203,6 +182,12 @@ png_crc_error(png_structp png_ptr) need_crc = 0; } +#ifdef PNG_IO_STATE_SUPPORTED + /* Inform the I/O callback that the chunk CRC is being read */ + /* PNG_IO_CHUNK_CRC requires the I/O to be done at once */ + png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC; +#endif + png_read_data(png_ptr, crc_bytes, 4); if (need_crc) @@ -228,7 +213,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, png_size_t chunklength, png_size_t prefix_size, png_size_t *newlength) { - static PNG_CONST char msg[] = "Error decoding compressed text"; + static PNG_CONST char msg[] = "Error decoding compressed chunk"; png_charp text; png_size_t text_size; @@ -290,7 +275,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; png_error(png_ptr, - "Not enough memory to decompress chunk."); + "Not enough memory to decompress chunk"); } png_memcpy(text + prefix_size, png_ptr->zbuf, text_size - prefix_size); @@ -302,16 +287,30 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, png_charp tmp; tmp = text; - text = (png_charp)png_malloc_warn(png_ptr, - (png_uint_32)(text_size + - png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if ((png_ptr->user_chunk_cache_max != 0) && + (--png_ptr->user_chunk_cache_max == 0)) + { + png_warning(png_ptr, "No space in chunk cache"); + text = NULL; + } + + else + { +#endif + text = (png_charp)png_malloc_warn(png_ptr, + (png_size_t)(text_size + + png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1)); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + } +#endif if (text == NULL) { png_free(png_ptr, tmp); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; png_error(png_ptr, - "Not enough memory to decompress chunk.."); + "Not enough memory to decompress chunk"); } png_memcpy(text, tmp, text_size); png_free(png_ptr, tmp); @@ -331,7 +330,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, } if (ret != Z_STREAM_END) { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) +#ifdef PNG_STDIO_SUPPORTED char umsg[52]; if (ret == Z_BUF_ERROR) @@ -362,7 +361,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; - png_error(png_ptr, "Not enough memory for text."); + png_error(png_ptr, "Not enough memory for text"); } png_memcpy(text, png_ptr->chunkdata, prefix_size); } @@ -378,7 +377,7 @@ png_decompress_chunk(png_structp png_ptr, int comp_type, } else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ { -#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) +#ifdef PNG_STDIO_SUPPORTED char umsg[50]; png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type); @@ -430,7 +429,7 @@ png_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->bit_depth = (png_byte)bit_depth; png_ptr->interlaced = (png_byte)interlace_type; png_ptr->color_type = (png_byte)color_type; -#if defined(PNG_MNG_FEATURES_SUPPORTED) +#ifdef PNG_MNG_FEATURES_SUPPORTED png_ptr->filter_type = (png_byte)filter_type; #endif png_ptr->compression_type = (png_byte)compression_type; @@ -473,7 +472,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_color palette[PNG_MAX_PALETTE_LENGTH]; int num, i; -#ifndef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED png_colorp pal_ptr; #endif @@ -501,7 +500,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, length); return; } -#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) +#ifndef PNG_READ_OPT_PLTE_SUPPORTED if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) { png_crc_finish(png_ptr, length); @@ -526,7 +525,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) num = (int)length / 3; -#ifndef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) { png_byte buf[3]; @@ -554,13 +553,13 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) * have an RGB image, the PLTE can be considered ancillary, so * we will act as though it is. */ -#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) +#ifndef PNG_READ_OPT_PLTE_SUPPORTED if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) #endif { png_crc_finish(png_ptr, 0); } -#if !defined(PNG_READ_OPT_PLTE_SUPPORTED) +#ifndef PNG_READ_OPT_PLTE_SUPPORTED else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ { /* If we don't want to use the data from an ancillary chunk, @@ -571,7 +570,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) { - png_chunk_error(png_ptr, "CRC error"); + png_chunk_benign_error(png_ptr, "CRC error"); } else { @@ -589,7 +588,7 @@ png_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_set_PLTE(png_ptr, info_ptr, palette, num); -#if defined(PNG_READ_tRNS_SUPPORTED) +#ifdef PNG_READ_tRNS_SUPPORTED if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) @@ -631,7 +630,7 @@ png_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ } -#if defined(PNG_READ_gAMA_SUPPORTED) +#ifdef PNG_READ_gAMA_SUPPORTED void /* PRIVATE */ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -656,7 +655,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Out of place gAMA chunk"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef PNG_READ_sRGB_SUPPORTED && !(info_ptr->valid & PNG_INFO_sRGB) #endif ) @@ -686,13 +685,13 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef PNG_READ_sRGB_SUPPORTED if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) { png_warning(png_ptr, "Ignoring incorrect gAMA value when sRGB is also present"); -#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_CONSOLE_IO_SUPPORTED fprintf(stderr, "gamma = (%d/100000)", (int)igamma); #endif return; @@ -712,7 +711,7 @@ png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_sBIT_SUPPORTED) +#ifdef PNG_READ_sBIT_SUPPORTED void /* PRIVATE */ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -778,7 +777,7 @@ png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_cHRM_SUPPORTED) +#ifdef PNG_READ_cHRM_SUPPORTED void /* PRIVATE */ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -806,7 +805,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Missing PLTE before cHRM"); if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef PNG_READ_sRGB_SUPPORTED && !(info_ptr->valid & PNG_INFO_sRGB) #endif ) @@ -858,7 +857,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) blue_y = (float)int_y_blue / (float)100000.0; #endif -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef PNG_READ_sRGB_SUPPORTED if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) { if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || @@ -872,7 +871,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_warning(png_ptr, "Ignoring incorrect cHRM value when sRGB is also present"); -#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_CONSOLE_IO_SUPPORTED #ifdef PNG_FLOATING_POINT_SUPPORTED fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", white_x, white_y, red_x, red_y); @@ -884,7 +883,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", int_x_green, int_y_green, int_x_blue, int_y_blue); #endif -#endif /* PNG_NO_CONSOLE_IO */ +#endif /* PNG_CONSOLE_IO_SUPPORTED */ } return; } @@ -902,7 +901,7 @@ png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef PNG_READ_sRGB_SUPPORTED void /* PRIVATE */ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -964,7 +963,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_warning(png_ptr, "Ignoring incorrect gAMA value when sRGB is also present"); -#ifndef PNG_NO_CONSOLE_IO +#ifdef PNG_CONSOLE_IO_SUPPORTED # ifdef PNG_FIXED_POINT_SUPPORTED fprintf(stderr, "incorrect gamma=(%d/100000)\n", (int)png_ptr->int_gamma); @@ -1000,7 +999,7 @@ png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif /* PNG_READ_sRGB_SUPPORTED */ -#if defined(PNG_READ_iCCP_SUPPORTED) +#ifdef PNG_READ_iCCP_SUPPORTED void /* PRIVATE */ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ @@ -1109,7 +1108,7 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; - png_warning(png_ptr, "Ignoring truncated iCCP profile."); + png_warning(png_ptr, "Ignoring truncated iCCP profile"); return; } @@ -1120,14 +1119,14 @@ png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif /* PNG_READ_iCCP_SUPPORTED */ -#if defined(PNG_READ_sPLT_SUPPORTED) +#ifdef PNG_READ_sPLT_SUPPORTED void /* PRIVATE */ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) /* Note: this does not properly handle chunks that are > 64K under DOS */ { png_bytep entry_start; png_sPLT_t new_palette; -#ifdef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED png_sPLT_entryp pp; #endif int data_length, entry_size, i; @@ -1136,6 +1135,23 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_sPLT"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for sPLT"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before sPLT"); @@ -1210,10 +1226,10 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) return; } -#ifndef PNG_NO_POINTER_INDEXING +#ifdef PNG_POINTER_INDEXING_SUPPORTED for (i = 0; i < new_palette.nentries; i++) { - png_sPLT_entryp pp = new_palette.entries + i; + pp = new_palette.entries + i; if (new_palette.depth == 8) { @@ -1265,7 +1281,7 @@ png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif /* PNG_READ_sPLT_SUPPORTED */ -#if defined(PNG_READ_tRNS_SUPPORTED) +#ifdef PNG_READ_tRNS_SUPPORTED void /* PRIVATE */ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1301,7 +1317,7 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_read(png_ptr, buf, 2); png_ptr->num_trans = 1; - png_ptr->trans_values.gray = png_get_uint_16(buf); + png_ptr->trans_color.gray = png_get_uint_16(buf); } else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) { @@ -1315,9 +1331,9 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_crc_read(png_ptr, buf, (png_size_t)length); png_ptr->num_trans = 1; - png_ptr->trans_values.red = png_get_uint_16(buf); - png_ptr->trans_values.green = png_get_uint_16(buf + 2); - png_ptr->trans_values.blue = png_get_uint_16(buf + 4); + png_ptr->trans_color.red = png_get_uint_16(buf); + png_ptr->trans_color.green = png_get_uint_16(buf + 2); + png_ptr->trans_color.blue = png_get_uint_16(buf + 4); } else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) { @@ -1356,11 +1372,11 @@ png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, - &(png_ptr->trans_values)); + &(png_ptr->trans_color)); } #endif -#if defined(PNG_READ_bKGD_SUPPORTED) +#ifdef PNG_READ_bKGD_SUPPORTED void /* PRIVATE */ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1449,7 +1465,7 @@ png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_hIST_SUPPORTED) +#ifdef PNG_READ_hIST_SUPPORTED void /* PRIVATE */ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1503,7 +1519,7 @@ png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_pHYs_SUPPORTED) +#ifdef PNG_READ_pHYs_SUPPORTED void /* PRIVATE */ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1546,7 +1562,7 @@ png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_oFFs_SUPPORTED) +#ifdef PNG_READ_oFFs_SUPPORTED void /* PRIVATE */ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1589,7 +1605,7 @@ png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_pCAL_SUPPORTED) +#ifdef PNG_READ_pCAL_SUPPORTED /* Read the pCAL chunk (described in the PNG Extensions document) */ void /* PRIVATE */ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -1624,7 +1640,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "No memory for pCAL purpose."); + png_warning(png_ptr, "No memory for pCAL purpose"); return; } slength = (png_size_t)length; @@ -1685,12 +1701,12 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(3, "Allocating pCAL parameters array"); params = (png_charpp)png_malloc_warn(png_ptr, - (png_uint_32)(nparams * png_sizeof(png_charp))) ; + (png_size_t)(nparams * png_sizeof(png_charp))); if (params == NULL) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; - png_warning(png_ptr, "No memory for pCAL params."); + png_warning(png_ptr, "No memory for pCAL params"); return; } @@ -1723,7 +1739,7 @@ png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_sCAL_SUPPORTED) +#ifdef PNG_READ_sCAL_SUPPORTED /* Read the sCAL chunk */ void /* PRIVATE */ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -1793,7 +1809,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); return; } - png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); + png_memcpy(swidth, ep, png_strlen(ep)); #endif #endif @@ -1828,7 +1844,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); return; } - png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); + png_memcpy(sheight, ep, png_strlen(ep)); #endif #endif @@ -1866,7 +1882,7 @@ png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_tIME_SUPPORTED) +#ifdef PNG_READ_tIME_SUPPORTED void /* PRIVATE */ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { @@ -1909,7 +1925,7 @@ png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) } #endif -#if defined(PNG_READ_tEXt_SUPPORTED) +#ifdef PNG_READ_tEXt_SUPPORTED /* Note: this does not properly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -1923,6 +1939,22 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_tEXt"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for tEXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before tEXt"); @@ -1944,7 +1976,7 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "No memory to process text chunk."); + png_warning(png_ptr, "No memory to process text chunk"); return; } slength = (png_size_t)length; @@ -1968,10 +2000,10 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) text++; text_ptr = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)png_sizeof(png_text)); + png_sizeof(png_text)); if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process text chunk."); + png_warning(png_ptr, "Not enough memory to process text chunk"); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; return; @@ -1992,11 +2024,11 @@ png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = NULL; png_free(png_ptr, text_ptr); if (ret) - png_warning(png_ptr, "Insufficient memory to process text chunk."); + png_warning(png_ptr, "Insufficient memory to process text chunk"); } #endif -#if defined(PNG_READ_zTXt_SUPPORTED) +#ifdef PNG_READ_zTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -2009,6 +2041,22 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_zTXt"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for zTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before zTXt"); @@ -2031,7 +2079,7 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "Out of memory processing zTXt chunk."); + png_warning(png_ptr, "Out of memory processing zTXt chunk"); return; } slength = (png_size_t)length; @@ -2072,10 +2120,10 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) (png_size_t)length, prefix_len, &data_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)png_sizeof(png_text)); + png_sizeof(png_text)); if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process zTXt chunk."); + png_warning(png_ptr, "Not enough memory to process zTXt chunk"); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; return; @@ -2096,11 +2144,11 @@ png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; if (ret) - png_error(png_ptr, "Insufficient memory to store zTXt chunk."); + png_error(png_ptr, "Insufficient memory to store zTXt chunk"); } #endif -#if defined(PNG_READ_iTXt_SUPPORTED) +#ifdef PNG_READ_iTXt_SUPPORTED /* Note: this does not correctly handle chunks that are > 64K under DOS */ void /* PRIVATE */ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) @@ -2114,6 +2162,22 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_iTXt"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for iTXt"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif if (!(png_ptr->mode & PNG_HAVE_IHDR)) png_error(png_ptr, "Missing IHDR before iTXt"); @@ -2136,7 +2200,7 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); if (png_ptr->chunkdata == NULL) { - png_warning(png_ptr, "No memory to process iTXt chunk."); + png_warning(png_ptr, "No memory to process iTXt chunk"); return; } slength = (png_size_t)length; @@ -2204,10 +2268,10 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) else data_len = png_strlen(png_ptr->chunkdata + prefix_len); text_ptr = (png_textp)png_malloc_warn(png_ptr, - (png_uint_32)png_sizeof(png_text)); + png_sizeof(png_text)); if (text_ptr == NULL) { - png_warning(png_ptr, "Not enough memory to process iTXt chunk."); + png_warning(png_ptr, "Not enough memory to process iTXt chunk"); png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; return; @@ -2226,7 +2290,7 @@ png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL; if (ret) - png_error(png_ptr, "Insufficient memory to store iTXt chunk."); + png_error(png_ptr, "Insufficient memory to store iTXt chunk"); } #endif @@ -2242,22 +2306,36 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_debug(1, "in png_handle_unknown"); +#ifdef PNG_SET_USER_LIMITS_SUPPORTED + if (png_ptr->user_chunk_cache_max != 0) + { + if (png_ptr->user_chunk_cache_max == 1) + { + png_crc_finish(png_ptr, length); + return; + } + if (--png_ptr->user_chunk_cache_max == 1) + { + png_warning(png_ptr, "No space in chunk cache for unknown chunk"); + png_crc_finish(png_ptr, length); + return; + } + } +#endif if (png_ptr->mode & PNG_HAVE_IDAT) { -#ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IDAT; -#endif + PNG_IDAT; if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ png_ptr->mode |= PNG_AFTER_IDAT; } if (!(png_ptr->chunk_name[0] & 0x20)) { -#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS -#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED && png_ptr->read_user_chunk_fn == NULL #endif ) @@ -2265,9 +2343,9 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_chunk_error(png_ptr, "unknown critical chunk"); } -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) -#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED || (png_ptr->read_user_chunk_fn != NULL) #endif ) @@ -2292,7 +2370,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); } -#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED if (png_ptr->read_user_chunk_fn != NULL) { /* Callback to user unknown chunk handler */ @@ -2304,7 +2382,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) if (ret == 0) { if (!(png_ptr->chunk_name[0] & 0x20)) -#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED) +#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) #endif @@ -2325,7 +2403,7 @@ png_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) png_crc_finish(png_ptr, skip); -#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) +#ifndef PNG_READ_USER_CHUNKS_SUPPORTED info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ #endif } @@ -2383,7 +2461,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_uint_32 i; png_uint_32 row_width = png_ptr->width; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; @@ -2438,7 +2516,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_uint_32 row_width = png_ptr->width; int value; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; @@ -2490,7 +2568,7 @@ png_combine_row(png_structp png_ptr, png_bytep row, int mask) png_uint_32 row_width = png_ptr->width; int value; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (png_ptr->transformations & PNG_PACKSWAP) { s_start = 0; @@ -2573,11 +2651,9 @@ png_do_read_interlace(png_structp png_ptr) png_bytep row = png_ptr->row_buf + 1; int pass = png_ptr->pass; png_uint_32 transformations = png_ptr->transformations; -#ifdef PNG_USE_LOCAL_ARRAYS /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Offset to next interlace block */ PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; -#endif png_debug(1, "in png_do_read_interlace"); if (row != NULL && row_info != NULL) @@ -2599,7 +2675,7 @@ png_do_read_interlace(png_structp png_ptr) png_uint_32 i; int j; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (transformations & PNG_PACKSWAP) { sshift = (int)((row_info->width + 7) & 0x07); @@ -2652,7 +2728,7 @@ png_do_read_interlace(png_structp png_ptr) int jstop = png_pass_inc[pass]; png_uint_32 i; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (transformations & PNG_PACKSWAP) { sshift = (int)(((row_info->width + 3) & 0x03) << 1); @@ -2708,7 +2784,7 @@ png_do_read_interlace(png_structp png_ptr) png_uint_32 i; int jstop = png_pass_inc[pass]; -#if defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifdef PNG_READ_PACKSWAP_SUPPORTED if (transformations & PNG_PACKSWAP) { sshift = (int)(((row_info->width + 1) & 0x01) << 2); @@ -2782,7 +2858,7 @@ png_do_read_interlace(png_structp png_ptr) row_info->width = final_width; row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); } -#if !defined(PNG_READ_PACKSWAP_SUPPORTED) +#ifndef PNG_READ_PACKSWAP_SUPPORTED transformations = transformations; /* Silence compiler warning */ #endif } @@ -2911,11 +2987,10 @@ png_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, } } -#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED +#ifdef PNG_SEQUENTIAL_READ_SUPPORTED void /* PRIVATE */ png_read_finish_row(png_structp png_ptr) { -#ifdef PNG_USE_LOCAL_ARRAYS #ifdef PNG_READ_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ @@ -2931,7 +3006,6 @@ png_read_finish_row(png_structp png_ptr) /* Offset to next interlace block in the y direction */ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif /* PNG_READ_INTERLACING_SUPPORTED */ -#endif png_debug(1, "in png_read_finish_row"); png_ptr->row_number++; @@ -2942,7 +3016,7 @@ png_read_finish_row(png_structp png_ptr) if (png_ptr->interlaced) { png_ptr->row_number = 0; - png_memset_check(png_ptr, png_ptr->prev_row, 0, + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); do { @@ -2977,9 +3051,7 @@ png_read_finish_row(png_structp png_ptr) if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { -#ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IDAT; -#endif + PNG_IDAT; char extra; int ret; @@ -3026,7 +3098,7 @@ png_read_finish_row(png_structp png_ptr) if (!(png_ptr->zstream.avail_out)) { - png_warning(png_ptr, "Extra compressed data."); + png_warning(png_ptr, "Extra compressed data"); png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; break; @@ -3043,12 +3115,11 @@ png_read_finish_row(png_structp png_ptr) png_ptr->mode |= PNG_AFTER_IDAT; } -#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */ +#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ void /* PRIVATE */ png_read_start_row(png_structp png_ptr) { -#ifdef PNG_USE_LOCAL_ARRAYS #ifdef PNG_READ_INTERLACING_SUPPORTED /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ @@ -3064,7 +3135,6 @@ png_read_start_row(png_structp png_ptr) /* Offset to next interlace block in the y direction */ PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; #endif -#endif int max_pixel_depth; png_size_t row_bytes; @@ -3098,12 +3168,12 @@ png_read_start_row(png_structp png_ptr) } max_pixel_depth = png_ptr->pixel_depth; -#if defined(PNG_READ_PACK_SUPPORTED) +#ifdef PNG_READ_PACK_SUPPORTED if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) max_pixel_depth = 8; #endif -#if defined(PNG_READ_EXPAND_SUPPORTED) +#ifdef PNG_READ_EXPAND_SUPPORTED if (png_ptr->transformations & PNG_EXPAND) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -3131,7 +3201,7 @@ png_read_start_row(png_structp png_ptr) } #endif -#if defined(PNG_READ_FILLER_SUPPORTED) +#ifdef PNG_READ_FILLER_SUPPORTED if (png_ptr->transformations & (PNG_FILLER)) { if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) @@ -3153,14 +3223,14 @@ png_read_start_row(png_structp png_ptr) } #endif -#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED) +#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED if (png_ptr->transformations & PNG_GRAY_TO_RGB) { if ( -#if defined(PNG_READ_EXPAND_SUPPORTED) +#ifdef PNG_READ_EXPAND_SUPPORTED (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || #endif -#if defined(PNG_READ_FILLER_SUPPORTED) +#ifdef PNG_READ_FILLER_SUPPORTED (png_ptr->transformations & (PNG_FILLER)) || #endif png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) @@ -3212,33 +3282,47 @@ defined(PNG_USER_TRANSFORM_PTR_SUPPORTED) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif - if (row_bytes + 64 > png_ptr->old_big_row_buf_size) + if (row_bytes + 48 > png_ptr->old_big_row_buf_size) { png_free(png_ptr, png_ptr->big_row_buf); - png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 64); if (png_ptr->interlaced) - png_memset(png_ptr->big_row_buf, 0, row_bytes + 64); + png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, + row_bytes + 48); + else + png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, + row_bytes + 48); + png_ptr->old_big_row_buf_size = row_bytes + 48; + +#ifdef PNG_ALIGNED_MEMORY_SUPPORTED + /* Use 16-byte aligned memory for row_buf with at least 16 bytes + * of padding before and after row_buf. + */ + png_ptr->row_buf = png_ptr->big_row_buf + 32 + - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16); + png_ptr->old_big_row_buf_size = row_bytes + 48; +#else + /* Use 32 bytes of padding before and 16 bytes after row_buf. */ png_ptr->row_buf = png_ptr->big_row_buf + 32; - png_ptr->old_big_row_buf_size = row_bytes + 64; +#endif + png_ptr->old_big_row_buf_size = row_bytes + 48; } #ifdef PNG_MAX_MALLOC_64K - if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) + if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L) png_error(png_ptr, "This image requires a row greater than 64KB"); #endif - if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) - png_error(png_ptr, "Row has too many bytes to allocate in memory."); + if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1)) + png_error(png_ptr, "Row has too many bytes to allocate in memory"); - if (row_bytes + 1 > png_ptr->old_prev_row_size) + if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size) { png_free(png_ptr, png_ptr->prev_row); png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( - row_bytes + 1)); - png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); - png_ptr->old_prev_row_size = row_bytes + 1; + png_ptr->rowbytes + 1)); + png_ptr->old_prev_row_size = png_ptr->rowbytes + 1; } - png_ptr->rowbytes = row_bytes; + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); png_debug1(3, "width = %lu,", png_ptr->width); png_debug1(3, "height = %lu,", png_ptr->height); |