pngrutil.c revision 4ce0ee15f268e0161438b4133936cb2826f7fd50
1893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* pngrutil.c - utilities to read a PNG file
3893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project *
45f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * Last changed in libpng 1.2.44 [June 26, 2010]
55f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott * Copyright (c) 1998-2010 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         {
2675f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            int copy = output_size - count;
2685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            if (avail < copy) copy = 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;
3835f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_charp text = png_malloc_warn(png_ptr,
3845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                        prefix_size + expanded_size + 1);
3855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
3865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         if (text != NULL)
387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            png_memcpy(text, png_ptr->chunkdata, prefix_size);
3895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            new_size = png_inflate(png_ptr,
3905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                (png_bytep)(png_ptr->chunkdata + prefix_size),
3915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                chunklength - prefix_size,
3925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                (png_bytep)(text + prefix_size), expanded_size);
3935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            text[prefix_size + expanded_size] = 0; /* just in case */
394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            if (new_size == expanded_size)
3965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            {
3975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               png_free(png_ptr, png_ptr->chunkdata);
3985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               png_ptr->chunkdata = text;
3995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               *newlength = prefix_size + expanded_size;
4005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               return; /* The success return! */
4015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            }
402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_warning(png_ptr, "png_inflate logic error");
4045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_free(png_ptr, text);
4055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         }
4065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         else
4075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott          png_warning(png_ptr, "Not enough memory to decompress chunk.");
4085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
4135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      char umsg[50];
415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
4175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott          comp_type);
418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, umsg);
419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Unknown zTXt compression type");
421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      /* The recovery is to simply drop the data. */
424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
4255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   /* Generic error return - leave the prefix, delete the compressed
4275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    * data, reallocate the chunkdata to remove the potentially large
4285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    * amount of compressed data.
4295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott    */
4305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
4315f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
4325f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (text != NULL)
4335f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
4345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         if (prefix_size > 0)
4355f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_memcpy(text, png_ptr->chunkdata, prefix_size);
4365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_free(png_ptr, png_ptr->chunkdata);
4375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_ptr->chunkdata = text;
4385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         /* This is an extra zero in the 'uncompressed' part. */
4405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         *(png_ptr->chunkdata + prefix_size) = 0x00;
4415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
4425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      /* Ignore a malloc error here - it is safe. */
4435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
4445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
4455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   *newlength = prefix_size;
446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
449a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read and check the IDHR chunk */
450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[13];
454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 width, height;
455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int bit_depth, color_type, compression_type, filter_type;
456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int interlace_type;
457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
4584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_IHDR");
459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IHDR)
461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Out of place IHDR");
462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
463a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Check the length */
464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 13)
465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Invalid IHDR chunk");
466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->mode |= PNG_HAVE_IHDR;
468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 13);
470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_finish(png_ptr, 0);
471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   width = png_get_uint_31(png_ptr, buf);
473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   height = png_get_uint_31(png_ptr, buf + 4);
474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   bit_depth = buf[8];
475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   color_type = buf[9];
476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   compression_type = buf[10];
477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   filter_type = buf[11];
478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   interlace_type = buf[12];
479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
480a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Set internal variables */
481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->width = width;
482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->height = height;
483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->bit_depth = (png_byte)bit_depth;
484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->interlaced = (png_byte)interlace_type;
485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->color_type = (png_byte)color_type;
4865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_MNG_FEATURES_SUPPORTED
487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->filter_type = (png_byte)filter_type;
488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->compression_type = (png_byte)compression_type;
490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
491a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Find number of channels */
492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (png_ptr->color_type)
493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_COLOR_TYPE_GRAY:
495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_COLOR_TYPE_PALETTE:
496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->channels = 1;
497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
498a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_COLOR_TYPE_RGB:
500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->channels = 3;
501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
502a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_COLOR_TYPE_GRAY_ALPHA:
504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->channels = 2;
505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
506a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_COLOR_TYPE_RGB_ALPHA:
508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->channels = 4;
509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
512a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Set up other useful info */
513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->channels);
5154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
5164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
5174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "channels = %d", png_ptr->channels);
5184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      color_type, interlace_type, compression_type, filter_type);
521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
523a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read and check the palette */
524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_color palette[PNG_MAX_PALETTE_LENGTH];
528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int num, i;
5295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED
530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_colorp pal_ptr;
531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_PLTE");
534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before PLTE");
537a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid PLTE after IDAT");
541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
544a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Duplicate PLTE chunk");
547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->mode |= PNG_HAVE_PLTE;
549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr,
553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        "Ignoring PLTE chunk in grayscale PNG");
554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
5575f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED
558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Invalid palette chunk");
570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_crc_finish(png_ptr, length);
571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
573a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott
574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_error(png_ptr, "Invalid palette chunk");
577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   num = (int)length / 3;
581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
5825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED
583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_byte buf[3];
586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      pal_ptr->red = buf[0];
589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      pal_ptr->green = buf[1];
590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      pal_ptr->blue = buf[2];
591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < num; i++)
594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_byte buf[3];
596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
598a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Don't depend upon png_color being any order */
599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].red = buf[0];
600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].green = buf[1];
601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      palette[i].blue = buf[2];
602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
606a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * whatever the normal CRC configuration tells us.  However, if we
607a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * have an RGB image, the PLTE can be considered ancillary, so
608a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * we will act as though it is.
609a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
6105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED
611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, 0);
615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
6165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_OPT_PLTE_SUPPORTED
617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* If we don't want to use the data from an ancillary chunk,
620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         we have two options: an error abort, or a warning and we
621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         ignore the data in this chunk (which should be OK, since
622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         it's considered ancillary for a RGB or RGBA image). */
623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_chunk_error(png_ptr, "CRC error");
628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_chunk_warning(png_ptr, "CRC error");
632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            return;
633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Otherwise, we (optionally) emit a warning and use the chunk. */
636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_chunk_warning(png_ptr, "CRC error");
639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_PLTE(png_ptr, info_ptr, palette, num);
644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tRNS_SUPPORTED
646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans > (png_uint_16)num)
651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->num_trans = (png_uint_16)num;
654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (info_ptr->num_trans > (png_uint_16)num)
656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            info_ptr->num_trans = (png_uint_16)num;
659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
6694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_IEND");
670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "No image in file");
674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 0)
679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect IEND chunk length");
681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_finish(png_ptr, length);
683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
684a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_gAMA_SUPPORTED
688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_fixed_point igamma;
692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   float file_gamma;
694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[4];
696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
6974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_gAMA");
698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before gAMA");
701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid gAMA after IDAT");
704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Should be an error, but we can cope with it */
709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Out of place gAMA chunk");
710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
7125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED
713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      )
716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate gAMA chunk");
718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 4)
723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect gAMA chunk length");
725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   igamma = (png_fixed_point)png_get_uint_32(buf);
734a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Check for zero gamma */
735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (igamma == 0)
736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr,
738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           "Ignoring gAMA chunk with gamma=0");
739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED
743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr,
747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
7485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED
7494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   file_gamma = (float)igamma / (float)100000.0;
757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  ifdef PNG_READ_GAMMA_SUPPORTED
758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_ptr->gamma = file_gamma;
759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  endif
760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_set_gAMA(png_ptr, info_ptr, file_gamma);
761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7685f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sBIT_SUPPORTED
769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t truelen;
773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[4];
774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
7754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_sBIT");
776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   buf[0] = buf[1] = buf[2] = buf[3] = 0;
778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sBIT");
781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid sBIT after IDAT");
784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Should be an error, but we can cope with it */
790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Out of place sBIT chunk");
791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate sBIT chunk");
795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      truelen = 3;
801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      truelen = (png_size_t)png_ptr->channels;
803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != truelen || length > 4)
805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect sBIT chunk length");
807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.green = buf[1];
819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.blue = buf[2];
820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.alpha = buf[3];
821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.gray = buf[0];
825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.green = buf[0];
827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.blue = buf[0];
828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->sig_bit.alpha = buf[1];
829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8345f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_cHRM_SUPPORTED
835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
8384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_byte buf[32];
839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int_y_green, int_x_blue, int_y_blue;
844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 uint_x, uint_y;
846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_cHRM");
848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before cHRM");
851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM after IDAT");
854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Should be an error, but we can cope with it */
859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before cHRM");
860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
861893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
8625f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED
863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      )
866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate cHRM chunk");
868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 32)
873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect cHRM chunk length");
875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, buf, 32);
8804215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_crc_finish(png_ptr, 0))
881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   uint_x = png_get_uint_32(buf);
8844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_y = png_get_uint_32(buf + 4);
8854215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   int_x_white = (png_fixed_point)uint_x;
8864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   int_y_white = (png_fixed_point)uint_y;
887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_x = png_get_uint_32(buf + 8);
8894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_y = png_get_uint_32(buf + 12);
890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_x_red = (png_fixed_point)uint_x;
891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_y_red = (png_fixed_point)uint_y;
892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_x = png_get_uint_32(buf + 16);
8944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_y = png_get_uint_32(buf + 20);
895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_x_green = (png_fixed_point)uint_x;
896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_y_green = (png_fixed_point)uint_y;
897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
8984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_x = png_get_uint_32(buf + 24);
8994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   uint_y = png_get_uint_32(buf + 28);
900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_x_blue = (png_fixed_point)uint_x;
901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int_y_blue = (png_fixed_point)uint_y;
902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   white_x = (float)int_x_white / (float)100000.0;
905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   white_y = (float)int_y_white / (float)100000.0;
906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   red_x   = (float)int_x_red   / (float)100000.0;
907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   red_y   = (float)int_y_red   / (float)100000.0;
908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   green_x = (float)int_x_green / (float)100000.0;
909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   green_y = (float)int_y_green / (float)100000.0;
910893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   blue_x  = (float)int_x_blue  / (float)100000.0;
911893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   blue_y  = (float)int_y_blue  / (float)100000.0;
912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED
915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr,
927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
9285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED
929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
9304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               white_x, white_y, red_x, red_y);
9324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               green_x, green_y, blue_x, blue_y);
934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
9354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
9365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               (long)int_x_white, (long)int_y_white,
9375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               (long)int_x_red, (long)int_y_red);
9384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
9395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               (long)int_x_green, (long)int_y_green,
9405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               (long)int_x_blue, (long)int_y_blue);
941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
9425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif /* PNG_CONSOLE_IO_SUPPORTED */
943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
947893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_cHRM(png_ptr, info_ptr,
950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_cHRM_fixed(png_ptr, info_ptr,
954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int_y_green, int_x_blue, int_y_blue);
956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sRGB_SUPPORTED
961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int intent;
965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[1];
966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
9674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_sRGB");
968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sRGB");
971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid sRGB after IDAT");
974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Should be an error, but we can cope with it */
979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Out of place sRGB chunk");
980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate sRGB chunk");
984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 1)
989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect sRGB chunk length");
991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 1);
996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   intent = buf[0];
1000a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Check for bad intent */
1001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (intent >= PNG_sRGB_INTENT_LAST)
1002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Unknown sRGB intent");
1004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
1008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
1009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_fixed_point igamma;
1011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      igamma=info_ptr->int_gamma;
1013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  ifdef PNG_FLOATING_POINT_SUPPORTED
1015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
1016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  endif
1017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
1019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr,
1021893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
10225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_CONSOLE_IO_SUPPORTED
1023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  ifdef PNG_FIXED_POINT_SUPPORTED
10244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         fprintf(stderr, "incorrect gamma=(%d/100000)\n",
10254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            (int)png_ptr->int_gamma);
1026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  else
1027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#    ifdef PNG_FLOATING_POINT_SUPPORTED
10284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
1029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#    endif
1030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#  endif
1031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_gAMA_SUPPORTED */
1035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_cHRM_SUPPORTED
1037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
1039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
1040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
1041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
1042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
1043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
1044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
1045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
1046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
1047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
1048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr,
1049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
1050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
1051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_FIXED_POINT_SUPPORTED */
1052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_cHRM_SUPPORTED */
1053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
1055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
1057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
10585f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iCCP_SUPPORTED
1059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
1062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte compression_type;
1064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep pC;
1065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp profile;
1066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 skip = 0;
1067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 profile_size, profile_length;
1068893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength, prefix_length, data_length;
1069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
10704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_iCCP");
1071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iCCP");
1074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid iCCP after IDAT");
1077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1078893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1079893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
1081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Should be an error, but we can cope with it */
1082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Out of place iCCP chunk");
1083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
1085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate iCCP chunk");
1087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
1092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > (png_uint_32)65535L)
1093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
1095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      skip = length - (png_uint_32)65535L;
1096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      length = (png_uint_32)65535L;
1097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
11014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
11034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
1106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
11074215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
11084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata[slength] = 0x00;
1113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   for (profile = png_ptr->chunkdata; *profile; profile++)
1115a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop to find end of name */ ;
1116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   ++profile;
1118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1119a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* There should be at least one zero (the compression type byte)
1120a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * following the separator, and we should be on it
1121a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
11224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if ( profile >= png_ptr->chunkdata + slength - 1)
1123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
11244215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
11254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Malformed iCCP chunk");
1127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1130a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Compression_type should always be zero */
1131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   compression_type = *profile++;
1132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (compression_type)
1133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
11354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
1136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                                 wrote nonzero) */
1137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   prefix_length = profile - png_ptr->chunkdata;
11404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_decompress_chunk(png_ptr, compression_type,
11414215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     slength, prefix_length, &data_length);
1142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   profile_length = data_length - prefix_length;
1144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ( prefix_length > data_length || profile_length < 4)
1146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
11474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
11484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
1150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
11544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
11554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   profile_size = ((*(pC    ))<<24) |
11564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  ((*(pC + 1))<<16) |
11574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  ((*(pC + 2))<< 8) |
11584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                  ((*(pC + 3))    );
1159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (profile_size < profile_length)
1161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      profile_length = profile_size;
1162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (profile_size > profile_length)
1164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
11654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
11664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
1168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
11724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     compression_type, png_ptr->chunkdata + prefix_length, profile_length);
11734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
11744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
1175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_iCCP_SUPPORTED */
1177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11785f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sPLT_SUPPORTED
1179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
1182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep entry_start;
1184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_sPLT_t new_palette;
11855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED
1186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_sPLT_entryp pp;
1187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int data_length, entry_size, i;
1189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 skip = 0;
1190893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength;
1191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
11924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_sPLT");
11934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
11945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED
11955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
11965f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (png_ptr->user_chunk_cache_max != 0)
11975f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
11985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (png_ptr->user_chunk_cache_max == 1)
11995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
12005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
12015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
12025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
12035f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (--png_ptr->user_chunk_cache_max == 1)
12045f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
12055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_warning(png_ptr, "No space in chunk cache for sPLT");
12065f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
12075f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
12085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
12095f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
12105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
1211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1212893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sPLT");
1214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid sPLT after IDAT");
1217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
1222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > (png_uint_32)65535L)
1223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
1225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      skip = length - (png_uint_32)65535L;
1226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      length = (png_uint_32)65535L;
1227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
12314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
1232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
12334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1235893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
1236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
12374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
12384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1240893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata[slength] = 0x00;
1243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
12455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       entry_start++)
1246a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop to find end of name */ ;
1247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   ++entry_start;
1248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1249a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* A sample depth should follow the separator, and we should be on it  */
12504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
1251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
12524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
12534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "malformed sPLT chunk");
1255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   new_palette.depth = *entry_start++;
1259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   entry_size = (new_palette.depth == 8 ? 6 : 10);
12604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
1261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1262a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Integrity-check the data length */
1263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (data_length % entry_size)
1264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
12654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
12664215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "sPLT chunk has bad length");
1268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   new_palette.nentries = (png_int_32) ( data_length / entry_size);
12724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if ((png_uint_32) new_palette.nentries >
12734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
1274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_warning(png_ptr, "sPLT chunk too long");
1276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       return;
1277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
1279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
1280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (new_palette.entries == NULL)
1281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_warning(png_ptr, "sPLT chunk requires too much memory");
1283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       return;
1284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
12865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_POINTER_INDEXING_SUPPORTED
1287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
1288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
12895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      pp = new_palette.entries + i;
1290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (new_palette.depth == 8)
1292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->red = *entry_start++;
1294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->green = *entry_start++;
1295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->blue = *entry_start++;
1296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->alpha = *entry_start++;
1297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1300893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
1301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->green = png_get_uint_16(entry_start); entry_start += 2;
1302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
1303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
1304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   pp = new_palette.entries;
1309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
1310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (new_palette.depth == 8)
1313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].red   = *entry_start++;
1315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].green = *entry_start++;
1316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].blue  = *entry_start++;
1317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].alpha = *entry_start++;
1318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
1320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
1322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
1323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
1324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
1325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
1327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1329893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1330a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Discard all chunk data except the name and stash that */
13314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   new_palette.name = png_ptr->chunkdata;
1332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
1334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
13364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
1337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, new_palette.entries);
1338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_sPLT_SUPPORTED */
1340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tRNS_SUPPORTED
1342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
1346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
13474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_tRNS");
1348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tRNS");
1351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid tRNS after IDAT");
1354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
1358893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate tRNS chunk");
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
1364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
1365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_byte buf[2];
1367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (length != 2)
1369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
1371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_crc_finish(png_ptr, length);
1372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
1376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->num_trans = 1;
1377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->trans_values.gray = png_get_uint_16(buf);
1378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
1380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1381893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_byte buf[6];
1382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1383893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (length != 6)
1384893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1385893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
1386893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_crc_finish(png_ptr, length);
1387893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1388893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1389893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_read(png_ptr, buf, (png_size_t)length);
1390893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->num_trans = 1;
1391893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->trans_values.red = png_get_uint_16(buf);
1392893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1393893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
1394893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!(png_ptr->mode & PNG_HAVE_PLTE))
1398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* Should be an error, but we can cope with it. */
1400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Missing PLTE before tRNS");
1401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (length > (png_uint_32)png_ptr->num_palette ||
1403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          length > PNG_MAX_PALETTE_LENGTH)
1404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
1406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_crc_finish(png_ptr, length);
1407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1408893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1409893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (length == 0)
1410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Zero length tRNS chunk");
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      png_crc_read(png_ptr, readbuf, (png_size_t)length);
1416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->num_trans = (png_uint_16)length;
1417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1419893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1420893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
1421893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->num_trans = 0;
1428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
1432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      &(png_ptr->trans_values));
1433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1435893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_bKGD_SUPPORTED
1437893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1438893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t truelen;
1441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[6];
1442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
14434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_bKGD");
1444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before bKGD");
1447893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1448893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid bKGD after IDAT");
1450893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
1454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            !(png_ptr->mode & PNG_HAVE_PLTE))
1455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before bKGD");
1457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1459893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1460893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
1461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1462893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate bKGD chunk");
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
1467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      truelen = 1;
1469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
1470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      truelen = 6;
1471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      truelen = 2;
1473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != truelen)
1475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect bKGD chunk length");
1477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1480893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1481893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
1482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* We convert the index value into RGB components so that we can allow
1486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * arbitrary RGB values for background when we have transparency, and
1487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * so it is easy to determine the RGB values of the background color
1488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project    * from the info_ptr struct. */
1489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
1490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.index = buf[0];
1492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (info_ptr && info_ptr->num_palette)
1493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
14944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project          if (buf[0] >= info_ptr->num_palette)
1495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          {
1496893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             png_warning(png_ptr, "Incorrect bKGD chunk index value");
1497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             return;
1498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          }
1499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->background.red =
1500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].red;
1501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->background.green =
1502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].green;
1503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_ptr->background.blue =
1504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].blue;
1505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
1508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.red =
1510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.green =
1511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.blue =
1512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.gray = png_get_uint_16(buf);
1513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
1515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.red = png_get_uint_16(buf);
1517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.green = png_get_uint_16(buf + 2);
1518893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->background.blue = png_get_uint_16(buf + 4);
1519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
1522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_hIST_SUPPORTED
1526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   unsigned int num, i;
1530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
1531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_hIST");
1533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before hIST");
1536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1538893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid hIST after IDAT");
1539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
1543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before hIST");
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 (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
1549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate hIST chunk");
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
1555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   num = length / 2 ;
1556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (num != (unsigned int) png_ptr->num_palette || num >
1557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (unsigned int) PNG_MAX_PALETTE_LENGTH)
1558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect hIST chunk length");
1560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < num; i++)
1565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_byte buf[2];
1567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
1569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      readbuf[i] = png_get_uint_16(buf);
1570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_hIST(png_ptr, info_ptr, readbuf);
1576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15795f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pHYs_SUPPORTED
1580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[9];
1584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 res_x, res_y;
1585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int unit_type;
1586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
15874215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_pHYs");
1588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pHYs");
1591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1593893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid pHYs after IDAT");
1594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
1598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate pHYs chunk");
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
1604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 9)
1605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect pHYs chunk length");
1607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
1612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   res_x = png_get_uint_32(buf);
1616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   res_y = png_get_uint_32(buf + 4);
1617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   unit_type = buf[8];
1618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
1619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_oFFs_SUPPORTED
1623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[9];
1627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_int_32 offset_x, offset_y;
1628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int unit_type;
1629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_oFFs");
1631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before oFFs");
1634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid oFFs after IDAT");
1637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
1641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate oFFs chunk");
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
1647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 9)
1648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect oFFs chunk length");
1650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
1655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   offset_x = png_get_int_32(buf);
1659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   offset_y = png_get_int_32(buf + 4);
1660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   unit_type = buf[8];
1661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
1662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16655f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_pCAL_SUPPORTED
1666a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read the pCAL chunk (described in the PNG Extensions document) */
1667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_int_32 X0, X1;
1671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte type, nparams;
1672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp buf, units, endptr;
1673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charpp params;
1674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength;
1675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int i;
1676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
16774215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_pCAL");
1678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pCAL");
1681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL after IDAT");
1684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
1688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate pCAL chunk");
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
16944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
1695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      length + 1);
16964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
16974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
16984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata == NULL)
1699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
1700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL purpose.");
1701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       return;
1702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
1703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
17044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
17084215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
17094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1713a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(3, "Finding end of pCAL purpose string");
17164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   for (buf = png_ptr->chunkdata; *buf; buf++)
1717a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
1718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   endptr = png_ptr->chunkdata + slength;
1720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* We need to have at least 12 bytes after the purpose string
1722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      in order to get the parameter information. */
1723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (endptr <= buf + 12)
1724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL data");
17264215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
17274215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1728893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1729893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
1732893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   X0 = png_get_int_32((png_bytep)buf+1);
1733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   X1 = png_get_int_32((png_bytep)buf+5);
1734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   type = buf[9];
1735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   nparams = buf[10];
1736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   units = buf + 11;
1737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(3, "Checking pCAL equation type and number of parameters");
1739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Check that we have the right number of parameters for known
1740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      equation types. */
1741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
1742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
1743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
1744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
1745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
17474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
17484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (type >= PNG_EQUATION_LAST)
1752893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
1754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (buf = units; *buf; buf++)
1757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Empty loop to move past the units string. */ ;
1758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(3, "Allocating pCAL parameters array");
17604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   params = (png_charpp)png_malloc_warn(png_ptr,
17614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      (png_uint_32)(nparams * png_sizeof(png_charp))) ;
1762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (params == NULL)
1763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
17644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       png_free(png_ptr, png_ptr->chunkdata);
17654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       png_ptr->chunkdata = NULL;
1766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL params.");
1767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       return;
1768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
1769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* Get pointers to the start of each parameter string. */
1771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (i = 0; i < (int)nparams; i++)
1772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      buf++; /* Skip the null string terminator from previous parameter. */
1774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17754215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_debug1(3, "Reading pCAL parameter %d", i);
1776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
1777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         /* Empty loop to move past each parameter string */ ;
1778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      /* Make sure we haven't run out of data yet */
1780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (buf > endptr)
1781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
1782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Invalid pCAL data");
17834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_free(png_ptr, png_ptr->chunkdata);
17844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         png_ptr->chunkdata = NULL;
1785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_free(png_ptr, params);
1786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
1787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
1788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
1791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      units, params);
1792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17934215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
17944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
1795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, params);
1796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
17995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_sCAL_SUPPORTED
1800a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Read the sCAL chunk */
1801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
18044215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_charp ep;
1805893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   double width, height;
1807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp vp;
1808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp swidth, sheight;
1811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength;
1814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
18154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_sCAL");
1816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sCAL");
1819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
1820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL after IDAT");
1822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
1826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate sCAL chunk");
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
18324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
1833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      length + 1);
18344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
18354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata == NULL)
18364215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
18374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
18385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_crc_finish(png_ptr, length);
18394215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
18404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
1841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
18424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
1843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
18464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
18474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1851a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
1852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1853a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
1854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   width = png_strtod(png_ptr, ep, &vp);
1857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (*vp)
1858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
18594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "malformed width string in sCAL chunk");
18605f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, png_ptr->chunkdata);
18615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_ptr->chunkdata = NULL;
18624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
1863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (swidth == NULL)
18684215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
18694215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
18705f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, png_ptr->chunkdata);
18715f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_ptr->chunkdata = NULL;
18724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
18734215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
1874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
1875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
18784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   for (ep = png_ptr->chunkdata; *ep; ep++)
1879a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
1880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   ep++;
1881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
18824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata + slength < ep)
1883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
18844215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "Truncated sCAL chunk");
18855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
18864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, swidth);
1887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
18884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
18894215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
18904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
1891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   height = png_strtod(png_ptr, ep, &vp);
1895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (*vp)
1896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
18974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "malformed height string in sCAL chunk");
18985f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, png_ptr->chunkdata);
18995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_ptr->chunkdata = NULL;
19005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
19015f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, swidth);
19025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
19034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
1904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (sheight == NULL)
19094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   {
19104215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
19115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, png_ptr->chunkdata);
19125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_ptr->chunkdata = NULL;
19135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
19145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_free(png_ptr, swidth);
19155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
19164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      return;
19174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   }
1918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
1919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19224215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata + slength < ep
1923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      || width <= 0. || height <= 0.
1925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      )
1927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL data");
19294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
19304215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
1931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free(png_ptr, swidth);
1933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_free(png_ptr, sheight);
1934893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1936893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1937893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
19404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
1941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
1942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
19434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
1944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1946893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
19484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
1949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, swidth);
1951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, sheight);
1952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19565f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tIME_SUPPORTED
1957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
1958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
1959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
1960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_byte buf[7];
1961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_time mod_time;
1962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_tIME");
1964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
1966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Out of place tIME chunk");
1967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
1968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Duplicate tIME chunk");
1970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
1975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
1976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1977893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length != 7)
1978893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
1979893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Incorrect tIME chunk length");
1980893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_crc_finish(png_ptr, length);
1981893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
1983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_read(png_ptr, buf, 7);
1985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
1986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
1987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.second = buf[6];
1989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.minute = buf[5];
1990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.hour = buf[4];
1991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.day = buf[3];
1992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.month = buf[2];
1993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   mod_time.year = png_get_uint_16(buf);
1994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
1995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_set_tIME(png_ptr, info_ptr, &mod_time);
1996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
1997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
1998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
19995f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_tEXt_SUPPORTED
2000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
2001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_textp text_ptr;
2005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp key;
2006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp text;
2007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 skip = 0;
2008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength;
2009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int ret;
2010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_tEXt");
20124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
20135f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED
20145f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (png_ptr->user_chunk_cache_max != 0)
20155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
20165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (png_ptr->user_chunk_cache_max == 1)
20175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
20185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
20195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
20205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
20215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (--png_ptr->user_chunk_cache_max == 1)
20225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
20235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_warning(png_ptr, "No space in chunk cache for tEXt");
20245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
20255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
20265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
20275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
20285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
2029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tEXt");
2032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
2034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
2035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
2037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > (png_uint_32)65535L)
2038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
2040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      skip = length - (png_uint_32)65535L;
2041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      length = (png_uint_32)65535L;
2042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
20464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
20474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
20484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata == NULL)
2049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_warning(png_ptr, "No memory to process text chunk.");
2051893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
20544215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
2057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
20584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
20594215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2060893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20634215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   key = png_ptr->chunkdata;
20644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
2065893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   key[slength] = 0x00;
2066893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2067893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (text = key; *text; text++)
2068a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop to find end of key */ ;
2069893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2070893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (text != key + slength)
2071893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      text++;
2072893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2073893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2074893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_uint_32)png_sizeof(png_text));
2075893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (text_ptr == NULL)
2076893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2077893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_warning(png_ptr, "Not enough memory to process text chunk.");
20784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_free(png_ptr, png_ptr->chunkdata);
20794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_ptr->chunkdata = NULL;
2080893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2081893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2082893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
2083893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->key = key;
2084893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
2085893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->lang = NULL;
2086893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->lang_key = NULL;
2087893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->itxt_length = 0;
2088893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2089893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->text = text;
2090893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->text_length = png_strlen(text);
2091893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20924215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
20944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
20954215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
2096893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, text_ptr);
2097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (ret)
2098893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_warning(png_ptr, "Insufficient memory to process text chunk.");
2099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2101893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21025f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_zTXt_SUPPORTED
2103a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Note: this does not correctly handle chunks that are > 64K under DOS */
2104893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2107893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_textp text_ptr;
2108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp text;
2109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int comp_type;
2110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int ret;
2111893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength, prefix_len, data_len;
2112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21134215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_zTXt");
21144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
21155f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED
21165f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (png_ptr->user_chunk_cache_max != 0)
21175f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
21185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (png_ptr->user_chunk_cache_max == 1)
21195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
21205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
21215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
21225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
21235f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (--png_ptr->user_chunk_cache_max == 1)
21245f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
21255f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_warning(png_ptr, "No space in chunk cache for zTXt");
21265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
21275f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
21285f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
21295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
21305f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
21314215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
2132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before zTXt");
2134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
2136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
2137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
2139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
2140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
2141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > (png_uint_32)65535L)
2142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
21434215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_warning(png_ptr, "zTXt chunk too large to fit in memory");
2144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_crc_finish(png_ptr, length);
2145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21494215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
21504215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
21514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata == NULL)
2152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
21534215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_warning(png_ptr, "Out of memory processing zTXt chunk.");
2154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
21574215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
2159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
21604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
21614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21654215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata[slength] = 0x00;
2166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21674215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   for (text = png_ptr->chunkdata; *text; text++)
2168a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
2169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* zTXt must have some text after the chunkdataword */
21714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (text >= png_ptr->chunkdata + slength - 2)
2172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Truncated zTXt chunk");
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   else
2179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       comp_type = *(++text);
2181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
2182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       {
2183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
2184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          comp_type = PNG_TEXT_COMPRESSION_zTXt;
2185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       }
2186a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       text++;        /* Skip the compression_method byte */
2187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
21884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   prefix_len = text - png_ptr->chunkdata;
2189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
21904215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_decompress_chunk(png_ptr, comp_type,
21914215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     (png_size_t)length, prefix_len, &data_len);
2192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
21944215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      (png_uint_32)png_sizeof(png_text));
2195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (text_ptr == NULL)
2196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
21974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
21984215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_free(png_ptr, png_ptr->chunkdata);
21994215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_ptr->chunkdata = NULL;
2200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->compression = comp_type;
22034215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->key = png_ptr->chunkdata;
2204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
2205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->lang = NULL;
2206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->lang_key = NULL;
2207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->itxt_length = 0;
2208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
22094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->text = png_ptr->chunkdata + prefix_len;
2210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->text_length = data_len;
2211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22124215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, text_ptr);
22154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
22164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
2217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (ret)
2218893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
2219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_iTXt_SUPPORTED
2223a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott/* Note: this does not correctly handle chunks that are > 64K under DOS */
2224893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2226893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_textp text_ptr;
2228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_charp key, lang, text, lang_key;
2229893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int comp_flag;
2230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int comp_type = 0;
2231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int ret;
2232893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_size_t slength, prefix_len, data_len;
2233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_iTXt");
22354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
22365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED
22375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (png_ptr->user_chunk_cache_max != 0)
22385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
22395f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (png_ptr->user_chunk_cache_max == 1)
22405f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
22415f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
22425f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
22435f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
22445f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (--png_ptr->user_chunk_cache_max == 1)
22455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
22465f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_warning(png_ptr, "No space in chunk cache for iTXt");
22475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
22485f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
22495f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
22505f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
22515f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
2252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
2254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iTXt");
2255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
2257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
2258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
2260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
2261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
2262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (length > (png_uint_32)65535L)
2263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
22644215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
2265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_crc_finish(png_ptr, length);
2266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2267893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22704215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
22714215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
22724215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->chunkdata == NULL)
2273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_warning(png_ptr, "No memory to process iTXt chunk.");
2275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   slength = (png_size_t)length;
22784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
2279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
2280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
22814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
22824215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22864215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata[slength] = 0x00;
2287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22884215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   for (lang = png_ptr->chunkdata; *lang; lang++)
2289a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
2290a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   lang++;        /* Skip NUL separator */
2291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   /* iTXt must have a language tag (possibly empty), two compression bytes,
2293a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * translated keyword (possibly empty), and possibly some text after the
2294a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * keyword
2295a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
2296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
22974215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (lang >= png_ptr->chunkdata + slength - 3)
2298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Truncated iTXt chunk");
23004215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
23014215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       comp_flag = *lang++;
2307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       comp_type = *lang++;
2308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (lang_key = lang; *lang_key; lang_key++)
2311a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
2312a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   lang_key++;        /* Skip NUL separator */
2313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23144215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (lang_key >= png_ptr->chunkdata + slength)
2315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Truncated iTXt chunk");
23174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
23184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2322893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   for (text = lang_key; *text; text++)
2323a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      /* Empty loop */ ;
2324a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   text++;        /* Skip NUL separator */
23254215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (text >= png_ptr->chunkdata + slength)
2326893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_warning(png_ptr, "Malformed iTXt chunk");
23284215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_free(png_ptr, png_ptr->chunkdata);
23294215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      png_ptr->chunkdata = NULL;
2330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
2331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23334215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   prefix_len = text - png_ptr->chunkdata;
2334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23354215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   key=png_ptr->chunkdata;
2336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (comp_flag)
23374215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       png_decompress_chunk(png_ptr, comp_type,
23384215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         (size_t)length, prefix_len, &data_len);
2339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
23404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      (png_uint_32)png_sizeof(png_text));
2343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (text_ptr == NULL)
2344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
23454215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
23464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_free(png_ptr, png_ptr->chunkdata);
23474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_ptr->chunkdata = NULL;
2348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     return;
2349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->compression = (int)comp_flag + 1;
23514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
23524215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->lang = png_ptr->chunkdata + (lang - key);
2353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->itxt_length = data_len;
2354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   text_ptr->text_length = 0;
23554215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->key = png_ptr->chunkdata;
23564215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   text_ptr->text = png_ptr->chunkdata + prefix_len;
2357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
2359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2360893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_free(png_ptr, text_ptr);
23614215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_free(png_ptr, png_ptr->chunkdata);
23624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_ptr->chunkdata = NULL;
2363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (ret)
2364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2367893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2368893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is called when we haven't found a handler for a
2369893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   chunk.  If there isn't a problem with the chunk itself (ie bad
2370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   chunk name, CRC, or a critical chunk), the chunk is silently ignored
2371893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2372893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   case it will be saved away to be written out later. */
2373893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2374893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
2375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 skip = 0;
2377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
23784215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_handle_unknown");
23794215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project
23805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_USER_LIMITS_SUPPORTED
23815f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   if (png_ptr->user_chunk_cache_max != 0)
23825f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   {
23835f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (png_ptr->user_chunk_cache_max == 1)
23845f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
23855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
23865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
23875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
23885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      if (--png_ptr->user_chunk_cache_max == 1)
23895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      {
23905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
23915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         png_crc_finish(png_ptr, length);
23925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott         return;
23935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      }
23945f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   }
23955f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif
2396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
2398893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
2400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      PNG_CONST PNG_IDAT;
2401893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2402a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
2403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->mode |= PNG_AFTER_IDAT;
2404893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2406893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->chunk_name[0] & 0x20))
2407893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
24085f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
24094215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2410893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           PNG_HANDLE_CHUNK_ALWAYS
24115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           && png_ptr->read_user_chunk_fn == NULL
2413893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        )
2415893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2416893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          png_chunk_error(png_ptr, "unknown critical chunk");
2417893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2418893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24195f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2420a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
24215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2422a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott       || (png_ptr->read_user_chunk_fn != NULL)
2423a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott#endif
2424a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott        )
2425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2426893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
2427893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       if (length > (png_uint_32)65535L)
2428893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       {
2429893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           png_warning(png_ptr, "unknown chunk too large to fit in memory");
2430893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           skip = length - (png_uint_32)65535L;
2431893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           length = (png_uint_32)65535L;
2432893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       }
2433893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2434893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2435a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott                  (png_charp)png_ptr->chunk_name,
2436893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_sizeof(png_ptr->unknown_chunk.name));
24375f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
24385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott           = '\0';
2439893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_ptr->unknown_chunk.size = (png_size_t)length;
2440893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       if (length == 0)
2441893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->unknown_chunk.data = NULL;
2442893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       else
2443893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       {
2444893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2445893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2446893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       }
24475f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
24484215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (png_ptr->read_user_chunk_fn != NULL)
2449893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       {
2450a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott          /* Callback to user unknown chunk handler */
2451893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          int ret;
2452893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          ret = (*(png_ptr->read_user_chunk_fn))
2453893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            (png_ptr, &png_ptr->unknown_chunk);
2454893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if (ret < 0)
2455893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             png_chunk_error(png_ptr, "error in user chunk");
2456893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          if (ret == 0)
2457893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          {
2458893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             if (!(png_ptr->chunk_name[0] & 0x20))
24595f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
24604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2461893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     PNG_HANDLE_CHUNK_ALWAYS)
2462a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott#endif
2463893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                   png_chunk_error(png_ptr, "unknown critical chunk");
2464893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             png_set_unknown_chunks(png_ptr, info_ptr,
2465893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               &png_ptr->unknown_chunk, 1);
2466893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project          }
2467893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       }
2468893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       else
2469893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2470893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2471893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_free(png_ptr, png_ptr->unknown_chunk.data);
2472893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       png_ptr->unknown_chunk.data = NULL;
2473893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2474893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2475893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2476893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      skip = length;
2477893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2478893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_crc_finish(png_ptr, skip);
2479893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
24805f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2481a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
2482893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2483893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2484893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2485893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* This function is called to verify that a chunk name is valid.
2486893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   This function can't have the "critical chunk check" incorporated
2487893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   into it, since in the future we will need to be able to call user
2488893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   functions to handle unknown critical chunks after we check that
2489893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   the chunk name itself is valid. */
2490893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2491893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
2492893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2493893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2494893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2495893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
24964215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_check_chunk_name");
2497893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2498893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2499893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2500893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_chunk_error(png_ptr, "invalid chunk type");
2501893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2502893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2503893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2504893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* Combines the row recently read in with the existing pixels in the
2505893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   row.  This routine takes care of alpha and transparency if requested.
2506893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   This routine also handles the two methods of progressive display
2507893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   of interlaced images, depending on the mask value.
2508893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   The mask value describes which pixels are to be combined with
2509893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   the row.  The pattern always repeats every 8 pixels, so just 8
2510893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   bits are needed.  A one indicates the pixel is to be combined,
2511893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   a zero indicates the pixel is to be skipped.  This is in addition
2512893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   to any alpha or transparency value associated with the pixel.  If
2513893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   you want all pixels to be combined, pass 0xff (255) in mask.  */
2514893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2515893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2516893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_combine_row(png_structp png_ptr, png_bytep row, int mask)
2517893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
25184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_combine_row");
2519893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (mask == 0xff)
2520893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2521893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_memcpy(row, png_ptr->row_buf + 1,
2522893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
2523893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2524893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
2525893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2526893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (png_ptr->row_info.pixel_depth)
2527893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2528893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 1:
2529893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2530893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
2531893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row;
2532893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_inc, s_start, s_end;
2533893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int m = 0x80;
2534893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int shift;
2535893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2536893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
2537893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
25385f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2539893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
2540893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2541893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_start = 0;
2542893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_end = 7;
2543893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_inc = 1;
2544893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2545893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2546893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2547893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2548893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_start = 7;
2549893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_end = 0;
2550893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_inc = -1;
2551893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2552893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2553893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            shift = s_start;
2554893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2555893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2556893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2557893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m & mask)
2558893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2559893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  int value;
2560893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2561893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x01;
2562893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
2563893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(value << shift);
2564893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2565893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2566893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == s_end)
2567893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2568893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = s_start;
2569893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
2570893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp++;
2571893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2572893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2573893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift += s_inc;
2574893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2575893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m == 1)
2576893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m = 0x80;
2577893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2578893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m >>= 1;
2579893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2580893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2581893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2582893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
2583893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2584893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
2585893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row;
2586893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_start, s_end, s_inc;
2587893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int m = 0x80;
2588893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int shift;
2589893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2590893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
2591893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int value;
2592893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
25935f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2594893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
2595893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2596893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 0;
2597893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 6;
2598893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = 2;
2599893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2600893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2601893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2602893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2603893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 6;
2604893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 0;
2605893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = -2;
2606893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2607893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2608893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            shift = s_start;
2609893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2610893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2611893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2612893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m & mask)
2613893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2614893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0x03;
2615893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
2616893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(value << shift);
2617893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2618893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2619893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == s_end)
2620893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2621893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = s_start;
2622893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
2623893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp++;
2624893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2625893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2626893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift += s_inc;
2627893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m == 1)
2628893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m = 0x80;
2629893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2630893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m >>= 1;
2631893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2632893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2633893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2634893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
2635893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2636893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
2637893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row;
2638893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_start, s_end, s_inc;
2639893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int m = 0x80;
2640893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int shift;
2641893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2642893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
2643893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int value;
2644893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
26455f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2646893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
2647893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2648893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 0;
2649893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 4;
2650893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = 4;
2651893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2652893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2653893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2654893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2655893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 4;
2656893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 0;
2657893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = -4;
2658893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2659893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            shift = s_start;
2660893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2661893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2662893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2663893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m & mask)
2664893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2665893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  value = (*sp >> shift) & 0xf;
2666893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
2667893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(value << shift);
2668893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2669893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2670893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (shift == s_end)
2671893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2672893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift = s_start;
2673893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp++;
2674893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp++;
2675893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2676893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2677893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  shift += s_inc;
2678893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m == 1)
2679893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m = 0x80;
2680893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2681893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m >>= 1;
2682893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2683893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2684893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2685893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         default:
2686893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2687893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
2688893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row;
2689893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
2690893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2691893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
2692893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte m = 0x80;
2693893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2694893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2695893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_width; i++)
2696893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2697893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m & mask)
2698893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2699893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_memcpy(dp, sp, pixel_bytes);
2700893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2701893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2702893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp += pixel_bytes;
2703893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dp += pixel_bytes;
2704893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2705893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (m == 1)
2706893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m = 0x80;
2707893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2708893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  m >>= 1;
2709893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2710893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2711893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2712893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2713893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
2714893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2715893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2716893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
2717893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project/* OLD pre-1.0.9 interface:
2718893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
2719893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 transformations)
2720893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project */
2721893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2722893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_do_read_interlace(png_structp png_ptr)
2723893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
2724893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_row_infop row_info = &(png_ptr->row_info);
2725893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep row = png_ptr->row_buf + 1;
2726893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int pass = png_ptr->pass;
2727893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_uint_32 transformations = png_ptr->transformations;
2728a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2729a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Offset to next interlace block */
2730893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
2731893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
27324215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_do_read_interlace");
2733893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row != NULL && row_info != NULL)
2734893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2735893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_uint_32 final_width;
2736893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2737893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      final_width = row_info->width * png_pass_inc[pass];
2738893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2739893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      switch (row_info->pixel_depth)
2740893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2741893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 1:
2742893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2743893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
2744893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
2745893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int sshift, dshift;
2746893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_start, s_end, s_inc;
2747893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int jstop = png_pass_inc[pass];
2748893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_byte v;
2749893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2750893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int j;
2751893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
27525f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2753893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (transformations & PNG_PACKSWAP)
2754893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2755893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                sshift = (int)((row_info->width + 7) & 0x07);
2756893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                dshift = (int)((final_width + 7) & 0x07);
2757893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_start = 7;
2758893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_end = 0;
2759893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_inc = -1;
2760893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2761893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2762893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2763893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2764893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                sshift = 7 - (int)((row_info->width + 7) & 0x07);
2765893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                dshift = 7 - (int)((final_width + 7) & 0x07);
2766893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_start = 0;
2767893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_end = 7;
2768893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                s_inc = 1;
2769893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2770893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2771893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_info->width; i++)
2772893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2773893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x01);
2774893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = 0; j < jstop; j++)
2775893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2776893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
2777893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
2778893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (dshift == s_end)
2779893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2780893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift = s_start;
2781893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
2782893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2783893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2784893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift += s_inc;
2785893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2786893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (sshift == s_end)
2787893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2788893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift = s_start;
2789893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
2790893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2791893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2792893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift += s_inc;
2793893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2794893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2795893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2796893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 2:
2797893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2798893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
2799893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
2800893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int sshift, dshift;
2801893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_start, s_end, s_inc;
2802893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int jstop = png_pass_inc[pass];
2803893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2804893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
28055f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2806893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (transformations & PNG_PACKSWAP)
2807893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2808893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
2809893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dshift = (int)(((final_width + 3) & 0x03) << 1);
2810893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 6;
2811893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 0;
2812893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = -2;
2813893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2814893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2815893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2816893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2817893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
2818893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
2819893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 0;
2820893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 6;
2821893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = 2;
2822893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2823893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2824893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_info->width; i++)
2825893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2826893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte v;
2827893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int j;
2828893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2829893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x03);
2830893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = 0; j < jstop; j++)
2831893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2832893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
2833893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
2834893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (dshift == s_end)
2835893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2836893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift = s_start;
2837893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
2838893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2839893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2840893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift += s_inc;
2841893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2842893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (sshift == s_end)
2843893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2844893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift = s_start;
2845893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
2846893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2847893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2848893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift += s_inc;
2849893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2850893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2851893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2852893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         case 4:
2853893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2854893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
2855893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
2856893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int sshift, dshift;
2857893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int s_start, s_end, s_inc;
2858893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2859893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int jstop = png_pass_inc[pass];
2860893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
28615f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACKSWAP_SUPPORTED
2862893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (transformations & PNG_PACKSWAP)
2863893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2864893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
2865893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dshift = (int)(((final_width + 1) & 0x01) << 2);
2866893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 4;
2867893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 0;
2868893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = -4;
2869893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2870893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            else
2871893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2872893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2873893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
2874893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
2875893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_start = 0;
2876893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_end = 4;
2877893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               s_inc = 4;
2878893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2879893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2880893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_info->width; i++)
2881893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2882893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
2883893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int j;
2884893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2885893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = 0; j < jstop; j++)
2886893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2887893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
2888893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
2889893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  if (dshift == s_end)
2890893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  {
2891893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift = s_start;
2892893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dp--;
2893893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  }
2894893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  else
2895893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                     dshift += s_inc;
2896893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2897893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (sshift == s_end)
2898893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2899893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift = s_start;
2900893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sp--;
2901893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2902893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
2903893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  sshift += s_inc;
2904893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2905893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2906893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2907893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         default:
2908893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2909893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
29105f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            png_bytep sp = row + (png_size_t)(row_info->width - 1)
29115f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott                * pixel_bytes;
2912893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
2913893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2914893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int jstop = png_pass_inc[pass];
2915893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_uint_32 i;
2916893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2917893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            for (i = 0; i < row_info->width; i++)
2918893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
2919893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte v[8];
2920893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               int j;
2921893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2922893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_memcpy(v, sp, pixel_bytes);
2923893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               for (j = 0; j < jstop; j++)
2924893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               {
2925893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_memcpy(dp, v, pixel_bytes);
2926893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  dp -= pixel_bytes;
2927893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               }
2928893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               sp -= pixel_bytes;
2929893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
2930893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
2931893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2932893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2933893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      row_info->width = final_width;
29344215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
2935893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
29365f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifndef PNG_READ_PACKSWAP_SUPPORTED
2937a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   transformations = transformations; /* Silence compiler warning */
2938893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
2939893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
2940893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
2941893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2942893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
2943893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
2944893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_bytep prev_row, int filter)
2945893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
29464215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_read_filter_row");
29474215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
2948893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   switch (filter)
2949893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
2950893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_FILTER_VALUE_NONE:
2951893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2952893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_FILTER_VALUE_SUB:
2953893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2954893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
2955893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
2956893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2957893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp = row + bpp;
2958893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep lp = row;
2959893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2960893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = bpp; i < istop; i++)
2961893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2962893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
2963893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rp++;
2964893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2965893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
2966893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
2967893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_FILTER_VALUE_UP:
2968893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2969893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
2970893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
2971893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp = row;
2972893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep pp = prev_row;
2973893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2974893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < istop; i++)
2975893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2976893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 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_AVG:
2982893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
2983893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
2984893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp = row;
2985893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep pp = prev_row;
2986893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep lp = row;
2987893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
2988893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 istop = row_info->rowbytes - bpp;
2989893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2990893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < bpp; i++)
2991893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2992893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
2993893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               ((int)(*pp++) / 2 )) & 0xff);
2994893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rp++;
2995893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
2996893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
2997893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < istop; i++)
2998893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
2999893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
3000893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               (int)(*pp++ + *lp++) / 2 ) & 0xff);
3001893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rp++;
3002893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3003893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
3004893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3005893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      case PNG_FILTER_VALUE_PAETH:
3006893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3007893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 i;
3008893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep rp = row;
3009893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep pp = prev_row;
3010893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep lp = row;
3011893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_bytep cp = prev_row;
3012893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
3013893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_uint_32 istop=row_info->rowbytes - bpp;
3014893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3015893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         for (i = 0; i < bpp; i++)
3016893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3017893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
3018893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rp++;
3019893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3020893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3021a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott         for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
3022893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3023893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            int a, b, c, pa, pb, pc, p;
3024893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3025893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            a = *lp++;
3026893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            b = *pp++;
3027893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            c = *cp++;
3028893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3029893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            p = b - c;
3030893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pc = a - c;
3031893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3032893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_ABS
3033893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pa = abs(p);
3034893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pb = abs(pc);
3035893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pc = abs(p + pc);
3036893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#else
3037893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pa = p < 0 ? -p : p;
3038893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pb = pc < 0 ? -pc : pc;
3039893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
3040893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3041893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3042893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            /*
3043893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (pa <= pb && pa <= pc)
3044893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  p = a;
3045893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else if (pb <= pc)
3046893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  p = b;
3047893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               else
3048893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  p = c;
3049893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             */
3050893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
30514215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project            p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
3052893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3053893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
3054893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            rp++;
3055893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3056893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
3057893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3058893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      default:
3059893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_warning(png_ptr, "Ignoring bad adaptive filter type");
30604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project         *row = 0;
3061893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         break;
3062893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3063893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3064893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
30654ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#ifdef PNG_INDEX_SUPPORTED
30664ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenvoid /* PRIVATE */
30674ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wenpng_set_interlaced_pass(png_structp png_ptr, int pass)
30684ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen{
30694ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
30704ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30714ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   /* Start of interlace block */
30724ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
30734ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30744ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   /* Offset to next interlace block */
30754ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
30764ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30774ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   /* Start of interlace block in the y direction */
30784ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
30794ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30804ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   /* Offset to next interlace block in the y direction */
30814ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
30824ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30834ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   png_ptr->pass = pass;
30844ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen   png_ptr->iwidth = (png_ptr->width +
30854ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen         png_pass_inc[png_ptr->pass] - 1 -
30864ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen         png_pass_start[png_ptr->pass]) /
30874ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen      png_pass_inc[png_ptr->pass];
30884ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen}
30894ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen#endif
30904ce0ee15f268e0161438b4133936cb2826f7fd50Joseph Wen
30915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3092893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3093893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_finish_row(png_structp png_ptr)
3094893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3095893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
3096a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3097893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3098a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Start of interlace block */
3099893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3100893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3101a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Offset to next interlace block */
3102893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3103893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3104a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Start of interlace block in the y direction */
3105893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3106893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3107a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Offset to next interlace block in the y direction */
3108893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3109893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
3110893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
31114215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_read_finish_row");
3112893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->row_number++;
3113893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->row_number < png_ptr->num_rows)
3114893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      return;
3115893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3116893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
3117893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->interlaced)
3118893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3119893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->row_number = 0;
3120893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_memset_check(png_ptr, png_ptr->prev_row, 0,
3121893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->rowbytes + 1);
3122893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      do
3123893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3124893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->pass++;
3125893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->pass >= 7)
3126893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3127893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->iwidth = (png_ptr->width +
3128893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_pass_inc[png_ptr->pass] - 1 -
3129893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_pass_start[png_ptr->pass]) /
3130893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_pass_inc[png_ptr->pass];
3131893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3132893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (!(png_ptr->transformations & PNG_INTERLACE))
3133893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3134893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->num_rows = (png_ptr->height +
3135893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_pass_yinc[png_ptr->pass] - 1 -
3136893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_pass_ystart[png_ptr->pass]) /
3137893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_pass_yinc[png_ptr->pass];
3138893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!(png_ptr->num_rows))
3139893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               continue;
3140893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3141893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
3142893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3143893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      } while (png_ptr->iwidth == 0);
3144893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3145893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->pass < 7)
3146893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         return;
3147893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3148893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
3149893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3150893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
3151893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3152893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
3153893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      PNG_CONST PNG_IDAT;
3154893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3155893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      char extra;
3156893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      int ret;
3157893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3158893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->zstream.next_out = (Byte *)&extra;
3159893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->zstream.avail_out = (uInt)1;
31604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project      for (;;)
3161893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3162893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (!(png_ptr->zstream.avail_in))
3163893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3164893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            while (!png_ptr->idat_size)
3165893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            {
3166893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_byte chunk_length[4];
3167893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3168893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_crc_finish(png_ptr, 0);
3169893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3170893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_read_data(png_ptr, chunk_length, 4);
3171893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
3172893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_reset_crc(png_ptr);
3173893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3174893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
3175893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                  png_error(png_ptr, "Not enough image data");
3176893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3177893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            }
3178893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
3179893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->zstream.next_in = png_ptr->zbuf;
3180893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (png_ptr->zbuf_size > png_ptr->idat_size)
3181893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
3182893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
3183893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->idat_size -= png_ptr->zstream.avail_in;
3184893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3185893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
3186893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (ret == Z_STREAM_END)
3187893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3188893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
3189893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               png_ptr->idat_size)
31905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott               png_warning(png_ptr, "Extra compressed data.");
3191893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
3192893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3193893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3194893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3195893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (ret != Z_OK)
3196893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
3197893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project                      "Decompression Error");
3198893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3199893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (!(png_ptr->zstream.avail_out))
3200893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3201893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_warning(png_ptr, "Extra compressed data.");
3202893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
3203893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
3204893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            break;
3205893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3206893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3207893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3208893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->zstream.avail_out = 0;
3209893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3210893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3211893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
32125f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott      png_warning(png_ptr, "Extra compression data.");
3213893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3214893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   inflateReset(&png_ptr->zstream);
3215893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3216893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->mode |= PNG_AFTER_IDAT;
3217893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
32185f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
3219893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3220893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectvoid /* PRIVATE */
3221893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectpng_read_start_row(png_structp png_ptr)
3222893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project{
3223893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
3224a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3225893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3226a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Start of interlace block */
3227893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3228893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3229a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Offset to next interlace block */
3230893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3231893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3232a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Start of interlace block in the y direction */
3233893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3234893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3235a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Offset to next interlace block in the y direction */
3236893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3237893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3238893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3239893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   int max_pixel_depth;
32404215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_size_t row_bytes;
3241893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
32424215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug(1, "in png_read_start_row");
3243893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->zstream.avail_in = 0;
3244893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_init_read_transformations(png_ptr);
3245893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
3246893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->interlaced)
3247893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3248893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (!(png_ptr->transformations & PNG_INTERLACE))
3249893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
3250893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            png_pass_ystart[0]) / png_pass_yinc[0];
3251893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
3252893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->num_rows = png_ptr->height;
3253893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3254893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->iwidth = (png_ptr->width +
3255893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_pass_inc[png_ptr->pass] - 1 -
3256893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_pass_start[png_ptr->pass]) /
3257893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_pass_inc[png_ptr->pass];
3258893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3259893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   else
3260893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
3261893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3262893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->num_rows = png_ptr->height;
3263893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_ptr->iwidth = png_ptr->width;
3264893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3265893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   max_pixel_depth = png_ptr->pixel_depth;
3266893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
32675f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_PACK_SUPPORTED
3268893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
3269893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      max_pixel_depth = 8;
3270893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3271893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
32725f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
3273893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
3274893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3275893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3276893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3277893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans)
3278893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 32;
3279893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
3280893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 24;
3281893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3282893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3283893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3284893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (max_pixel_depth < 8)
3285893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 8;
3286893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans)
3287893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth *= 2;
3288893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3289893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3290893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3291893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (png_ptr->num_trans)
3292893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         {
3293893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth *= 4;
3294893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth /= 3;
3295893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         }
3296893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3297893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3298893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3299893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
33005f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED
3301893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & (PNG_FILLER))
3302893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3303893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
3304893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         max_pixel_depth = 32;
3305893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
3306893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3307893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (max_pixel_depth <= 8)
3308893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 16;
3309893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
3310893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 32;
3311893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3312893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
3313893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3314893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (max_pixel_depth <= 32)
3315893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 32;
3316893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
3317893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 64;
3318893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3319893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3320893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3321893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
33225f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
3323893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
3324893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3325893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      if (
33265f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_EXPAND_SUPPORTED
3327893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
3328893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
33295f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott#ifdef PNG_READ_FILLER_SUPPORTED
3330893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        (png_ptr->transformations & (PNG_FILLER)) ||
3331893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3332893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
3333893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3334893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (max_pixel_depth <= 16)
3335893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 32;
3336893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
3337893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 64;
3338893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3339893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      else
3340893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      {
3341893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         if (max_pixel_depth <= 8)
3342893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           {
3343893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3344893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               max_pixel_depth = 32;
3345893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project             else
3346893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project               max_pixel_depth = 24;
3347893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project           }
3348893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
3349893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 64;
3350893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         else
3351893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project            max_pixel_depth = 48;
3352893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      }
3353893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3354893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3355893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3356893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
3357893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Projectdefined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
33584215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (png_ptr->transformations & PNG_USER_TRANSFORM)
3359893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     {
33604215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       int user_pixel_depth = png_ptr->user_transform_depth*
3361893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         png_ptr->user_transform_channels;
33624215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project       if (user_pixel_depth > max_pixel_depth)
3363893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project         max_pixel_depth=user_pixel_depth;
3364893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project     }
3365893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3366893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3367a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Align the width on the next larger 8 pixels.  Mainly used
3368a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * for interlacing
3369a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
3370893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3371a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   /* Calculate the maximum bytes needed, adding a byte and a pixel
3372a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    * for safety's sake
3373a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott    */
33744215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
3375893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      1 + ((max_pixel_depth + 7) >> 3);
3376893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
3377893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   if (row_bytes > (png_uint_32)65536L)
3378893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
3379893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3380893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
33814215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3382893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
33834215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project     png_free(png_ptr, png_ptr->big_row_buf);
3384a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott     if (png_ptr->interlaced)
33855f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
33865f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            row_bytes + 64);
33875f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott     else
33885f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
33895f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott            row_bytes + 64);
33905f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott     png_ptr->old_big_row_buf_size = row_bytes + 64;
33915f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott
33925f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott     /* Use 32 bytes of padding before and after row_buf. */
3393a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott     png_ptr->row_buf = png_ptr->big_row_buf + 32;
3394a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott     png_ptr->old_big_row_buf_size = row_bytes + 64;
3395893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3396893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3397893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
3398a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
3399893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
3400893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif
3401a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
3402893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
3403893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3404a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   if (row_bytes + 1 > png_ptr->old_prev_row_size)
3405893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   {
3406a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_free(png_ptr, png_ptr->prev_row);
3407a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3408a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott        row_bytes + 1));
3409a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3410a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott      png_ptr->old_prev_row_size = row_bytes + 1;
3411893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   }
3412893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3413a0bb96c34e65378853ee518bac502842d26c2d1aPatrick Scott   png_ptr->rowbytes = row_bytes;
3414893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
34154215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "width = %lu,", png_ptr->width);
34164215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "height = %lu,", png_ptr->height);
34174215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
34184215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
34194215dd1533c56e1a89ae6f1d6ea68677fac27fdaThe Android Open Source Project   png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
34205f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott   png_debug1(3, "irowbytes = %lu",
34215f6bd84e375226bf228fc8ac90318957ec9e1e7fPatrick Scott       PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
3422893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project
3423893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project   png_ptr->flags |= PNG_FLAG_ROW_INIT;
3424893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project}
3425893912bfc2683463dc3e2c445336752d012563d3The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
3426