diff options
| author | Albrecht Schlosser <albrechts.fltk@online.de> | 2011-03-22 09:11:57 +0000 |
|---|---|---|
| committer | Albrecht Schlosser <albrechts.fltk@online.de> | 2011-03-22 09:11:57 +0000 |
| commit | 8920d929444aa486a55478184b88caa24a253efd (patch) | |
| tree | 669accf3c7acf5394fe82f00647f9d981cc717d9 /png/pngpread.c | |
| parent | dfc067ecfcecb67c31935a005edc477a163b64c5 (diff) | |
Updated the bundled libpng to v1.5.1 (released Feb 3, 2011).
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3@8523 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'png/pngpread.c')
| -rw-r--r-- | png/pngpread.c | 635 |
1 files changed, 381 insertions, 254 deletions
diff --git a/png/pngpread.c b/png/pngpread.c index 7adb7b854..7b1149bab 100644 --- a/png/pngpread.c +++ b/png/pngpread.c @@ -1,8 +1,8 @@ /* pngpread.c - read a png file in push mode * - * Last changed in libpng 1.2.38 [July 16, 2009] - * Copyright (c) 1998-2009 Glenn Randers-Pehrson + * Last changed in libpng 1.5.1 [February 3, 2011] + * Copyright (c) 1998-2011 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,8 +11,8 @@ * and license in png.h */ -#define PNG_INTERNAL -#include "png.h" +#include "pngpriv.h" + #ifdef PNG_PROGRESSIVE_READ_SUPPORTED /* Push model modes */ @@ -28,7 +28,7 @@ void PNGAPI png_process_data(png_structp png_ptr, png_infop info_ptr, - png_bytep buffer, png_size_t buffer_size) + png_bytep buffer, png_size_t buffer_size) { if (png_ptr == NULL || info_ptr == NULL) return; @@ -41,6 +41,64 @@ png_process_data(png_structp png_ptr, png_infop info_ptr, } } +png_size_t PNGAPI +png_process_data_pause(png_structp png_ptr, int save) +{ + if (png_ptr != NULL) + { + /* It's easiest for the caller if we do the save, then the caller doesn't + * have to supply the same data again: + */ + if (save) + png_push_save_buffer(png_ptr); + else + { + /* This includes any pending saved bytes: */ + png_size_t remaining = png_ptr->buffer_size; + png_ptr->buffer_size = 0; + + /* So subtract the saved buffer size, unless all the data + * is actually 'saved', in which case we just return 0 + */ + if (png_ptr->save_buffer_size < remaining) + return remaining - png_ptr->save_buffer_size; + } + } + + return 0; +} + +png_uint_32 PNGAPI +png_process_data_skip(png_structp png_ptr) +{ + png_uint_32 remaining = 0; + + if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && + png_ptr->skip_length > 0) + { + /* At the end of png_process_data the buffer size must be 0 (see the loop + * above) so we can detect a broken call here: + */ + if (png_ptr->buffer_size != 0) + png_error(png_ptr, + "png_process_data_skip called inside png_process_data"); + + /* If is impossible for there to be a saved buffer at this point - + * otherwise we could not be in SKIP mode. This will also happen if + * png_process_skip is called inside png_process_data (but only very + * rarely.) + */ + if (png_ptr->save_buffer_size != 0) + png_error(png_ptr, "png_process_data_skip called with saved data"); + + remaining = png_ptr->skip_length; + png_ptr->skip_length = 0; + png_ptr->process_mode = PNG_READ_CHUNK_MODE; + } + + return remaining; +} + /* What we do with the incoming data depends on what we were previously * doing before we ran out of data... */ @@ -70,7 +128,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) break; } -#if defined(PNG_READ_tEXt_SUPPORTED) +#ifdef PNG_READ_tEXt_SUPPORTED case PNG_READ_tEXt_MODE: { png_push_read_tEXt(png_ptr, info_ptr); @@ -78,7 +136,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_zTXt_SUPPORTED) +#ifdef PNG_READ_zTXt_SUPPORTED case PNG_READ_zTXt_MODE: { png_push_read_zTXt(png_ptr, info_ptr); @@ -86,7 +144,7 @@ png_process_some_data(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_iTXt_SUPPORTED) +#ifdef PNG_READ_iTXt_SUPPORTED case PNG_READ_iTXt_MODE: { png_push_read_iTXt(png_ptr, info_ptr); @@ -126,7 +184,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) } png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), - num_to_check); + num_to_check); png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) @@ -134,6 +192,7 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) if (num_checked < 4 && png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) png_error(png_ptr, "Not a PNG file"); + else png_error(png_ptr, "PNG file corrupted by ASCII conversion"); } @@ -149,63 +208,62 @@ png_push_read_sig(png_structp png_ptr, png_infop info_ptr) void /* PRIVATE */ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) { -#ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IHDR; - PNG_CONST PNG_IDAT; - PNG_CONST PNG_IEND; - PNG_CONST PNG_PLTE; -#if defined(PNG_READ_bKGD_SUPPORTED) - PNG_CONST PNG_bKGD; + PNG_IHDR; + PNG_IDAT; + PNG_IEND; + PNG_PLTE; +#ifdef PNG_READ_bKGD_SUPPORTED + PNG_bKGD; #endif -#if defined(PNG_READ_cHRM_SUPPORTED) - PNG_CONST PNG_cHRM; +#ifdef PNG_READ_cHRM_SUPPORTED + PNG_cHRM; #endif -#if defined(PNG_READ_gAMA_SUPPORTED) - PNG_CONST PNG_gAMA; +#ifdef PNG_READ_gAMA_SUPPORTED + PNG_gAMA; #endif -#if defined(PNG_READ_hIST_SUPPORTED) - PNG_CONST PNG_hIST; +#ifdef PNG_READ_hIST_SUPPORTED + PNG_hIST; #endif -#if defined(PNG_READ_iCCP_SUPPORTED) - PNG_CONST PNG_iCCP; +#ifdef PNG_READ_iCCP_SUPPORTED + PNG_iCCP; #endif -#if defined(PNG_READ_iTXt_SUPPORTED) - PNG_CONST PNG_iTXt; +#ifdef PNG_READ_iTXt_SUPPORTED + PNG_iTXt; #endif -#if defined(PNG_READ_oFFs_SUPPORTED) - PNG_CONST PNG_oFFs; +#ifdef PNG_READ_oFFs_SUPPORTED + PNG_oFFs; #endif -#if defined(PNG_READ_pCAL_SUPPORTED) - PNG_CONST PNG_pCAL; +#ifdef PNG_READ_pCAL_SUPPORTED + PNG_pCAL; #endif -#if defined(PNG_READ_pHYs_SUPPORTED) - PNG_CONST PNG_pHYs; +#ifdef PNG_READ_pHYs_SUPPORTED + PNG_pHYs; #endif -#if defined(PNG_READ_sBIT_SUPPORTED) - PNG_CONST PNG_sBIT; +#ifdef PNG_READ_sBIT_SUPPORTED + PNG_sBIT; #endif -#if defined(PNG_READ_sCAL_SUPPORTED) - PNG_CONST PNG_sCAL; +#ifdef PNG_READ_sCAL_SUPPORTED + PNG_sCAL; #endif -#if defined(PNG_READ_sRGB_SUPPORTED) - PNG_CONST PNG_sRGB; +#ifdef PNG_READ_sRGB_SUPPORTED + PNG_sRGB; #endif -#if defined(PNG_READ_sPLT_SUPPORTED) - PNG_CONST PNG_sPLT; +#ifdef PNG_READ_sPLT_SUPPORTED + PNG_sPLT; #endif -#if defined(PNG_READ_tEXt_SUPPORTED) - PNG_CONST PNG_tEXt; +#ifdef PNG_READ_tEXt_SUPPORTED + PNG_tEXt; #endif -#if defined(PNG_READ_tIME_SUPPORTED) - PNG_CONST PNG_tIME; +#ifdef PNG_READ_tIME_SUPPORTED + PNG_tIME; #endif -#if defined(PNG_READ_tRNS_SUPPORTED) - PNG_CONST PNG_tRNS; +#ifdef PNG_READ_tRNS_SUPPORTED + PNG_tRNS; #endif -#if defined(PNG_READ_zTXt_SUPPORTED) - PNG_CONST PNG_zTXt; +#ifdef PNG_READ_zTXt_SUPPORTED + PNG_zTXt; #endif -#endif /* PNG_USE_LOCAL_ARRAYS */ + /* 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 @@ -231,8 +289,8 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } if (!png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) - if (png_ptr->mode & PNG_AFTER_IDAT) - png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; + if (png_ptr->mode & PNG_AFTER_IDAT) + png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; if (!png_memcmp(png_ptr->chunk_name, png_IHDR, 4)) { @@ -285,7 +343,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) png_error(png_ptr, "Missing IHDR before IDAT"); else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && - !(png_ptr->mode & PNG_HAVE_PLTE)) + !(png_ptr->mode & PNG_HAVE_PLTE)) png_error(png_ptr, "Missing PLTE before IDAT"); } } @@ -322,19 +380,21 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) return; if (png_ptr->mode & PNG_AFTER_IDAT) - png_error(png_ptr, "Too many IDAT's found"); + png_benign_error(png_ptr, "Too many IDATs found"); } png_ptr->idat_size = png_ptr->push_length; png_ptr->mode |= PNG_HAVE_IDAT; png_ptr->process_mode = PNG_READ_IDAT_MODE; png_push_have_info(png_ptr, info_ptr); - png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; png_ptr->zstream.next_out = png_ptr->row_buf; return; } -#if defined(PNG_READ_gAMA_SUPPORTED) +#ifdef PNG_READ_gAMA_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_gAMA, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -347,7 +407,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_sBIT_SUPPORTED) +#ifdef PNG_READ_sBIT_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_sBIT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -360,7 +420,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_cHRM_SUPPORTED) +#ifdef PNG_READ_cHRM_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_cHRM, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -373,7 +433,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_sRGB_SUPPORTED) +#ifdef 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) @@ -386,7 +446,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_iCCP_SUPPORTED) +#ifdef PNG_READ_iCCP_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_iCCP, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -399,7 +459,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_sPLT_SUPPORTED) +#ifdef PNG_READ_sPLT_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_sPLT, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -412,7 +472,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_tRNS_SUPPORTED) +#ifdef PNG_READ_tRNS_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_tRNS, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -425,7 +485,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_bKGD_SUPPORTED) +#ifdef PNG_READ_bKGD_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_bKGD, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -438,7 +498,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_hIST_SUPPORTED) +#ifdef PNG_READ_hIST_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_hIST, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -451,7 +511,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_pHYs_SUPPORTED) +#ifdef PNG_READ_pHYs_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_pHYs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -464,7 +524,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_oFFs_SUPPORTED) +#ifdef PNG_READ_oFFs_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_oFFs, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -477,7 +537,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_pCAL_SUPPORTED) +#ifdef PNG_READ_pCAL_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_pCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -490,7 +550,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_sCAL_SUPPORTED) +#ifdef PNG_READ_sCAL_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_sCAL, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -503,7 +563,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_tIME_SUPPORTED) +#ifdef PNG_READ_tIME_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_tIME, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -516,7 +576,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_tEXt_SUPPORTED) +#ifdef PNG_READ_tEXt_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_tEXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -529,7 +589,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_zTXt_SUPPORTED) +#ifdef PNG_READ_zTXt_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_zTXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -542,7 +602,7 @@ png_push_read_chunk(png_structp png_ptr, png_infop info_ptr) } #endif -#if defined(PNG_READ_iTXt_SUPPORTED) +#ifdef PNG_READ_iTXt_SUPPORTED else if (!png_memcmp(png_ptr->chunk_name, png_iTXt, 4)) { if (png_ptr->push_length + 4 > png_ptr->buffer_size) @@ -580,32 +640,45 @@ png_push_crc_finish(png_structp png_ptr) { if (png_ptr->skip_length && png_ptr->save_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'save_buffer_size', but + * they are of different types and we don't know which variable has the + * fewest bits. Carefully select the smaller and cast it to the type of + * the larger - this cannot overflow. Do not cast in the following test + * - it will break on either 16 or 64 bit platforms. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; - if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size) - save_size = (png_size_t)png_ptr->skip_length; else - save_size = png_ptr->save_buffer_size; + skip_length = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - png_ptr->skip_length -= save_size; + png_ptr->skip_length -= skip_length; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } if (png_ptr->skip_length && png_ptr->current_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 skip_length = png_ptr->skip_length; + + /* We want the smaller of 'skip_length' and 'current_buffer_size', here, + * the same problem exists as above and the same solution. + */ + if (skip_length < save_size) + save_size = (png_size_t)skip_length; - if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size) - save_size = (png_size_t)png_ptr->skip_length; else - save_size = png_ptr->current_buffer_size; + skip_length = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->skip_length -= save_size; + png_ptr->skip_length -= skip_length; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; @@ -623,7 +696,7 @@ png_push_crc_finish(png_structp png_ptr) } } -void PNGAPI +void PNGCBAPI png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) { png_bytep ptr; @@ -638,6 +711,7 @@ png_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) if (length < png_ptr->save_buffer_size) save_size = length; + else save_size = png_ptr->save_buffer_size; @@ -678,28 +752,35 @@ png_push_save_buffer(png_structp png_ptr) istop = png_ptr->save_buffer_size; for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; - i < istop; i++, sp++, dp++) + i < istop; i++, sp++, dp++) { *dp = *sp; } } } if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > - png_ptr->save_buffer_max) + png_ptr->save_buffer_max) { png_size_t new_max; png_bytep old_buffer; if (png_ptr->save_buffer_size > PNG_SIZE_MAX - - (png_ptr->current_buffer_size + 256)) + (png_ptr->current_buffer_size + 256)) { - png_error(png_ptr, "Potential overflow of save_buffer"); + png_error(png_ptr, "Potential overflow of save_buffer"); } 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, - (png_uint_32)new_max); + png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, + (png_size_t)new_max); + + if (png_ptr->save_buffer == NULL) + { + png_free(png_ptr, old_buffer); + png_error(png_ptr, "Insufficient memory for save_buffer"); + } + 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; @@ -728,9 +809,7 @@ png_push_restore_buffer(png_structp png_ptr, png_bytep buffer, void /* PRIVATE */ png_push_read_IDAT(png_structp png_ptr) { -#ifdef PNG_USE_LOCAL_ARRAYS - PNG_CONST PNG_IDAT; -#endif + PNG_IDAT; if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) { png_byte chunk_length[4]; @@ -750,8 +829,10 @@ png_push_read_IDAT(png_structp png_ptr) if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) { png_ptr->process_mode = PNG_READ_CHUNK_MODE; + if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) png_error(png_ptr, "Not enough compressed data"); + return; } @@ -759,49 +840,52 @@ png_push_read_IDAT(png_structp png_ptr) } if (png_ptr->idat_size && png_ptr->save_buffer_size) { - png_size_t save_size; - - if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size) - { - save_size = (png_size_t)png_ptr->idat_size; + png_size_t save_size = png_ptr->save_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; + + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. Do not cast in the following test - it + * will break on either 16 or 64 bit platforms. + */ + if (idat_size < save_size) + save_size = (png_size_t)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; + idat_size = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); + png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); - png_ptr->idat_size -= save_size; + png_ptr->idat_size -= idat_size; png_ptr->buffer_size -= save_size; png_ptr->save_buffer_size -= save_size; png_ptr->save_buffer_ptr += save_size; } + if (png_ptr->idat_size && png_ptr->current_buffer_size) { - png_size_t save_size; + png_size_t save_size = png_ptr->current_buffer_size; + png_uint_32 idat_size = png_ptr->idat_size; - if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size) - { - save_size = (png_size_t)png_ptr->idat_size; + /* We want the smaller of 'idat_size' and 'current_buffer_size', but they + * are of different types and we don't know which variable has the fewest + * bits. Carefully select the smaller and cast it to the type of the + * larger - this cannot overflow. + */ + if (idat_size < save_size) + save_size = (png_size_t)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; + idat_size = (png_uint_32)save_size; png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); - if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) - png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); - png_ptr->idat_size -= save_size; + png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); + + png_ptr->idat_size -= idat_size; png_ptr->buffer_size -= save_size; png_ptr->current_buffer_size -= save_size; png_ptr->current_buffer_ptr += save_size; @@ -824,60 +908,104 @@ void /* PRIVATE */ png_process_IDAT_data(png_structp png_ptr, png_bytep buffer, png_size_t buffer_length) { - int ret; - - if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length) - png_error(png_ptr, "Extra compression data"); + /* The caller checks for a non-zero buffer length. */ + if (!(buffer_length > 0) || buffer == NULL) + png_error(png_ptr, "No IDAT data (internal error)"); + /* This routine must process all the data it has been given + * before returning, calling the row callback as required to + * handle the uncompressed results. + */ png_ptr->zstream.next_in = buffer; png_ptr->zstream.avail_in = (uInt)buffer_length; - for (;;) + + /* Keep going until the decompressed data is all processed + * or the stream marked as finished. + */ + while (png_ptr->zstream.avail_in > 0 && + !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) { - ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); - if (ret != Z_OK) + int ret; + + /* We have data for zlib, but we must check that zlib + * has someplace to put the results. It doesn't matter + * if we don't expect any results -- it may be the input + * data is just the LZ end code. + */ + if (!(png_ptr->zstream.avail_out > 0)) { - if (ret == Z_STREAM_END) - { - if (png_ptr->zstream.avail_in) - png_error(png_ptr, "Extra compressed data"); + png_ptr->zstream.avail_out = + (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, + png_ptr->iwidth) + 1; - if (!(png_ptr->zstream.avail_out)) - { - png_push_process_row(png_ptr); - } + png_ptr->zstream.next_out = png_ptr->row_buf; + } - png_ptr->mode |= PNG_AFTER_IDAT; - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; - } - else if (ret == Z_BUF_ERROR) - break; + /* Using Z_SYNC_FLUSH here means that an unterminated + * LZ stream (a stream with a missing end code) can still + * be handled, otherwise (Z_NO_FLUSH) a future zlib + * implementation might defer output and therefore + * change the current behavior (see comments in inflate.c + * for why this doesn't happen at present with zlib 1.2.5). + */ + ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); + + /* Check for any failure before proceeding. */ + if (ret != Z_OK && ret != Z_STREAM_END) + { + /* Terminate the decompression. */ + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* This may be a truncated stream (missing or + * damaged end code). Treat that as a warning. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) + png_warning(png_ptr, "Truncated compressed data in IDAT"); else - png_error(png_ptr, "Decompression Error"); + png_error(png_ptr, "Decompression error in IDAT"); + + /* Skip the check on unprocessed input */ + return; } - if (!(png_ptr->zstream.avail_out)) + + /* Did inflate output any data? */ + if (png_ptr->zstream.next_out != png_ptr->row_buf) { - if (( -#if defined(PNG_READ_INTERLACING_SUPPORTED) - png_ptr->interlaced && png_ptr->pass > 6) || - (!png_ptr->interlaced && -#endif - png_ptr->row_number == png_ptr->num_rows)) + /* Is this unexpected data after the last row? + * If it is, artificially terminate the LZ output + * here. + */ + if (png_ptr->row_number >= png_ptr->num_rows || + png_ptr->pass > 6) { - if (png_ptr->zstream.avail_in) - png_warning(png_ptr, "Too much data in IDAT chunks"); - png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; - break; + /* Extra data. */ + png_warning(png_ptr, "Extra compressed data in IDAT"); + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; + + /* Do no more processing; skip the unprocessed + * input check below. + */ + return; } - png_push_process_row(png_ptr); - png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes; - png_ptr->zstream.next_out = png_ptr->row_buf; + + /* Do we have a complete row? */ + if (png_ptr->zstream.avail_out == 0) + png_push_process_row(png_ptr); } - else - break; + /* And check for the end of the stream. */ + if (ret == Z_STREAM_END) + png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; } + + /* All the data should have been processed, if anything + * is left at this point we have bytes of IDAT data + * after the zlib end code. + */ + if (png_ptr->zstream.avail_in > 0) + png_warning(png_ptr, "Extra compression data in IDAT"); } void /* PRIVATE */ @@ -893,23 +1021,22 @@ png_push_process_row(png_structp png_ptr) png_ptr->row_info.width); 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_ptr->row_buf + 1, png_ptr->prev_row + 1, + (int)(png_ptr->row_buf[0])); - png_memcpy_check(png_ptr, png_ptr->prev_row, png_ptr->row_buf, - png_ptr->rowbytes + 1); + png_memcpy(png_ptr->prev_row, png_ptr->row_buf, png_ptr->rowbytes + 1); if (png_ptr->transformations || (png_ptr->flags&PNG_FLAG_STRIP_ALPHA)) png_do_read_transformations(png_ptr); -#if defined(PNG_READ_INTERLACING_SUPPORTED) +#ifdef PNG_READ_INTERLACING_SUPPORTED /* Blow up interlaced rows to full size */ if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) { if (png_ptr->pass < 6) /* old interface (pre-1.0.9): png_do_read_interlace(&(png_ptr->row_info), - png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); + png_ptr->row_buf + 1, png_ptr->pass, png_ptr->transformations); */ png_do_read_interlace(png_ptr); @@ -928,7 +1055,7 @@ png_push_process_row(png_structp png_ptr) { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } @@ -937,14 +1064,14 @@ png_push_process_row(png_structp png_ptr) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } if (png_ptr->pass == 6 && png_ptr->height <= 4) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } @@ -964,7 +1091,7 @@ png_push_process_row(png_structp png_ptr) { for (i = 0; i < 4 && png_ptr->pass == 2; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } @@ -984,7 +1111,7 @@ png_push_process_row(png_structp png_ptr) for (i = 0; i < 4 && png_ptr->pass == 2; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } @@ -992,7 +1119,7 @@ png_push_process_row(png_structp png_ptr) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } @@ -1014,7 +1141,7 @@ png_push_process_row(png_structp png_ptr) { for (i = 0; i < 2 && png_ptr->pass == 4; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } @@ -1034,13 +1161,13 @@ png_push_process_row(png_structp png_ptr) for (i = 0; i < 2 && png_ptr->pass == 4; i++) { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } if (png_ptr->pass == 6) /* Pass 5 might be empty */ { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } @@ -1059,12 +1186,14 @@ png_push_process_row(png_structp png_ptr) if (png_ptr->pass == 6) /* Skip top generated row */ { - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } break; } + + default: case 6: { png_push_have_row(png_ptr, png_ptr->row_buf + 1); @@ -1073,7 +1202,7 @@ png_push_process_row(png_structp png_ptr) if (png_ptr->pass != 6) break; - png_push_have_row(png_ptr, png_bytep_NULL); + png_push_have_row(png_ptr, NULL); png_read_push_finish_row(png_ptr); } } @@ -1089,7 +1218,6 @@ png_push_process_row(png_structp png_ptr) void /* PRIVATE */ png_read_push_finish_row(png_structp png_ptr) { -#ifdef PNG_USE_LOCAL_ARRAYS /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ /* Start of interlace block */ @@ -1108,25 +1236,24 @@ png_read_push_finish_row(png_structp png_ptr) * it, uncomment it here and in png.h PNG_CONST int FARDATA png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; */ -#endif png_ptr->row_number++; if (png_ptr->row_number < png_ptr->num_rows) return; -#if defined(PNG_READ_INTERLACING_SUPPORTED) +#ifdef PNG_READ_INTERLACING_SUPPORTED if (png_ptr->interlaced) { png_ptr->row_number = 0; - png_memset_check(png_ptr, png_ptr->prev_row, 0, - png_ptr->rowbytes + 1); + png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); + do { png_ptr->pass++; if ((png_ptr->pass == 1 && png_ptr->width < 5) || (png_ptr->pass == 3 && png_ptr->width < 3) || (png_ptr->pass == 5 && png_ptr->width < 2)) - png_ptr->pass++; + png_ptr->pass++; if (png_ptr->pass > 7) png_ptr->pass--; @@ -1135,35 +1262,33 @@ png_read_push_finish_row(png_structp png_ptr) break; png_ptr->iwidth = (png_ptr->width + - png_pass_inc[png_ptr->pass] - 1 - - png_pass_start[png_ptr->pass]) / - png_pass_inc[png_ptr->pass]; - - png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, - png_ptr->iwidth) + 1; + png_pass_inc[png_ptr->pass] - 1 - + png_pass_start[png_ptr->pass]) / + png_pass_inc[png_ptr->pass]; if (png_ptr->transformations & PNG_INTERLACE) break; png_ptr->num_rows = (png_ptr->height + - png_pass_yinc[png_ptr->pass] - 1 - - png_pass_ystart[png_ptr->pass]) / - png_pass_yinc[png_ptr->pass]; + png_pass_yinc[png_ptr->pass] - 1 - + png_pass_ystart[png_ptr->pass]) / + png_pass_yinc[png_ptr->pass]; } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); } #endif /* PNG_READ_INTERLACING_SUPPORTED */ } -#if defined(PNG_READ_tEXt_SUPPORTED) +#ifdef PNG_READ_tEXt_SUPPORTED void /* PRIVATE */ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ png_error(png_ptr, "Out of place tEXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ + /*NOT REACHED*/ } #ifdef PNG_MAX_MALLOC_64K @@ -1178,7 +1303,7 @@ png_push_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(length + 1)); + (png_size_t)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1218,7 +1343,7 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) png_push_crc_finish(png_ptr); -#if defined(PNG_MAX_MALLOC_64K) +#ifdef PNG_MAX_MALLOC_64K if (png_ptr->skip_length) return; #endif @@ -1231,14 +1356,12 @@ 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, - (png_uint_32)png_sizeof(png_text)); + text_ptr = (png_textp)png_malloc(png_ptr, png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; text_ptr->key = key; -#ifdef PNG_iTXt_SUPPORTED + text_ptr->itxt_length = 0; text_ptr->lang = NULL; text_ptr->lang_key = NULL; -#endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); @@ -1248,21 +1371,22 @@ png_push_read_tEXt(png_structp png_ptr, png_infop info_ptr) png_ptr->current_text = NULL; if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk."); + png_warning(png_ptr, "Insufficient memory to store text chunk"); } } #endif -#if defined(PNG_READ_zTXt_SUPPORTED) +#ifdef PNG_READ_zTXt_SUPPORTED void /* PRIVATE */ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - png_error(png_ptr, "Out of place zTXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ - } + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place zTXt"); + /*NOT REACHED*/ + } #ifdef PNG_MAX_MALLOC_64K /* We can't handle zTXt chunks > 64K, since we don't have enough space @@ -1278,7 +1402,7 @@ png_push_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(length + 1)); + (png_size_t)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1343,9 +1467,9 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text++; - png_ptr->zstream.next_in = (png_bytep )text; + png_ptr->zstream.next_in = (png_bytep)text; png_ptr->zstream.avail_in = (uInt)(png_ptr->current_text_size - - (text - key)); + (text - key)); png_ptr->zstream.next_out = png_ptr->zbuf; png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size; @@ -1366,42 +1490,45 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_free(png_ptr, text); return; } + if (!(png_ptr->zstream.avail_out) || ret == Z_STREAM_END) { if (text == NULL) { text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(png_ptr->zbuf_size - - png_ptr->zstream.avail_out + key_size + 1)); + (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_ptr->zbuf_size - png_ptr->zstream.avail_out); png_memcpy(text, key, key_size); text_size = key_size + png_ptr->zbuf_size - - png_ptr->zstream.avail_out; + png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } + else { png_charp tmp; tmp = text; text = (png_charp)png_malloc(png_ptr, text_size + - (png_uint_32)(png_ptr->zbuf_size - - png_ptr->zstream.avail_out + 1)); + (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, - png_ptr->zbuf_size - png_ptr->zstream.avail_out); + png_ptr->zbuf_size - png_ptr->zstream.avail_out); text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out; *(text + text_size) = '\0'; } + if (ret != Z_STREAM_END) { png_ptr->zstream.next_out = png_ptr->zbuf; @@ -1434,13 +1561,12 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) text += key_size; text_ptr = (png_textp)png_malloc(png_ptr, - (png_uint_32)png_sizeof(png_text)); + png_sizeof(png_text)); text_ptr->compression = PNG_TEXT_COMPRESSION_zTXt; text_ptr->key = key; -#ifdef PNG_iTXt_SUPPORTED + text_ptr->itxt_length = 0; text_ptr->lang = NULL; text_ptr->lang_key = NULL; -#endif text_ptr->text = text; ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); @@ -1449,21 +1575,22 @@ png_push_read_zTXt(png_structp png_ptr, png_infop info_ptr) png_free(png_ptr, text_ptr); if (ret) - png_warning(png_ptr, "Insufficient memory to store text chunk."); + png_warning(png_ptr, "Insufficient memory to store text chunk"); } } #endif -#if defined(PNG_READ_iTXt_SUPPORTED) +#ifdef PNG_READ_iTXt_SUPPORTED void /* PRIVATE */ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { if (!(png_ptr->mode & PNG_HAVE_IHDR) || (png_ptr->mode & PNG_HAVE_IEND)) - { - png_error(png_ptr, "Out of place iTXt"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ - } + { + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ + png_error(png_ptr, "Out of place iTXt"); + /*NOT REACHED*/ + } #ifdef PNG_MAX_MALLOC_64K png_ptr->skip_length = 0; /* This may not be necessary */ @@ -1477,7 +1604,7 @@ png_push_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 #endif png_ptr->current_text = (png_charp)png_malloc(png_ptr, - (png_uint_32)(length + 1)); + (png_size_t)(length + 1)); png_ptr->current_text[length] = '\0'; png_ptr->current_text_ptr = png_ptr->current_text; png_ptr->current_text_size = (png_size_t)length; @@ -1503,6 +1630,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) png_ptr->current_text_left -= text_size; png_ptr->current_text_ptr += text_size; } + if (!(png_ptr->current_text_left)) { png_textp text_ptr; @@ -1521,7 +1649,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) png_push_crc_finish(png_ptr); -#if defined(PNG_MAX_MALLOC_64K) +#ifdef PNG_MAX_MALLOC_64K if (png_ptr->skip_length) return; #endif @@ -1546,15 +1674,15 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) if (lang_key < key + png_ptr->current_text_size - 1) { - for (; *text; text++) - /* Empty loop */ ; + for (; *text; text++) + /* Empty loop */ ; } if (text < key + png_ptr->current_text_size) text++; text_ptr = (png_textp)png_malloc(png_ptr, - (png_uint_32)png_sizeof(png_text)); + png_sizeof(png_text)); text_ptr->compression = comp_flag + 2; text_ptr->key = key; @@ -1570,7 +1698,7 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) png_free(png_ptr, text_ptr); if (ret) - png_warning(png_ptr, "Insufficient memory to store iTXt chunk."); + png_warning(png_ptr, "Insufficient memory to store iTXt chunk"); } } #endif @@ -1581,41 +1709,41 @@ png_push_read_iTXt(png_structp png_ptr, png_infop info_ptr) */ void /* PRIVATE */ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 - length) + length) { png_uint_32 skip = 0; if (!(png_ptr->chunk_name[0] & 0x20)) { -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS -#if defined(PNG_READ_USER_CHUNKS_SUPPORTED) - && png_ptr->read_user_chunk_fn == NULL + PNG_HANDLE_CHUNK_ALWAYS +#ifdef PNG_READ_USER_CHUNKS_SUPPORTED + && png_ptr->read_user_chunk_fn == NULL #endif - ) + ) #endif png_chunk_error(png_ptr, "unknown critical chunk"); - info_ptr = info_ptr; /* To quiet some compiler warnings */ + PNG_UNUSED(info_ptr) /* To quiet some compiler warnings */ } -#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED) +#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED if (png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) { #ifdef PNG_MAX_MALLOC_64K if (length > (png_uint_32)65535L) { - png_warning(png_ptr, "unknown chunk too large to fit in memory"); - skip = length - (png_uint_32)65535L; - length = (png_uint_32)65535L; + png_warning(png_ptr, "unknown chunk too large to fit in memory"); + skip = length - (png_uint_32)65535L; + length = (png_uint_32)65535L; } #endif png_memcpy((png_charp)png_ptr->unknown_chunk.name, - (png_charp)png_ptr->chunk_name, - png_sizeof(png_ptr->unknown_chunk.name)); + (png_charp)png_ptr->chunk_name, + png_sizeof(png_ptr->unknown_chunk.name)); png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name) - 1] - = '\0'; + = '\0'; png_ptr->unknown_chunk.size = (png_size_t)length; @@ -1625,17 +1753,17 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 else { png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, - (png_uint_32)length); + (png_size_t)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 */ int ret; ret = (*(png_ptr->read_user_chunk_fn)) - (png_ptr, &png_ptr->unknown_chunk); + (png_ptr, &png_ptr->unknown_chunk); if (ret < 0) png_chunk_error(png_ptr, "error in user chunk"); @@ -1644,16 +1772,16 @@ png_push_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 { if (!(png_ptr->chunk_name[0] & 0x20)) if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != - PNG_HANDLE_CHUNK_ALWAYS) + PNG_HANDLE_CHUNK_ALWAYS) png_chunk_error(png_ptr, "unknown critical chunk"); png_set_unknown_chunks(png_ptr, info_ptr, - &png_ptr->unknown_chunk, 1); + &png_ptr->unknown_chunk, 1); } } else #endif - png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); + png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); png_free(png_ptr, png_ptr->unknown_chunk.data); png_ptr->unknown_chunk.data = NULL; } @@ -1687,13 +1815,12 @@ png_push_have_row(png_structp png_ptr, png_bytep row) } void PNGAPI -png_progressive_combine_row (png_structp png_ptr, - png_bytep old_row, png_bytep new_row) +png_progressive_combine_row (png_structp png_ptr, png_bytep old_row, + png_const_bytep new_row) { -#ifdef PNG_USE_LOCAL_ARRAYS PNG_CONST int FARDATA png_pass_dsp_mask[7] = {0xff, 0x0f, 0xff, 0x33, 0xff, 0x55, 0xff}; -#endif + if (png_ptr == NULL) return; @@ -1703,8 +1830,8 @@ png_progressive_combine_row (png_structp png_ptr, void PNGAPI png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, - png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, - png_progressive_end_ptr end_fn) + png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, + png_progressive_end_ptr end_fn) { if (png_ptr == NULL) return; @@ -1717,7 +1844,7 @@ png_set_progressive_read_fn(png_structp png_ptr, png_voidp progressive_ptr, } png_voidp PNGAPI -png_get_progressive_ptr(png_structp png_ptr) +png_get_progressive_ptr(png_const_structp png_ptr) { if (png_ptr == NULL) return (NULL); |
