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