18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pngrutil.c - utilities to read a PNG file
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
4c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Last changed in libpng 1.2.45 [July 7, 2011]
5c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Copyright (c) 1998-2011 Glenn Randers-Pehrson
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
9c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * This code is released under the libpng license.
10c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * For conditions of distribution and use, see the disclaimer
11c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * and license in png.h
12c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner *
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This file contains routines that are only called from within
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * libpng itself during the course of reading an image.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_INTERNAL
18c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#define PNG_NO_PEDANTIC_WARNINGS
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "png.h"
20c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_SUPPORTED
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define WIN32_WCE_OLD
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
27c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#  ifdef WIN32_WCE_OLD
28c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* The strtod() function is not supported on WindowsCE */
29c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr,
30c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    char **endptr)
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   double result = 0;
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int len;
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   wchar_t *str, *end;
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
37c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( NULL != str )
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      result = wcstod(str, &end);
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, str);
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return result;
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  else
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    define png_strtod(p,a,b) strtod(a,b)
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_32 PNGAPI
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_31(png_structp png_ptr, png_bytep buf)
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
56c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 i = png_get_uint_32(buf);
58c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#else
59c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Avoid an extra function call by inlining the result. */
60c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
61c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      ((png_uint_32)(*(buf + 1)) << 16) +
62c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      ((png_uint_32)(*(buf + 2)) << 8) +
63c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      (png_uint_32)(*(buf + 3));
64c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (i > PNG_UINT_31_MAX)
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_error(png_ptr, "PNG unsigned integer out of range.");
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_32 PNGAPI
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_32(png_bytep buf)
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_uint_32)(*(buf + 1)) << 16) +
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_uint_32)(*(buf + 2)) << 8) +
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_32)(*(buf + 3));
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data is stored in the PNG file in two's complement format, and it is
84c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * assumed that the machine format for signed integers is the same.
85c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_int_32 PNGAPI
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_int_32(png_bytep buf)
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 i = ((png_int_32)(*buf) << 24) +
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_int_32)(*(buf + 1)) << 16) +
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_int_32)(*(buf + 2)) << 8) +
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_int_32)(*(buf + 3));
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_16 PNGAPI
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_16(png_bytep buf)
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_16)(*(buf + 1)));
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
108c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Read the chunk header (length + type name).
109c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Put the type name into png_ptr->chunk_name, and return the length.
110c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
111c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_uint_32 /* PRIVATE */
112c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_read_chunk_header(png_structp png_ptr)
113c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner{
114c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_byte buf[8];
115c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_uint_32 length;
116c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
117c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Read the length and the chunk name */
118c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_read_data(png_ptr, buf, 8);
119c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   length = png_get_uint_31(png_ptr, buf);
120c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
121c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Put the chunk name into png_ptr->chunk_name */
122c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_memcpy(png_ptr->chunk_name, buf + 4, 4);
123c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
124c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug2(0, "Reading %s chunk, length = %lu",
125c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunk_name, length);
126c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
127c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Reset the crc and run it over the chunk name */
128c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_reset_crc(png_ptr);
129c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_calculate_crc(png_ptr, png_ptr->chunk_name, 4);
130c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
131c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Check to see if chunk name is valid */
132c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
133c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
134c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   return length;
135c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
136c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Read data, and (optionally) run it through the CRC. */
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
141c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr == NULL)
142c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_read_data(png_ptr, buf, length);
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_calculate_crc(png_ptr, buf, length);
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
147c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_INDEX_SUPPORTED
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Optionally skip data and then check the CRC.  Depending on whether we
149c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * are reading a ancillary or critical chunk, and how the program has set
150c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * things up, we may calculate the CRC on the data and print a message.
151c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Returns '1' if there was a CRC error, '0' otherwise.
152c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint /* PRIVATE */
154c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_opt_crc_finish(png_structp png_ptr, png_uint_32 skip, int check_crc)
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t i;
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t istop = png_ptr->zbuf_size;
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = (png_size_t)skip; i > istop; i -= istop)
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (i)
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, png_ptr->zbuf, i);
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_error(png_ptr))
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
170c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (!check_crc) {
171c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_chunk_warning(png_ptr, "CRC error");
172c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return (1);
173c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
175c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_warning(png_ptr, "CRC error");
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_error(png_ptr, "CRC error");
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return (1);
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (0);
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
190c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
191c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
192c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Optionally skip data and then check the CRC.  Depending on whether we
193c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * are reading a ancillary or critical chunk, and how the program has set
194c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * things up, we may calculate the CRC on the data and print a message.
195c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Returns '1' if there was a CRC error, '0' otherwise.
196c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
197c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerint /* PRIVATE */
198c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_crc_finish(png_structp png_ptr, png_uint_32 skip)
199c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner{
200c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   return png_opt_crc_finish(png_ptr, skip, 1);
201c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Compare the CRC stored in the PNG file with that calculated by libpng from
204c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * the data it has read thus far.
205c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint /* PRIVATE */
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_crc_error(png_structp png_ptr)
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte crc_bytes[4];
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 crc;
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int need_crc = 1;
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         need_crc = 0;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else                                                    /* critical */
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         need_crc = 0;
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_read_data(png_ptr, crc_bytes, 4);
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (need_crc)
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      crc = png_get_uint_32(crc_bytes);
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return ((int)(crc != png_ptr->crc));
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return (0);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    defined(PNG_READ_iCCP_SUPPORTED)
238c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerstatic png_size_t
239c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_inflate(png_structp png_ptr, const png_byte *data, png_size_t size,
240c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        png_bytep output, png_size_t output_size)
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
242c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_size_t count = 0;
243c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
244c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->zstream.next_in = (png_bytep)data; /* const_cast: VALID */
245c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->zstream.avail_in = size;
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
247c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   while (1)
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
249c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      int ret, avail;
250c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
251c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Reset the output buffer each time round - we empty it
252c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * after every inflate call.
253c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.next_out = png_ptr->zbuf;
255c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->zstream.avail_out = png_ptr->zbuf_size;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
257c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      ret = inflate(&png_ptr->zstream, Z_NO_FLUSH);
258c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      avail = png_ptr->zbuf_size - png_ptr->zstream.avail_out;
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
260c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* First copy/count any new output - but only if we didn't
261c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * get an error code.
262c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
263c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if ((ret == Z_OK || ret == Z_STREAM_END) && avail > 0)
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
265c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         if (output != 0 && output_size > count)
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
267c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_size_t copy = output_size - count;
268c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            if ((png_size_t) avail < copy) copy = (png_size_t) avail;
269c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_memcpy(output + count, png_ptr->zbuf, copy);
270c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         }
271c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         count += avail;
272c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
274c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (ret == Z_OK)
275c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         continue;
276c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
277c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Termination conditions - always reset the zstream, it
278c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * must be left in inflateInit state.
279c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
280c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->zstream.avail_in = 0;
281c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      inflateReset(&png_ptr->zstream);
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
283c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (ret == Z_STREAM_END)
284c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return count; /* NOTE: may be zero. */
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
286c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Now handle the error codes - the API always returns 0
287c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * and the error message is dumped into the uncompressed
288c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * buffer if available.
289c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
290c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
291c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         PNG_CONST char *msg;
292c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         if (png_ptr->zstream.msg != 0)
293c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            msg = png_ptr->zstream.msg;
294c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         else
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
296c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
297c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            char umsg[52];
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
299c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            switch (ret)
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
301c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               case Z_BUF_ERROR:
302c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  msg = "Buffer error in compressed datastream in %s chunk";
303c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  break;
304c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               case Z_DATA_ERROR:
305c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  msg = "Data error in compressed datastream in %s chunk";
306c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  break;
307c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               default:
308c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  msg = "Incomplete compressed datastream in %s chunk";
309c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  break;
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
311c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
312c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_snprintf(umsg, sizeof umsg, msg, png_ptr->chunk_name);
313c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            msg = umsg;
314c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#else
315c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            msg = "Damaged compressed datastream in chunk other than IDAT";
316c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
318c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
319c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, msg);
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
321c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
322c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* 0 means an error - notice that this code simple ignores
323c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * zero length compressed chunks as a result.
324c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
325c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return 0;
326c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
327c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
328c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
329c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/*
330c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * Decompress trailing data in a chunk.  The assumption is that chunkdata
331c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * points at an allocated area holding the contents of a chunk with a
332c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * trailing compressed part.  What we get back is an allocated area
333c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * holding the original prefix part and an uncompressed version of the
334c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner * trailing part (the malloc area passed in is freed).
335c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner */
336c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnervoid /* PRIVATE */
337c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_decompress_chunk(png_structp png_ptr, int comp_type,
338c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    png_size_t chunklength,
339c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    png_size_t prefix_size, png_size_t *newlength)
340c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner{
341c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* The caller should guarantee this */
342c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (prefix_size > chunklength)
343c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
344c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* The recovery is to delete the chunk. */
345c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "invalid chunklength");
346c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      prefix_size = 0; /* To delete everything */
347c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
348c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
349c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   else if (comp_type == PNG_COMPRESSION_TYPE_BASE)
350c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
351c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_size_t expanded_size = png_inflate(png_ptr,
352c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                (png_bytep)(png_ptr->chunkdata + prefix_size),
353c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                chunklength - prefix_size,
354c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                0/*output*/, 0/*output size*/);
355c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
356c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Now check the limits on this chunk - if the limit fails the
357c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * compressed data will be removed, the prefix will remain.
358c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
359c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED
360c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_malloc_max &&
361c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          (prefix_size + expanded_size >= png_ptr->user_chunk_malloc_max - 1))
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
363c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#  ifdef PNG_USER_CHUNK_MALLOC_MAX
364c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if ((PNG_USER_CHUNK_MALLOC_MAX > 0) &&
365c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          prefix_size + expanded_size >= PNG_USER_CHUNK_MALLOC_MAX - 1)
366c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#  endif
367c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
368c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "Exceeded size limit while expanding chunk");
369c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
370c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* If the size is zero either there was an error and a message
371c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * has already been output (warning) or the size really is zero
372c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * and we have nothing to do - the code will exit through the
373c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       * error case below.
374c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       */
375c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_SET_CHUNK_MALLOC_LIMIT_SUPPORTED) || \
376c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    defined(PNG_USER_CHUNK_MALLOC_MAX)
377c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      else
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
379c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (expanded_size > 0)
380c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
381c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         /* Success (maybe) - really uncompress the chunk. */
382c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_size_t new_size = 0;
383c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_charp text = NULL;
384c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
385c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         /* Need to check for both truncation (64-bit) and integer overflow. */
386c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         if (prefix_size + expanded_size > prefix_size &&
387c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner             prefix_size + expanded_size < 0xffffffffU)
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
389c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner             text = png_malloc_warn(png_ptr, prefix_size + expanded_size + 1);
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
392c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         if (text != NULL)
393c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         {
394c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_memcpy(text, png_ptr->chunkdata, prefix_size);
395c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            new_size = png_inflate(png_ptr,
396c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                (png_bytep)(png_ptr->chunkdata + prefix_size),
397c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                chunklength - prefix_size,
398c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                (png_bytep)(text + prefix_size), expanded_size);
399c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            text[prefix_size + expanded_size] = 0; /* just in case */
400c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
401c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            if (new_size == expanded_size)
402c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            {
403c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               png_free(png_ptr, png_ptr->chunkdata);
404c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               png_ptr->chunkdata = text;
405c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               *newlength = prefix_size + expanded_size;
406c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               return; /* The success return! */
407c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            }
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
409c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_warning(png_ptr, "png_inflate logic error");
410c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_free(png_ptr, text);
411c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         }
412c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         else
413c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          png_warning(png_ptr, "Not enough memory to decompress chunk.");
414c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
416c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
419c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_STDIO_SUPPORTED) && !defined(_WIN32_WCE)
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      char umsg[50];
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
422c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_snprintf(umsg, sizeof umsg, "Unknown zTXt compression type %d",
423c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          comp_type);
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, umsg);
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unknown zTXt compression type");
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
429c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* The recovery is to simply drop the data. */
430c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
431c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
432c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Generic error return - leave the prefix, delete the compressed
433c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * data, reallocate the chunkdata to remove the potentially large
434c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * amount of compressed data.
435c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
436c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
437c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_charp text = png_malloc_warn(png_ptr, prefix_size + 1);
438c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (text != NULL)
439c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
440c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         if (prefix_size > 0)
441c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_memcpy(text, png_ptr->chunkdata, prefix_size);
442c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_free(png_ptr, png_ptr->chunkdata);
443c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_ptr->chunkdata = text;
444c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
445c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         /* This is an extra zero in the 'uncompressed' part. */
446c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         *(png_ptr->chunkdata + prefix_size) = 0x00;
447c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
448c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Ignore a malloc error here - it is safe. */
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
451c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   *newlength = prefix_size;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
455c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Read and check the IDHR chunk */
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[13];
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 width, height;
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int bit_depth, color_type, compression_type, filter_type;
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int interlace_type;
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
464c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_IHDR");
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IHDR)
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Out of place IHDR");
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
469c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Check the length */
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 13)
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Invalid IHDR chunk");
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_HAVE_IHDR;
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 13);
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_finish(png_ptr, 0);
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   width = png_get_uint_31(png_ptr, buf);
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   height = png_get_uint_31(png_ptr, buf + 4);
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   bit_depth = buf[8];
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   color_type = buf[9];
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   compression_type = buf[10];
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   filter_type = buf[11];
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   interlace_type = buf[12];
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
486c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Set internal variables */
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->width = width;
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->height = height;
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->bit_depth = (png_byte)bit_depth;
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->interlaced = (png_byte)interlace_type;
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->color_type = (png_byte)color_type;
492c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_MNG_FEATURES_SUPPORTED
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->filter_type = (png_byte)filter_type;
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->compression_type = (png_byte)compression_type;
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
497c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Find number of channels */
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (png_ptr->color_type)
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_GRAY:
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_PALETTE:
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 1;
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
504c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_RGB:
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 3;
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
508c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_GRAY_ALPHA:
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 2;
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
512c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_RGB_ALPHA:
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 4;
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
518c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Set up other useful info */
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->channels);
521c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->width);
522c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "bit_depth = %d", png_ptr->bit_depth);
523c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "channels = %d", png_ptr->channels);
524c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "rowbytes = %lu", png_ptr->rowbytes);
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      color_type, interlace_type, compression_type, filter_type);
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
529c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Read and check the palette */
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_color palette[PNG_MAX_PALETTE_LENGTH];
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int num, i;
535c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_POINTER_INDEXING_SUPPORTED
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_colorp pal_ptr;
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
539c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_PLTE");
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before PLTE");
543c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid PLTE after IDAT");
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
550c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Duplicate PLTE chunk");
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_HAVE_PLTE;
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr,
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        "Ignoring PLTE chunk in grayscale PNG");
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
563c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifndef PNG_READ_OPT_PLTE_SUPPORTED
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Invalid palette chunk");
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
579c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_error(png_ptr, "Invalid palette chunk");
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   num = (int)length / 3;
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
588c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_POINTER_INDEXING_SUPPORTED
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[3];
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->red = buf[0];
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->green = buf[1];
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->blue = buf[2];
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < num; i++)
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[3];
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
604c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Don't depend upon png_color being any order */
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].red = buf[0];
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].green = buf[1];
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].blue = buf[2];
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
612c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * whatever the normal CRC configuration tells us.  However, if we
613c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * have an RGB image, the PLTE can be considered ancillary, so
614c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * we will act as though it is.
615c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
616c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifndef PNG_READ_OPT_PLTE_SUPPORTED
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 0);
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
622c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifndef PNG_READ_OPT_PLTE_SUPPORTED
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* If we don't want to use the data from an ancillary chunk,
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         we have two options: an error abort, or a warning and we
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         ignore the data in this chunk (which should be OK, since
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         it's considered ancillary for a RGB or RGBA image). */
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_chunk_error(png_ptr, "CRC error");
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_chunk_warning(png_ptr, "CRC error");
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Otherwise, we (optionally) emit a warning and use the chunk. */
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_warning(png_ptr, "CRC error");
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_PLTE(png_ptr, info_ptr, palette, num);
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
651c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_tRNS_SUPPORTED
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans > (png_uint_16)num)
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->num_trans = (png_uint_16)num;
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (info_ptr->num_trans > (png_uint_16)num)
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            info_ptr->num_trans = (png_uint_16)num;
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
675c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_IEND");
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "No image in file");
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 0)
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect IEND chunk length");
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_finish(png_ptr, length);
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
690c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
693c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_gAMA_SUPPORTED
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point igamma;
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   float file_gamma;
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[4];
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
703c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_gAMA");
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before gAMA");
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid gAMA after IDAT");
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place gAMA chunk");
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
718c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sRGB_SUPPORTED
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate gAMA chunk");
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 4)
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect gAMA chunk length");
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   igamma = (png_fixed_point)png_get_uint_32(buf);
740c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Check for zero gamma */
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (igamma == 0)
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring gAMA chunk with gamma=0");
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
748c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sRGB_SUPPORTED
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
754c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_CONSOLE_IO_SUPPORTED
755c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   file_gamma = (float)igamma / (float)100000.0;
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_READ_GAMMA_SUPPORTED
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_ptr->gamma = file_gamma;
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_set_gAMA(png_ptr, info_ptr, file_gamma);
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
774c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sBIT_SUPPORTED
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t truelen;
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[4];
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
781c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_sBIT");
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   buf[0] = buf[1] = buf[2] = buf[3] = 0;
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sBIT");
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sBIT after IDAT");
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place sBIT chunk");
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sBIT chunk");
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 3;
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = (png_size_t)png_ptr->channels;
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != truelen || length > 4)
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect sBIT chunk length");
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.green = buf[1];
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.blue = buf[2];
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.alpha = buf[3];
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.gray = buf[0];
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.green = buf[0];
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.blue = buf[0];
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.alpha = buf[1];
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
840c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_cHRM_SUPPORTED
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
844c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_byte buf[32];
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_y_green, int_x_blue, int_y_blue;
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 uint_x, uint_y;
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
853c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_cHRM");
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before cHRM");
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM after IDAT");
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before cHRM");
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
868c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sRGB_SUPPORTED
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate cHRM chunk");
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 32)
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect cHRM chunk length");
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
885c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, buf, 32);
886c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_crc_finish(png_ptr, 0))
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_x = png_get_uint_32(buf);
890c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_y = png_get_uint_32(buf + 4);
891c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   int_x_white = (png_fixed_point)uint_x;
892c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   int_y_white = (png_fixed_point)uint_y;
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
894c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_x = png_get_uint_32(buf + 8);
895c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_y = png_get_uint_32(buf + 12);
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_red = (png_fixed_point)uint_x;
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_red = (png_fixed_point)uint_y;
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
899c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_x = png_get_uint_32(buf + 16);
900c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_y = png_get_uint_32(buf + 20);
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_green = (png_fixed_point)uint_x;
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_green = (png_fixed_point)uint_y;
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
904c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_x = png_get_uint_32(buf + 24);
905c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   uint_y = png_get_uint_32(buf + 28);
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_blue = (png_fixed_point)uint_x;
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_blue = (png_fixed_point)uint_y;
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   white_x = (float)int_x_white / (float)100000.0;
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   white_y = (float)int_y_white / (float)100000.0;
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   red_x   = (float)int_x_red   / (float)100000.0;
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   red_y   = (float)int_y_red   / (float)100000.0;
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   green_x = (float)int_x_green / (float)100000.0;
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   green_y = (float)int_y_green / (float)100000.0;
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   blue_x  = (float)int_x_blue  / (float)100000.0;
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   blue_y  = (float)int_y_blue  / (float)100000.0;
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
920c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sRGB_SUPPORTED
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr,
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
934c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_CONSOLE_IO_SUPPORTED
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
936c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               white_x, white_y, red_x, red_y);
938c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            fprintf(stderr, "gx=%f, gy=%f, bx=%f, by=%f\n",
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               green_x, green_y, blue_x, blue_y);
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
941c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            fprintf(stderr, "wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
942c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               (long)int_x_white, (long)int_y_white,
943c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               (long)int_x_red, (long)int_y_red);
944c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
945c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               (long)int_x_green, (long)int_y_green,
946c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               (long)int_x_blue, (long)int_y_blue);
947c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
948c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif /* PNG_CONSOLE_IO_SUPPORTED */
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_cHRM(png_ptr, info_ptr,
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_cHRM_fixed(png_ptr, info_ptr,
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_y_green, int_x_blue, int_y_blue);
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
966c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sRGB_SUPPORTED
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int intent;
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[1];
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
973c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_sRGB");
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sRGB");
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sRGB after IDAT");
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place sRGB chunk");
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sRGB chunk");
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 1)
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect sRGB chunk length");
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 1);
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   intent = buf[0];
1006c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Check for bad intent */
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (intent >= PNG_sRGB_INTENT_LAST)
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unknown sRGB intent");
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point igamma;
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      igamma=info_ptr->int_gamma;
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_FLOATING_POINT_SUPPORTED
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
1028c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_CONSOLE_IO_SUPPORTED
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_FIXED_POINT_SUPPORTED
1030c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         fprintf(stderr, "incorrect gamma=(%d/100000)\n",
1031c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            (int)png_ptr->int_gamma);
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  else
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    ifdef PNG_FLOATING_POINT_SUPPORTED
1034c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         fprintf(stderr, "incorrect gamma=%f\n", png_ptr->gamma);
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    endif
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_gAMA_SUPPORTED */
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_READ_cHRM_SUPPORTED
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr,
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_FIXED_POINT_SUPPORTED */
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_cHRM_SUPPORTED */
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1064c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_iCCP_SUPPORTED
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte compression_type;
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep pC;
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp profile;
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 profile_size, profile_length;
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_length, data_length;
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1076c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_iCCP");
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iCCP");
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid iCCP after IDAT");
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place iCCP chunk");
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate iCCP chunk");
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1106c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1107c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
1109c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1113c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1114c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1118c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00;
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1120c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (profile = png_ptr->chunkdata; *profile; profile++)
1121c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop to find end of name */ ;
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ++profile;
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1125c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* There should be at least one zero (the compression type byte)
1126c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * following the separator, and we should be on it
1127c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
1128c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if ( profile >= png_ptr->chunkdata + slength - 1)
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1130c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1131c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Malformed iCCP chunk");
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1136c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Compression_type should always be zero */
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   compression_type = *profile++;
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (compression_type)
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
1141c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      compression_type = 0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 wrote nonzero) */
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1145c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   prefix_length = profile - png_ptr->chunkdata;
1146c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_decompress_chunk(png_ptr, compression_type,
1147c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     slength, prefix_length, &data_length);
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   profile_length = data_length - prefix_length;
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( prefix_length > data_length || profile_length < 4)
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1153c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1154c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
1160c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   pC = (png_bytep)(png_ptr->chunkdata + prefix_length);
1161c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   profile_size = ((*(pC    ))<<24) |
1162c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  ((*(pC + 1))<<16) |
1163c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  ((*(pC + 2))<< 8) |
1164c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  ((*(pC + 3))    );
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1166c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (profile_size < profile_length)
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      profile_length = profile_size;
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1169c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (profile_size > profile_length)
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1171c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1172c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1177c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
1178c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     compression_type, png_ptr->chunkdata + prefix_length, profile_length);
1179c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1180c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_iCCP_SUPPORTED */
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1184c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sPLT_SUPPORTED
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep entry_start;
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_sPLT_t new_palette;
1191c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_POINTER_INDEXING_SUPPORTED
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_sPLT_entryp pp;
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int data_length, entry_size, i;
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1198c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_sPLT");
1199c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
1200c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USER_LIMITS_SUPPORTED
1201c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
1202c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->user_chunk_cache_max != 0)
1203c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1204c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_cache_max == 1)
1205c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
1206c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
1207c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
1208c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
1209c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (--png_ptr->user_chunk_cache_max == 1)
1210c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
1211c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "No space in chunk cache for sPLT");
1212c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
1213c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
1214c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
1215c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
1216c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sPLT");
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sPLT after IDAT");
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1236c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1237c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
1239c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1243c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1244c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1248c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00;
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1250c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (entry_start = (png_bytep)png_ptr->chunkdata; *entry_start;
1251c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       entry_start++)
1252c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop to find end of name */ ;
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ++entry_start;
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1255c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* A sample depth should follow the separator, and we should be on it  */
1256c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (entry_start > (png_bytep)png_ptr->chunkdata + slength - 2)
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1258c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1259c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "malformed sPLT chunk");
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.depth = *entry_start++;
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   entry_size = (new_palette.depth == 8 ? 6 : 10);
1266c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1268c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Integrity-check the data length */
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (data_length % entry_size)
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1271c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1272c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "sPLT chunk has bad length");
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.nentries = (png_int_32) ( data_length / entry_size);
1278c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if ((png_uint_32) new_palette.nentries >
1279c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "sPLT chunk too long");
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (new_palette.entries == NULL)
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "sPLT chunk requires too much memory");
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1292c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_POINTER_INDEXING_SUPPORTED
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1295c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      pp = new_palette.entries + i;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (new_palette.depth == 8)
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->red = *entry_start++;
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->green = *entry_start++;
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->blue = *entry_start++;
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->alpha = *entry_start++;
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->green = png_get_uint_16(entry_start); entry_start += 2;
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   pp = new_palette.entries;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (new_palette.depth == 8)
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].red   = *entry_start++;
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].green = *entry_start++;
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].blue  = *entry_start++;
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].alpha = *entry_start++;
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1336c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Discard all chunk data except the name and stash that */
1337c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   new_palette.name = png_ptr->chunkdata;
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1341c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1342c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, new_palette.entries);
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sPLT_SUPPORTED */
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1347c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_tRNS_SUPPORTED
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1353c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_tRNS");
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tRNS");
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid tRNS after IDAT");
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate tRNS chunk");
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[2];
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length != 2)
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 1;
1383c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->trans_values.gray = png_get_uint_16(buf);
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[6];
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length != 6)
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, (png_size_t)length);
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 1;
1397c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->trans_values.red = png_get_uint_16(buf);
1398c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
1399c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->mode & PNG_HAVE_PLTE))
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         /* Should be an error, but we can cope with it. */
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Missing PLTE before tRNS");
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length > (png_uint_32)png_ptr->num_palette ||
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          length > PNG_MAX_PALETTE_LENGTH)
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length == 0)
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Zero length tRNS chunk");
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, readbuf, (png_size_t)length);
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = (png_uint_16)length;
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 0;
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      &(png_ptr->trans_values));
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1442c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_bKGD_SUPPORTED
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t truelen;
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[6];
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1449c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_bKGD");
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before bKGD");
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid bKGD after IDAT");
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !(png_ptr->mode & PNG_HAVE_PLTE))
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before bKGD");
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate bKGD chunk");
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 1;
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 6;
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 2;
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != truelen)
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect bKGD chunk length");
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We convert the index value into RGB components so that we can allow
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * arbitrary RGB values for background when we have transparency, and
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * so it is easy to determine the RGB values of the background color
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * from the info_ptr struct. */
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.index = buf[0];
1498c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (info_ptr && info_ptr->num_palette)
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1500c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          if (buf[0] >= info_ptr->num_palette)
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          {
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             png_warning(png_ptr, "Incorrect bKGD chunk index value");
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             return;
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          }
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.red =
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].red;
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.green =
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].green;
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.blue =
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].blue;
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.red =
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.green =
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.blue =
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.gray = png_get_uint_16(buf);
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.red = png_get_uint_16(buf);
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.green = png_get_uint_16(buf + 2);
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.blue = png_get_uint_16(buf + 4);
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1531c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_hIST_SUPPORTED
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unsigned int num, i;
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1538c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_hIST");
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before hIST");
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid hIST after IDAT");
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before hIST");
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate hIST chunk");
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   num = length / 2 ;
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (num != (unsigned int) png_ptr->num_palette || num >
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (unsigned int) PNG_MAX_PALETTE_LENGTH)
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect hIST chunk length");
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < num; i++)
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[2];
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      readbuf[i] = png_get_uint_16(buf);
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_hIST(png_ptr, info_ptr, readbuf);
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1585c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_pHYs_SUPPORTED
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[9];
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 res_x, res_y;
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int unit_type;
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1593c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_pHYs");
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pHYs");
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pHYs after IDAT");
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate pHYs chunk");
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 9)
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect pHYs chunk length");
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   res_x = png_get_uint_32(buf);
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   res_y = png_get_uint_32(buf + 4);
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unit_type = buf[8];
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1628c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_oFFs_SUPPORTED
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[9];
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 offset_x, offset_y;
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int unit_type;
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1636c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_oFFs");
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before oFFs");
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid oFFs after IDAT");
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate oFFs chunk");
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 9)
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect oFFs chunk length");
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset_x = png_get_int_32(buf);
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset_y = png_get_int_32(buf + 4);
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unit_type = buf[8];
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1671c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_pCAL_SUPPORTED
1672c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Read the pCAL chunk (described in the PNG Extensions document) */
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 X0, X1;
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte type, nparams;
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp buf, units, endptr;
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charpp params;
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int i;
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1683c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_pCAL");
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pCAL");
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL after IDAT");
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate pCAL chunk");
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1700c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)",
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length + 1);
1702c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1703c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1704c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata == NULL)
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL purpose.");
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
1710c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1714c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1715c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1719c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1721c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(3, "Finding end of pCAL purpose string");
1722c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (buf = png_ptr->chunkdata; *buf; buf++)
1723c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1725c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   endptr = png_ptr->chunkdata + slength;
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We need to have at least 12 bytes after the purpose string
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      in order to get the parameter information. */
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (endptr <= buf + 12)
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL data");
1732c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1733c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1737c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units");
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   X0 = png_get_int_32((png_bytep)buf+1);
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   X1 = png_get_int_32((png_bytep)buf+5);
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   type = buf[9];
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   nparams = buf[10];
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   units = buf + 11;
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1744c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(3, "Checking pCAL equation type and number of parameters");
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Check that we have the right number of parameters for known
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      equation types. */
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
1753c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1754c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (type >= PNG_EQUATION_LAST)
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (buf = units; *buf; buf++)
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Empty loop to move past the units string. */ ;
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1765c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(3, "Allocating pCAL parameters array");
1766c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   params = (png_charpp)png_malloc_warn(png_ptr,
1767c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      (png_uint_32)(nparams * png_sizeof(png_charp))) ;
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (params == NULL)
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
1770c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_free(png_ptr, png_ptr->chunkdata);
1771c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_ptr->chunkdata = NULL;
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL params.");
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Get pointers to the start of each parameter string. */
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < (int)nparams; i++)
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      buf++; /* Skip the null string terminator from previous parameter. */
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1781c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_debug1(3, "Reading pCAL parameter %d", i);
1782c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      for (params[i] = buf; buf <= endptr && *buf != 0x00; buf++)
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         /* Empty loop to move past each parameter string */ ;
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Make sure we haven't run out of data yet */
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (buf > endptr)
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Invalid pCAL data");
1789c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_free(png_ptr, png_ptr->chunkdata);
1790c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_ptr->chunkdata = NULL;
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_free(png_ptr, params);
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1796c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_set_pCAL(png_ptr, info_ptr, png_ptr->chunkdata, X0, X1, type, nparams,
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      units, params);
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1799c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1800c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, params);
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1805c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_sCAL_SUPPORTED
1806c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Read the sCAL chunk */
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1810c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_charp ep;
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   double width, height;
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp vp;
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp swidth, sheight;
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1821c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_sCAL");
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sCAL");
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL after IDAT");
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sCAL chunk");
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1838c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Need unit type, width, \0, height: minimum 4 bytes */
1839c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   else if (length < 4)
1840c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1841c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "sCAL chunk too short");
1842c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_crc_finish(png_ptr, length);
1843c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1844c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
1845c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
1846c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)",
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length + 1);
1848c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
1849c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata == NULL)
1850c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1851c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Out of memory while processing sCAL chunk");
1852c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_crc_finish(png_ptr, length);
1853c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1854c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
1856c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1860c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1861c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1865c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00; /* Null terminate the last string */
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1867c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   ep = png_ptr->chunkdata + 1;        /* Skip unit byte */
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   width = png_strtod(png_ptr, ep, &vp);
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (*vp)
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1873c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "malformed width string in sCAL chunk");
1874c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1875c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
1876c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (swidth == NULL)
1882c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1883c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
1884c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1885c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
1886c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1887c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1892c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (ep = png_ptr->chunkdata; *ep; ep++)
1893c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ep++;
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1896c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata + slength < ep)
1897c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1898c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Truncated sCAL chunk");
1899c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1900c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, swidth);
1901c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
1902c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1903c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
1904c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1905c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
1906c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   height = png_strtod(png_ptr, ep, &vp);
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (*vp)
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1911c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "malformed height string in sCAL chunk");
1912c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1913c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
1914c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1915c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, swidth);
1916c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
1917c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
1922c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (sheight == NULL)
1923c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
1924c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
1925c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1926c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
1927c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
1928c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, swidth);
1929c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
1930c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
1931c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1936c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata + slength < ep
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      || width <= 0. || height <= 0.
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL data");
1943c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
1944c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, swidth);
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, sheight);
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
1954c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_set_sCAL(png_ptr, info_ptr, png_ptr->chunkdata[0], width, height);
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
1957c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_set_sCAL_s(png_ptr, info_ptr, png_ptr->chunkdata[0], swidth, sheight);
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1961c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
1962c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, swidth);
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, sheight);
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1970c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_tIME_SUPPORTED
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[7];
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_time mod_time;
19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1977c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_tIME");
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Out of place tIME chunk");
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate tIME chunk");
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 7)
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect tIME chunk length");
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 7);
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.second = buf[6];
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.minute = buf[5];
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.hour = buf[4];
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.day = buf[3];
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.month = buf[2];
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.year = png_get_uint_16(buf);
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_tIME(png_ptr, info_ptr, &mod_time);
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2013c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_tEXt_SUPPORTED
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp key;
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp text;
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2025c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_tEXt");
2026c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
2027c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USER_LIMITS_SUPPORTED
2028c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->user_chunk_cache_max != 0)
2029c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2030c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_cache_max == 1)
2031c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2032c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2033c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2034c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2035c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (--png_ptr->user_chunk_cache_max == 1)
2036c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2037c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "No space in chunk cache for tEXt");
2038c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2039c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2040c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2041c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
2042c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tEXt");
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2059c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2060c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
2061c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2062c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata == NULL)
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "No memory to process text chunk.");
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
2068c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2072c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2073c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2077c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   key = png_ptr->chunkdata;
2078c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   key[slength] = 0x00;
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (text = key; *text; text++)
2082c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop to find end of key */ ;
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text != key + slength)
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      text++;
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_32)png_sizeof(png_text));
20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text_ptr == NULL)
20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "Not enough memory to process text chunk.");
2092c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_free(png_ptr, png_ptr->chunkdata);
2093c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->chunkdata = NULL;
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->key = key;
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang = NULL;
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang_key = NULL;
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->itxt_length = 0;
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text = text;
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text_length = png_strlen(text);
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2106c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2108c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2109c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, text_ptr);
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (ret)
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "Insufficient memory to process text chunk.");
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2116c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_zTXt_SUPPORTED
2117c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Note: this does not correctly handle chunks that are > 64K under DOS */
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp text;
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_type;
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_len, data_len;
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2127c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_zTXt");
2128c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
2129c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USER_LIMITS_SUPPORTED
2130c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->user_chunk_cache_max != 0)
2131c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2132c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_cache_max == 1)
2133c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2134c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2135c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2136c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2137c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (--png_ptr->user_chunk_cache_max == 1)
2138c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2139c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "No space in chunk cache for zTXt");
2140c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2141c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2142c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2143c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
2144c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2145c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before zTXt");
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2157c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_warning(png_ptr, "zTXt chunk too large to fit in memory");
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_crc_finish(png_ptr, length);
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2163c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2164c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2165c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata == NULL)
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2167c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_warning(png_ptr, "Out of memory processing zTXt chunk.");
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
2171c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2174c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2175c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2179c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00;
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2181c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (text = png_ptr->chunkdata; *text; text++)
2182c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* zTXt must have some text after the chunkdataword */
2185c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (text >= png_ptr->chunkdata + slength - 2)
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Truncated zTXt chunk");
2188c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2189c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_type = *(++text);
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       {
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          comp_type = PNG_TEXT_COMPRESSION_zTXt;
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       }
2200c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       text++;        /* Skip the compression_method byte */
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2202c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   prefix_len = text - png_ptr->chunkdata;
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2204c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_decompress_chunk(png_ptr, comp_type,
2205c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     (png_size_t)length, prefix_len, &data_len);
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2208c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      (png_uint_32)png_sizeof(png_text));
22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text_ptr == NULL)
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2211c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
2212c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_free(png_ptr, png_ptr->chunkdata);
2213c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->chunkdata = NULL;
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->compression = comp_type;
2217c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->key = png_ptr->chunkdata;
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang = NULL;
22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang_key = NULL;
22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->itxt_length = 0;
22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2223c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->text = png_ptr->chunkdata + prefix_len;
22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text_length = data_len;
22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2226c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, text_ptr);
2229c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2230c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (ret)
22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2236c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_iTXt_SUPPORTED
2237c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Note: this does not correctly handle chunks that are > 64K under DOS */
22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
22398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp key, lang, text, lang_key;
22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_flag;
22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_type = 0;
22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_len, data_len;
22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2248c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_iTXt");
2249c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
2250c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USER_LIMITS_SUPPORTED
2251c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->user_chunk_cache_max != 0)
2252c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2253c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_cache_max == 1)
2254c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2255c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2256c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2257c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2258c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (--png_ptr->user_chunk_cache_max == 1)
2259c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2260c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "No space in chunk cache for iTXt");
2261c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2262c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2263c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2264c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
2265c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iTXt");
22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2278c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_warning(png_ptr, "iTXt chunk too large to fit in memory");
22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_crc_finish(png_ptr, length);
22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2284c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2285c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
2286c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->chunkdata == NULL)
22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "No memory to process iTXt chunk.");
22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
2292c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2295c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2296c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2300c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata[slength] = 0x00;
23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2302c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (lang = png_ptr->chunkdata; *lang; lang++)
2303c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
2304c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   lang++;        /* Skip NUL separator */
23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* iTXt must have a language tag (possibly empty), two compression bytes,
2307c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * translated keyword (possibly empty), and possibly some text after the
2308c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * keyword
2309c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
23108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2311c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (lang >= png_ptr->chunkdata + slength - 3)
23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Truncated iTXt chunk");
2314c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2315c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_flag = *lang++;
23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_type = *lang++;
23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (lang_key = lang; *lang_key; lang_key++)
2325c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
2326c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   lang_key++;        /* Skip NUL separator */
23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2328c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (lang_key >= png_ptr->chunkdata + slength)
2329c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2330c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Truncated iTXt chunk");
2331c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2332c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
2333c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2336c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   for (text = lang_key; *text; text++)
2337c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      /* Empty loop */ ;
2338c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text++;        /* Skip NUL separator */
2339c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (text >= png_ptr->chunkdata + slength)
2340c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2341c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Malformed iTXt chunk");
2342c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->chunkdata);
2343c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->chunkdata = NULL;
2344c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      return;
2345c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2347c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   prefix_len = text - png_ptr->chunkdata;
23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2349c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   key=png_ptr->chunkdata;
2350c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (comp_flag)
2351c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_decompress_chunk(png_ptr, comp_type,
2352c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         (size_t)length, prefix_len, &data_len);
2353c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   else
2354c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       data_len = png_strlen(png_ptr->chunkdata + prefix_len);
2355c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr = (png_textp)png_malloc_warn(png_ptr,
2356c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      (png_uint_32)png_sizeof(png_text));
2357c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (text_ptr == NULL)
2358c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2359c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
2360c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_free(png_ptr, png_ptr->chunkdata);
2361c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->chunkdata = NULL;
2362c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     return;
2363c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
2364c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->compression = (int)comp_flag + 1;
2365c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->lang_key = png_ptr->chunkdata + (lang_key - key);
2366c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->lang = png_ptr->chunkdata + (lang - key);
2367c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->itxt_length = data_len;
2368c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->text_length = 0;
2369c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->key = png_ptr->chunkdata;
2370c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   text_ptr->text = png_ptr->chunkdata + prefix_len;
23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2372c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   ret = png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2374c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, text_ptr);
2375c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_free(png_ptr, png_ptr->chunkdata);
2376c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->chunkdata = NULL;
2377c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (ret)
2378c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
2379c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
2380c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2382c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* This function is called when we haven't found a handler for a
2383c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   chunk.  If there isn't a problem with the chunk itself (ie bad
2384c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   chunk name, CRC, or a critical chunk), the chunk is silently ignored
2385c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
2386c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   case it will be saved away to be written out later. */
23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
2388c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2390c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_uint_32 skip = 0;
23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2392c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_handle_unknown");
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2394c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USER_LIMITS_SUPPORTED
2395c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->user_chunk_cache_max != 0)
23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2397c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_ptr->user_chunk_cache_max == 1)
2398c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2399c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2400c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2401c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
2402c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (--png_ptr->user_chunk_cache_max == 1)
2403c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      {
2404c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
2405c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_finish(png_ptr, length);
2406c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         return;
2407c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      }
24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2409c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2411c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->mode & PNG_HAVE_IDAT)
24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
2413c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_USE_LOCAL_ARRAYS
2414c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      PNG_CONST PNG_IDAT;
2415c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2416c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
2417c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_ptr->mode |= PNG_AFTER_IDAT;
2418c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2420c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (!(png_ptr->chunk_name[0] & 0x20))
2421c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2422c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2423c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2424c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           PNG_HANDLE_CHUNK_ALWAYS
2425c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2426c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           && png_ptr->read_user_chunk_fn == NULL
2427c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2428c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        )
2429c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2430c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          png_chunk_error(png_ptr, "unknown critical chunk");
2431c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2433c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
2434c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
2435c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2436c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       || (png_ptr->read_user_chunk_fn != NULL)
2437c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2438c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        )
2439c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2440c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_MAX_MALLOC_64K
2441c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       if (length > (png_uint_32)65535L)
2442c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       {
2443c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           png_warning(png_ptr, "unknown chunk too large to fit in memory");
2444c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           skip = length - (png_uint_32)65535L;
2445c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           length = (png_uint_32)65535L;
2446c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       }
2447c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2448c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_memcpy((png_charp)png_ptr->unknown_chunk.name,
2449c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  (png_charp)png_ptr->chunk_name,
2450c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                  png_sizeof(png_ptr->unknown_chunk.name));
2451c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_ptr->unknown_chunk.name[png_sizeof(png_ptr->unknown_chunk.name)-1]
2452c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner           = '\0';
2453c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_ptr->unknown_chunk.size = (png_size_t)length;
2454c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       if (length == 0)
2455c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_ptr->unknown_chunk.data = NULL;
2456c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       else
2457c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       {
2458c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
2459c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
2460c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       }
2461c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
2462c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       if (png_ptr->read_user_chunk_fn != NULL)
2463c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       {
2464c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          /* Callback to user unknown chunk handler */
2465c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          int ret;
2466c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          ret = (*(png_ptr->read_user_chunk_fn))
2467c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            (png_ptr, &png_ptr->unknown_chunk);
2468c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          if (ret < 0)
2469c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner             png_chunk_error(png_ptr, "error in user chunk");
2470c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          if (ret == 0)
2471c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          {
2472c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner             if (!(png_ptr->chunk_name[0] & 0x20))
2473c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
2474c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
2475c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                     PNG_HANDLE_CHUNK_ALWAYS)
2476c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2477c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                   png_chunk_error(png_ptr, "unknown critical chunk");
2478c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner             png_set_unknown_chunks(png_ptr, info_ptr,
2479c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               &png_ptr->unknown_chunk, 1);
2480c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner          }
2481c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       }
2482c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       else
2483c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2484c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
2485c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_free(png_ptr, png_ptr->unknown_chunk.data);
2486c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       png_ptr->unknown_chunk.data = NULL;
2487c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
2488c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   else
2489c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif
2490c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      skip = length;
24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2492c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_crc_finish(png_ptr, skip);
24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2494c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
2495c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2497c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2499c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* This function is called to verify that a chunk name is valid.
2500c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   This function can't have the "critical chunk check" incorporated
2501c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   into it, since in the future we will need to be able to call user
2502c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   functions to handle unknown critical chunks after we check that
2503c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   the chunk name itself is valid. */
25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2505c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2507c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnervoid /* PRIVATE */
2508c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
2509c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner{
2510c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_check_chunk_name");
2511c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
2512c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
2513c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
2514c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_chunk_error(png_ptr, "invalid chunk type");
25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2518c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner/* Combines the row recently read in with the existing pixels in the
2519c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   row.  This routine takes care of alpha and transparency if requested.
2520c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   This routine also handles the two methods of progressive display
2521c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   of interlaced images, depending on the mask value.
2522c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   The mask value describes which pixels are to be combined with
2523c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   the row.  The pattern always repeats every 8 pixels, so just 8
2524c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   bits are needed.  A one indicates the pixel is to be combined,
2525c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   a zero indicates the pixel is to be skipped.  This is in addition
2526c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   to any alpha or transparency value associated with the pixel.  If
2527c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   you want all pixels to be combined, pass 0xff (255) in mask.  */
25288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_combine_row(png_structp png_ptr, png_bytep row, int mask)
25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2532c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_combine_row");
25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (mask == 0xff)
25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_memcpy(row, png_ptr->row_buf + 1,
25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (png_ptr->row_info.pixel_depth)
25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:
25438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_inc, s_start, s_end;
25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2552c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 0;
25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 7;
25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = 1;
25588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 7;
25638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 0;
25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = -1;
25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  int value;
25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x01;
25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:
25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2607c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
26278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x03;
26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
26308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
26368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
26428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
26488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:
26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
26508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
26528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
26538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
26548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
26558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2659c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
26618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
26648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
26658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
26678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
26688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
26708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
26718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
26728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
26748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
26768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
26788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0xf;
26808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
26818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
26828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
26858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
26878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
26888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
26898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
26928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
26938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
26948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
26968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
26988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
26998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default:
27008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
27018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
27028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
27038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
27048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
27058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
27068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_byte m = 0x80;
27078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
27108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
27128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
27138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dp, sp, pixel_bytes);
27148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
27158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sp += pixel_bytes;
27178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dp += pixel_bytes;
27188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
27208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
27218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
27228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
27238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
27258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
27268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
27278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
27288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
27298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
27318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* OLD pre-1.0.9 interface:
27328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
27338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 transformations)
27348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
27358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
27368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_do_read_interlace(png_structp png_ptr)
27378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
27388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_row_infop row_info = &(png_ptr->row_info);
27398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep row = png_ptr->row_buf + 1;
27408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int pass = png_ptr->pass;
27418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 transformations = png_ptr->transformations;
2742c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
2743c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block */
27448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
27458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2746c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_do_read_interlace");
27478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (row != NULL && row_info != NULL)
27488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
27498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_uint_32 final_width;
27508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      final_width = row_info->width * png_pass_inc[pass];
27528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (row_info->pixel_depth)
27548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
27558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:
27568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
27578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
27588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
27598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
27608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
27618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
27628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_byte v;
27638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
27648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int j;
27658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2766c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
27678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
27688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sshift = (int)((row_info->width + 7) & 0x07);
27708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dshift = (int)((final_width + 7) & 0x07);
27718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 7;
27728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 0;
27738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = -1;
27748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
27768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
27778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sshift = 7 - (int)((row_info->width + 7) & 0x07);
27798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dshift = 7 - (int)((final_width + 7) & 0x07);
27808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 0;
27818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 7;
27828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = 1;
27838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
27868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x01);
27888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
27898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
27908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
27918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
27928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
27938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
27948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
27958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
27968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
27978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
27988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
27998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
28008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
28018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
28028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
28038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
28048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
28058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
28068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
28078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
28098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
28108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:
28118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
28128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
28138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
28148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
28158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
28168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
28178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
28188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2819c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
28208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
28218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
28238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)(((final_width + 3) & 0x03) << 1);
28248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
28258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
28268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
28278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
28298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
28308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
28328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
28338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
28348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
28358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
28368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
28398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v;
28418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
28428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x03);
28448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
28458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
28468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
28478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
28488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
28498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
28508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
28518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
28528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
28538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
28548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
28558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
28568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
28578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
28588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
28598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
28608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
28618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
28628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
28638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
28658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
28668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:
28678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
28688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
28698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
28708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
28718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
28728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
28738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
28748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2875c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACKSWAP_SUPPORTED
28768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
28778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
28798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)(((final_width + 1) & 0x01) << 2);
28808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
28818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
28828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
28838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
28858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
28868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
28888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
28898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
28908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
28918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
28928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
28958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
28978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
28988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
29008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
29028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
29038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
29048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
29058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
29068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
29078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
29088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
29098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
29108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
29128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
29148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
29158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
29178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
29188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
29208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default:
29228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
29238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
2924c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            png_bytep sp = row + (png_size_t)(row_info->width - 1)
2925c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner                * pixel_bytes;
29268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
29278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
29298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
29308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
29328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
29338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v[8];
29348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
29358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(v, sp, pixel_bytes);
29378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
29388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dp, v, pixel_bytes);
29408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp -= pixel_bytes;
29418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sp -= pixel_bytes;
29438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
29458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
29478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      row_info->width = final_width;
2948c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
29498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
2950c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifndef PNG_READ_PACKSWAP_SUPPORTED
2951c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   transformations = transformations; /* Silence compiler warning */
29528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
29538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
29548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
29558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
29578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
29588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep prev_row, int filter)
29598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
2960c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_read_filter_row");
2961c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug2(2, "row = %lu, filter = %d", png_ptr->row_number, filter);
29628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (filter)
29638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
29648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_NONE:
29658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
29668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_SUB:
29678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
29688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
29698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
29708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
29718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row + bpp;
29728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
29738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = bpp; i < istop; i++)
29758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
29768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
29778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
29788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
29808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
29818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_UP:
29828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
29838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
29848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
29858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
29868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
29878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < istop; i++)
29898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
29908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
29918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
29928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
29948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
29958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_AVG:
29968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
29978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
29988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
29998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
30008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
30018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
30028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes - bpp;
30038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < bpp; i++)
30058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
30068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
30078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ((int)(*pp++) / 2 )) & 0xff);
30088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
30098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
30108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < istop; i++)
30128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
30138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
30148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               (int)(*pp++ + *lp++) / 2 ) & 0xff);
30158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
30168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
30178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
30188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
30198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_PAETH:
30208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
30218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
30228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
30238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
30248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
30258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep cp = prev_row;
30268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
30278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop=row_info->rowbytes - bpp;
30288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < bpp; i++)
30308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
30318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
30328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
30338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
30348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3035c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         for (i = 0; i < istop; i++)   /* Use leftover rp,pp */
30368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
30378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int a, b, c, pa, pb, pc, p;
30388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a = *lp++;
30408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            b = *pp++;
30418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            c = *cp++;
30428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = b - c;
30448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = a - c;
30458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_ABS
30478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pa = abs(p);
30488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pb = abs(pc);
30498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = abs(p + pc);
30508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
30518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pa = p < 0 ? -p : p;
30528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pb = pc < 0 ? -pc : pc;
30538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
30548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
30558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /*
30578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (pa <= pb && pa <= pc)
30588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = a;
30598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pb <= pc)
30608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = b;
30618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
30628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = c;
30638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             */
30648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3065c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
30668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
30678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
30688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
30698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
30708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
30718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
30728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
30738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Ignoring bad adaptive filter type");
3074c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         *row = 0;
30758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
30768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
30778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
30788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3079c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_INDEX_SUPPORTED
30808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
3081c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_set_interlaced_pass(png_structp png_ptr, int pass)
30828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3083c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
30848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3085c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block */
30868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
30878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3088c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block */
30898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
30908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3091c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block in the y direction */
30928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
30938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3094c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block in the y direction */
30958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3096c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3097c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->pass = pass;
3098c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->iwidth = (png_ptr->width +
3099c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_pass_inc[png_ptr->pass] - 1 -
3100c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner         png_pass_start[png_ptr->pass]) /
3101c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_pass_inc[png_ptr->pass];
3102c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner}
31038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
31048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3105c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
3106c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnervoid /* PRIVATE */
3107c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turnerpng_read_finish_row(png_structp png_ptr)
3108c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner{
3109c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_INTERLACING_SUPPORTED
3110c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
3111c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3112c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block */
3113c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
3114c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3115c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block */
3116c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
3117c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3118c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block in the y direction */
3119c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
3120c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3121c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block in the y direction */
3122c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
3123c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif /* PNG_READ_INTERLACING_SUPPORTED */
3124c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3125c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_read_finish_row");
31268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->row_number++;
31278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->row_number < png_ptr->num_rows)
31288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
31298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3130c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_INTERLACING_SUPPORTED
31318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->interlaced)
31328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
31338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->row_number = 0;
31348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_memset_check(png_ptr, png_ptr->prev_row, 0,
31358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->rowbytes + 1);
31368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do
31378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
31388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->pass++;
31398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->pass >= 7)
31408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
31418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->iwidth = (png_ptr->width +
31428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_inc[png_ptr->pass] - 1 -
31438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_start[png_ptr->pass]) /
31448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_inc[png_ptr->pass];
31458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->transformations & PNG_INTERLACE))
31478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
31488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->num_rows = (png_ptr->height +
31498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_yinc[png_ptr->pass] - 1 -
31508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_ystart[png_ptr->pass]) /
31518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_yinc[png_ptr->pass];
31528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(png_ptr->num_rows))
31538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               continue;
31548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
31558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
31568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
31578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      } while (png_ptr->iwidth == 0);
31588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->pass < 7)
31608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
31618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
3162c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif /* PNG_READ_INTERLACING_SUPPORTED */
31638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
31658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
31668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
31678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      PNG_CONST PNG_IDAT;
31688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
31698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      char extra;
31708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int ret;
31718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.next_out = (Byte *)&extra;
31738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_out = (uInt)1;
3174c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      for (;;)
31758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
31768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->zstream.avail_in))
31778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
31788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (!png_ptr->idat_size)
31798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
31808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte chunk_length[4];
31818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_crc_finish(png_ptr, 0);
31838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_read_data(png_ptr, chunk_length, 4);
31858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
31868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_reset_crc(png_ptr);
31878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
3188c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))
31898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_error(png_ptr, "Not enough image data");
31908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
31928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
31938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->zstream.next_in = png_ptr->zbuf;
31948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->zbuf_size > png_ptr->idat_size)
31958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
31968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
31978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->idat_size -= png_ptr->zstream.avail_in;
31988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
31998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
32008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret == Z_STREAM_END)
32018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
32028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
32038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->idat_size)
3204c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner               png_warning(png_ptr, "Extra compressed data.");
32058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
32068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
32078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
32088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
32098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret != Z_OK)
32108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
32118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      "Decompression Error");
32128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->zstream.avail_out))
32148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
32158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Extra compressed data.");
32168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
32178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
32188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
32198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
32208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
32228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_out = 0;
32238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
32248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
3226c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_warning(png_ptr, "Extra compression data.");
32278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   inflateReset(&png_ptr->zstream);
32298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_AFTER_IDAT;
32318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3232c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
32338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
32358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_start_row(png_structp png_ptr)
32368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3237c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_INTERLACING_SUPPORTED
3238c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
32398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3240c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block */
32418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
32428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3243c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block */
32448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
32458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3246c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Start of interlace block in the y direction */
32478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
32488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3249c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Offset to next interlace block in the y direction */
32508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
32518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
32528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int max_pixel_depth;
3254c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_size_t row_bytes;
32558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3256c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug(1, "in png_read_start_row");
32578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->zstream.avail_in = 0;
32588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_init_read_transformations(png_ptr);
3259c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_INTERLACING_SUPPORTED
32608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->interlaced)
32618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
32628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->transformations & PNG_INTERLACE))
32638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
32648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_ystart[0]) / png_pass_yinc[0];
32658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
32668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->num_rows = png_ptr->height;
32678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->iwidth = (png_ptr->width +
32698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_inc[png_ptr->pass] - 1 -
32708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_start[png_ptr->pass]) /
32718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_inc[png_ptr->pass];
32728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
32738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
3274c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#endif /* PNG_READ_INTERLACING_SUPPORTED */
32758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
32768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_rows = png_ptr->height;
32778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->iwidth = png_ptr->width;
32788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
32798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   max_pixel_depth = png_ptr->pixel_depth;
32808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3281c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_PACK_SUPPORTED
32828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
32838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      max_pixel_depth = 8;
32848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
32858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3286c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_EXPAND_SUPPORTED
32878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
32888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
32898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
32908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
32918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
32928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
32938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
32948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 24;
32958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
32968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
32978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
32988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth < 8)
32998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 8;
33008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
33018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth *= 2;
33028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
33048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
33068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
33078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth *= 4;
33088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth /= 3;
33098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
33108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
33128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3314c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_FILLER_SUPPORTED
33158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & (PNG_FILLER))
33168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
33178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
33188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         max_pixel_depth = 32;
33198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
33208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 8)
33228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 16;
33238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
33248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
33258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
33278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 32)
33298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
33308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
33318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
33328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
33348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3336c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
33378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
33388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
33398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (
3340c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_EXPAND_SUPPORTED
33418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
33428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3343c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner#ifdef PNG_READ_FILLER_SUPPORTED
33448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (png_ptr->transformations & (PNG_FILLER)) ||
33458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
33478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 16)
33498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
33508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
33518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
33528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
33548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 8)
33568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           {
33578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
33588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               max_pixel_depth = 32;
33598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             else
33608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               max_pixel_depth = 24;
33618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           }
33628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
33638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
33648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
33658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 48;
33668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
33678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
33688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
33718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdefined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
3372c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (png_ptr->transformations & PNG_USER_TRANSFORM)
33738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
3374c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       int user_pixel_depth = png_ptr->user_transform_depth*
33758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->user_transform_channels;
3376c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       if (user_pixel_depth > max_pixel_depth)
33778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         max_pixel_depth=user_pixel_depth;
33788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
33798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3381c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Align the width on the next larger 8 pixels.  Mainly used
3382c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * for interlacing
3383c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
33848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
3385c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   /* Calculate the maximum bytes needed, adding a byte and a pixel
3386c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    * for safety's sake
3387c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner    */
3388c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   row_bytes = PNG_ROWBYTES(max_pixel_depth, row_bytes) +
33898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      1 + ((max_pixel_depth + 7) >> 3);
33908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
33918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (row_bytes > (png_uint_32)65536L)
33928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
33938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3394c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3395c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
3396c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
3397c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_free(png_ptr, png_ptr->big_row_buf);
3398c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     if (png_ptr->interlaced)
3399c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
3400c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            row_bytes + 64);
3401c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     else
3402c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
3403c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner            row_bytes + 64);
3404c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->old_big_row_buf_size = row_bytes + 64;
3405c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3406c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     /* Use 32 bytes of padding before and after row_buf. */
3407c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->row_buf = png_ptr->big_row_buf + 32;
3408c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner     png_ptr->old_big_row_buf_size = row_bytes + 64;
3409c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
34108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
3412c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
34138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
34148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3415c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
34168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
34178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3418c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   if (row_bytes + 1 > png_ptr->old_prev_row_size)
3419c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   {
3420c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_free(png_ptr, png_ptr->prev_row);
3421c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
3422c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner        row_bytes + 1));
3423c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
3424c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner      png_ptr->old_prev_row_size = row_bytes + 1;
3425c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   }
3426c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner
3427c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_ptr->rowbytes = row_bytes;
34288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3429c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "width = %lu,", png_ptr->width);
3430c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "height = %lu,", png_ptr->height);
3431c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "iwidth = %lu,", png_ptr->iwidth);
3432c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "num_rows = %lu,", png_ptr->num_rows);
3433c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "rowbytes = %lu,", png_ptr->rowbytes);
3434c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner   png_debug1(3, "irowbytes = %lu",
3435c7702eb5df5f3e72ceedfcd5fb60b94c0a945934David 'Digit' Turner       PNG_ROWBYTES(png_ptr->pixel_depth, png_ptr->iwidth) + 1);
34368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->flags |= PNG_FLAG_ROW_INIT;
34388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
34398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
3440