1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngrutil.c - utilities to read a PNG file 3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 466dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier * Last changed in libpng 1.2.45 [July 7, 2011] 566dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier * Copyright (c) 1998-2011 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.) 8893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * 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 12a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * 13893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * This file contains routines that are only called from within 14893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * libpng itself during the course of reading an image. 15893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 16893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define PNG_INTERNAL 185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#define PNG_NO_PEDANTIC_WARNINGS 19893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#include "png.h" 205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_SUPPORTED 21893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500) 23893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# define WIN32_WCE_OLD 24893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 25893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott# ifdef WIN32_WCE_OLD 28a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* The strtod() function is not supported on WindowsCE */ 295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, 305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott char **endptr) 31893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 32893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double result = 0; 33893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int len; 34893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wchar_t *str, *end; 35893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 36893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0); 374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t)); 38893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ( NULL != str ) 39893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 40893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len); 41893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project result = wcstod(str, &end); 42893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL); 43893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *endptr = (char *)nptr + (png_strlen(nptr) - len + 1); 44893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, str); 45893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 46893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return result; 47893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 48893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# else 49893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# define png_strtod(p,a,b) strtod(a,b) 50893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# endif 51893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 52893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 53893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 PNGAPI 54893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_get_uint_31(png_structp png_ptr, png_bytep buf) 55893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED 57893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i = png_get_uint_32(buf); 584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project#else 594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project /* Avoid an extra function call by inlining the result. */ 604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_uint_32 i = ((png_uint_32)(*buf) << 24) + 614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ((png_uint_32)(*(buf + 1)) << 16) + 624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ((png_uint_32)(*(buf + 2)) << 8) + 634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_uint_32)(*(buf + 3)); 644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project#endif 65893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (i > PNG_UINT_31_MAX) 66893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "PNG unsigned integer out of range."); 67893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (i); 68893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 69893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED 70893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */ 71893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_32 PNGAPI 72893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_get_uint_32(png_bytep buf) 73893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 74893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i = ((png_uint_32)(*buf) << 24) + 75893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((png_uint_32)(*(buf + 1)) << 16) + 76893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((png_uint_32)(*(buf + 2)) << 8) + 77893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_32)(*(buf + 3)); 78893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 79893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (i); 80893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 81893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 82893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Grab a signed 32-bit integer from a buffer in big-endian format. The 83893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * data is stored in the PNG file in two's complement format, and it is 84a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * assumed that the machine format for signed integers is the same. 85a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 86893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_int_32 PNGAPI 87893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_get_int_32(png_bytep buf) 88893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 89893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_int_32 i = ((png_int_32)(*buf) << 24) + 90893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((png_int_32)(*(buf + 1)) << 16) + 91893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((png_int_32)(*(buf + 2)) << 8) + 92893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_int_32)(*(buf + 3)); 93893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 94893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (i); 95893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 96893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 97893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */ 98893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_uint_16 PNGAPI 99893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_get_uint_16(png_bytep buf) 100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) + 102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_16)(*(buf + 1))); 103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (i); 105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */ 107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project/* Read the chunk header (length + type name). 1094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project * Put the type name into png_ptr->chunk_name, and return the length. 1104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project */ 1114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectpng_uint_32 /* PRIVATE */ 1124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Projectpng_read_chunk_header(png_structp png_ptr) 1134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project{ 1144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_byte buf[8]; 1154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_uint_32 length; 1164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 117a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Read the length and the chunk name */ 1184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_read_data(png_ptr, buf, 8); 1194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project length = png_get_uint_31(png_ptr, buf); 1204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 121a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Put the chunk name into png_ptr->chunk_name */ 1224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_memcpy(png_ptr->chunk_name, buf + 4, 4); 1234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 1244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug2(0, "Reading %s chunk, length = %lu", 1254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunk_name, length); 1264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 127a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Reset the crc and run it over the chunk name */ 1284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_reset_crc(png_ptr); 1294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_calculate_crc(png_ptr, png_ptr->chunk_name, 4); 1304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 131a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Check to see if chunk name is valid */ 1324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_check_chunk_name(png_ptr, png_ptr->chunk_name); 1334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 1344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return length; 1354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project} 1364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Read data, and (optionally) run it through the CRC. */ 138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length) 140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 141a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr == NULL) 142a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott return; 143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_data(png_ptr, buf, length); 144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_calculate_crc(png_ptr, buf, length); 145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1474ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#ifdef PNG_INDEX_SUPPORTED 148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Optionally skip data and then check the CRC. Depending on whether we 149a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * are reading a ancillary or critical chunk, and how the program has set 150a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * things up, we may calculate the CRC on the data and print a message. 151a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * Returns '1' if there was a CRC error, '0' otherwise. 152a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint /* PRIVATE */ 1544ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenpng_opt_crc_finish(png_structp png_ptr, png_uint_32 skip, int check_crc) 155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t i; 157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t istop = png_ptr->zbuf_size; 158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = (png_size_t)skip; i > istop; i -= istop) 160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size); 162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (i) 164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, png_ptr->zbuf, i); 166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_error(png_ptr)) 169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1704ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen if (!check_crc) { 1714ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_chunk_warning(png_ptr, "CRC error"); 1724ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen return (1); 1734ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen } 174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (((png_ptr->chunk_name[0] & 0x20) && /* Ancillary */ 175a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) || 176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (!(png_ptr->chunk_name[0] & 0x20) && /* Critical */ 177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE))) 178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_warning(png_ptr, "CRC error"); 180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "CRC error"); 184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (1); 186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (0); 189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1904ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#endif 1914ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 1924ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen/* Optionally skip data and then check the CRC. Depending on whether we 1934ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen * are reading a ancillary or critical chunk, and how the program has set 1944ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen * things up, we may calculate the CRC on the data and print a message. 1954ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen * Returns '1' if there was a CRC error, '0' otherwise. 1964ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen */ 1974ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenint /* PRIVATE */ 1984ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenpng_crc_finish(png_structp png_ptr, png_uint_32 skip) 1994ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen{ 2004ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen return png_opt_crc_finish(png_ptr, skip, 1); 2014ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen} 202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Compare the CRC stored in the PNG file with that calculated by libpng from 204a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * the data it has read thus far. 205a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectint /* PRIVATE */ 207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_crc_error(png_structp png_ptr) 208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte crc_bytes[4]; 210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 crc; 211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int need_crc = 1; 212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->chunk_name[0] & 0x20) /* ancillary */ 214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) == 216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN)) 217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project need_crc = 0; 218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* critical */ 220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE) 222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project need_crc = 0; 223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_data(png_ptr, crc_bytes, 4); 226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (need_crc) 228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project crc = png_get_uint_32(crc_bytes); 230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return ((int)(crc != png_ptr->crc)); 231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return (0); 234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \ 237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project defined(PNG_READ_iCCP_SUPPORTED) 2385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scottstatic png_size_t 2395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scottpng_inflate(png_structp png_ptr, const png_byte *data, png_size_t size, 2405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_bytep output, png_size_t output_size) 241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_size_t count = 0; 2435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */ 2455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.avail_in = size; 246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott while (1) 248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott int ret, avail; 2505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Reset the output buffer each time round - we empty it 2525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * after every inflate call. 2535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.next_out = png_ptr->zbuf; 2555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.avail_out = png_ptr->zbuf_size; 256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott ret = inflate(&png_ptr->zstream, Z_NO_FLUSH); 2585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out; 259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* First copy/count any new output - but only if we didn't 2615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * get an error code. 2625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 2635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0) 264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (output != 0 && output_size > count) 266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 26754d908dc93dbbaacd15b8a53b29a8fb88b6c472cGeremy Condra png_size_t copy = output_size - count; 26854d908dc93dbbaacd15b8a53b29a8fb88b6c472cGeremy Condra if ((png_size_t) avail < copy) copy = (png_size_t) avail; 2695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_memcpy(output + count, png_ptr->zbuf, copy); 2705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 2715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott count += avail; 2725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (ret == Z_OK) 2755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott continue; 276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Termination conditions - always reset the zstream, it 2785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * must be left in inflateInit state. 2795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 2805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->zstream.avail_in = 0; 2815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott inflateReset(&png_ptr->zstream); 282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2835f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (ret == Z_STREAM_END) 2845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return count; /* NOTE: may be zero. */ 2855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 2865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Now handle the error codes - the API always returns 0 2875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * and the error message is dumped into the uncompressed 2885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * buffer if available. 2895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 2905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 2915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott PNG_CONST char *msg; 2925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->zstream.msg != 0) 2935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = png_ptr->zstream.msg; 2945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott else 295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 2975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott char umsg[52]; 298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott switch (ret) 300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott case Z_BUF_ERROR: 3025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = "Buffer error in compressed datastream in %s chunk"; 3035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott break; 3045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott case Z_DATA_ERROR: 3055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = "Data error in compressed datastream in %s chunk"; 3065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott break; 3075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott default: 3085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = "Incomplete compressed datastream in %s chunk"; 3095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott break; 310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name); 3135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = umsg; 3145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#else 3155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott msg = "Damaged compressed datastream in chunk other than IDAT"; 3165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, msg); 320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* 0 means an error - notice that this code simple ignores 3235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * zero length compressed chunks as a result. 3245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 3255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return 0; 3265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 3275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott} 328a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott/* 3305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * Decompress trailing data in a chunk. The assumption is that chunkdata 3315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * points at an allocated area holding the contents of a chunk with a 3325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * trailing compressed part. What we get back is an allocated area 3335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * holding the original prefix part and an uncompressed version of the 3345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * trailing part (the malloc area passed in is freed). 3355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 3365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scottvoid /* PRIVATE */ 3375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scottpng_decompress_chunk(png_structp png_ptr, int comp_type, 3385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_size_t chunklength, 3395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_size_t prefix_size, png_size_t *newlength) 3405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott{ 3415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* The caller should guarantee this */ 3425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (prefix_size > chunklength) 3435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 3445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* The recovery is to delete the chunk. */ 3455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "invalid chunklength"); 3465f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott prefix_size = 0; /* To delete everything */ 3475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 348a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott else if (comp_type == PNG_COMPRESSION_TYPE_BASE) 3505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 3515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_size_t expanded_size = png_inflate(png_ptr, 3525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_bytep)(png_ptr->chunkdata + prefix_size), 3535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott chunklength - prefix_size, 3545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 0/*output*/, 0/*output size*/); 355a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 3565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Now check the limits on this chunk - if the limit fails the 3575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * compressed data will be removed, the prefix will remain. 3585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 3595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED 3605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_malloc_max && 3615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1)) 362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 3635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott# ifdef PNG_USER_CHUNK_MALLOC_MAX 3645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if ((PNG_USER_CHUNK_MALLOC_MAX > 0) && 3655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1) 3665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott# endif 367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "Exceeded size limit while expanding chunk"); 3695f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* If the size is zero either there was an error and a message 3715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * has already been output (warning) or the size really is zero 3725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * and we have nothing to do - the code will exit through the 3735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * error case below. 3745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 3755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \ 3765f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott defined(PNG_USER_CHUNK_MALLOC_MAX) 3775f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott else 3785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 3795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (expanded_size > 0) 3805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 3815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Success (maybe) - really uncompress the chunk. */ 3825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_size_t new_size = 0; 383ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke png_charp text = NULL; 384ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke 385ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke /* Need to check for both truncation (64-bit) and integer overflow. */ 386ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke if (prefix_size + expanded_size > prefix_size && 387ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke prefix_size + expanded_size < 0xffffffffU) 388ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke { 389ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke text = png_malloc_warn(png_ptr, prefix_size + expanded_size + 1); 390ccee121fae4c60a5dee6fce51195185694c376c3Dave Burke } 3915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 3925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (text != NULL) 393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_memcpy(text, png_ptr->chunkdata, prefix_size); 3955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott new_size = png_inflate(png_ptr, 3965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_bytep)(png_ptr->chunkdata + prefix_size), 3975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott chunklength - prefix_size, 3985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (png_bytep)(text + prefix_size), expanded_size); 3995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott text[prefix_size + expanded_size] = 0; /* just in case */ 400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (new_size == expanded_size) 4025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 4035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 4045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = text; 4055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *newlength = prefix_size + expanded_size; 4065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; /* The success return! */ 4075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "png_inflate logic error"); 4105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, text); 4115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 4125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott else 4135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "Not enough memory to decompress chunk."); 4145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */ 418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 4195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE) 420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project char umsg[50]; 421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d", 4235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott comp_type); 424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, umsg); 425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Unknown zTXt compression type"); 427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* The recovery is to simply drop the data. */ 430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 4315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Generic error return - leave the prefix, delete the compressed 4335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * data, reallocate the chunkdata to remove the potentially large 4345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * amount of compressed data. 4355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott */ 4365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 4375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_charp text = png_malloc_warn(png_ptr, prefix_size + 1); 4385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (text != NULL) 4395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 4405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (prefix_size > 0) 4415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_memcpy(text, png_ptr->chunkdata, prefix_size); 4425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 4435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = text; 4445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* This is an extra zero in the 'uncompressed' part. */ 4465f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *(png_ptr->chunkdata + prefix_size) = 0x00; 4475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 4485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Ignore a malloc error here - it is safe. */ 4495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 4505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 4515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott *newlength = prefix_size; 452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 455a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read and check the IDHR chunk */ 456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[13]; 460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 width, height; 461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int bit_depth, color_type, compression_type, filter_type; 462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int interlace_type; 463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 4644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_IHDR"); 465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IHDR) 467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Out of place IHDR"); 468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 469a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Check the length */ 470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 13) 471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Invalid IHDR chunk"); 472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_HAVE_IHDR; 474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 13); 476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, 0); 477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project width = png_get_uint_31(png_ptr, buf); 479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project height = png_get_uint_31(png_ptr, buf + 4); 480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bit_depth = buf[8]; 481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project color_type = buf[9]; 482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project compression_type = buf[10]; 483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project filter_type = buf[11]; 484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project interlace_type = buf[12]; 485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 486a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Set internal variables */ 487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->width = width; 488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->height = height; 489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->bit_depth = (png_byte)bit_depth; 490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->interlaced = (png_byte)interlace_type; 491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->color_type = (png_byte)color_type; 4925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_MNG_FEATURES_SUPPORTED 493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->filter_type = (png_byte)filter_type; 494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->compression_type = (png_byte)compression_type; 496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 497a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Find number of channels */ 498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->color_type) 499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY: 501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_PALETTE: 502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->channels = 1; 503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 504a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB: 506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->channels = 3; 507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 508a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_GRAY_ALPHA: 510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->channels = 2; 511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 512a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_COLOR_TYPE_RGB_ALPHA: 514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->channels = 4; 515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 518a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Set up other useful info */ 519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth * 520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->channels); 5214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width); 5224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "bit_depth = %d", png_ptr->bit_depth); 5234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "channels = %d", png_ptr->channels); 5244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes); 525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, 526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project color_type, interlace_type, compression_type, filter_type); 527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 529a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read and check the palette */ 530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_color palette[PNG_MAX_PALETTE_LENGTH]; 534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int num, i; 5355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED 536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_colorp pal_ptr; 537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_PLTE"); 540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before PLTE"); 543a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid PLTE after IDAT"); 547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 550a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Duplicate PLTE chunk"); 553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_HAVE_PLTE; 555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR)) 557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring PLTE chunk in grayscale PNG"); 560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 5635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED 564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3) 572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE) 574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid palette chunk"); 576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 579a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott 580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Invalid palette chunk"); 583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num = (int)length / 3; 587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 5885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED 589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++) 590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[3]; 592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 3); 594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pal_ptr->red = buf[0]; 595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pal_ptr->green = buf[1]; 596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pal_ptr->blue = buf[2]; 597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num; i++) 600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[3]; 602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 3); 604a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Don't depend upon png_color being any order */ 605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].red = buf[0]; 606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].green = buf[1]; 607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project palette[i].blue = buf[2]; 608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* If we actually NEED the PLTE chunk (ie for a paletted image), we do 612a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * whatever the normal CRC configuration tells us. However, if we 613a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * have an RGB image, the PLTE can be considered ancillary, so 614a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * we will act as though it is. 615a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 6165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED 617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, 0); 621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 6225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED 623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_crc_error(png_ptr)) /* Only if we have a CRC error */ 624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* If we don't want to use the data from an ancillary chunk, 626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project we have two options: an error abort, or a warning and we 627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ignore the data in this chunk (which should be OK, since 628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project it's considered ancillary for a RGB or RGBA image). */ 629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE)) 630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN) 632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "CRC error"); 634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_warning(png_ptr, "CRC error"); 638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Otherwise, we (optionally) emit a warning and use the chunk. */ 642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) 643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_warning(png_ptr, "CRC error"); 645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_PLTE(png_ptr, info_ptr, palette, num); 650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 6515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tRNS_SUPPORTED 652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->num_trans > (png_uint_16)num) 657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Truncating incorrect tRNS chunk length"); 659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_trans = (png_uint_16)num; 660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr->num_trans > (png_uint_16)num) 662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Truncating incorrect info tRNS chunk length"); 664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project info_ptr->num_trans = (png_uint_16)num; 665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 6754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_IEND"); 676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT)) 678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "No image in file"); 680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND); 683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 0) 685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect IEND chunk length"); 687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 690a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 6935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_gAMA_SUPPORTED 694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_fixed_point igamma; 698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project float file_gamma; 700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[4]; 702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 7034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_gAMA"); 704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before gAMA"); 707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid gAMA after IDAT"); 710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it */ 715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Out of place gAMA chunk"); 716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA) 7185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project && !(info_ptr->valid & PNG_INFO_sRGB) 720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ) 722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate gAMA chunk"); 724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 4) 729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect gAMA chunk length"); 731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 4); 736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project igamma = (png_fixed_point)png_get_uint_32(buf); 740a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Check for zero gamma */ 741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (igamma == 0) 742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring gAMA chunk with gamma=0"); 745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 7485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring incorrect gAMA value when sRGB is also present"); 7545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED 7554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "gamma = (%d/100000)", (int)igamma); 756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */ 760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project file_gamma = (float)igamma / (float)100000.0; 763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# ifdef PNG_READ_GAMMA_SUPPORTED 764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->gamma = file_gamma; 765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# endif 766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_gAMA(png_ptr, info_ptr, file_gamma); 767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_gAMA_fixed(png_ptr, info_ptr, igamma); 770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 7745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sBIT_SUPPORTED 775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t truelen; 779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[4]; 780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 7814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_sBIT"); 782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project buf[0] = buf[1] = buf[2] = buf[3] = 0; 784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before sBIT"); 787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid sBIT after IDAT"); 790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it */ 796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Out of place sBIT chunk"); 797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT)) 799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate sBIT chunk"); 801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project truelen = 3; 807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project truelen = (png_size_t)png_ptr->channels; 809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != truelen || length > 4) 811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect sBIT chunk length"); 813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, truelen); 818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.red = buf[0]; 824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.green = buf[1]; 825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.blue = buf[2]; 826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.alpha = buf[3]; 827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.gray = buf[0]; 831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.red = buf[0]; 832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.green = buf[0]; 833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.blue = buf[0]; 834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->sig_bit.alpha = buf[1]; 835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit)); 837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_cHRM_SUPPORTED 841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 8444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_byte buf[32]; 845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y; 847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_y_green, int_x_blue, int_y_blue; 850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 uint_x, uint_y; 852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_cHRM"); 854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before cHRM"); 857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid cHRM after IDAT"); 860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it */ 865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Missing PLTE before cHRM"); 866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM) 8685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project && !(info_ptr->valid & PNG_INFO_sRGB) 870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ) 872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate cHRM chunk"); 874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 32) 879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect cHRM chunk length"); 881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, buf, 32); 8864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_crc_finish(png_ptr, 0)) 887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project uint_x = png_get_uint_32(buf); 8904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_y = png_get_uint_32(buf + 4); 8914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project int_x_white = (png_fixed_point)uint_x; 8924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project int_y_white = (png_fixed_point)uint_y; 893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_x = png_get_uint_32(buf + 8); 8954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_y = png_get_uint_32(buf + 12); 896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_x_red = (png_fixed_point)uint_x; 897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_y_red = (png_fixed_point)uint_y; 898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 8994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_x = png_get_uint_32(buf + 16); 9004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_y = png_get_uint_32(buf + 20); 901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_x_green = (png_fixed_point)uint_x; 902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_y_green = (png_fixed_point)uint_y; 903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_x = png_get_uint_32(buf + 24); 9054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project uint_y = png_get_uint_32(buf + 28); 906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_x_blue = (png_fixed_point)uint_x; 907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_y_blue = (png_fixed_point)uint_y; 908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project white_x = (float)int_x_white / (float)100000.0; 911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project white_y = (float)int_y_white / (float)100000.0; 912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project red_x = (float)int_x_red / (float)100000.0; 913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project red_y = (float)int_y_red / (float)100000.0; 914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project green_x = (float)int_x_green / (float)100000.0; 915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project green_y = (float)int_y_green / (float)100000.0; 916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project blue_x = (float)int_x_blue / (float)100000.0; 917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project blue_y = (float)int_y_blue / (float)100000.0; 918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB)) 922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (PNG_OUT_OF_RANGE(int_x_white, 31270, 1000) || 924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_y_white, 32900, 1000) || 925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_x_red, 64000L, 1000) || 926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_y_red, 33000, 1000) || 927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_x_green, 30000, 1000) || 928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) || 929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_x_blue, 15000, 1000) || 930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(int_y_blue, 6000, 1000)) 931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring incorrect cHRM value when sRGB is also present"); 9345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED 935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 9364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n", 937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project white_x, white_y, red_x, red_y); 9384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n", 939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project green_x, green_y, blue_x, blue_y); 940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 9414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n", 9425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (long)int_x_white, (long)int_y_white, 9435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (long)int_x_red, (long)int_y_red); 9444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n", 9455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (long)int_x_green, (long)int_y_green, 9465f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott (long)int_x_blue, (long)int_y_blue); 947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 9485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif /* PNG_CONSOLE_IO_SUPPORTED */ 949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */ 953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_cHRM(png_ptr, info_ptr, 956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y); 957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_cHRM_fixed(png_ptr, info_ptr, 960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_x_white, int_y_white, int_x_red, int_y_red, int_x_green, 961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int_y_green, int_x_blue, int_y_blue); 962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED 967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int intent; 971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[1]; 972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 9734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_sRGB"); 974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before sRGB"); 977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid sRGB after IDAT"); 980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it */ 985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Out of place sRGB chunk"); 986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB)) 988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate sRGB chunk"); 990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 1) 995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect sRGB chunk length"); 997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 1); 1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project intent = buf[0]; 1006a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Check for bad intent */ 1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (intent >= PNG_sRGB_INTENT_LAST) 1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Unknown sRGB intent"); 1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED) 1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)) 1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_fixed_point igamma; 1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project igamma=info_ptr->int_gamma; 1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# ifdef PNG_FLOATING_POINT_SUPPORTED 1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project igamma=(png_fixed_point)(info_ptr->gamma * 100000.); 1022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# endif 1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (PNG_OUT_OF_RANGE(igamma, 45500L, 500)) 1025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring incorrect gAMA value when sRGB is also present"); 10285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED 1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# ifdef PNG_FIXED_POINT_SUPPORTED 10304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "incorrect gamma=(%d/100000)\n", 10314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (int)png_ptr->int_gamma); 1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# else 1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# ifdef PNG_FLOATING_POINT_SUPPORTED 10344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma); 1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# endif 1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project# endif 1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_gAMA_SUPPORTED */ 1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_cHRM_SUPPORTED 1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)) 1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270, 1000) || 1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900, 1000) || 1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_x_red, 64000L, 1000) || 1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_y_red, 33000, 1000) || 1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000, 1000) || 1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) || 1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_x_blue, 15000, 1000) || 1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_OUT_OF_RANGE(info_ptr->int_y_blue, 6000, 1000)) 1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, 1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Ignoring incorrect cHRM value when sRGB is also present"); 1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_FIXED_POINT_SUPPORTED */ 1058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_cHRM_SUPPORTED */ 1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent); 1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */ 1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 10645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iCCP_SUPPORTED 1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */ 1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte compression_type; 1070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep pC; 1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp profile; 1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 skip = 0; 1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 profile_size, profile_length; 1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength, prefix_length, data_length; 1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 10764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_iCCP"); 1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before iCCP"); 1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid iCCP after IDAT"); 1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_PLTE) 1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it */ 1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Out of place iCCP chunk"); 1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP)) 1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate iCCP chunk"); 1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "iCCP chunk too large to fit in memory"); 1101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project skip = length - (png_uint_32)65535L; 1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length = (png_uint_32)65535L; 1103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 11094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, skip)) 1112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 11134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata[slength] = 0x00; 1119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11204215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (profile = png_ptr->chunkdata; *profile; profile++) 1121a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop to find end of name */ ; 1122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++profile; 1124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1125a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* There should be at least one zero (the compression type byte) 1126a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * following the separator, and we should be on it 1127a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 11284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if ( profile >= png_ptr->chunkdata + slength - 1) 1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 11304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Malformed iCCP chunk"); 1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1136a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Compression_type should always be zero */ 1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project compression_type = *profile++; 1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (compression_type) 1139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk"); 11414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project compression_type = 0x00; /* Reset it to zero (libpng-1.0.6 through 1.0.8 1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project wrote nonzero) */ 1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project prefix_length = profile - png_ptr->chunkdata; 11464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_decompress_chunk(png_ptr, compression_type, 11474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project slength, prefix_length, &data_length); 1148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project profile_length = data_length - prefix_length; 1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ( prefix_length > data_length || profile_length < 4) 1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 11534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Profile size field missing from iCCP chunk"); 1156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Check the profile_size recorded in the first 32 bits of the ICC profile */ 11604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project pC = (png_bytep)(png_ptr->chunkdata + prefix_length); 11614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project profile_size = ((*(pC ))<<24) | 11624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ((*(pC + 1))<<16) | 11634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ((*(pC + 2))<< 8) | 11644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ((*(pC + 3)) ); 1165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (profile_size < profile_length) 1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project profile_length = profile_size; 1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (profile_size > profile_length) 1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 11714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Ignoring truncated iCCP profile."); 1174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata, 11784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project compression_type, png_ptr->chunkdata + prefix_length, profile_length); 11794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 11804215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_iCCP_SUPPORTED */ 1183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sPLT_SUPPORTED 1185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */ 1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep entry_start; 1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_sPLT_t new_palette; 11915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED 1192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_sPLT_entryp pp; 1193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int data_length, entry_size, i; 1195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 skip = 0; 1196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength; 1197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 11984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_sPLT"); 11994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 12005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED 12015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 12025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max != 0) 12035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 12045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max == 1) 12055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 12065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 12075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 12085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 12095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (--png_ptr->user_chunk_cache_max == 1) 12105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 12115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "No space in chunk cache for sPLT"); 12125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 12135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 12145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 12155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 12165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before sPLT"); 1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid sPLT after IDAT"); 1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "sPLT chunk too large to fit in memory"); 1231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project skip = length - (png_uint_32)65535L; 1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length = (png_uint_32)65535L; 1233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 12364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 12374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1); 1238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 12394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, skip)) 1242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 12434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 12444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 12484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata[slength] = 0x00; 1249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 12505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start; 12515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott entry_start++) 1252a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop to find end of name */ ; 1253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ++entry_start; 1254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1255a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* A sample depth should follow the separator, and we should be on it */ 12564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2) 1257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 12584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 12594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "malformed sPLT chunk"); 1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project new_palette.depth = *entry_start++; 1265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project entry_size = (new_palette.depth == 8 ? 6 : 10); 12664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata)); 1267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1268a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Integrity-check the data length */ 1269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (data_length % entry_size) 1270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 12714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 12724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "sPLT chunk has bad length"); 1274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project new_palette.nentries = (png_int_32) ( data_length / entry_size); 12784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if ((png_uint_32) new_palette.nentries > 12794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry))) 1280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "sPLT chunk too long"); 1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project new_palette.entries = (png_sPLT_entryp)png_malloc_warn( 1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry)); 1286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (new_palette.entries == NULL) 1287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "sPLT chunk requires too much memory"); 1289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 12925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED 1293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < new_palette.nentries; i++) 1294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 12955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott pp = new_palette.entries + i; 1296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (new_palette.depth == 8) 1298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->red = *entry_start++; 1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->green = *entry_start++; 1301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->blue = *entry_start++; 1302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->alpha = *entry_start++; 1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->red = png_get_uint_16(entry_start); entry_start += 2; 1307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->green = png_get_uint_16(entry_start); entry_start += 2; 1308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->blue = png_get_uint_16(entry_start); entry_start += 2; 1309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->alpha = png_get_uint_16(entry_start); entry_start += 2; 1310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp = new_palette.entries; 1315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < new_palette.nentries; i++) 1316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (new_palette.depth == 8) 1319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].red = *entry_start++; 1321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].green = *entry_start++; 1322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].blue = *entry_start++; 1323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].alpha = *entry_start++; 1324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].red = png_get_uint_16(entry_start); entry_start += 2; 1328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].green = png_get_uint_16(entry_start); entry_start += 2; 1329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].blue = png_get_uint_16(entry_start); entry_start += 2; 1330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2; 1331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pp->frequency = png_get_uint_16(entry_start); entry_start += 2; 1333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1336a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Discard all chunk data except the name and stash that */ 13374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project new_palette.name = png_ptr->chunkdata; 1338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_sPLT(png_ptr, info_ptr, &new_palette, 1); 1340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 13414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 13424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, new_palette.entries); 1344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sPLT_SUPPORTED */ 1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 13475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tRNS_SUPPORTED 1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte readbuf[PNG_MAX_PALETTE_LENGTH]; 1352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 13534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_tRNS"); 1354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before tRNS"); 1357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid tRNS after IDAT"); 1360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS)) 1364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate tRNS chunk"); 1366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 1371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[2]; 1373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 2) 1375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect tRNS chunk length"); 1377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 2); 1382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_trans = 1; 1383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->trans_values.gray = png_get_uint_16(buf); 1384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 1386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[6]; 1388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 6) 1390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect tRNS chunk length"); 1392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, (png_size_t)length); 1396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_trans = 1; 1397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->trans_values.red = png_get_uint_16(buf); 1398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->trans_values.green = png_get_uint_16(buf + 2); 1399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->trans_values.blue = png_get_uint_16(buf + 4); 1400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Should be an error, but we can cope with it. */ 1406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Missing PLTE before tRNS"); 1407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)png_ptr->num_palette || 1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length > PNG_MAX_PALETTE_LENGTH) 1410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect tRNS chunk length"); 1412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length == 0) 1416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Zero length tRNS chunk"); 1418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, readbuf, (png_size_t)length); 1422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_trans = (png_uint_16)length; 1423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "tRNS chunk not allowed with alpha channel"); 1427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_trans = 0; 1434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans, 1438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project &(png_ptr->trans_values)); 1439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 14425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_bKGD_SUPPORTED 1443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t truelen; 1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[6]; 1448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 14494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_bKGD"); 1450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before bKGD"); 1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid bKGD after IDAT"); 1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE && 1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project !(png_ptr->mode & PNG_HAVE_PLTE)) 1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Missing PLTE before bKGD"); 1463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD)) 1467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate bKGD chunk"); 1469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project truelen = 1; 1475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR) 1476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project truelen = 6; 1477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project truelen = 2; 1479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != truelen) 1481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect bKGD chunk length"); 1483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, truelen); 1488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* We convert the index value into RGB components so that we can allow 1492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * arbitrary RGB values for background when we have transparency, and 1493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * so it is easy to determine the RGB values of the background color 1494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project * from the info_ptr struct. */ 1495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 1496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.index = buf[0]; 1498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (info_ptr && info_ptr->num_palette) 1499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 15004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (buf[0] >= info_ptr->num_palette) 1501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect bKGD chunk index value"); 1503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.red = 1506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_16)png_ptr->palette[buf[0]].red; 1507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.green = 1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_16)png_ptr->palette[buf[0]].green; 1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.blue = 1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_16)png_ptr->palette[buf[0]].blue; 1511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */ 1514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.red = 1516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.green = 1517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.blue = 1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.gray = png_get_uint_16(buf); 1519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 1521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.red = png_get_uint_16(buf); 1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.green = png_get_uint_16(buf + 2); 1524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->background.blue = png_get_uint_16(buf + 4); 1525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background)); 1528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 15315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_hIST_SUPPORTED 1532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project unsigned int num, i; 1536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH]; 1537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 15384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_hIST"); 1539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before hIST"); 1542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid hIST after IDAT"); 1545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (!(png_ptr->mode & PNG_HAVE_PLTE)) 1549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Missing PLTE before hIST"); 1551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST)) 1555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate hIST chunk"); 1557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project num = length / 2 ; 1562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (num != (unsigned int) png_ptr->num_palette || num > 1563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (unsigned int) PNG_MAX_PALETTE_LENGTH) 1564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect hIST chunk length"); 1566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < num; i++) 1571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[2]; 1573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 2); 1575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project readbuf[i] = png_get_uint_16(buf); 1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_hIST(png_ptr, info_ptr, readbuf); 1582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 15855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pHYs_SUPPORTED 1586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[9]; 1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 res_x, res_y; 1591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int unit_type; 1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 15934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_pHYs"); 1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before pHYs"); 1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid pHYs after IDAT"); 1600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs)) 1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate pHYs chunk"); 1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 9) 1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect pHYs chunk length"); 1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 9); 1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project res_x = png_get_uint_32(buf); 1622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project res_y = png_get_uint_32(buf + 4); 1623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project unit_type = buf[8]; 1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type); 1625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_oFFs_SUPPORTED 1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[9]; 1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_int_32 offset_x, offset_y; 1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int unit_type; 1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_oFFs"); 1637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before oFFs"); 1640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid oFFs after IDAT"); 1643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs)) 1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate oFFs chunk"); 1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 9) 1654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect oFFs chunk length"); 1656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 9); 1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project offset_x = png_get_int_32(buf); 1665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project offset_y = png_get_int_32(buf + 4); 1666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project unit_type = buf[8]; 1667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type); 1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pCAL_SUPPORTED 1672a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read the pCAL chunk (described in the PNG Extensions document) */ 1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_int_32 X0, X1; 1677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte type, nparams; 1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp buf, units, endptr; 1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charpp params; 1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength; 1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int i; 1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 16834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_pCAL"); 1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before pCAL"); 1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid pCAL after IDAT"); 1690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL)) 1694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate pCAL chunk"); 1696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)", 1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length + 1); 17024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 17044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata == NULL) 1705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "No memory for pCAL purpose."); 1707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 17104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 17144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1719a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(3, "Finding end of pCAL purpose string"); 17224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (buf = png_ptr->chunkdata; *buf; buf++) 1723a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project endptr = png_ptr->chunkdata + slength; 1726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* We need to have at least 12 bytes after the purpose string 1728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project in order to get the parameter information. */ 1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (endptr <= buf + 12) 1730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid pCAL data"); 17324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(3, "Reading pCAL X0, X1, type, nparams, and units"); 1738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project X0 = png_get_int_32((png_bytep)buf+1); 1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project X1 = png_get_int_32((png_bytep)buf+5); 1740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project type = buf[9]; 1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project nparams = buf[10]; 1742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project units = buf + 11; 1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(3, "Checking pCAL equation type and number of parameters"); 1745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Check that we have the right number of parameters for known 1746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project equation types. */ 1747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((type == PNG_EQUATION_LINEAR && nparams != 2) || 1748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (type == PNG_EQUATION_BASE_E && nparams != 3) || 1749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (type == PNG_EQUATION_ARBITRARY && nparams != 3) || 1750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (type == PNG_EQUATION_HYPERBOLIC && nparams != 4)) 1751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid pCAL parameters for equation type"); 17534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (type >= PNG_EQUATION_LAST) 1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Unrecognized equation type for pCAL chunk"); 1760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (buf = units; *buf; buf++) 1763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Empty loop to move past the units string. */ ; 1764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(3, "Allocating pCAL parameters array"); 17664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project params = (png_charpp)png_malloc_warn(png_ptr, 17674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_uint_32)(nparams * png_sizeof(png_charp))) ; 1768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (params == NULL) 1769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 17704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "No memory for pCAL params."); 1773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Get pointers to the start of each parameter string. */ 1777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < (int)nparams; i++) 1778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project buf++; /* Skip the null string terminator from previous parameter. */ 1780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "Reading pCAL parameter %d", i); 1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++) 1783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Empty loop to move past each parameter string */ ; 1784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* Make sure we haven't run out of data yet */ 1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (buf > endptr) 1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid pCAL data"); 17894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 17904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, params); 1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams, 1797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project units, params); 1798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 17994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 18004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, params); 1802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sCAL_SUPPORTED 1806a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read the sCAL chunk */ 1807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 18104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_charp ep; 1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project double width, height; 1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp vp; 1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 1816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp swidth, sheight; 1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength; 1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18214215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_sCAL"); 1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before sCAL"); 1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->mode & PNG_HAVE_IDAT) 1826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid sCAL after IDAT"); 1828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL)) 1832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate sCAL chunk"); 1834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 183866dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier /* Need unit type, width, \0, height: minimum 4 bytes */ 183966dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier else if (length < 4) 184066dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier { 184166dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier png_warning(png_ptr, "sCAL chunk too short"); 184266dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier png_crc_finish(png_ptr, length); 184366dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier return; 184466dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier } 184566dce0da6a5db51ee0c2875517d3a6ca6cbbe53dEric Vannier 18464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)", 1847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length + 1); 18484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 18494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata == NULL) 18504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project { 18514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Out of memory while processing sCAL chunk"); 18525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 18534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 18544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project } 1855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 18564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 1857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 1859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 18604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 18614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1865a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */ 1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1867a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott ep = png_ptr->chunkdata + 1; /* Skip unit byte */ 1868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 1870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project width = png_strtod(png_ptr, ep, &vp); 1871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*vp) 1872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 18734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "malformed width string in sCAL chunk"); 18745f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 18755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = NULL; 18764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 1877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 1880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (swidth == NULL) 18824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project { 18834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Out of memory while processing sCAL chunk width"); 18845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 18855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = NULL; 18864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 18874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project } 1888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(swidth, ep, (png_size_t)png_strlen(ep)); 1889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (ep = png_ptr->chunkdata; *ep; ep++) 1893a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 1894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ep++; 1895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 18964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata + slength < ep) 1897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 18984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Truncated sCAL chunk"); 18995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 19004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, swidth); 1901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 19024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 19034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 19044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 1905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 1908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project height = png_strtod(png_ptr, ep, &vp); 1909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (*vp) 1910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 19114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "malformed height string in sCAL chunk"); 19125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 19135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = NULL; 19145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 19155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, swidth); 19165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 19174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1); 1922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (sheight == NULL) 19234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project { 19244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Out of memory while processing sCAL chunk height"); 19255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, png_ptr->chunkdata); 19265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->chunkdata = NULL; 19275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 19285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_free(png_ptr, swidth); 19295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 19304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project return; 19314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project } 1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(sheight, ep, (png_size_t)png_strlen(ep)); 1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata + slength < ep 1937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project || width <= 0. || height <= 0. 1939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ) 1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Invalid sCAL data"); 19434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 19444215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, swidth); 1947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, sheight); 1948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED 19544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height); 1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 1956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED 19574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight); 1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 19624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 1963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED) 1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, swidth); 1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, sheight); 1966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 1968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 1969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tIME_SUPPORTED 1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte buf[7]; 1975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_time mod_time; 1976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 19774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_tIME"); 1978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 1980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Out of place tIME chunk"); 1981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME)) 1982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Duplicate tIME chunk"); 1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IDAT) 1989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 1990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length != 7) 1992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 1993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Incorrect tIME chunk length"); 1994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 1995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 1996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 1997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, buf, 7); 1999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 2000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.second = buf[6]; 2003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.minute = buf[5]; 2004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.hour = buf[4]; 2005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.day = buf[3]; 2006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.month = buf[2]; 2007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project mod_time.year = png_get_uint_16(buf); 2008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_tIME(png_ptr, info_ptr, &mod_time); 2010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tEXt_SUPPORTED 2014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */ 2015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_textp text_ptr; 2019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp key; 2020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp text; 2021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 skip = 0; 2022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength; 2023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ret; 2024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_tEXt"); 20264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 20275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED 20285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max != 0) 20295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 20305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max == 1) 20315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 20325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 20335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 20345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 20355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (--png_ptr->user_chunk_cache_max == 1) 20365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 20375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "No space in chunk cache for tEXt"); 20385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 20395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 20405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 20415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 20425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 2043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before tEXt"); 2046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IDAT) 2048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 2051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 2052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "tEXt chunk too large to fit in memory"); 2054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project skip = length - (png_uint_32)65535L; 2055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length = (png_uint_32)65535L; 2056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 20604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 20614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 20624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata == NULL) 2063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "No memory to process text chunk."); 2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 20684215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, skip)) 2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 20724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 20734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 20774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project key = png_ptr->chunkdata; 20784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 2079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project key[slength] = 0x00; 2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (text = key; *text; text++) 2082a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop to find end of key */ ; 2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (text != key + slength) 2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text++; 2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr = (png_textp)png_malloc_warn(png_ptr, 2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_32)png_sizeof(png_text)); 2089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (text_ptr == NULL) 2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Not enough memory to process text chunk."); 20924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 20934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->compression = PNG_TEXT_COMPRESSION_NONE; 2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->key = key; 2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED 2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->lang = NULL; 2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->lang_key = NULL; 2101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->itxt_length = 0; 2102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->text = text; 2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->text_length = png_strlen(text); 2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21064215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 21094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, text_ptr); 2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret) 2112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Insufficient memory to process text chunk."); 2113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_zTXt_SUPPORTED 2117a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Note: this does not correctly handle chunks that are > 64K under DOS */ 2118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_textp text_ptr; 2122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp text; 2123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int comp_type; 2124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ret; 2125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength, prefix_len, data_len; 2126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_zTXt"); 21284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 21295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED 21305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max != 0) 21315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 21325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max == 1) 21335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 21345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 21355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 21365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 21375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (--png_ptr->user_chunk_cache_max == 1) 21385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 21395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "No space in chunk cache for zTXt"); 21405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 21415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 21425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 21435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 21445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 21454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 2146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before zTXt"); 2148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IDAT) 2150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 2151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 2153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* We will no doubt have problems with chunks even half this size, but 2154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project there is no hard and fast rule to tell us where to stop. */ 2155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 2156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 21574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "zTXt chunk too large to fit in memory"); 2158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 2159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 21644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 21654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata == NULL) 2166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 21674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Out of memory processing zTXt chunk."); 2168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 21714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 2173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 21744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 21754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata[slength] = 0x00; 2180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 21814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (text = png_ptr->chunkdata; *text; text++) 2182a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 2183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* zTXt must have some text after the chunkdataword */ 21854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (text >= png_ptr->chunkdata + slength - 2) 2186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Truncated zTXt chunk"); 21884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 21894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project comp_type = *(++text); 2195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (comp_type != PNG_TEXT_COMPRESSION_zTXt) 2196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Unknown compression type in zTXt chunk"); 2198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project comp_type = PNG_TEXT_COMPRESSION_zTXt; 2199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2200a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott text++; /* Skip the compression_method byte */ 2201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 22024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project prefix_len = text - png_ptr->chunkdata; 2203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_decompress_chunk(png_ptr, comp_type, 22054215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_size_t)length, prefix_len, &data_len); 2206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr = (png_textp)png_malloc_warn(png_ptr, 22084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (png_uint_32)png_sizeof(png_text)); 2209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (text_ptr == NULL) 2210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 22114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Not enough memory to process zTXt chunk."); 22124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 22134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->compression = comp_type; 22174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->key = png_ptr->chunkdata; 2218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED 2219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->lang = NULL; 2220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->lang_key = NULL; 2221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->itxt_length = 0; 2222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 22234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->text = png_ptr->chunkdata + prefix_len; 2224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->text_length = data_len; 2225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, text_ptr); 22294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 22304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret) 2232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Insufficient memory to store zTXt chunk."); 2233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iTXt_SUPPORTED 2237a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Note: this does not correctly handle chunks that are > 64K under DOS */ 2238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_textp text_ptr; 2242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_charp key, lang, text, lang_key; 2243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int comp_flag; 2244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int comp_type = 0; 2245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ret; 2246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t slength, prefix_len, data_len; 2247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_iTXt"); 22494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 22505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED 22515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max != 0) 22525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 22535f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max == 1) 22545f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 22555f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 22565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 22575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 22585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (--png_ptr->user_chunk_cache_max == 1) 22595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 22605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "No space in chunk cache for iTXt"); 22615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 22625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 22635f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 22645f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 22655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 2266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->mode & PNG_HAVE_IHDR)) 2268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Missing IHDR before iTXt"); 2269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IDAT) 2271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 2272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 2274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* We will no doubt have problems with chunks even half this size, but 2275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project there is no hard and fast rule to tell us where to stop. */ 2276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 2277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 22784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "iTXt chunk too large to fit in memory"); 2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, length); 2280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 22844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 22854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1); 22864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->chunkdata == NULL) 2287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "No memory to process iTXt chunk."); 2289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project slength = (png_size_t)length; 22924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); 2293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_crc_finish(png_ptr, 0)) 2294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 22954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 22964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata[slength] = 0x00; 2301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23024215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (lang = png_ptr->chunkdata; *lang; lang++) 2303a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 2304a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott lang++; /* Skip NUL separator */ 2305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* iTXt must have a language tag (possibly empty), two compression bytes, 2307a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * translated keyword (possibly empty), and possibly some text after the 2308a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * keyword 2309a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 2310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (lang >= png_ptr->chunkdata + slength - 3) 2312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Truncated iTXt chunk"); 23144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 23154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project comp_flag = *lang++; 2321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project comp_type = *lang++; 2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (lang_key = lang; *lang_key; lang_key++) 2325a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 2326a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott lang_key++; /* Skip NUL separator */ 2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (lang_key >= png_ptr->chunkdata + slength) 2329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Truncated iTXt chunk"); 23314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 23324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (text = lang_key; *text; text++) 2337a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Empty loop */ ; 2338a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott text++; /* Skip NUL separator */ 23394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (text >= png_ptr->chunkdata + slength) 2340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Malformed iTXt chunk"); 23424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 23434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project prefix_len = text - png_ptr->chunkdata; 2348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project key=png_ptr->chunkdata; 2350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (comp_flag) 23514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_decompress_chunk(png_ptr, comp_type, 23524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project (size_t)length, prefix_len, &data_len); 2353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 23544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project data_len = png_strlen(png_ptr->chunkdata + prefix_len); 2355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr = (png_textp)png_malloc_warn(png_ptr, 2356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_uint_32)png_sizeof(png_text)); 2357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (text_ptr == NULL) 2358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 23594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_warning(png_ptr, "Not enough memory to process iTXt chunk."); 23604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 23614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->compression = (int)comp_flag + 1; 23654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key); 23664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->lang = png_ptr->chunkdata + (lang - key); 2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->itxt_length = data_len; 2368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project text_ptr->text_length = 0; 23694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->key = png_ptr->chunkdata; 23704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project text_ptr->text = png_ptr->chunkdata + prefix_len; 2371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1); 2373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, text_ptr); 23754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->chunkdata); 23764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_ptr->chunkdata = NULL; 2377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret) 2378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Insufficient memory to store iTXt chunk."); 2379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is called when we haven't found a handler for a 2383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project chunk. If there isn't a problem with the chunk itself (ie bad 2384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project chunk name, CRC, or a critical chunk), the chunk is silently ignored 2385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which 2386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case it will be saved away to be written out later. */ 2387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length) 2389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 skip = 0; 2391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 23924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_handle_unknown"); 23934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project 23945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED 23955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max != 0) 23965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 23975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (png_ptr->user_chunk_cache_max == 1) 23985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 23995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 24005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 24015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 24025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott if (--png_ptr->user_chunk_cache_max == 1) 24035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott { 24045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "No space in chunk cache for unknown chunk"); 24055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_crc_finish(png_ptr, length); 24065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott return; 24075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 24085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott } 24095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif 2410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->mode & PNG_HAVE_IDAT) 2412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 2414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST PNG_IDAT; 2415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2416a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) /* Not an IDAT */ 2417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 2418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->chunk_name[0] & 0x20)) 2421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 24225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 24234215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_HANDLE_CHUNK_ALWAYS 24255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project && png_ptr->read_user_chunk_fn == NULL 2427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ) 2429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "unknown critical chunk"); 2431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 24335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED 2434a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) 24355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 2436a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott || (png_ptr->read_user_chunk_fn != NULL) 2437a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott#endif 2438a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott ) 2439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 2441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length > (png_uint_32)65535L) 2442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "unknown chunk too large to fit in memory"); 2444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project skip = length - (png_uint_32)65535L; 2445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project length = (png_uint_32)65535L; 2446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy((png_charp)png_ptr->unknown_chunk.name, 2449a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott (png_charp)png_ptr->chunk_name, 2450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_sizeof(png_ptr->unknown_chunk.name)); 24515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1] 24525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott = '\0'; 2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->unknown_chunk.size = (png_size_t)length; 2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (length == 0) 2455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->unknown_chunk.data = NULL; 2456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length); 2459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length); 2460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 24615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED 24624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->read_user_chunk_fn != NULL) 2463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2464a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Callback to user unknown chunk handler */ 2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ret; 2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ret = (*(png_ptr->read_user_chunk_fn)) 2467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr, &png_ptr->unknown_chunk); 2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret < 0) 2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "error in user chunk"); 2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret == 0) 2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->chunk_name[0] & 0x20)) 24735f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED 24744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != 2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_HANDLE_CHUNK_ALWAYS) 2476a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott#endif 2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "unknown critical chunk"); 2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_unknown_chunks(png_ptr, info_ptr, 2479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project &png_ptr->unknown_chunk, 1); 2480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1); 2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_free(png_ptr, png_ptr->unknown_chunk.data); 2486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->unknown_chunk.data = NULL; 2487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project skip = length; 2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, skip); 2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 24945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_USER_CHUNKS_SUPPORTED 2495a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */ 2496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is called to verify that a chunk name is valid. 2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This function can't have the "critical chunk check" incorporated 2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project into it, since in the future we will need to be able to call user 2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project functions to handle unknown critical chunks after we check that 2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project the chunk name itself is valid. */ 2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97)) 2506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_check_chunk_name(png_structp png_ptr, png_bytep chunk_name) 2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 25104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_check_chunk_name"); 2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) || 2512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3])) 2513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_chunk_error(png_ptr, "invalid chunk type"); 2515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Combines the row recently read in with the existing pixels in the 2519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row. This routine takes care of alpha and transparency if requested. 2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project This routine also handles the two methods of progressive display 2521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project of interlaced images, depending on the mask value. 2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project The mask value describes which pixels are to be combined with 2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project the row. The pattern always repeats every 8 pixels, so just 8 2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project bits are needed. A one indicates the pixel is to be combined, 2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project a zero indicates the pixel is to be skipped. This is in addition 2526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project to any alpha or transparency value associated with the pixel. If 2527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project you want all pixels to be combined, pass 0xff (255) in mask. */ 2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_combine_row(png_structp png_ptr, png_bytep row, int mask) 2531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 25324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_combine_row"); 2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (mask == 0xff) 2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(row, png_ptr->row_buf + 1, 2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width)); 2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (png_ptr->row_info.pixel_depth) 2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = png_ptr->row_buf + 1; 2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row; 2546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_inc, s_start, s_end; 2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int m = 0x80; 2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift; 2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = png_ptr->width; 2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 25525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_PACKSWAP) 2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 7; 2557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 1; 2558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 7; 2563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -1; 2565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m & mask) 2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int value; 2574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x01; 2576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff); 2577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(value << shift); 2578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == s_end) 2581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 2584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp++; 2585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += s_inc; 2588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m == 1) 2590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m = 0x80; 2591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m >>= 1; 2593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 2597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = png_ptr->row_buf + 1; 2599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row; 2600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_start, s_end, s_inc; 2601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int m = 0x80; 2602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift; 2603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = png_ptr->width; 2605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int value; 2606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_PACKSWAP) 2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 6; 2612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 2; 2613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 6; 2618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -2; 2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m & mask) 2627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0x03; 2629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff); 2630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(value << shift); 2631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == s_end) 2634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 2637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp++; 2638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += s_inc; 2641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m == 1) 2642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m = 0x80; 2643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m >>= 1; 2645893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 2649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = png_ptr->row_buf + 1; 2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row; 2652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_start, s_end, s_inc; 2653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int m = 0x80; 2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int shift; 2655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = png_ptr->width; 2657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int value; 2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 26595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_PACKSWAP) 2661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 4; 2664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 4; 2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 4; 2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -4; 2672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m & mask) 2678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project value = (*sp >> shift) & 0xf; 2680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff); 2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(value << shift); 2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (shift == s_end) 2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift = s_start; 2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp++; 2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp++; 2689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project shift += s_inc; 2692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m == 1) 2693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m = 0x80; 2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m >>= 1; 2696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = png_ptr->row_buf + 1; 2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row; 2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3); 2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 row_width = png_ptr->width; 2706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte m = 0x80; 2707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_width; i++) 2710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m & mask) 2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(dp, sp, pixel_bytes); 2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp += pixel_bytes; 2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp += pixel_bytes; 2718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (m == 1) 2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m = 0x80; 2721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project m >>= 1; 2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED 2731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* OLD pre-1.0.9 interface: 2732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass, 2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 transformations) 2734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_interlace(png_structp png_ptr) 2737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_row_infop row_info = &(png_ptr->row_info); 2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep row = png_ptr->row_buf + 1; 2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int pass = png_ptr->pass; 2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 transformations = png_ptr->transformations; 2742a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 2743a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block */ 2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 2745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 27464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_do_read_interlace"); 2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row != NULL && row_info != NULL) 2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 final_width; 2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project final_width = row_info->width * png_pass_inc[pass]; 2752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (row_info->pixel_depth) 2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 1: 2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3); 2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row + (png_size_t)((final_width - 1) >> 3); 2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int sshift, dshift; 2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_start, s_end, s_inc; 2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int jstop = png_pass_inc[pass]; 2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v; 2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 27665f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (transformations & PNG_PACKSWAP) 2768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = (int)((row_info->width + 7) & 0x07); 2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = (int)((final_width + 7) & 0x07); 2771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 7; 2772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -1; 2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = 7 - (int)((row_info->width + 7) & 0x07); 2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = 7 - (int)((final_width + 7) & 0x07); 2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 7; 2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 1; 2783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_info->width; i++) 2786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_byte)((*sp >> sshift) & 0x01); 2788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < jstop; j++) 2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff); 2791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(v << dshift); 2792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (dshift == s_end) 2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = s_start; 2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 2796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift += s_inc; 2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (sshift == s_end) 2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = s_start; 2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift += s_inc; 2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 2: 2811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2); 2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2); 2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int sshift, dshift; 2815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_start, s_end, s_inc; 2816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int jstop = png_pass_inc[pass]; 2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (transformations & PNG_PACKSWAP) 2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = (int)(((row_info->width + 3) & 0x03) << 1); 2823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = (int)(((final_width + 3) & 0x03) << 1); 2824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 6; 2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -2; 2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1); 2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1); 2833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 6; 2835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 2; 2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_info->width; i++) 2839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v; 2841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 2842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project v = (png_byte)((*sp >> sshift) & 0x03); 2844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < jstop; j++) 2845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff); 2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(v << dshift); 2848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (dshift == s_end) 2849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = s_start; 2851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 2852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift += s_inc; 2855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (sshift == s_end) 2857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = s_start; 2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 2860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift += s_inc; 2863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case 4: 2867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1); 2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row + (png_size_t)((final_width - 1) >> 1); 2870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int sshift, dshift; 2871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int s_start, s_end, s_inc; 2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int jstop = png_pass_inc[pass]; 2874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 28755f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED 2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (transformations & PNG_PACKSWAP) 2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = (int)(((row_info->width + 1) & 0x01) << 2); 2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = (int)(((final_width + 1) & 0x01) << 2); 2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 4; 2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 0; 2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = -4; 2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2); 2888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2); 2889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_start = 0; 2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_end = 4; 2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project s_inc = 4; 2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_info->width; i++) 2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v = (png_byte)((*sp >> sshift) & 0xf); 2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < jstop; j++) 2900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff); 2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *dp |= (png_byte)(v << dshift); 2903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (dshift == s_end) 2904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift = s_start; 2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp--; 2907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dshift += s_inc; 2910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (sshift == s_end) 2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift = s_start; 2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp--; 2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 2917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sshift += s_inc; 2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 2922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_size_t pixel_bytes = (row_info->pixel_depth >> 3); 29245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_bytep sp = row + (png_size_t)(row_info->width - 1) 29255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * pixel_bytes; 2926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes; 2927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int jstop = png_pass_inc[pass]; 2929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < row_info->width; i++) 2932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte v[8]; 2934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int j; 2935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(v, sp, pixel_bytes); 2937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (j = 0; j < jstop; j++) 2938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memcpy(dp, v, pixel_bytes); 2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project dp -= pixel_bytes; 2941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project sp -= pixel_bytes; 2943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_info->width = final_width; 29484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width); 2949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 29505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_PACKSWAP_SUPPORTED 2951a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott transformations = transformations; /* Silence compiler warning */ 2952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 2953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 2954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */ 2955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 2957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row, 2958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep prev_row, int filter) 2959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 29604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_read_filter_row"); 29614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter); 2962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project switch (filter) 2963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_FILTER_VALUE_NONE: 2965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_FILTER_VALUE_SUB: 2967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 istop = row_info->rowbytes; 2970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 2971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep rp = row + bpp; 2972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep lp = row; 2973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = bpp; i < istop; i++) 2975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff); 2977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 2978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_FILTER_VALUE_UP: 2982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 istop = row_info->rowbytes; 2985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep rp = row; 2986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep pp = prev_row; 2987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 2988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < istop; i++) 2989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 2991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 2992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 2994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 2995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_FILTER_VALUE_AVG: 2996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 2997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 2998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep rp = row; 2999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep pp = prev_row; 3000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep lp = row; 3001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 istop = row_info->rowbytes - bpp; 3003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < bpp; i++) 3005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + 3007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ((int)(*pp++) / 2 )) & 0xff); 3008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 3009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < istop; i++) 3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + 3014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (int)(*pp++ + *lp++) / 2 ) & 0xff); 3015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 3016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project case PNG_FILTER_VALUE_PAETH: 3020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 i; 3022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep rp = row; 3023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep pp = prev_row; 3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep lp = row; 3025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_bytep cp = prev_row; 3026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3; 3027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_uint_32 istop=row_info->rowbytes - bpp; 3028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project for (i = 0; i < bpp; i++) 3030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff); 3032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 3033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3035a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott for (i = 0; i < istop; i++) /* Use leftover rp,pp */ 3036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int a, b, c, pa, pb, pc, p; 3038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project a = *lp++; 3040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project b = *pp++; 3041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project c = *cp++; 3042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = b - c; 3044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pc = a - c; 3045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_ABS 3047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pa = abs(p); 3048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pb = abs(pc); 3049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pc = abs(p + pc); 3050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else 3051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pa = p < 0 ? -p : p; 3052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pb = pc < 0 ? -pc : pc; 3053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project pc = (p + pc) < 0 ? -(p + pc) : p + pc; 3054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project /* 3057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (pa <= pb && pa <= pc) 3058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = a; 3059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (pb <= pc) 3060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = b; 3061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project p = c; 3063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */ 3064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 30654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c; 3066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *rp = (png_byte)(((int)(*rp) + p) & 0xff); 3068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project rp++; 3069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project default: 3073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Ignoring bad adaptive filter type"); 30744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project *row = 0; 3075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 3078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 30794ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#ifdef PNG_INDEX_SUPPORTED 30804ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenvoid /* PRIVATE */ 30814ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenpng_set_interlaced_pass(png_structp png_ptr, int pass) 30824ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen{ 30834ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 30844ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 30854ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen /* Start of interlace block */ 30864ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 30874ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 30884ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen /* Offset to next interlace block */ 30894ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 30904ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 30914ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen /* Start of interlace block in the y direction */ 30924ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 30934ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 30944ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen /* Offset to next interlace block in the y direction */ 30954ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 30964ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 30974ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_ptr->pass = pass; 30984ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_ptr->iwidth = (png_ptr->width + 30994ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_pass_inc[png_ptr->pass] - 1 - 31004ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_pass_start[png_ptr->pass]) / 31014ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen png_pass_inc[png_ptr->pass]; 31024ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen} 31034ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#endif 31044ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen 31055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_SEQUENTIAL_READ_SUPPORTED 3106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 3107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_finish_row(png_structp png_ptr) 3108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 3109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED 3110a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3112a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block */ 3113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3115a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block */ 3116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3118a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block in the y direction */ 3119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3121a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block in the y direction */ 3122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 31254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_read_finish_row"); 3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->row_number++; 3127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->row_number < png_ptr->num_rows) 3128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 3129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED 3131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->interlaced) 3132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->row_number = 0; 3134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_memset_check(png_ptr, png_ptr->prev_row, 0, 3135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->rowbytes + 1); 3136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project do 3137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->pass++; 3139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass >= 7) 3140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->iwidth = (png_ptr->width + 3142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_inc[png_ptr->pass] - 1 - 3143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_start[png_ptr->pass]) / 3144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_inc[png_ptr->pass]; 3145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->transformations & PNG_INTERLACE)) 3147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_rows = (png_ptr->height + 3149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_yinc[png_ptr->pass] - 1 - 3150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_ystart[png_ptr->pass]) / 3151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_yinc[png_ptr->pass]; 3152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->num_rows)) 3153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project continue; 3154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else /* if (png_ptr->transformations & PNG_INTERLACE) */ 3156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } while (png_ptr->iwidth == 0); 3158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->pass < 7) 3160893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project return; 3161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED)) 3165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS 3167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST PNG_IDAT; 3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project char extra; 3170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int ret; 3171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.next_out = (Byte *)&extra; 3173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_out = (uInt)1; 31744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project for (;;) 3175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->zstream.avail_in)) 3177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project while (!png_ptr->idat_size) 3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_byte chunk_length[4]; 3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_finish(png_ptr, 0); 3183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_read_data(png_ptr, chunk_length, 4); 3185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length); 3186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_reset_crc(png_ptr); 3187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, png_ptr->chunk_name, 4); 3188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4)) 3189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Not enough image data"); 3190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size; 3193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.next_in = png_ptr->zbuf; 3194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->zbuf_size > png_ptr->idat_size) 3195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size; 3196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in); 3197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->idat_size -= png_ptr->zstream.avail_in; 3198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH); 3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret == Z_STREAM_END) 3201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in || 3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->idat_size) 32045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "Extra compressed data."); 3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 3206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (ret != Z_OK) 3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg : 3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project "Decompression Error"); 3212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->zstream.avail_out)) 3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_warning(png_ptr, "Extra compressed data."); 3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 3217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED; 3218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project break; 3219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_out = 0; 3223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->idat_size || png_ptr->zstream.avail_in) 32265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_warning(png_ptr, "Extra compression data."); 3227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project inflateReset(&png_ptr->zstream); 3229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->mode |= PNG_AFTER_IDAT; 3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 32325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */ 3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */ 3235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_start_row(png_structp png_ptr) 3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{ 3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED 3238a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */ 3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3240a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block */ 3241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0}; 3242893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3243a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block */ 3244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1}; 3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3246a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Start of interlace block in the y direction */ 3247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1}; 3248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3249a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Offset to next interlace block in the y direction */ 3250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2}; 3251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project int max_pixel_depth; 32544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_size_t row_bytes; 3255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 32564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug(1, "in png_read_start_row"); 3257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->zstream.avail_in = 0; 3258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_init_read_transformations(png_ptr); 3259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED 3260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->interlaced) 3261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (!(png_ptr->transformations & PNG_INTERLACE)) 3263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 - 3264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_ystart[0]) / png_pass_yinc[0]; 3265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_rows = png_ptr->height; 3267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->iwidth = (png_ptr->width + 3269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_inc[png_ptr->pass] - 1 - 3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_start[png_ptr->pass]) / 3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_pass_inc[png_ptr->pass]; 3272893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */ 3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->num_rows = png_ptr->height; 3277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->iwidth = png_ptr->width; 3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = png_ptr->pixel_depth; 3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 32815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED 3282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8) 3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 8; 3284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 32865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_EXPAND) 3288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->num_trans) 3292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 24; 3295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (max_pixel_depth < 8) 3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 8; 3300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->num_trans) 3301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth *= 2; 3302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->num_trans) 3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth *= 4; 3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth /= 3; 3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 33145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 3315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & (PNG_FILLER)) 3316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE) 3318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY) 3320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (max_pixel_depth <= 8) 3322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 16; 3323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB) 3327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (max_pixel_depth <= 32) 3329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 64; 3332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 33365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED 3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->transformations & PNG_GRAY_TO_RGB) 3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if ( 33405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED 3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) || 3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 33435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED 3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project (png_ptr->transformations & (PNG_FILLER)) || 3345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) 3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (max_pixel_depth <= 16) 3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 64; 3352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (max_pixel_depth <= 8) 3356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 32; 3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 24; 3361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3362893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA) 3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 64; 3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project else 3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth = 48; 3366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \ 3371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_USER_TRANSFORM_PTR_SUPPORTED) 33724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (png_ptr->transformations & PNG_USER_TRANSFORM) 3373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project int user_pixel_depth = png_ptr->user_transform_depth* 3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->user_transform_channels; 33764215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (user_pixel_depth > max_pixel_depth) 3377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project max_pixel_depth=user_pixel_depth; 3378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3381a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Align the width on the next larger 8 pixels. Mainly used 3382a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * for interlacing 3383a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 3384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7)); 3385a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott /* Calculate the maximum bytes needed, adding a byte and a pixel 3386a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott * for safety's sake 3387a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott */ 33884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) + 3389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 1 + ((max_pixel_depth + 7) >> 3); 3390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 3391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project if (row_bytes > (png_uint_32)65536L) 3392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "This image requires a row greater than 64KB"); 3393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 33954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project if (row_bytes + 64 > png_ptr->old_big_row_buf_size) 3396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 33974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_free(png_ptr, png_ptr->big_row_buf); 3398a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (png_ptr->interlaced) 33995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr, 34005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott row_bytes + 64); 34015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott else 34025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, 34035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott row_bytes + 64); 34045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_ptr->old_big_row_buf_size = row_bytes + 64; 34055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott 34065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott /* Use 32 bytes of padding before and after row_buf. */ 3407a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->row_buf = png_ptr->big_row_buf + 32; 3408a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->old_big_row_buf_size = row_bytes + 64; 3409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K 3412a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L) 3413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "This image requires a row greater than 64KB"); 3414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif 3415a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1)) 3416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_error(png_ptr, "Row has too many bytes to allocate in memory."); 3417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3418a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott if (row_bytes + 1 > png_ptr->old_prev_row_size) 3419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project { 3420a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_free(png_ptr, png_ptr->prev_row); 3421a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)( 3422a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott row_bytes + 1)); 3423a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1); 3424a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->old_prev_row_size = row_bytes + 1; 3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project } 3426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3427a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott png_ptr->rowbytes = row_bytes; 3428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 34294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "width = %lu,", png_ptr->width); 34304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "height = %lu,", png_ptr->height); 34314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "iwidth = %lu,", png_ptr->iwidth); 34324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "num_rows = %lu,", png_ptr->num_rows); 34334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes); 34345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott png_debug1(3, "irowbytes = %lu", 34355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1); 3436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project 3437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project png_ptr->flags |= PNG_FLAG_ROW_INIT; 3438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project} 3439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED */ 3440