13965825b97a5809454f5810f7e603cbd02daa036scroggo 23965825b97a5809454f5810f7e603cbd02daa036scroggo/* pngpread.c - read a png file in push mode 33965825b97a5809454f5810f7e603cbd02daa036scroggo * 43965825b97a5809454f5810f7e603cbd02daa036scroggo * Last changed in libpng 1.6.18 [July 23, 2015] 53965825b97a5809454f5810f7e603cbd02daa036scroggo * Copyright (c) 1998-2002,2004,2006-2015 Glenn Randers-Pehrson 63965825b97a5809454f5810f7e603cbd02daa036scroggo * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 73965825b97a5809454f5810f7e603cbd02daa036scroggo * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 83965825b97a5809454f5810f7e603cbd02daa036scroggo * 93965825b97a5809454f5810f7e603cbd02daa036scroggo * This code is released under the libpng license. 103965825b97a5809454f5810f7e603cbd02daa036scroggo * For conditions of distribution and use, see the disclaimer 113965825b97a5809454f5810f7e603cbd02daa036scroggo * and license in png.h 123965825b97a5809454f5810f7e603cbd02daa036scroggo */ 133965825b97a5809454f5810f7e603cbd02daa036scroggo 143965825b97a5809454f5810f7e603cbd02daa036scroggo#include "pngpriv.h" 153965825b97a5809454f5810f7e603cbd02daa036scroggo 163965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 173965825b97a5809454f5810f7e603cbd02daa036scroggo 183965825b97a5809454f5810f7e603cbd02daa036scroggo/* Push model modes */ 193965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_SIG_MODE 0 203965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_CHUNK_MODE 1 213965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_IDAT_MODE 2 223965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_tEXt_MODE 4 233965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_zTXt_MODE 5 243965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_DONE_MODE 6 253965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_READ_iTXt_MODE 7 263965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_ERROR_MODE 8 273965825b97a5809454f5810f7e603cbd02daa036scroggo 283965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_PUSH_SAVE_BUFFER_IF_FULL \ 293965825b97a5809454f5810f7e603cbd02daa036scroggoif (png_ptr->push_length + 4 > png_ptr->buffer_size) \ 303965825b97a5809454f5810f7e603cbd02daa036scroggo { png_push_save_buffer(png_ptr); return; } 313965825b97a5809454f5810f7e603cbd02daa036scroggo#define PNG_PUSH_SAVE_BUFFER_IF_LT(N) \ 323965825b97a5809454f5810f7e603cbd02daa036scroggoif (png_ptr->buffer_size < N) \ 333965825b97a5809454f5810f7e603cbd02daa036scroggo { png_push_save_buffer(png_ptr); return; } 343965825b97a5809454f5810f7e603cbd02daa036scroggo 353965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI 363965825b97a5809454f5810f7e603cbd02daa036scroggopng_process_data(png_structrp png_ptr, png_inforp info_ptr, 373965825b97a5809454f5810f7e603cbd02daa036scroggo png_bytep buffer, png_size_t buffer_size) 383965825b97a5809454f5810f7e603cbd02daa036scroggo{ 393965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL || info_ptr == NULL) 403965825b97a5809454f5810f7e603cbd02daa036scroggo return; 413965825b97a5809454f5810f7e603cbd02daa036scroggo 423965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_restore_buffer(png_ptr, buffer, buffer_size); 433965825b97a5809454f5810f7e603cbd02daa036scroggo 443965825b97a5809454f5810f7e603cbd02daa036scroggo while (png_ptr->buffer_size) 453965825b97a5809454f5810f7e603cbd02daa036scroggo { 463965825b97a5809454f5810f7e603cbd02daa036scroggo png_process_some_data(png_ptr, info_ptr); 473965825b97a5809454f5810f7e603cbd02daa036scroggo } 483965825b97a5809454f5810f7e603cbd02daa036scroggo} 493965825b97a5809454f5810f7e603cbd02daa036scroggo 503965825b97a5809454f5810f7e603cbd02daa036scroggopng_size_t PNGAPI 513965825b97a5809454f5810f7e603cbd02daa036scroggopng_process_data_pause(png_structrp png_ptr, int save) 523965825b97a5809454f5810f7e603cbd02daa036scroggo{ 533965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr != NULL) 543965825b97a5809454f5810f7e603cbd02daa036scroggo { 553965825b97a5809454f5810f7e603cbd02daa036scroggo /* It's easiest for the caller if we do the save; then the caller doesn't 563965825b97a5809454f5810f7e603cbd02daa036scroggo * have to supply the same data again: 573965825b97a5809454f5810f7e603cbd02daa036scroggo */ 583965825b97a5809454f5810f7e603cbd02daa036scroggo if (save != 0) 593965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_save_buffer(png_ptr); 603965825b97a5809454f5810f7e603cbd02daa036scroggo else 613965825b97a5809454f5810f7e603cbd02daa036scroggo { 623965825b97a5809454f5810f7e603cbd02daa036scroggo /* This includes any pending saved bytes: */ 633965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t remaining = png_ptr->buffer_size; 643965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size = 0; 653965825b97a5809454f5810f7e603cbd02daa036scroggo 663965825b97a5809454f5810f7e603cbd02daa036scroggo /* So subtract the saved buffer size, unless all the data 673965825b97a5809454f5810f7e603cbd02daa036scroggo * is actually 'saved', in which case we just return 0 683965825b97a5809454f5810f7e603cbd02daa036scroggo */ 693965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_size < remaining) 703965825b97a5809454f5810f7e603cbd02daa036scroggo return remaining - png_ptr->save_buffer_size; 713965825b97a5809454f5810f7e603cbd02daa036scroggo } 723965825b97a5809454f5810f7e603cbd02daa036scroggo } 733965825b97a5809454f5810f7e603cbd02daa036scroggo 743965825b97a5809454f5810f7e603cbd02daa036scroggo return 0; 753965825b97a5809454f5810f7e603cbd02daa036scroggo} 763965825b97a5809454f5810f7e603cbd02daa036scroggo 773965825b97a5809454f5810f7e603cbd02daa036scroggopng_uint_32 PNGAPI 783965825b97a5809454f5810f7e603cbd02daa036scroggopng_process_data_skip(png_structrp png_ptr) 793965825b97a5809454f5810f7e603cbd02daa036scroggo{ 803965825b97a5809454f5810f7e603cbd02daa036scroggo /* TODO: Deprecate and remove this API. 813965825b97a5809454f5810f7e603cbd02daa036scroggo * Somewhere the implementation of this seems to have been lost, 823965825b97a5809454f5810f7e603cbd02daa036scroggo * or abandoned. It was only to support some internal back-door access 833965825b97a5809454f5810f7e603cbd02daa036scroggo * to png_struct) in libpng-1.4.x. 843965825b97a5809454f5810f7e603cbd02daa036scroggo */ 853965825b97a5809454f5810f7e603cbd02daa036scroggo png_app_warning(png_ptr, 863965825b97a5809454f5810f7e603cbd02daa036scroggo"png_process_data_skip is not implemented in any current version of libpng"); 873965825b97a5809454f5810f7e603cbd02daa036scroggo return 0; 883965825b97a5809454f5810f7e603cbd02daa036scroggo} 893965825b97a5809454f5810f7e603cbd02daa036scroggo 903965825b97a5809454f5810f7e603cbd02daa036scroggo/* What we do with the incoming data depends on what we were previously 913965825b97a5809454f5810f7e603cbd02daa036scroggo * doing before we ran out of data... 923965825b97a5809454f5810f7e603cbd02daa036scroggo */ 933965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 943965825b97a5809454f5810f7e603cbd02daa036scroggopng_process_some_data(png_structrp png_ptr, png_inforp info_ptr) 953965825b97a5809454f5810f7e603cbd02daa036scroggo{ 963965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL) 973965825b97a5809454f5810f7e603cbd02daa036scroggo return; 983965825b97a5809454f5810f7e603cbd02daa036scroggo 993965825b97a5809454f5810f7e603cbd02daa036scroggo switch (png_ptr->process_mode) 1003965825b97a5809454f5810f7e603cbd02daa036scroggo { 1013965825b97a5809454f5810f7e603cbd02daa036scroggo case PNG_READ_SIG_MODE: 1023965825b97a5809454f5810f7e603cbd02daa036scroggo { 1033965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_read_sig(png_ptr, info_ptr); 1043965825b97a5809454f5810f7e603cbd02daa036scroggo break; 1053965825b97a5809454f5810f7e603cbd02daa036scroggo } 1063965825b97a5809454f5810f7e603cbd02daa036scroggo 1073965825b97a5809454f5810f7e603cbd02daa036scroggo case PNG_READ_CHUNK_MODE: 1083965825b97a5809454f5810f7e603cbd02daa036scroggo { 1093965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_read_chunk(png_ptr, info_ptr); 1103965825b97a5809454f5810f7e603cbd02daa036scroggo break; 1113965825b97a5809454f5810f7e603cbd02daa036scroggo } 1123965825b97a5809454f5810f7e603cbd02daa036scroggo 1133965825b97a5809454f5810f7e603cbd02daa036scroggo case PNG_READ_IDAT_MODE: 1143965825b97a5809454f5810f7e603cbd02daa036scroggo { 1153965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_read_IDAT(png_ptr); 1163965825b97a5809454f5810f7e603cbd02daa036scroggo break; 1173965825b97a5809454f5810f7e603cbd02daa036scroggo } 1183965825b97a5809454f5810f7e603cbd02daa036scroggo 1193965825b97a5809454f5810f7e603cbd02daa036scroggo default: 1203965825b97a5809454f5810f7e603cbd02daa036scroggo { 1213965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size = 0; 1223965825b97a5809454f5810f7e603cbd02daa036scroggo break; 1233965825b97a5809454f5810f7e603cbd02daa036scroggo } 1243965825b97a5809454f5810f7e603cbd02daa036scroggo } 1253965825b97a5809454f5810f7e603cbd02daa036scroggo} 1263965825b97a5809454f5810f7e603cbd02daa036scroggo 1273965825b97a5809454f5810f7e603cbd02daa036scroggo/* Read any remaining signature bytes from the stream and compare them with 1283965825b97a5809454f5810f7e603cbd02daa036scroggo * the correct PNG signature. It is possible that this routine is called 1293965825b97a5809454f5810f7e603cbd02daa036scroggo * with bytes already read from the signature, either because they have been 1303965825b97a5809454f5810f7e603cbd02daa036scroggo * checked by the calling application, or because of multiple calls to this 1313965825b97a5809454f5810f7e603cbd02daa036scroggo * routine. 1323965825b97a5809454f5810f7e603cbd02daa036scroggo */ 1333965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 1343965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) 1353965825b97a5809454f5810f7e603cbd02daa036scroggo{ 1363965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ 1373965825b97a5809454f5810f7e603cbd02daa036scroggo num_to_check = 8 - num_checked; 1383965825b97a5809454f5810f7e603cbd02daa036scroggo 1393965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->buffer_size < num_to_check) 1403965825b97a5809454f5810f7e603cbd02daa036scroggo { 1413965825b97a5809454f5810f7e603cbd02daa036scroggo num_to_check = png_ptr->buffer_size; 1423965825b97a5809454f5810f7e603cbd02daa036scroggo } 1433965825b97a5809454f5810f7e603cbd02daa036scroggo 1443965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 1453965825b97a5809454f5810f7e603cbd02daa036scroggo num_to_check); 1463965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); 1473965825b97a5809454f5810f7e603cbd02daa036scroggo 1483965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 1493965825b97a5809454f5810f7e603cbd02daa036scroggo { 1503965825b97a5809454f5810f7e603cbd02daa036scroggo if (num_checked < 4 && 1513965825b97a5809454f5810f7e603cbd02daa036scroggo png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 1523965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Not a PNG file"); 1533965825b97a5809454f5810f7e603cbd02daa036scroggo 1543965825b97a5809454f5810f7e603cbd02daa036scroggo else 1553965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 1563965825b97a5809454f5810f7e603cbd02daa036scroggo } 1573965825b97a5809454f5810f7e603cbd02daa036scroggo else 1583965825b97a5809454f5810f7e603cbd02daa036scroggo { 1593965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->sig_bytes >= 8) 1603965825b97a5809454f5810f7e603cbd02daa036scroggo { 1613965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->process_mode = PNG_READ_CHUNK_MODE; 1623965825b97a5809454f5810f7e603cbd02daa036scroggo } 1633965825b97a5809454f5810f7e603cbd02daa036scroggo } 1643965825b97a5809454f5810f7e603cbd02daa036scroggo} 1653965825b97a5809454f5810f7e603cbd02daa036scroggo 1663965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 1673965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) 1683965825b97a5809454f5810f7e603cbd02daa036scroggo{ 1693965825b97a5809454f5810f7e603cbd02daa036scroggo png_uint_32 chunk_name; 1703965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 1713965825b97a5809454f5810f7e603cbd02daa036scroggo int keep; /* unknown handling method */ 1723965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 1733965825b97a5809454f5810f7e603cbd02daa036scroggo 1743965825b97a5809454f5810f7e603cbd02daa036scroggo /* First we make sure we have enough data for the 4-byte chunk name 1753965825b97a5809454f5810f7e603cbd02daa036scroggo * and the 4-byte chunk length before proceeding with decoding the 1763965825b97a5809454f5810f7e603cbd02daa036scroggo * chunk data. To fully decode each of these chunks, we also make 1773965825b97a5809454f5810f7e603cbd02daa036scroggo * sure we have enough data in the buffer for the 4-byte CRC at the 1783965825b97a5809454f5810f7e603cbd02daa036scroggo * end of every chunk (except IDAT, which is handled separately). 1793965825b97a5809454f5810f7e603cbd02daa036scroggo */ 1803965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) 1813965825b97a5809454f5810f7e603cbd02daa036scroggo { 1823965825b97a5809454f5810f7e603cbd02daa036scroggo png_byte chunk_length[4]; 1833965825b97a5809454f5810f7e603cbd02daa036scroggo png_byte chunk_tag[4]; 1843965825b97a5809454f5810f7e603cbd02daa036scroggo 1853965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_LT(8) 1863965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_fill_buffer(png_ptr, chunk_length, 4); 1873965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 1883965825b97a5809454f5810f7e603cbd02daa036scroggo png_reset_crc(png_ptr); 1893965825b97a5809454f5810f7e603cbd02daa036scroggo png_crc_read(png_ptr, chunk_tag, 4); 1903965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); 1913965825b97a5809454f5810f7e603cbd02daa036scroggo png_check_chunk_name(png_ptr, png_ptr->chunk_name); 1923965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 1933965825b97a5809454f5810f7e603cbd02daa036scroggo } 1943965825b97a5809454f5810f7e603cbd02daa036scroggo 1953965825b97a5809454f5810f7e603cbd02daa036scroggo chunk_name = png_ptr->chunk_name; 1963965825b97a5809454f5810f7e603cbd02daa036scroggo 1973965825b97a5809454f5810f7e603cbd02daa036scroggo if (chunk_name == png_IDAT) 1983965825b97a5809454f5810f7e603cbd02daa036scroggo { 1993965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) 2003965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 2013965825b97a5809454f5810f7e603cbd02daa036scroggo 2023965825b97a5809454f5810f7e603cbd02daa036scroggo /* If we reach an IDAT chunk, this means we have read all of the 2033965825b97a5809454f5810f7e603cbd02daa036scroggo * header chunks, and we can start reading the image (or if this 2043965825b97a5809454f5810f7e603cbd02daa036scroggo * is called after the image has been read - we have an error). 2053965825b97a5809454f5810f7e603cbd02daa036scroggo */ 2063965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_HAVE_IHDR) == 0) 2073965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Missing IHDR before IDAT"); 2083965825b97a5809454f5810f7e603cbd02daa036scroggo 2093965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 2103965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->mode & PNG_HAVE_PLTE) == 0) 2113965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Missing PLTE before IDAT"); 2123965825b97a5809454f5810f7e603cbd02daa036scroggo 2133965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_HAVE_IDAT; 2143965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->process_mode = PNG_READ_IDAT_MODE; 2153965825b97a5809454f5810f7e603cbd02daa036scroggo 2163965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT) == 0) 2173965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->push_length == 0) 2183965825b97a5809454f5810f7e603cbd02daa036scroggo return; 2193965825b97a5809454f5810f7e603cbd02daa036scroggo 2203965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_AFTER_IDAT) != 0) 2213965825b97a5809454f5810f7e603cbd02daa036scroggo png_benign_error(png_ptr, "Too many IDATs found"); 2223965825b97a5809454f5810f7e603cbd02daa036scroggo } 2233965825b97a5809454f5810f7e603cbd02daa036scroggo 2243965825b97a5809454f5810f7e603cbd02daa036scroggo if (chunk_name == png_IHDR) 2253965825b97a5809454f5810f7e603cbd02daa036scroggo { 2263965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->push_length != 13) 2273965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Invalid IHDR length"); 2283965825b97a5809454f5810f7e603cbd02daa036scroggo 2293965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2303965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); 2313965825b97a5809454f5810f7e603cbd02daa036scroggo } 2323965825b97a5809454f5810f7e603cbd02daa036scroggo 2333965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_IEND) 2343965825b97a5809454f5810f7e603cbd02daa036scroggo { 2353965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2363965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); 2373965825b97a5809454f5810f7e603cbd02daa036scroggo 2383965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->process_mode = PNG_READ_DONE_MODE; 2393965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_end(png_ptr, info_ptr); 2403965825b97a5809454f5810f7e603cbd02daa036scroggo } 2413965825b97a5809454f5810f7e603cbd02daa036scroggo 2423965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 2433965825b97a5809454f5810f7e603cbd02daa036scroggo else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 2443965825b97a5809454f5810f7e603cbd02daa036scroggo { 2453965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2463965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); 2473965825b97a5809454f5810f7e603cbd02daa036scroggo 2483965825b97a5809454f5810f7e603cbd02daa036scroggo if (chunk_name == png_PLTE) 2493965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_HAVE_PLTE; 2503965825b97a5809454f5810f7e603cbd02daa036scroggo } 2513965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 2523965825b97a5809454f5810f7e603cbd02daa036scroggo 2533965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_PLTE) 2543965825b97a5809454f5810f7e603cbd02daa036scroggo { 2553965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2563965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); 2573965825b97a5809454f5810f7e603cbd02daa036scroggo } 2583965825b97a5809454f5810f7e603cbd02daa036scroggo 2593965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_IDAT) 2603965825b97a5809454f5810f7e603cbd02daa036scroggo { 2613965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->idat_size = png_ptr->push_length; 2623965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->process_mode = PNG_READ_IDAT_MODE; 2633965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_info(png_ptr, info_ptr); 2643965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.avail_out = 2653965825b97a5809454f5810f7e603cbd02daa036scroggo (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, 2663965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->iwidth) + 1; 2673965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.next_out = png_ptr->row_buf; 2683965825b97a5809454f5810f7e603cbd02daa036scroggo return; 2693965825b97a5809454f5810f7e603cbd02daa036scroggo } 2703965825b97a5809454f5810f7e603cbd02daa036scroggo 2713965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_gAMA_SUPPORTED 2723965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->chunk_name == png_gAMA) 2733965825b97a5809454f5810f7e603cbd02daa036scroggo { 2743965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2753965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); 2763965825b97a5809454f5810f7e603cbd02daa036scroggo } 2773965825b97a5809454f5810f7e603cbd02daa036scroggo 2783965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 2793965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_sBIT_SUPPORTED 2803965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->chunk_name == png_sBIT) 2813965825b97a5809454f5810f7e603cbd02daa036scroggo { 2823965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2833965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); 2843965825b97a5809454f5810f7e603cbd02daa036scroggo } 2853965825b97a5809454f5810f7e603cbd02daa036scroggo 2863965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 2873965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_cHRM_SUPPORTED 2883965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->chunk_name == png_cHRM) 2893965825b97a5809454f5810f7e603cbd02daa036scroggo { 2903965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2913965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); 2923965825b97a5809454f5810f7e603cbd02daa036scroggo } 2933965825b97a5809454f5810f7e603cbd02daa036scroggo 2943965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 2953965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_sRGB_SUPPORTED 2963965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_sRGB) 2973965825b97a5809454f5810f7e603cbd02daa036scroggo { 2983965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 2993965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); 3003965825b97a5809454f5810f7e603cbd02daa036scroggo } 3013965825b97a5809454f5810f7e603cbd02daa036scroggo 3023965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3033965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_iCCP_SUPPORTED 3043965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->chunk_name == png_iCCP) 3053965825b97a5809454f5810f7e603cbd02daa036scroggo { 3063965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3073965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); 3083965825b97a5809454f5810f7e603cbd02daa036scroggo } 3093965825b97a5809454f5810f7e603cbd02daa036scroggo 3103965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3113965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_sPLT_SUPPORTED 3123965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_sPLT) 3133965825b97a5809454f5810f7e603cbd02daa036scroggo { 3143965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3153965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); 3163965825b97a5809454f5810f7e603cbd02daa036scroggo } 3173965825b97a5809454f5810f7e603cbd02daa036scroggo 3183965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3193965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_tRNS_SUPPORTED 3203965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_tRNS) 3213965825b97a5809454f5810f7e603cbd02daa036scroggo { 3223965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3233965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); 3243965825b97a5809454f5810f7e603cbd02daa036scroggo } 3253965825b97a5809454f5810f7e603cbd02daa036scroggo 3263965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3273965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_bKGD_SUPPORTED 3283965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_bKGD) 3293965825b97a5809454f5810f7e603cbd02daa036scroggo { 3303965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3313965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); 3323965825b97a5809454f5810f7e603cbd02daa036scroggo } 3333965825b97a5809454f5810f7e603cbd02daa036scroggo 3343965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3353965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_hIST_SUPPORTED 3363965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_hIST) 3373965825b97a5809454f5810f7e603cbd02daa036scroggo { 3383965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3393965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); 3403965825b97a5809454f5810f7e603cbd02daa036scroggo } 3413965825b97a5809454f5810f7e603cbd02daa036scroggo 3423965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3433965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_pHYs_SUPPORTED 3443965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_pHYs) 3453965825b97a5809454f5810f7e603cbd02daa036scroggo { 3463965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3473965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); 3483965825b97a5809454f5810f7e603cbd02daa036scroggo } 3493965825b97a5809454f5810f7e603cbd02daa036scroggo 3503965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3513965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_oFFs_SUPPORTED 3523965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_oFFs) 3533965825b97a5809454f5810f7e603cbd02daa036scroggo { 3543965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3553965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); 3563965825b97a5809454f5810f7e603cbd02daa036scroggo } 3573965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3583965825b97a5809454f5810f7e603cbd02daa036scroggo 3593965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_pCAL_SUPPORTED 3603965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_pCAL) 3613965825b97a5809454f5810f7e603cbd02daa036scroggo { 3623965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3633965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); 3643965825b97a5809454f5810f7e603cbd02daa036scroggo } 3653965825b97a5809454f5810f7e603cbd02daa036scroggo 3663965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3673965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_sCAL_SUPPORTED 3683965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_sCAL) 3693965825b97a5809454f5810f7e603cbd02daa036scroggo { 3703965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3713965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); 3723965825b97a5809454f5810f7e603cbd02daa036scroggo } 3733965825b97a5809454f5810f7e603cbd02daa036scroggo 3743965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3753965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_tIME_SUPPORTED 3763965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_tIME) 3773965825b97a5809454f5810f7e603cbd02daa036scroggo { 3783965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3793965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); 3803965825b97a5809454f5810f7e603cbd02daa036scroggo } 3813965825b97a5809454f5810f7e603cbd02daa036scroggo 3823965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3833965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_tEXt_SUPPORTED 3843965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_tEXt) 3853965825b97a5809454f5810f7e603cbd02daa036scroggo { 3863965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3873965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); 3883965825b97a5809454f5810f7e603cbd02daa036scroggo } 3893965825b97a5809454f5810f7e603cbd02daa036scroggo 3903965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3913965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_zTXt_SUPPORTED 3923965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_zTXt) 3933965825b97a5809454f5810f7e603cbd02daa036scroggo { 3943965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 3953965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); 3963965825b97a5809454f5810f7e603cbd02daa036scroggo } 3973965825b97a5809454f5810f7e603cbd02daa036scroggo 3983965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 3993965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_iTXt_SUPPORTED 4003965825b97a5809454f5810f7e603cbd02daa036scroggo else if (chunk_name == png_iTXt) 4013965825b97a5809454f5810f7e603cbd02daa036scroggo { 4023965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 4033965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); 4043965825b97a5809454f5810f7e603cbd02daa036scroggo } 4053965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 4063965825b97a5809454f5810f7e603cbd02daa036scroggo 4073965825b97a5809454f5810f7e603cbd02daa036scroggo else 4083965825b97a5809454f5810f7e603cbd02daa036scroggo { 4093965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_FULL 4103965825b97a5809454f5810f7e603cbd02daa036scroggo png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, 4113965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_HANDLE_CHUNK_AS_DEFAULT); 4123965825b97a5809454f5810f7e603cbd02daa036scroggo } 4133965825b97a5809454f5810f7e603cbd02daa036scroggo 4143965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 4153965825b97a5809454f5810f7e603cbd02daa036scroggo} 4163965825b97a5809454f5810f7e603cbd02daa036scroggo 4173965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGCBAPI 4183965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) 4193965825b97a5809454f5810f7e603cbd02daa036scroggo{ 4203965825b97a5809454f5810f7e603cbd02daa036scroggo png_bytep ptr; 4213965825b97a5809454f5810f7e603cbd02daa036scroggo 4223965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL) 4233965825b97a5809454f5810f7e603cbd02daa036scroggo return; 4243965825b97a5809454f5810f7e603cbd02daa036scroggo 4253965825b97a5809454f5810f7e603cbd02daa036scroggo ptr = buffer; 4263965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_size != 0) 4273965825b97a5809454f5810f7e603cbd02daa036scroggo { 4283965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t save_size; 4293965825b97a5809454f5810f7e603cbd02daa036scroggo 4303965825b97a5809454f5810f7e603cbd02daa036scroggo if (length < png_ptr->save_buffer_size) 4313965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = length; 4323965825b97a5809454f5810f7e603cbd02daa036scroggo 4333965825b97a5809454f5810f7e603cbd02daa036scroggo else 4343965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = png_ptr->save_buffer_size; 4353965825b97a5809454f5810f7e603cbd02daa036scroggo 4363965825b97a5809454f5810f7e603cbd02daa036scroggo memcpy(ptr, png_ptr->save_buffer_ptr, save_size); 4373965825b97a5809454f5810f7e603cbd02daa036scroggo length -= save_size; 4383965825b97a5809454f5810f7e603cbd02daa036scroggo ptr += save_size; 4393965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size -= save_size; 4403965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_size -= save_size; 4413965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_ptr += save_size; 4423965825b97a5809454f5810f7e603cbd02daa036scroggo } 4433965825b97a5809454f5810f7e603cbd02daa036scroggo if (length != 0 && png_ptr->current_buffer_size != 0) 4443965825b97a5809454f5810f7e603cbd02daa036scroggo { 4453965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t save_size; 4463965825b97a5809454f5810f7e603cbd02daa036scroggo 4473965825b97a5809454f5810f7e603cbd02daa036scroggo if (length < png_ptr->current_buffer_size) 4483965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = length; 4493965825b97a5809454f5810f7e603cbd02daa036scroggo 4503965825b97a5809454f5810f7e603cbd02daa036scroggo else 4513965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = png_ptr->current_buffer_size; 4523965825b97a5809454f5810f7e603cbd02daa036scroggo 4533965825b97a5809454f5810f7e603cbd02daa036scroggo memcpy(ptr, png_ptr->current_buffer_ptr, save_size); 4543965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size -= save_size; 4553965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_size -= save_size; 4563965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_ptr += save_size; 4573965825b97a5809454f5810f7e603cbd02daa036scroggo } 4583965825b97a5809454f5810f7e603cbd02daa036scroggo} 4593965825b97a5809454f5810f7e603cbd02daa036scroggo 4603965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 4613965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_save_buffer(png_structrp png_ptr) 4623965825b97a5809454f5810f7e603cbd02daa036scroggo{ 4633965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_size != 0) 4643965825b97a5809454f5810f7e603cbd02daa036scroggo { 4653965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) 4663965825b97a5809454f5810f7e603cbd02daa036scroggo { 4673965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t i, istop; 4683965825b97a5809454f5810f7e603cbd02daa036scroggo png_bytep sp; 4693965825b97a5809454f5810f7e603cbd02daa036scroggo png_bytep dp; 4703965825b97a5809454f5810f7e603cbd02daa036scroggo 4713965825b97a5809454f5810f7e603cbd02daa036scroggo istop = png_ptr->save_buffer_size; 4723965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; 4733965825b97a5809454f5810f7e603cbd02daa036scroggo i < istop; i++, sp++, dp++) 4743965825b97a5809454f5810f7e603cbd02daa036scroggo { 4753965825b97a5809454f5810f7e603cbd02daa036scroggo *dp = *sp; 4763965825b97a5809454f5810f7e603cbd02daa036scroggo } 4773965825b97a5809454f5810f7e603cbd02daa036scroggo } 4783965825b97a5809454f5810f7e603cbd02daa036scroggo } 4793965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > 4803965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_max) 4813965825b97a5809454f5810f7e603cbd02daa036scroggo { 4823965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t new_max; 4833965825b97a5809454f5810f7e603cbd02daa036scroggo png_bytep old_buffer; 4843965825b97a5809454f5810f7e603cbd02daa036scroggo 4853965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 4863965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->current_buffer_size + 256)) 4873965825b97a5809454f5810f7e603cbd02daa036scroggo { 4883965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Potential overflow of save_buffer"); 4893965825b97a5809454f5810f7e603cbd02daa036scroggo } 4903965825b97a5809454f5810f7e603cbd02daa036scroggo 4913965825b97a5809454f5810f7e603cbd02daa036scroggo new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; 4923965825b97a5809454f5810f7e603cbd02daa036scroggo old_buffer = png_ptr->save_buffer; 4933965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, 4943965825b97a5809454f5810f7e603cbd02daa036scroggo (png_size_t)new_max); 4953965825b97a5809454f5810f7e603cbd02daa036scroggo 4963965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->save_buffer == NULL) 4973965825b97a5809454f5810f7e603cbd02daa036scroggo { 4983965825b97a5809454f5810f7e603cbd02daa036scroggo png_free(png_ptr, old_buffer); 4993965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Insufficient memory for save_buffer"); 5003965825b97a5809454f5810f7e603cbd02daa036scroggo } 5013965825b97a5809454f5810f7e603cbd02daa036scroggo 5021915b0bab2b48cf8bf85dc49e76994b033f25450scroggo#if 0 5031915b0bab2b48cf8bf85dc49e76994b033f25450scroggo // This is the code checked into libpng. Calling memcpy with a null 5041915b0bab2b48cf8bf85dc49e76994b033f25450scroggo // source is undefined, even if count is 0, but libpng does not 5051915b0bab2b48cf8bf85dc49e76994b033f25450scroggo // currently check for null or 0. The Skia fix is below. 5061915b0bab2b48cf8bf85dc49e76994b033f25450scroggo // skbug.com/5390 5073965825b97a5809454f5810f7e603cbd02daa036scroggo memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); 5081915b0bab2b48cf8bf85dc49e76994b033f25450scroggo#else 5091915b0bab2b48cf8bf85dc49e76994b033f25450scroggo if (old_buffer) 5101915b0bab2b48cf8bf85dc49e76994b033f25450scroggo memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); 5111915b0bab2b48cf8bf85dc49e76994b033f25450scroggo else if (png_ptr->save_buffer_size) 5121915b0bab2b48cf8bf85dc49e76994b033f25450scroggo png_error(png_ptr, "save_buffer error"); 5131915b0bab2b48cf8bf85dc49e76994b033f25450scroggo#endif 5143965825b97a5809454f5810f7e603cbd02daa036scroggo png_free(png_ptr, old_buffer); 5153965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_max = new_max; 5163965825b97a5809454f5810f7e603cbd02daa036scroggo } 5173965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->current_buffer_size) 5183965825b97a5809454f5810f7e603cbd02daa036scroggo { 5193965825b97a5809454f5810f7e603cbd02daa036scroggo memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, 5203965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); 5213965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_size += png_ptr->current_buffer_size; 5223965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_size = 0; 5233965825b97a5809454f5810f7e603cbd02daa036scroggo } 5243965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_ptr = png_ptr->save_buffer; 5253965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size = 0; 5263965825b97a5809454f5810f7e603cbd02daa036scroggo} 5273965825b97a5809454f5810f7e603cbd02daa036scroggo 5283965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 5293965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, 5303965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t buffer_length) 5313965825b97a5809454f5810f7e603cbd02daa036scroggo{ 5323965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer = buffer; 5333965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_size = buffer_length; 5343965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; 5353965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_ptr = png_ptr->current_buffer; 5363965825b97a5809454f5810f7e603cbd02daa036scroggo} 5373965825b97a5809454f5810f7e603cbd02daa036scroggo 5383965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 5393965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_read_IDAT(png_structrp png_ptr) 5403965825b97a5809454f5810f7e603cbd02daa036scroggo{ 5413965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->mode & PNG_HAVE_CHUNK_HEADER) == 0) 5423965825b97a5809454f5810f7e603cbd02daa036scroggo { 5433965825b97a5809454f5810f7e603cbd02daa036scroggo png_byte chunk_length[4]; 5443965825b97a5809454f5810f7e603cbd02daa036scroggo png_byte chunk_tag[4]; 5453965825b97a5809454f5810f7e603cbd02daa036scroggo 5463965825b97a5809454f5810f7e603cbd02daa036scroggo /* TODO: this code can be commoned up with the same code in push_read */ 5473965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_LT(8) 5483965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_fill_buffer(png_ptr, chunk_length, 4); 5493965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 5503965825b97a5809454f5810f7e603cbd02daa036scroggo png_reset_crc(png_ptr); 5513965825b97a5809454f5810f7e603cbd02daa036scroggo png_crc_read(png_ptr, chunk_tag, 4); 5523965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); 5533965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 5543965825b97a5809454f5810f7e603cbd02daa036scroggo 5553965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->chunk_name != png_IDAT) 5563965825b97a5809454f5810f7e603cbd02daa036scroggo { 5573965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->process_mode = PNG_READ_CHUNK_MODE; 5583965825b97a5809454f5810f7e603cbd02daa036scroggo 5593965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) 5603965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Not enough compressed data"); 5613965825b97a5809454f5810f7e603cbd02daa036scroggo 5623965825b97a5809454f5810f7e603cbd02daa036scroggo return; 5633965825b97a5809454f5810f7e603cbd02daa036scroggo } 5643965825b97a5809454f5810f7e603cbd02daa036scroggo 5653965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->idat_size = png_ptr->push_length; 5663965825b97a5809454f5810f7e603cbd02daa036scroggo } 5673965825b97a5809454f5810f7e603cbd02daa036scroggo 5683965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->idat_size != 0 && png_ptr->save_buffer_size != 0) 5693965825b97a5809454f5810f7e603cbd02daa036scroggo { 5703965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t save_size = png_ptr->save_buffer_size; 5713965825b97a5809454f5810f7e603cbd02daa036scroggo png_uint_32 idat_size = png_ptr->idat_size; 5723965825b97a5809454f5810f7e603cbd02daa036scroggo 5733965825b97a5809454f5810f7e603cbd02daa036scroggo /* We want the smaller of 'idat_size' and 'current_buffer_size', but they 5743965825b97a5809454f5810f7e603cbd02daa036scroggo * are of different types and we don't know which variable has the fewest 5753965825b97a5809454f5810f7e603cbd02daa036scroggo * bits. Carefully select the smaller and cast it to the type of the 5763965825b97a5809454f5810f7e603cbd02daa036scroggo * larger - this cannot overflow. Do not cast in the following test - it 5773965825b97a5809454f5810f7e603cbd02daa036scroggo * will break on either 16-bit or 64-bit platforms. 5783965825b97a5809454f5810f7e603cbd02daa036scroggo */ 5793965825b97a5809454f5810f7e603cbd02daa036scroggo if (idat_size < save_size) 5803965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = (png_size_t)idat_size; 5813965825b97a5809454f5810f7e603cbd02daa036scroggo 5823965825b97a5809454f5810f7e603cbd02daa036scroggo else 5833965825b97a5809454f5810f7e603cbd02daa036scroggo idat_size = (png_uint_32)save_size; 5843965825b97a5809454f5810f7e603cbd02daa036scroggo 5853965825b97a5809454f5810f7e603cbd02daa036scroggo png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 5863965825b97a5809454f5810f7e603cbd02daa036scroggo 5873965825b97a5809454f5810f7e603cbd02daa036scroggo png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); 5883965825b97a5809454f5810f7e603cbd02daa036scroggo 5893965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->idat_size -= idat_size; 5903965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size -= save_size; 5913965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_size -= save_size; 5923965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->save_buffer_ptr += save_size; 5933965825b97a5809454f5810f7e603cbd02daa036scroggo } 5943965825b97a5809454f5810f7e603cbd02daa036scroggo 5953965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->idat_size != 0 && png_ptr->current_buffer_size != 0) 5963965825b97a5809454f5810f7e603cbd02daa036scroggo { 5973965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t save_size = png_ptr->current_buffer_size; 5983965825b97a5809454f5810f7e603cbd02daa036scroggo png_uint_32 idat_size = png_ptr->idat_size; 5993965825b97a5809454f5810f7e603cbd02daa036scroggo 6003965825b97a5809454f5810f7e603cbd02daa036scroggo /* We want the smaller of 'idat_size' and 'current_buffer_size', but they 6013965825b97a5809454f5810f7e603cbd02daa036scroggo * are of different types and we don't know which variable has the fewest 6023965825b97a5809454f5810f7e603cbd02daa036scroggo * bits. Carefully select the smaller and cast it to the type of the 6033965825b97a5809454f5810f7e603cbd02daa036scroggo * larger - this cannot overflow. 6043965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6053965825b97a5809454f5810f7e603cbd02daa036scroggo if (idat_size < save_size) 6063965825b97a5809454f5810f7e603cbd02daa036scroggo save_size = (png_size_t)idat_size; 6073965825b97a5809454f5810f7e603cbd02daa036scroggo 6083965825b97a5809454f5810f7e603cbd02daa036scroggo else 6093965825b97a5809454f5810f7e603cbd02daa036scroggo idat_size = (png_uint_32)save_size; 6103965825b97a5809454f5810f7e603cbd02daa036scroggo 6113965825b97a5809454f5810f7e603cbd02daa036scroggo png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 6123965825b97a5809454f5810f7e603cbd02daa036scroggo 6133965825b97a5809454f5810f7e603cbd02daa036scroggo png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); 6143965825b97a5809454f5810f7e603cbd02daa036scroggo 6153965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->idat_size -= idat_size; 6163965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->buffer_size -= save_size; 6173965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_size -= save_size; 6183965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->current_buffer_ptr += save_size; 6193965825b97a5809454f5810f7e603cbd02daa036scroggo } 6203965825b97a5809454f5810f7e603cbd02daa036scroggo 6213965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->idat_size == 0) 6223965825b97a5809454f5810f7e603cbd02daa036scroggo { 6233965825b97a5809454f5810f7e603cbd02daa036scroggo PNG_PUSH_SAVE_BUFFER_IF_LT(4) 6243965825b97a5809454f5810f7e603cbd02daa036scroggo png_crc_finish(png_ptr, 0); 6253965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 6263965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->mode |= PNG_AFTER_IDAT; 6273965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zowner = 0; 6283965825b97a5809454f5810f7e603cbd02daa036scroggo } 6293965825b97a5809454f5810f7e603cbd02daa036scroggo} 6303965825b97a5809454f5810f7e603cbd02daa036scroggo 6313965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 6323965825b97a5809454f5810f7e603cbd02daa036scroggopng_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, 6333965825b97a5809454f5810f7e603cbd02daa036scroggo png_size_t buffer_length) 6343965825b97a5809454f5810f7e603cbd02daa036scroggo{ 6353965825b97a5809454f5810f7e603cbd02daa036scroggo /* The caller checks for a non-zero buffer length. */ 6363965825b97a5809454f5810f7e603cbd02daa036scroggo if (!(buffer_length > 0) || buffer == NULL) 6373965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "No IDAT data (internal error)"); 6383965825b97a5809454f5810f7e603cbd02daa036scroggo 6393965825b97a5809454f5810f7e603cbd02daa036scroggo /* This routine must process all the data it has been given 6403965825b97a5809454f5810f7e603cbd02daa036scroggo * before returning, calling the row callback as required to 6413965825b97a5809454f5810f7e603cbd02daa036scroggo * handle the uncompressed results. 6423965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6433965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.next_in = buffer; 6443965825b97a5809454f5810f7e603cbd02daa036scroggo /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ 6453965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.avail_in = (uInt)buffer_length; 6463965825b97a5809454f5810f7e603cbd02daa036scroggo 6473965825b97a5809454f5810f7e603cbd02daa036scroggo /* Keep going until the decompressed data is all processed 6483965825b97a5809454f5810f7e603cbd02daa036scroggo * or the stream marked as finished. 6493965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6503965825b97a5809454f5810f7e603cbd02daa036scroggo while (png_ptr->zstream.avail_in > 0 && 6513965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) == 0) 6523965825b97a5809454f5810f7e603cbd02daa036scroggo { 6533965825b97a5809454f5810f7e603cbd02daa036scroggo int ret; 6543965825b97a5809454f5810f7e603cbd02daa036scroggo 6553965825b97a5809454f5810f7e603cbd02daa036scroggo /* We have data for zlib, but we must check that zlib 6563965825b97a5809454f5810f7e603cbd02daa036scroggo * has someplace to put the results. It doesn't matter 6573965825b97a5809454f5810f7e603cbd02daa036scroggo * if we don't expect any results -- it may be the input 6583965825b97a5809454f5810f7e603cbd02daa036scroggo * data is just the LZ end code. 6593965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6603965825b97a5809454f5810f7e603cbd02daa036scroggo if (!(png_ptr->zstream.avail_out > 0)) 6613965825b97a5809454f5810f7e603cbd02daa036scroggo { 6623965825b97a5809454f5810f7e603cbd02daa036scroggo /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ 6633965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, 6643965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->iwidth) + 1); 6653965825b97a5809454f5810f7e603cbd02daa036scroggo 6663965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zstream.next_out = png_ptr->row_buf; 6673965825b97a5809454f5810f7e603cbd02daa036scroggo } 6683965825b97a5809454f5810f7e603cbd02daa036scroggo 6693965825b97a5809454f5810f7e603cbd02daa036scroggo /* Using Z_SYNC_FLUSH here means that an unterminated 6703965825b97a5809454f5810f7e603cbd02daa036scroggo * LZ stream (a stream with a missing end code) can still 6713965825b97a5809454f5810f7e603cbd02daa036scroggo * be handled, otherwise (Z_NO_FLUSH) a future zlib 6723965825b97a5809454f5810f7e603cbd02daa036scroggo * implementation might defer output and therefore 6733965825b97a5809454f5810f7e603cbd02daa036scroggo * change the current behavior (see comments in inflate.c 6743965825b97a5809454f5810f7e603cbd02daa036scroggo * for why this doesn't happen at present with zlib 1.2.5). 6753965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6763965825b97a5809454f5810f7e603cbd02daa036scroggo ret = PNG_INFLATE(png_ptr, Z_SYNC_FLUSH); 6773965825b97a5809454f5810f7e603cbd02daa036scroggo 6783965825b97a5809454f5810f7e603cbd02daa036scroggo /* Check for any failure before proceeding. */ 6793965825b97a5809454f5810f7e603cbd02daa036scroggo if (ret != Z_OK && ret != Z_STREAM_END) 6803965825b97a5809454f5810f7e603cbd02daa036scroggo { 6813965825b97a5809454f5810f7e603cbd02daa036scroggo /* Terminate the decompression. */ 6823965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 6833965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zowner = 0; 6843965825b97a5809454f5810f7e603cbd02daa036scroggo 6853965825b97a5809454f5810f7e603cbd02daa036scroggo /* This may be a truncated stream (missing or 6863965825b97a5809454f5810f7e603cbd02daa036scroggo * damaged end code). Treat that as a warning. 6873965825b97a5809454f5810f7e603cbd02daa036scroggo */ 6883965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_number >= png_ptr->num_rows || 6893965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->pass > 6) 6903965825b97a5809454f5810f7e603cbd02daa036scroggo png_warning(png_ptr, "Truncated compressed data in IDAT"); 6913965825b97a5809454f5810f7e603cbd02daa036scroggo 6923965825b97a5809454f5810f7e603cbd02daa036scroggo else 6933965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "Decompression error in IDAT"); 6943965825b97a5809454f5810f7e603cbd02daa036scroggo 6953965825b97a5809454f5810f7e603cbd02daa036scroggo /* Skip the check on unprocessed input */ 6963965825b97a5809454f5810f7e603cbd02daa036scroggo return; 6973965825b97a5809454f5810f7e603cbd02daa036scroggo } 6983965825b97a5809454f5810f7e603cbd02daa036scroggo 6993965825b97a5809454f5810f7e603cbd02daa036scroggo /* Did inflate output any data? */ 7003965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->zstream.next_out != png_ptr->row_buf) 7013965825b97a5809454f5810f7e603cbd02daa036scroggo { 7023965825b97a5809454f5810f7e603cbd02daa036scroggo /* Is this unexpected data after the last row? 7033965825b97a5809454f5810f7e603cbd02daa036scroggo * If it is, artificially terminate the LZ output 7043965825b97a5809454f5810f7e603cbd02daa036scroggo * here. 7053965825b97a5809454f5810f7e603cbd02daa036scroggo */ 7063965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_number >= png_ptr->num_rows || 7073965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->pass > 6) 7083965825b97a5809454f5810f7e603cbd02daa036scroggo { 7093965825b97a5809454f5810f7e603cbd02daa036scroggo /* Extra data. */ 7103965825b97a5809454f5810f7e603cbd02daa036scroggo png_warning(png_ptr, "Extra compressed data in IDAT"); 7113965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 7123965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->zowner = 0; 7133965825b97a5809454f5810f7e603cbd02daa036scroggo 7143965825b97a5809454f5810f7e603cbd02daa036scroggo /* Do no more processing; skip the unprocessed 7153965825b97a5809454f5810f7e603cbd02daa036scroggo * input check below. 7163965825b97a5809454f5810f7e603cbd02daa036scroggo */ 7173965825b97a5809454f5810f7e603cbd02daa036scroggo return; 7183965825b97a5809454f5810f7e603cbd02daa036scroggo } 7193965825b97a5809454f5810f7e603cbd02daa036scroggo 7203965825b97a5809454f5810f7e603cbd02daa036scroggo /* Do we have a complete row? */ 7213965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->zstream.avail_out == 0) 7223965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_process_row(png_ptr); 7233965825b97a5809454f5810f7e603cbd02daa036scroggo } 7243965825b97a5809454f5810f7e603cbd02daa036scroggo 7253965825b97a5809454f5810f7e603cbd02daa036scroggo /* And check for the end of the stream. */ 7263965825b97a5809454f5810f7e603cbd02daa036scroggo if (ret == Z_STREAM_END) 7273965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 7283965825b97a5809454f5810f7e603cbd02daa036scroggo } 7293965825b97a5809454f5810f7e603cbd02daa036scroggo 7303965825b97a5809454f5810f7e603cbd02daa036scroggo /* All the data should have been processed, if anything 7313965825b97a5809454f5810f7e603cbd02daa036scroggo * is left at this point we have bytes of IDAT data 7323965825b97a5809454f5810f7e603cbd02daa036scroggo * after the zlib end code. 7333965825b97a5809454f5810f7e603cbd02daa036scroggo */ 7343965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->zstream.avail_in > 0) 7353965825b97a5809454f5810f7e603cbd02daa036scroggo png_warning(png_ptr, "Extra compression data in IDAT"); 7363965825b97a5809454f5810f7e603cbd02daa036scroggo} 7373965825b97a5809454f5810f7e603cbd02daa036scroggo 7383965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 7393965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_process_row(png_structrp png_ptr) 7403965825b97a5809454f5810f7e603cbd02daa036scroggo{ 7413965825b97a5809454f5810f7e603cbd02daa036scroggo /* 1.5.6: row_info moved out of png_struct to a local here. */ 7423965825b97a5809454f5810f7e603cbd02daa036scroggo png_row_info row_info; 7433965825b97a5809454f5810f7e603cbd02daa036scroggo 7443965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ 7453965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.color_type = png_ptr->color_type; 7463965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.bit_depth = png_ptr->bit_depth; 7473965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.channels = png_ptr->channels; 7483965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.pixel_depth = png_ptr->pixel_depth; 7493965825b97a5809454f5810f7e603cbd02daa036scroggo row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); 7503965825b97a5809454f5810f7e603cbd02daa036scroggo 7513965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) 7523965825b97a5809454f5810f7e603cbd02daa036scroggo { 7533965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) 7543965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, 7553965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->prev_row + 1, png_ptr->row_buf[0]); 7563965825b97a5809454f5810f7e603cbd02daa036scroggo else 7573965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "bad adaptive filter value"); 7583965825b97a5809454f5810f7e603cbd02daa036scroggo } 7593965825b97a5809454f5810f7e603cbd02daa036scroggo 7603965825b97a5809454f5810f7e603cbd02daa036scroggo /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before 7613965825b97a5809454f5810f7e603cbd02daa036scroggo * 1.5.6, while the buffer really is this big in current versions of libpng 7623965825b97a5809454f5810f7e603cbd02daa036scroggo * it may not be in the future, so this was changed just to copy the 7633965825b97a5809454f5810f7e603cbd02daa036scroggo * interlaced row count: 7643965825b97a5809454f5810f7e603cbd02daa036scroggo */ 7653965825b97a5809454f5810f7e603cbd02daa036scroggo memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); 7663965825b97a5809454f5810f7e603cbd02daa036scroggo 7673965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_TRANSFORMS_SUPPORTED 7683965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->transformations != 0) 7693965825b97a5809454f5810f7e603cbd02daa036scroggo png_do_read_transformations(png_ptr, &row_info); 7703965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 7713965825b97a5809454f5810f7e603cbd02daa036scroggo 7723965825b97a5809454f5810f7e603cbd02daa036scroggo /* The transformed pixel depth should match the depth now in row_info. */ 7733965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->transformed_pixel_depth == 0) 7743965825b97a5809454f5810f7e603cbd02daa036scroggo { 7753965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->transformed_pixel_depth = row_info.pixel_depth; 7763965825b97a5809454f5810f7e603cbd02daa036scroggo if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) 7773965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "progressive row overflow"); 7783965825b97a5809454f5810f7e603cbd02daa036scroggo } 7793965825b97a5809454f5810f7e603cbd02daa036scroggo 7803965825b97a5809454f5810f7e603cbd02daa036scroggo else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) 7813965825b97a5809454f5810f7e603cbd02daa036scroggo png_error(png_ptr, "internal progressive row size calculation error"); 7823965825b97a5809454f5810f7e603cbd02daa036scroggo 7833965825b97a5809454f5810f7e603cbd02daa036scroggo 7843965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_INTERLACING_SUPPORTED 7853965825b97a5809454f5810f7e603cbd02daa036scroggo /* Expand interlaced rows to full size */ 7863965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->interlaced != 0 && 7873965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->transformations & PNG_INTERLACE) != 0) 7883965825b97a5809454f5810f7e603cbd02daa036scroggo { 7893965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass < 6) 7903965825b97a5809454f5810f7e603cbd02daa036scroggo png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 7913965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->transformations); 7923965825b97a5809454f5810f7e603cbd02daa036scroggo 7933965825b97a5809454f5810f7e603cbd02daa036scroggo switch (png_ptr->pass) 7943965825b97a5809454f5810f7e603cbd02daa036scroggo { 7953965825b97a5809454f5810f7e603cbd02daa036scroggo case 0: 7963965825b97a5809454f5810f7e603cbd02daa036scroggo { 7973965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 7983965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 8 && png_ptr->pass == 0; i++) 7993965825b97a5809454f5810f7e603cbd02daa036scroggo { 8003965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 8013965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ 8023965825b97a5809454f5810f7e603cbd02daa036scroggo } 8033965825b97a5809454f5810f7e603cbd02daa036scroggo 8043965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 2) /* Pass 1 might be empty */ 8053965825b97a5809454f5810f7e603cbd02daa036scroggo { 8063965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 4 && png_ptr->pass == 2; i++) 8073965825b97a5809454f5810f7e603cbd02daa036scroggo { 8083965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8093965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8103965825b97a5809454f5810f7e603cbd02daa036scroggo } 8113965825b97a5809454f5810f7e603cbd02daa036scroggo } 8123965825b97a5809454f5810f7e603cbd02daa036scroggo 8133965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 4 && png_ptr->height <= 4) 8143965825b97a5809454f5810f7e603cbd02daa036scroggo { 8153965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 4; i++) 8163965825b97a5809454f5810f7e603cbd02daa036scroggo { 8173965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8183965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8193965825b97a5809454f5810f7e603cbd02daa036scroggo } 8203965825b97a5809454f5810f7e603cbd02daa036scroggo } 8213965825b97a5809454f5810f7e603cbd02daa036scroggo 8223965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 6 && png_ptr->height <= 4) 8233965825b97a5809454f5810f7e603cbd02daa036scroggo { 8243965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8253965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8263965825b97a5809454f5810f7e603cbd02daa036scroggo } 8273965825b97a5809454f5810f7e603cbd02daa036scroggo 8283965825b97a5809454f5810f7e603cbd02daa036scroggo break; 8293965825b97a5809454f5810f7e603cbd02daa036scroggo } 8303965825b97a5809454f5810f7e603cbd02daa036scroggo 8313965825b97a5809454f5810f7e603cbd02daa036scroggo case 1: 8323965825b97a5809454f5810f7e603cbd02daa036scroggo { 8333965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 8343965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 8 && png_ptr->pass == 1; i++) 8353965825b97a5809454f5810f7e603cbd02daa036scroggo { 8363965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 8373965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8383965825b97a5809454f5810f7e603cbd02daa036scroggo } 8393965825b97a5809454f5810f7e603cbd02daa036scroggo 8403965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 2) /* Skip top 4 generated rows */ 8413965825b97a5809454f5810f7e603cbd02daa036scroggo { 8423965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 4 && png_ptr->pass == 2; i++) 8433965825b97a5809454f5810f7e603cbd02daa036scroggo { 8443965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8453965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8463965825b97a5809454f5810f7e603cbd02daa036scroggo } 8473965825b97a5809454f5810f7e603cbd02daa036scroggo } 8483965825b97a5809454f5810f7e603cbd02daa036scroggo 8493965825b97a5809454f5810f7e603cbd02daa036scroggo break; 8503965825b97a5809454f5810f7e603cbd02daa036scroggo } 8513965825b97a5809454f5810f7e603cbd02daa036scroggo 8523965825b97a5809454f5810f7e603cbd02daa036scroggo case 2: 8533965825b97a5809454f5810f7e603cbd02daa036scroggo { 8543965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 8553965825b97a5809454f5810f7e603cbd02daa036scroggo 8563965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 4 && png_ptr->pass == 2; i++) 8573965825b97a5809454f5810f7e603cbd02daa036scroggo { 8583965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 8593965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8603965825b97a5809454f5810f7e603cbd02daa036scroggo } 8613965825b97a5809454f5810f7e603cbd02daa036scroggo 8623965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 4 && png_ptr->pass == 2; i++) 8633965825b97a5809454f5810f7e603cbd02daa036scroggo { 8643965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8653965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8663965825b97a5809454f5810f7e603cbd02daa036scroggo } 8673965825b97a5809454f5810f7e603cbd02daa036scroggo 8683965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 4) /* Pass 3 might be empty */ 8693965825b97a5809454f5810f7e603cbd02daa036scroggo { 8703965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 4; i++) 8713965825b97a5809454f5810f7e603cbd02daa036scroggo { 8723965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8733965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8743965825b97a5809454f5810f7e603cbd02daa036scroggo } 8753965825b97a5809454f5810f7e603cbd02daa036scroggo } 8763965825b97a5809454f5810f7e603cbd02daa036scroggo 8773965825b97a5809454f5810f7e603cbd02daa036scroggo break; 8783965825b97a5809454f5810f7e603cbd02daa036scroggo } 8793965825b97a5809454f5810f7e603cbd02daa036scroggo 8803965825b97a5809454f5810f7e603cbd02daa036scroggo case 3: 8813965825b97a5809454f5810f7e603cbd02daa036scroggo { 8823965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 8833965825b97a5809454f5810f7e603cbd02daa036scroggo 8843965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 4 && png_ptr->pass == 3; i++) 8853965825b97a5809454f5810f7e603cbd02daa036scroggo { 8863965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 8873965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8883965825b97a5809454f5810f7e603cbd02daa036scroggo } 8893965825b97a5809454f5810f7e603cbd02daa036scroggo 8903965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 4) /* Skip top two generated rows */ 8913965825b97a5809454f5810f7e603cbd02daa036scroggo { 8923965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 4; i++) 8933965825b97a5809454f5810f7e603cbd02daa036scroggo { 8943965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 8953965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 8963965825b97a5809454f5810f7e603cbd02daa036scroggo } 8973965825b97a5809454f5810f7e603cbd02daa036scroggo } 8983965825b97a5809454f5810f7e603cbd02daa036scroggo 8993965825b97a5809454f5810f7e603cbd02daa036scroggo break; 9003965825b97a5809454f5810f7e603cbd02daa036scroggo } 9013965825b97a5809454f5810f7e603cbd02daa036scroggo 9023965825b97a5809454f5810f7e603cbd02daa036scroggo case 4: 9033965825b97a5809454f5810f7e603cbd02daa036scroggo { 9043965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 9053965825b97a5809454f5810f7e603cbd02daa036scroggo 9063965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 4; i++) 9073965825b97a5809454f5810f7e603cbd02daa036scroggo { 9083965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 9093965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9103965825b97a5809454f5810f7e603cbd02daa036scroggo } 9113965825b97a5809454f5810f7e603cbd02daa036scroggo 9123965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 4; i++) 9133965825b97a5809454f5810f7e603cbd02daa036scroggo { 9143965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 9153965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9163965825b97a5809454f5810f7e603cbd02daa036scroggo } 9173965825b97a5809454f5810f7e603cbd02daa036scroggo 9183965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 6) /* Pass 5 might be empty */ 9193965825b97a5809454f5810f7e603cbd02daa036scroggo { 9203965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 9213965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9223965825b97a5809454f5810f7e603cbd02daa036scroggo } 9233965825b97a5809454f5810f7e603cbd02daa036scroggo 9243965825b97a5809454f5810f7e603cbd02daa036scroggo break; 9253965825b97a5809454f5810f7e603cbd02daa036scroggo } 9263965825b97a5809454f5810f7e603cbd02daa036scroggo 9273965825b97a5809454f5810f7e603cbd02daa036scroggo case 5: 9283965825b97a5809454f5810f7e603cbd02daa036scroggo { 9293965825b97a5809454f5810f7e603cbd02daa036scroggo int i; 9303965825b97a5809454f5810f7e603cbd02daa036scroggo 9313965825b97a5809454f5810f7e603cbd02daa036scroggo for (i = 0; i < 2 && png_ptr->pass == 5; i++) 9323965825b97a5809454f5810f7e603cbd02daa036scroggo { 9333965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 9343965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9353965825b97a5809454f5810f7e603cbd02daa036scroggo } 9363965825b97a5809454f5810f7e603cbd02daa036scroggo 9373965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass == 6) /* Skip top generated row */ 9383965825b97a5809454f5810f7e603cbd02daa036scroggo { 9393965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 9403965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9413965825b97a5809454f5810f7e603cbd02daa036scroggo } 9423965825b97a5809454f5810f7e603cbd02daa036scroggo 9433965825b97a5809454f5810f7e603cbd02daa036scroggo break; 9443965825b97a5809454f5810f7e603cbd02daa036scroggo } 9453965825b97a5809454f5810f7e603cbd02daa036scroggo 9463965825b97a5809454f5810f7e603cbd02daa036scroggo default: 9473965825b97a5809454f5810f7e603cbd02daa036scroggo case 6: 9483965825b97a5809454f5810f7e603cbd02daa036scroggo { 9493965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 9503965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9513965825b97a5809454f5810f7e603cbd02daa036scroggo 9523965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass != 6) 9533965825b97a5809454f5810f7e603cbd02daa036scroggo break; 9543965825b97a5809454f5810f7e603cbd02daa036scroggo 9553965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, NULL); 9563965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9573965825b97a5809454f5810f7e603cbd02daa036scroggo } 9583965825b97a5809454f5810f7e603cbd02daa036scroggo } 9593965825b97a5809454f5810f7e603cbd02daa036scroggo } 9603965825b97a5809454f5810f7e603cbd02daa036scroggo else 9613965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 9623965825b97a5809454f5810f7e603cbd02daa036scroggo { 9633965825b97a5809454f5810f7e603cbd02daa036scroggo png_push_have_row(png_ptr, png_ptr->row_buf + 1); 9643965825b97a5809454f5810f7e603cbd02daa036scroggo png_read_push_finish_row(png_ptr); 9653965825b97a5809454f5810f7e603cbd02daa036scroggo } 9663965825b97a5809454f5810f7e603cbd02daa036scroggo} 9673965825b97a5809454f5810f7e603cbd02daa036scroggo 9683965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 9693965825b97a5809454f5810f7e603cbd02daa036scroggopng_read_push_finish_row(png_structrp png_ptr) 9703965825b97a5809454f5810f7e603cbd02daa036scroggo{ 9713965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_INTERLACING_SUPPORTED 9723965825b97a5809454f5810f7e603cbd02daa036scroggo /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 9733965825b97a5809454f5810f7e603cbd02daa036scroggo 9743965825b97a5809454f5810f7e603cbd02daa036scroggo /* Start of interlace block */ 9753965825b97a5809454f5810f7e603cbd02daa036scroggo static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; 9763965825b97a5809454f5810f7e603cbd02daa036scroggo 9773965825b97a5809454f5810f7e603cbd02daa036scroggo /* Offset to next interlace block */ 9783965825b97a5809454f5810f7e603cbd02daa036scroggo static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; 9793965825b97a5809454f5810f7e603cbd02daa036scroggo 9803965825b97a5809454f5810f7e603cbd02daa036scroggo /* Start of interlace block in the y direction */ 9813965825b97a5809454f5810f7e603cbd02daa036scroggo static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; 9823965825b97a5809454f5810f7e603cbd02daa036scroggo 9833965825b97a5809454f5810f7e603cbd02daa036scroggo /* Offset to next interlace block in the y direction */ 9843965825b97a5809454f5810f7e603cbd02daa036scroggo static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; 9853965825b97a5809454f5810f7e603cbd02daa036scroggo 9863965825b97a5809454f5810f7e603cbd02daa036scroggo /* Height of interlace block. This is not currently used - if you need 9873965825b97a5809454f5810f7e603cbd02daa036scroggo * it, uncomment it here and in png.h 9883965825b97a5809454f5810f7e603cbd02daa036scroggo static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; 9893965825b97a5809454f5810f7e603cbd02daa036scroggo */ 9903965825b97a5809454f5810f7e603cbd02daa036scroggo#endif 9913965825b97a5809454f5810f7e603cbd02daa036scroggo 9923965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->row_number++; 9933965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_number < png_ptr->num_rows) 9943965825b97a5809454f5810f7e603cbd02daa036scroggo return; 9953965825b97a5809454f5810f7e603cbd02daa036scroggo 9963965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_INTERLACING_SUPPORTED 9973965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->interlaced != 0) 9983965825b97a5809454f5810f7e603cbd02daa036scroggo { 9993965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->row_number = 0; 10003965825b97a5809454f5810f7e603cbd02daa036scroggo memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 10013965825b97a5809454f5810f7e603cbd02daa036scroggo 10023965825b97a5809454f5810f7e603cbd02daa036scroggo do 10033965825b97a5809454f5810f7e603cbd02daa036scroggo { 10043965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->pass++; 10053965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->pass == 1 && png_ptr->width < 5) || 10063965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->pass == 3 && png_ptr->width < 3) || 10073965825b97a5809454f5810f7e603cbd02daa036scroggo (png_ptr->pass == 5 && png_ptr->width < 2)) 10083965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->pass++; 10093965825b97a5809454f5810f7e603cbd02daa036scroggo 10103965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass > 7) 10113965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->pass--; 10123965825b97a5809454f5810f7e603cbd02daa036scroggo 10133965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->pass >= 7) 10143965825b97a5809454f5810f7e603cbd02daa036scroggo break; 10153965825b97a5809454f5810f7e603cbd02daa036scroggo 10163965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->iwidth = (png_ptr->width + 10173965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_inc[png_ptr->pass] - 1 - 10183965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_start[png_ptr->pass]) / 10193965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_inc[png_ptr->pass]; 10203965825b97a5809454f5810f7e603cbd02daa036scroggo 10213965825b97a5809454f5810f7e603cbd02daa036scroggo if ((png_ptr->transformations & PNG_INTERLACE) != 0) 10223965825b97a5809454f5810f7e603cbd02daa036scroggo break; 10233965825b97a5809454f5810f7e603cbd02daa036scroggo 10243965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->num_rows = (png_ptr->height + 10253965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_yinc[png_ptr->pass] - 1 - 10263965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_ystart[png_ptr->pass]) / 10273965825b97a5809454f5810f7e603cbd02daa036scroggo png_pass_yinc[png_ptr->pass]; 10283965825b97a5809454f5810f7e603cbd02daa036scroggo 10293965825b97a5809454f5810f7e603cbd02daa036scroggo } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); 10303965825b97a5809454f5810f7e603cbd02daa036scroggo } 10313965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* READ_INTERLACING */ 10323965825b97a5809454f5810f7e603cbd02daa036scroggo} 10333965825b97a5809454f5810f7e603cbd02daa036scroggo 10343965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 10353965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_have_info(png_structrp png_ptr, png_inforp info_ptr) 10363965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10373965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->info_fn != NULL) 10383965825b97a5809454f5810f7e603cbd02daa036scroggo (*(png_ptr->info_fn))(png_ptr, info_ptr); 10393965825b97a5809454f5810f7e603cbd02daa036scroggo} 10403965825b97a5809454f5810f7e603cbd02daa036scroggo 10413965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 10423965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_have_end(png_structrp png_ptr, png_inforp info_ptr) 10433965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10443965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->end_fn != NULL) 10453965825b97a5809454f5810f7e603cbd02daa036scroggo (*(png_ptr->end_fn))(png_ptr, info_ptr); 10463965825b97a5809454f5810f7e603cbd02daa036scroggo} 10473965825b97a5809454f5810f7e603cbd02daa036scroggo 10483965825b97a5809454f5810f7e603cbd02daa036scroggovoid /* PRIVATE */ 10493965825b97a5809454f5810f7e603cbd02daa036scroggopng_push_have_row(png_structrp png_ptr, png_bytep row) 10503965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10513965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr->row_fn != NULL) 10523965825b97a5809454f5810f7e603cbd02daa036scroggo (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, 10533965825b97a5809454f5810f7e603cbd02daa036scroggo (int)png_ptr->pass); 10543965825b97a5809454f5810f7e603cbd02daa036scroggo} 10553965825b97a5809454f5810f7e603cbd02daa036scroggo 10563965825b97a5809454f5810f7e603cbd02daa036scroggo#ifdef PNG_READ_INTERLACING_SUPPORTED 10573965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI 10583965825b97a5809454f5810f7e603cbd02daa036scroggopng_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, 10593965825b97a5809454f5810f7e603cbd02daa036scroggo png_const_bytep new_row) 10603965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10613965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL) 10623965825b97a5809454f5810f7e603cbd02daa036scroggo return; 10633965825b97a5809454f5810f7e603cbd02daa036scroggo 10643965825b97a5809454f5810f7e603cbd02daa036scroggo /* new_row is a flag here - if it is NULL then the app callback was called 10653965825b97a5809454f5810f7e603cbd02daa036scroggo * from an empty row (see the calls to png_struct::row_fn below), otherwise 10663965825b97a5809454f5810f7e603cbd02daa036scroggo * it must be png_ptr->row_buf+1 10673965825b97a5809454f5810f7e603cbd02daa036scroggo */ 10683965825b97a5809454f5810f7e603cbd02daa036scroggo if (new_row != NULL) 10693965825b97a5809454f5810f7e603cbd02daa036scroggo png_combine_row(png_ptr, old_row, 1/*blocky display*/); 10703965825b97a5809454f5810f7e603cbd02daa036scroggo} 10713965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* READ_INTERLACING */ 10723965825b97a5809454f5810f7e603cbd02daa036scroggo 10733965825b97a5809454f5810f7e603cbd02daa036scroggovoid PNGAPI 10743965825b97a5809454f5810f7e603cbd02daa036scroggopng_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, 10753965825b97a5809454f5810f7e603cbd02daa036scroggo png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, 10763965825b97a5809454f5810f7e603cbd02daa036scroggo png_progressive_end_ptr end_fn) 10773965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10783965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL) 10793965825b97a5809454f5810f7e603cbd02daa036scroggo return; 10803965825b97a5809454f5810f7e603cbd02daa036scroggo 10813965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->info_fn = info_fn; 10823965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->row_fn = row_fn; 10833965825b97a5809454f5810f7e603cbd02daa036scroggo png_ptr->end_fn = end_fn; 10843965825b97a5809454f5810f7e603cbd02daa036scroggo 10853965825b97a5809454f5810f7e603cbd02daa036scroggo png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); 10863965825b97a5809454f5810f7e603cbd02daa036scroggo} 10873965825b97a5809454f5810f7e603cbd02daa036scroggo 10883965825b97a5809454f5810f7e603cbd02daa036scroggopng_voidp PNGAPI 10893965825b97a5809454f5810f7e603cbd02daa036scroggopng_get_progressive_ptr(png_const_structrp png_ptr) 10903965825b97a5809454f5810f7e603cbd02daa036scroggo{ 10913965825b97a5809454f5810f7e603cbd02daa036scroggo if (png_ptr == NULL) 10923965825b97a5809454f5810f7e603cbd02daa036scroggo return (NULL); 10933965825b97a5809454f5810f7e603cbd02daa036scroggo 10943965825b97a5809454f5810f7e603cbd02daa036scroggo return png_ptr->io_ptr; 10953965825b97a5809454f5810f7e603cbd02daa036scroggo} 10963965825b97a5809454f5810f7e603cbd02daa036scroggo#endif /* PROGRESSIVE_READ */ 1097