1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngpread.c - read a png file in push mode 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 4b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Last changed in libpng 1.6.10 [March 6, 2014] 5b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari * Copyright (c) 1998-2014 Glenn Randers-Pehrson 6893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) 7893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) 8a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 9a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * This code is released under the libpng license. 10a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * For conditions of distribution and use, see the disclaimer 11a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * and license in png.h 12893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 14b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#include "pngpriv.h" 15b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_PROGRESSIVE_READ_SUPPORTED 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Push model modes */ 19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_SIG_MODE 0 20893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_CHUNK_MODE 1 21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_IDAT_MODE 2 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_SKIP_MODE 3 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_tEXt_MODE 4 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_zTXt_MODE 5 25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_DONE_MODE 6 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_READ_iTXt_MODE 7 27893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_ERROR_MODE 8 28893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 29893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 30b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_process_data(png_structrp png_ptr, png_inforp info_ptr, 31b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_bytep buffer, png_size_t buffer_size) 32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 33a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL || info_ptr == NULL) 34a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 35a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_restore_buffer(png_ptr, buffer, buffer_size); 37893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (png_ptr->buffer_size) 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_process_some_data(png_ptr, info_ptr); 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 44b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_size_t PNGAPI 45b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_process_data_pause(png_structrp png_ptr, int save) 46b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 47b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr != NULL) 48b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 49b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* It's easiest for the caller if we do the save, then the caller doesn't 50b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * have to supply the same data again: 51b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 52b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (save) 53b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_save_buffer(png_ptr); 54b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 55b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 56b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* This includes any pending saved bytes: */ 57b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t remaining = png_ptr->buffer_size; 58b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->buffer_size = 0; 59b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 60b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* So subtract the saved buffer size, unless all the data 61b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is actually 'saved', in which case we just return 0 62b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 63b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->save_buffer_size < remaining) 64b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return remaining - png_ptr->save_buffer_size; 65b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 66b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 67b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 68b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return 0; 69b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 70b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 71b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_uint_32 PNGAPI 72b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_process_data_skip(png_structrp png_ptr) 73b50c217251b086440efcdb273c22f86a06c80cbaChris Craik{ 74b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 remaining = 0; 75b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 76b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr != NULL && png_ptr->process_mode == PNG_SKIP_MODE && 77b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->skip_length > 0) 78b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 79b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* At the end of png_process_data the buffer size must be 0 (see the loop 80b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * above) so we can detect a broken call here: 81b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 82b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->buffer_size != 0) 83b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, 84b50c217251b086440efcdb273c22f86a06c80cbaChris Craik "png_process_data_skip called inside png_process_data"); 85b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 86b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If is impossible for there to be a saved buffer at this point - 87b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * otherwise we could not be in SKIP mode. This will also happen if 88b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * png_process_skip is called inside png_process_data (but only very 89b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * rarely.) 90b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 91b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->save_buffer_size != 0) 92b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "png_process_data_skip called with saved data"); 93b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 94b50c217251b086440efcdb273c22f86a06c80cbaChris Craik remaining = png_ptr->skip_length; 95b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->skip_length = 0; 96b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->process_mode = PNG_READ_CHUNK_MODE; 97b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 98b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 99b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return remaining; 100b50c217251b086440efcdb273c22f86a06c80cbaChris Craik} 101b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* What we do with the incoming data depends on what we were previously 103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * doing before we ran out of data... 104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 106b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_process_some_data(png_structrp png_ptr, png_inforp info_ptr) 107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 108a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 109a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 110a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->process_mode) 112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_READ_SIG_MODE: 114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_read_sig(png_ptr, info_ptr); 116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 118a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_READ_CHUNK_MODE: 120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_read_chunk(png_ptr, info_ptr); 122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 124a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_READ_IDAT_MODE: 126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_read_IDAT(png_ptr); 128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 130a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_SKIP_MODE: 132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_crc_finish(png_ptr); 134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 136a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size = 0; 140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Read any remaining signature bytes from the stream and compare them with 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * the correct PNG signature. It is possible that this routine is called 147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * with bytes already read from the signature, either because they have been 148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * checked by the calling application, or because of multiple calls to this 149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * routine. 150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 152b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_read_sig(png_structrp png_ptr, png_inforp info_ptr) 153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 154b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t num_checked = png_ptr->sig_bytes, /* SAFE, does not exceed 8 */ 155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_to_check = 8 - num_checked; 156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->buffer_size < num_to_check) 158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num_to_check = png_ptr->buffer_size; 160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_fill_buffer(png_ptr, &(info_ptr->signature[num_checked]), 163b50c217251b086440efcdb273c22f86a06c80cbaChris Craik num_to_check); 1644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->sig_bytes = (png_byte)(png_ptr->sig_bytes + num_to_check); 165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_sig_cmp(info_ptr->signature, num_checked, num_to_check)) 167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num_checked < 4 && 169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_sig_cmp(info_ptr->signature, num_checked, num_to_check - 4)) 170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Not a PNG file"); 171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "PNG file corrupted by ASCII conversion"); 174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->sig_bytes >= 8) 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_READ_CHUNK_MODE; 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 185b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr) 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 187b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 chunk_name; 188b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 189b50c217251b086440efcdb273c22f86a06c80cbaChris Craik int keep; /* unknown handling method */ 190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* First we make sure we have enough data for the 4 byte chunk name 193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * and the 4 byte chunk length before proceeding with decoding the 194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * chunk data. To fully decode each of these chunks, we also make 195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * sure we have enough data in the buffer for the 4 byte CRC at the 196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * end of every chunk (except IDAT, which is handled separately). 197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte chunk_length[4]; 201b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte chunk_tag[4]; 202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->buffer_size < 8) 204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_fill_buffer(png_ptr, chunk_length, 4); 2104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_reset_crc(png_ptr); 212b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_crc_read(png_ptr, chunk_tag, 4); 213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); 2144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_check_chunk_name(png_ptr, png_ptr->chunk_name); 215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 218b50c217251b086440efcdb273c22f86a06c80cbaChris Craik chunk_name = png_ptr->chunk_name; 219b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 220b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (chunk_name == png_IDAT) 221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->mode & PNG_AFTER_IDAT) 223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_HAVE_CHUNK_AFTER_IDAT; 224b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 225b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* If we reach an IDAT chunk, this means we have read all of the 226b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * header chunks, and we can start reading the image (or if this 227b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * is called after the image has been read - we have an error). 228b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 229b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->mode & PNG_HAVE_IHDR)) 230b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "Missing IHDR before IDAT"); 231b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 232b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 233b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->mode & PNG_HAVE_PLTE)) 234b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "Missing PLTE before IDAT"); 235b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 236b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->mode |= PNG_HAVE_IDAT; 237b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari png_ptr->process_mode = PNG_READ_IDAT_MODE; 238b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 239b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->mode & PNG_HAVE_CHUNK_AFTER_IDAT)) 240b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->push_length == 0) 241b50c217251b086440efcdb273c22f86a06c80cbaChris Craik return; 242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 243b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->mode & PNG_AFTER_IDAT) 244b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_benign_error(png_ptr, "Too many IDATs found"); 245b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 246b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 247b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (chunk_name == png_IHDR) 248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->push_length != 13) 2504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_error(png_ptr, "Invalid IHDR length"); 251a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 257a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_IHDR(png_ptr, info_ptr, png_ptr->push_length); 259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 260a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_IEND) 262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 268a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_IEND(png_ptr, info_ptr, png_ptr->push_length); 270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_READ_DONE_MODE; 272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_end(png_ptr, info_ptr); 273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 274a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 276b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if ((keep = png_chunk_unknown_handling(png_ptr, chunk_name)) != 0) 277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 283a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 284b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, keep); 285a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 286b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (chunk_name == png_PLTE) 287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_HAVE_PLTE; 288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 290b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 291b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_PLTE) 292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_PLTE(png_ptr, info_ptr, png_ptr->push_length); 299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 300a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 301b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_IDAT) 302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->idat_size = png_ptr->push_length; 304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_READ_IDAT_MODE; 305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_info(png_ptr, info_ptr); 3065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.avail_out = 3075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (uInt) PNG_ROWBYTES(png_ptr->pixel_depth, 3085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->iwidth) + 1; 309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.next_out = png_ptr->row_buf; 310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 312a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_gAMA_SUPPORTED 314b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->chunk_name == png_gAMA) 315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 321a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_gAMA(png_ptr, info_ptr, png_ptr->push_length); 323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 324a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sBIT_SUPPORTED 327b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->chunk_name == png_sBIT) 328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 334a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_sBIT(png_ptr, info_ptr, png_ptr->push_length); 336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 337a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_cHRM_SUPPORTED 340b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->chunk_name == png_cHRM) 341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 347a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_cHRM(png_ptr, info_ptr, png_ptr->push_length); 349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 350a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 353b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_sRGB) 354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 360a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_sRGB(png_ptr, info_ptr, png_ptr->push_length); 362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 363a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iCCP_SUPPORTED 366b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->chunk_name == png_iCCP) 367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 373a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_iCCP(png_ptr, info_ptr, png_ptr->push_length); 375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 376a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sPLT_SUPPORTED 379b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_sPLT) 380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 386a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_sPLT(png_ptr, info_ptr, png_ptr->push_length); 388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 389a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tRNS_SUPPORTED 392b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_tRNS) 393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 399a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_tRNS(png_ptr, info_ptr, png_ptr->push_length); 401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 402a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_bKGD_SUPPORTED 405b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_bKGD) 406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 412a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_bKGD(png_ptr, info_ptr, png_ptr->push_length); 414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 415a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_hIST_SUPPORTED 418b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_hIST) 419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 425a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_hIST(png_ptr, info_ptr, png_ptr->push_length); 427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 428a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pHYs_SUPPORTED 431b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_pHYs) 432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 438a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_pHYs(png_ptr, info_ptr, png_ptr->push_length); 440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 441a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_oFFs_SUPPORTED 444b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_oFFs) 445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 451a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_oFFs(png_ptr, info_ptr, png_ptr->push_length); 453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 455a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 4565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pCAL_SUPPORTED 457b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_pCAL) 458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 464a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_pCAL(png_ptr, info_ptr, png_ptr->push_length); 466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 467a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sCAL_SUPPORTED 470b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_sCAL) 471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 477a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_sCAL(png_ptr, info_ptr, png_ptr->push_length); 479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 480a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tIME_SUPPORTED 483b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_tIME) 484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 490a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_handle_tIME(png_ptr, info_ptr, png_ptr->push_length); 492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 493a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 4955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tEXt_SUPPORTED 496b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_tEXt) 497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 503a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 504b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_handle_tEXt(png_ptr, info_ptr, png_ptr->push_length); 505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 506a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 5085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_zTXt_SUPPORTED 509b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_zTXt) 510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 516a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 517b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_handle_zTXt(png_ptr, info_ptr, png_ptr->push_length); 518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 519a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 5215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iTXt_SUPPORTED 522b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (chunk_name == png_iTXt) 523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 529a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 530b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_handle_iTXt(png_ptr, info_ptr, png_ptr->push_length); 531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 533b478e66e7c2621eef5f465e4629ce642db00716bSireesh Tripurari 534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->push_length + 4 > png_ptr->buffer_size) 537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 541b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_handle_unknown(png_ptr, info_ptr, png_ptr->push_length, 542b50c217251b086440efcdb273c22f86a06c80cbaChris Craik PNG_HANDLE_CHUNK_AS_DEFAULT); 543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 549b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_crc_skip(png_structrp png_ptr, png_uint_32 skip) 550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_SKIP_MODE; 552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->skip_length = skip; 553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 556b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_crc_finish(png_structrp png_ptr) 557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->skip_length && png_ptr->save_buffer_size) 559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 560b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t save_size = png_ptr->save_buffer_size; 561b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 skip_length = png_ptr->skip_length; 562b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 563b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We want the smaller of 'skip_length' and 'save_buffer_size', but 564b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * they are of different types and we don't know which variable has the 565b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * fewest bits. Carefully select the smaller and cast it to the type of 566b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the larger - this cannot overflow. Do not cast in the following test 567b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * - it will break on either 16 or 64 bit platforms. 568b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 569b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (skip_length < save_size) 570b50c217251b086440efcdb273c22f86a06c80cbaChris Craik save_size = (png_size_t)skip_length; 571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 573b50c217251b086440efcdb273c22f86a06c80cbaChris Craik skip_length = (png_uint_32)save_size; 574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 577b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->skip_length -= skip_length; 578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_size -= save_size; 580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_ptr += save_size; 581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->skip_length && png_ptr->current_buffer_size) 583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 584b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t save_size = png_ptr->current_buffer_size; 585b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 skip_length = png_ptr->skip_length; 586b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 587b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We want the smaller of 'skip_length' and 'current_buffer_size', here, 588b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * the same problem exists as above and the same solution. 589b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 590b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (skip_length < save_size) 591b50c217251b086440efcdb273c22f86a06c80cbaChris Craik save_size = (png_size_t)skip_length; 592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 594b50c217251b086440efcdb273c22f86a06c80cbaChris Craik skip_length = (png_uint_32)save_size; 595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 598b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->skip_length -= skip_length; 599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_size -= save_size; 601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_ptr += save_size; 602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!png_ptr->skip_length) 604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->buffer_size < 4) 606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, 0); 612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_READ_CHUNK_MODE; 613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 616b50c217251b086440efcdb273c22f86a06c80cbaChris Craikvoid PNGCBAPI 617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_push_fill_buffer(png_structp png_ptr, png_bytep buffer, png_size_t length) 618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep ptr; 620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 621a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 622a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 623a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ptr = buffer; 625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->save_buffer_size) 626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t save_size; 628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length < png_ptr->save_buffer_size) 630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save_size = length; 631b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save_size = png_ptr->save_buffer_size; 634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 635b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memcpy(ptr, png_ptr->save_buffer_ptr, save_size); 636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length -= save_size; 637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ptr += save_size; 638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_size -= save_size; 640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_ptr += save_size; 641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length && png_ptr->current_buffer_size) 643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t save_size; 645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length < png_ptr->current_buffer_size) 647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save_size = length; 648a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project save_size = png_ptr->current_buffer_size; 651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 652b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memcpy(ptr, png_ptr->current_buffer_ptr, save_size); 653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_size -= save_size; 655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_ptr += save_size; 656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 660b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_save_buffer(png_structrp png_ptr) 661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->save_buffer_size) 663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->save_buffer_ptr != png_ptr->save_buffer) 665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 6664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_size_t i, istop; 667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp; 668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp; 669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project istop = png_ptr->save_buffer_size; 671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0, sp = png_ptr->save_buffer_ptr, dp = png_ptr->save_buffer; 672b50c217251b086440efcdb273c22f86a06c80cbaChris Craik i < istop; i++, sp++, dp++) 673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp = *sp; 675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->save_buffer_size + png_ptr->current_buffer_size > 679b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->save_buffer_max) 680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t new_max; 682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep old_buffer; 683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->save_buffer_size > PNG_SIZE_MAX - 685b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_ptr->current_buffer_size + 256)) 686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 687b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "Potential overflow of save_buffer"); 688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 689a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project new_max = png_ptr->save_buffer_size + png_ptr->current_buffer_size + 256; 691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project old_buffer = png_ptr->save_buffer; 6925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->save_buffer = (png_bytep)png_malloc_warn(png_ptr, 693b50c217251b086440efcdb273c22f86a06c80cbaChris Craik (png_size_t)new_max); 694b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 6955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->save_buffer == NULL) 6965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 697b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_free(png_ptr, old_buffer); 698b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "Insufficient memory for save_buffer"); 6995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 700b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 701b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memcpy(png_ptr->save_buffer, old_buffer, png_ptr->save_buffer_size); 702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, old_buffer); 703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_max = new_max; 704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->current_buffer_size) 706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 707b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memcpy(png_ptr->save_buffer + png_ptr->save_buffer_size, 708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_ptr, png_ptr->current_buffer_size); 709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_size += png_ptr->current_buffer_size; 710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_size = 0; 711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_ptr = png_ptr->save_buffer; 713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size = 0; 714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 717b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_restore_buffer(png_structrp png_ptr, png_bytep buffer, 718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t buffer_length) 719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer = buffer; 721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_size = buffer_length; 722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size = buffer_length + png_ptr->save_buffer_size; 723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_ptr = png_ptr->current_buffer; 724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 727b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_read_IDAT(png_structrp png_ptr) 728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_CHUNK_HEADER)) 730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte chunk_length[4]; 732b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_byte chunk_tag[4]; 733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 734b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: this code can be commoned up with the same code in push_read */ 735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->buffer_size < 8) 736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_fill_buffer(png_ptr, chunk_length, 4); 7424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->push_length = png_get_uint_31(png_ptr, chunk_length); 743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_reset_crc(png_ptr); 744b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_crc_read(png_ptr, chunk_tag, 4); 745b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->chunk_name = PNG_CHUNK_FROM_STRING(chunk_tag); 746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; 747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 748b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->chunk_name != png_IDAT) 749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->process_mode = PNG_READ_CHUNK_MODE; 751b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 752b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (!(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Not enough compressed data"); 754b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->idat_size = png_ptr->push_length; 759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 760b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->idat_size && png_ptr->save_buffer_size) 762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 763b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t save_size = png_ptr->save_buffer_size; 764b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 idat_size = png_ptr->idat_size; 765b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 766b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We want the smaller of 'idat_size' and 'current_buffer_size', but they 767b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * are of different types and we don't know which variable has the fewest 768b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * bits. Carefully select the smaller and cast it to the type of the 769b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * larger - this cannot overflow. Do not cast in the following test - it 770b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * will break on either 16 or 64 bit platforms. 771b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 772b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (idat_size < save_size) 773b50c217251b086440efcdb273c22f86a06c80cbaChris Craik save_size = (png_size_t)idat_size; 774a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 776b50c217251b086440efcdb273c22f86a06c80cbaChris Craik idat_size = (png_uint_32)save_size; 777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size); 779a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 7805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size); 781a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 782b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->idat_size -= idat_size; 783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_size -= save_size; 785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->save_buffer_ptr += save_size; 786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 787b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->idat_size && png_ptr->current_buffer_size) 789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 790b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_size_t save_size = png_ptr->current_buffer_size; 791b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_uint_32 idat_size = png_ptr->idat_size; 792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 793b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* We want the smaller of 'idat_size' and 'current_buffer_size', but they 794b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * are of different types and we don't know which variable has the fewest 795b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * bits. Carefully select the smaller and cast it to the type of the 796b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * larger - this cannot overflow. 797b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 798b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (idat_size < save_size) 799b50c217251b086440efcdb273c22f86a06c80cbaChris Craik save_size = (png_size_t)idat_size; 800a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 802b50c217251b086440efcdb273c22f86a06c80cbaChris Craik idat_size = (png_uint_32)save_size; 803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size); 8055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size); 807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 808b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->idat_size -= idat_size; 809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->buffer_size -= save_size; 810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_size -= save_size; 811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->current_buffer_ptr += save_size; 812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!png_ptr->idat_size) 814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->buffer_size < 4) 816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_save_buffer(png_ptr); 818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, 0); 822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER; 823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 824b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->zowner = 0; 825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 829b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_process_IDAT_data(png_structrp png_ptr, png_bytep buffer, 830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t buffer_length) 831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* The caller checks for a non-zero buffer length. */ 8335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (!(buffer_length > 0) || buffer == NULL) 8345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_error(png_ptr, "No IDAT data (internal error)"); 835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* This routine must process all the data it has been given 8375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * before returning, calling the row callback as required to 8385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * handle the uncompressed results. 8395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.next_in = buffer; 841b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ 842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_in = (uInt)buffer_length; 8435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Keep going until the decompressed data is all processed 8455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * or the stream marked as finished. 8465f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 8475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott while (png_ptr->zstream.avail_in > 0 && 848b50c217251b086440efcdb273c22f86a06c80cbaChris Craik !(png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)) 849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 8505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott int ret; 851a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 8525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* We have data for zlib, but we must check that zlib 853b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * has someplace to put the results. It doesn't matter 8545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * if we don't expect any results -- it may be the input 8555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * data is just the LZ end code. 8565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 8575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (!(png_ptr->zstream.avail_out > 0)) 8585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 859b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* TODO: WARNING: TRUNCATION ERROR: DANGER WILL ROBINSON: */ 860b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->zstream.avail_out = (uInt)(PNG_ROWBYTES(png_ptr->pixel_depth, 861b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->iwidth) + 1); 862b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 8635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.next_out = png_ptr->row_buf; 8645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Using Z_SYNC_FLUSH here means that an unterminated 867b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * LZ stream (a stream with a missing end code) can still 868b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * be handled, otherwise (Z_NO_FLUSH) a future zlib 869b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * implementation might defer output and therefore 870b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * change the current behavior (see comments in inflate.c 871b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * for why this doesn't happen at present with zlib 1.2.5). 8725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 8735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH); 874a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 8755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Check for any failure before proceeding. */ 8765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (ret != Z_OK && ret != Z_STREAM_END) 8775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 878b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Terminate the decompression. */ 879b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 880b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->zowner = 0; 8815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* This may be a truncated stream (missing or 883b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * damaged end code). Treat that as a warning. 884b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 8855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->row_number >= png_ptr->num_rows || 886b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->pass > 6) 887b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, "Truncated compressed data in IDAT"); 8885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 889b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 890b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "Decompression error in IDAT"); 891b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 892b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Skip the check on unprocessed input */ 8935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 8955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 8965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Did inflate output any data? */ 8975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->zstream.next_out != png_ptr->row_buf) 898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 899b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Is this unexpected data after the last row? 900b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * If it is, artificially terminate the LZ output 901b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * here. 902b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 9035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->row_number >= png_ptr->num_rows || 904b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->pass > 6) 905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 906b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Extra data. */ 907b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, "Extra compressed data in IDAT"); 908b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 909b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->zowner = 0; 910b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 911b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Do no more processing; skip the unprocessed 912b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * input check below. 913b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 9145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 915b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 9165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 917b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* Do we have a complete row? */ 918b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->zstream.avail_out == 0) 919b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_process_row(png_ptr); 920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 921a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 9225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* And check for the end of the stream. */ 9235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (ret == Z_STREAM_END) 924b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; 925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 9265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 9275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* All the data should have been processed, if anything 9285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * is left at this point we have bytes of IDAT data 9295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * after the zlib end code. 9305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 9315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->zstream.avail_in > 0) 932b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_warning(png_ptr, "Extra compression data in IDAT"); 933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 936b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_process_row(png_structrp png_ptr) 937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 938b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* 1.5.6: row_info moved out of png_struct to a local here. */ 939b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_row_info row_info; 940b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 941b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.width = png_ptr->iwidth; /* NOTE: width of current interlaced row */ 942b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.color_type = png_ptr->color_type; 943b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.bit_depth = png_ptr->bit_depth; 944b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.channels = png_ptr->channels; 945b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.pixel_depth = png_ptr->pixel_depth; 946b50c217251b086440efcdb273c22f86a06c80cbaChris Craik row_info.rowbytes = PNG_ROWBYTES(row_info.pixel_depth, row_info.width); 947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 948b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->row_buf[0] > PNG_FILTER_VALUE_NONE) 949b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 950b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->row_buf[0] < PNG_FILTER_VALUE_LAST) 951b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_read_filter_row(png_ptr, &row_info, png_ptr->row_buf + 1, 952b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->prev_row + 1, png_ptr->row_buf[0]); 953b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else 954b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "bad adaptive filter value"); 955b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 957b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* libpng 1.5.6: the following line was copying png_ptr->rowbytes before 958b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * 1.5.6, while the buffer really is this big in current versions of libpng 959b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it may not be in the future, so this was changed just to copy the 960b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * interlaced row count: 961b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 962b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memcpy(png_ptr->prev_row, png_ptr->row_buf, row_info.rowbytes + 1); 963b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 964b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_TRANSFORMS_SUPPORTED 965b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformations) 966b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_do_read_transformations(png_ptr, &row_info); 967b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif 968b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 969b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* The transformed pixel depth should match the depth now in row_info. */ 970b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (png_ptr->transformed_pixel_depth == 0) 971b50c217251b086440efcdb273c22f86a06c80cbaChris Craik { 972b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformed_pixel_depth = row_info.pixel_depth; 973b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (row_info.pixel_depth > png_ptr->maximum_pixel_depth) 974b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "progressive row overflow"); 975b50c217251b086440efcdb273c22f86a06c80cbaChris Craik } 976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 977b50c217251b086440efcdb273c22f86a06c80cbaChris Craik else if (png_ptr->transformed_pixel_depth != row_info.pixel_depth) 978b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_error(png_ptr, "internal progressive row size calculation error"); 979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INTERLACING_SUPPORTED 982a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Blow up interlaced rows to full size */ 983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->interlaced && (png_ptr->transformations & PNG_INTERLACE)) 984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass < 6) 986b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_do_read_interlace(&row_info, png_ptr->row_buf + 1, png_ptr->pass, 987b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->transformations); 988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->pass) 990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 0: 992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 8 && png_ptr->pass == 0; i++) 995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 997a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_read_push_finish_row(png_ptr); /* Updates png_ptr->pass */ 998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 999a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1000a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 2) /* Pass 1 might be empty */ 1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 4 && png_ptr->pass == 2; i++) 1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1004b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1008a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass == 4 && png_ptr->height <= 4) 1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1013b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1017a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass == 6 && png_ptr->height <= 4) 1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1020b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1023a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1026a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 1028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 8 && png_ptr->pass == 1; i++) 1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1035a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1036a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 2) /* Skip top 4 generated rows */ 1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 4 && png_ptr->pass == 2; i++) 1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1040b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1044a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1047a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1051a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 4 && png_ptr->pass == 2; i++) 1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1057a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 4 && png_ptr->pass == 2; i++) 1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1060b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1063a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1064a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 4) /* Pass 3 might be empty */ 1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1068b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1072a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1075a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 3: 1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1079a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 4 && png_ptr->pass == 3; i++) 1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1085a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1086a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 4) /* Skip top two generated rows */ 1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1090b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1094a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1097a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1101a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1107a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 4; i++) 1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1110b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1113a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1114a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 6) /* Pass 5 might be empty */ 1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1116b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1119a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1122a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 5: 1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1126a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < 2 && png_ptr->pass == 5; i++) 1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1132a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1133a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->pass == 6) /* Skip top generated row */ 1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1135b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1138a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1141b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1142b50c217251b086440efcdb273c22f86a06c80cbaChris Craik default: 1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 6: 1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1147a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass != 6) 1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 1150a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1151b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_push_have_row(png_ptr, NULL); 1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_push_have_row(png_ptr, png_ptr->row_buf + 1); 1160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_push_finish_row(png_ptr); 1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1165b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_read_push_finish_row(png_structrp png_ptr) 1166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1167b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_INTERLACING_SUPPORTED 1168a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1170a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block */ 1171b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static PNG_CONST png_byte png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; 1172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1173a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block */ 1174b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static PNG_CONST png_byte png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; 1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1176a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block in the y direction */ 1177b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static PNG_CONST png_byte png_pass_ystart[] = {0, 0, 4, 0, 2, 0, 1}; 1178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1179a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block in the y direction */ 1180b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static PNG_CONST png_byte png_pass_yinc[] = {8, 8, 8, 4, 4, 2, 2}; 1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Height of interlace block. This is not currently used - if you need 1183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * it, uncomment it here and in png.h 1184b50c217251b086440efcdb273c22f86a06c80cbaChris Craik static PNG_CONST png_byte png_pass_height[] = {8, 8, 4, 4, 2, 2, 1}; 1185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->row_number++; 1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->row_number < png_ptr->num_rows) 1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_INTERLACING_SUPPORTED 1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->interlaced) 1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->row_number = 0; 1196b50c217251b086440efcdb273c22f86a06c80cbaChris Craik memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1); 1197b50c217251b086440efcdb273c22f86a06c80cbaChris Craik 1198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 1199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 12004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->pass++; 12014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if ((png_ptr->pass == 1 && png_ptr->width < 5) || 12024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_ptr->pass == 3 && png_ptr->width < 3) || 12034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_ptr->pass == 5 && png_ptr->width < 2)) 1204b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_ptr->pass++; 12054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 12064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->pass > 7) 12074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->pass--; 1208a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 12094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->pass >= 7) 12104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project break; 12114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 12124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->iwidth = (png_ptr->width + 1213b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_inc[png_ptr->pass] - 1 - 1214b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_start[png_ptr->pass]) / 1215b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_inc[png_ptr->pass]; 12164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 12174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->transformations & PNG_INTERLACE) 12184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project break; 12194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 12204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->num_rows = (png_ptr->height + 1221b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_yinc[png_ptr->pass] - 1 - 1222b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_ystart[png_ptr->pass]) / 1223b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_pass_yinc[png_ptr->pass]; 1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } while (png_ptr->iwidth == 0 || png_ptr->num_rows == 0); 1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1227a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1231b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_have_info(png_structrp png_ptr, png_inforp info_ptr) 1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->info_fn != NULL) 1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (*(png_ptr->info_fn))(png_ptr, info_ptr); 1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1238b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_have_end(png_structrp png_ptr, png_inforp info_ptr) 1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->end_fn != NULL) 1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (*(png_ptr->end_fn))(png_ptr, info_ptr); 1242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1245b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_push_have_row(png_structrp png_ptr, png_bytep row) 1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->row_fn != NULL) 1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (*(png_ptr->row_fn))(png_ptr, row, png_ptr->row_number, 1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (int)png_ptr->pass); 1250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1252b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#ifdef PNG_READ_INTERLACING_SUPPORTED 1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 1254b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_progressive_combine_row(png_const_structrp png_ptr, png_bytep old_row, 1255b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_const_bytep new_row) 1256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1257a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 1258a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 1259a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1260b50c217251b086440efcdb273c22f86a06c80cbaChris Craik /* new_row is a flag here - if it is NULL then the app callback was called 1261b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * from an empty row (see the calls to png_struct::row_fn below), otherwise 1262b50c217251b086440efcdb273c22f86a06c80cbaChris Craik * it must be png_ptr->row_buf+1 1263b50c217251b086440efcdb273c22f86a06c80cbaChris Craik */ 1264b50c217251b086440efcdb273c22f86a06c80cbaChris Craik if (new_row != NULL) 1265b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_combine_row(png_ptr, old_row, 1/*display*/); 1266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1267b50c217251b086440efcdb273c22f86a06c80cbaChris Craik#endif /* PNG_READ_INTERLACING_SUPPORTED */ 1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid PNGAPI 1270b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_set_progressive_read_fn(png_structrp png_ptr, png_voidp progressive_ptr, 1271b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_progressive_info_ptr info_fn, png_progressive_row_ptr row_fn, 1272b50c217251b086440efcdb273c22f86a06c80cbaChris Craik png_progressive_end_ptr end_fn) 1273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1274a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 1275a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 1276a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->info_fn = info_fn; 1278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->row_fn = row_fn; 1279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->end_fn = end_fn; 1280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_read_fn(png_ptr, progressive_ptr, png_push_fill_buffer); 1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_voidp PNGAPI 1285b50c217251b086440efcdb273c22f86a06c80cbaChris Craikpng_get_progressive_ptr(png_const_structrp png_ptr) 1286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1287a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 1288a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return (NULL); 1289a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return png_ptr->io_ptr; 1291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_PROGRESSIVE_READ_SUPPORTED */ 1293