18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* pngrutil.c - utilities to read a PNG file
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Last changed in libpng 1.2.19 August 18, 2007
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * For conditions of distribution and use, see copyright notice in png.h
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 1998-2007 Glenn Randers-Pehrson
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This file contains routines that are only called from within
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * libpng itself during the course of reading an image.
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define PNG_INTERNAL
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "png.h"
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_SUPPORTED)
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  define WIN32_WCE_OLD
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  if defined(WIN32_WCE_OLD)
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* strtod() function is not supported on WindowsCE */
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   double result = 0;
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int len;
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   wchar_t *str, *end;
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   str = (wchar_t *)png_malloc(png_ptr, len * sizeof(wchar_t));
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( NULL != str )
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      result = wcstod(str, &end);
388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, str);
418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return result;
438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  else
458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    define png_strtod(p,a,b) strtod(a,b)
468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_32 PNGAPI
508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_31(png_structp png_ptr, png_bytep buf)
518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 i = png_get_uint_32(buf);
538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (i > PNG_UINT_31_MAX)
548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_error(png_ptr, "PNG unsigned integer out of range.");
558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_32 PNGAPI
608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_32(png_bytep buf)
618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_uint_32)(*(buf + 1)) << 16) +
648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_uint_32)(*(buf + 2)) << 8) +
658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_32)(*(buf + 3));
668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab a signed 32-bit integer from a buffer in big-endian format.  The
718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * data is stored in the PNG file in two's complement format, and it is
728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * assumed that the machine format for signed integers is the same. */
738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_int_32 PNGAPI
748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_int_32(png_bytep buf)
758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 i = ((png_int_32)(*buf) << 24) +
778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_int_32)(*(buf + 1)) << 16) +
788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      ((png_int_32)(*(buf + 2)) << 8) +
798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_int_32)(*(buf + 3));
808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Grab an unsigned 16-bit integer from a buffer in big-endian format. */
858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_uint_16 PNGAPI
868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_get_uint_16(png_bytep buf)
878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_16 i = (png_uint_16)(((png_uint_16)(*buf) << 8) +
898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_16)(*(buf + 1)));
908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (i);
928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Read data, and (optionally) run it through the CRC. */
968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_crc_read(png_structp png_ptr, png_bytep buf, png_size_t length)
988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(png_ptr == NULL) return;
1008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_read_data(png_ptr, buf, length);
1018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_calculate_crc(png_ptr, buf, length);
1028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Optionally skip data and then check the CRC.  Depending on whether we
1058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   are reading a ancillary or critical chunk, and how the program has set
1068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   things up, we may calculate the CRC on the data and print a message.
1078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   Returns '1' if there was a CRC error, '0' otherwise. */
1088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint /* PRIVATE */
1098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_crc_finish(png_structp png_ptr, png_uint_32 skip)
1108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t i;
1128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t istop = png_ptr->zbuf_size;
1138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = (png_size_t)skip; i > istop; i -= istop)
1158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zbuf_size);
1178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (i)
1198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, png_ptr->zbuf, i);
1218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_error(png_ptr))
1248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (((png_ptr->chunk_name[0] & 0x20) &&                /* Ancillary */
1268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           !(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)) ||
1278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (!(png_ptr->chunk_name[0] & 0x20) &&             /* Critical  */
1288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_USE)))
1298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_warning(png_ptr, "CRC error");
1318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
1328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
1338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
1348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_error(png_ptr, "CRC error");
1358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
1368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return (1);
1378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return (0);
1408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Compare the CRC stored in the PNG file with that calculated by libpng from
1438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the data it has read thus far. */
1448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint /* PRIVATE */
1458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_crc_error(png_structp png_ptr)
1468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte crc_bytes[4];
1488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 crc;
1498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int need_crc = 1;
1508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->chunk_name[0] & 0x20)                     /* ancillary */
1528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if ((png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_MASK) ==
1548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (PNG_FLAG_CRC_ANCILLARY_USE | PNG_FLAG_CRC_ANCILLARY_NOWARN))
1558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         need_crc = 0;
1568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else                                                    /* critical */
1588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->flags & PNG_FLAG_CRC_CRITICAL_IGNORE)
1608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         need_crc = 0;
1618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_read_data(png_ptr, crc_bytes, 4);
1648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (need_crc)
1668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      crc = png_get_uint_32(crc_bytes);
1688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return ((int)(crc != png_ptr->crc));
1698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
1708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
1718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return (0);
1728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
1738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_zTXt_SUPPORTED) || defined(PNG_READ_iTXt_SUPPORTED) || \
1758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    defined(PNG_READ_iCCP_SUPPORTED)
1768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
1778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Decompress trailing data in a chunk.  The assumption is that chunkdata
1788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * points at an allocated area holding the contents of a chunk with a
1798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * trailing compressed part.  What we get back is an allocated area
1808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * holding the original prefix part and an uncompressed version of the
1818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * trailing part (the malloc area passed in is freed).
1828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
1838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_charp /* PRIVATE */
1848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_decompress_chunk(png_structp png_ptr, int comp_type,
1858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              png_charp chunkdata, png_size_t chunklength,
1868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              png_size_t prefix_size, png_size_t *newlength)
1878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
1888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   static PNG_CONST char msg[] = "Error decoding compressed text";
1898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp text;
1908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t text_size;
1918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
1928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (comp_type == PNG_COMPRESSION_TYPE_BASE)
1938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
1948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int ret = Z_OK;
1958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.next_in = (png_bytep)(chunkdata + prefix_size);
1968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_in = (uInt)(chunklength - prefix_size);
1978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.next_out = png_ptr->zbuf;
1988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
1998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      text_size = 0;
2018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      text = NULL;
2028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      while (png_ptr->zstream.avail_in)
2048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
2058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
2068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret != Z_OK && ret != Z_STREAM_END)
2078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
2088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->zstream.msg != NULL)
2098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_warning(png_ptr, png_ptr->zstream.msg);
2108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
2118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_warning(png_ptr, msg);
2128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            inflateReset(&png_ptr->zstream);
2138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->zstream.avail_in = 0;
2148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (text ==  NULL)
2168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text_size = prefix_size + png_sizeof(msg) + 1;
2188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text = (png_charp)png_malloc_warn(png_ptr, text_size);
2198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (text ==  NULL)
2208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 {
2218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    png_free(png_ptr,chunkdata);
2228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    png_error(png_ptr,"Not enough memory to decompress chunk");
2238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 }
2248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(text, chunkdata, prefix_size);
2258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            text[text_size - 1] = 0x00;
2288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Copy what we can of the error message into the text chunk */
2308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            text_size = (png_size_t)(chunklength - (text - chunkdata) - 1);
2318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            text_size = png_sizeof(msg) > text_size ? text_size :
2328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_sizeof(msg);
2338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_memcpy(text + prefix_size, msg, text_size + 1);
2348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
2358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
2368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!png_ptr->zstream.avail_out || ret == Z_STREAM_END)
2378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
2388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (text == NULL)
2398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
2408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text_size = prefix_size +
2418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   png_ptr->zbuf_size - png_ptr->zstream.avail_out;
2428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text = (png_charp)png_malloc_warn(png_ptr, text_size + 1);
2438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (text ==  NULL)
2448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 {
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    png_free(png_ptr,chunkdata);
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    png_error(png_ptr,"Not enough memory to decompress chunk.");
2478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 }
2488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(text + prefix_size, png_ptr->zbuf,
2498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    text_size - prefix_size);
2508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(text, chunkdata, prefix_size);
2518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *(text + text_size) = 0x00;
2528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
2548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_charp tmp;
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               tmp = text;
2588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text = (png_charp)png_malloc_warn(png_ptr,
2598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  (png_uint_32)(text_size +
2608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
2618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (text == NULL)
2628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
2638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_free(png_ptr, tmp);
2648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_free(png_ptr, chunkdata);
2658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_error(png_ptr,"Not enough memory to decompress chunk..");
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
2678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(text, tmp, text_size);
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_free(png_ptr, tmp);
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(text + text_size, png_ptr->zbuf,
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  (png_ptr->zbuf_size - png_ptr->zstream.avail_out));
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               text_size += png_ptr->zbuf_size - png_ptr->zstream.avail_out;
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *(text + text_size) = 0x00;
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ret == Z_STREAM_END)
2758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               break;
2768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
2778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->zstream.next_out = png_ptr->zbuf;
2798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
2828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (ret != Z_STREAM_END)
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         char umsg[52];
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret == Z_BUF_ERROR)
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_snprintf(umsg, 52,
2908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                "Buffer error in compressed datastream in %s chunk",
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                png_ptr->chunk_name);
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else if (ret == Z_DATA_ERROR)
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_snprintf(umsg, 52,
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                "Data error in compressed datastream in %s chunk",
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                png_ptr->chunk_name);
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_snprintf(umsg, 52,
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                "Incomplete compressed datastream in %s chunk",
2998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                png_ptr->chunk_name);
3008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, umsg);
3018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
3038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            "Incomplete compressed datastream in chunk other than IDAT");
3048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         text_size=prefix_size;
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (text ==  NULL)
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            text = (png_charp)png_malloc_warn(png_ptr, text_size+1);
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (text == NULL)
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              {
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                png_free(png_ptr, chunkdata);
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                png_error(png_ptr,"Not enough memory for text.");
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              }
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_memcpy(text, chunkdata, prefix_size);
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
3168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         *(text + text_size) = 0x00;
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      inflateReset(&png_ptr->zstream);
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_in = 0;
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
3238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      chunkdata = text;
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *newlength=text_size;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      char umsg[50];
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_snprintf(umsg, 50,
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         "Unknown zTXt compression type %d", comp_type);
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, umsg);
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unknown zTXt compression type");
3368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *(chunkdata + prefix_size) = 0x00;
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *newlength=prefix_size;
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   return chunkdata;
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* read and check the IDHR chunk */
3478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
3488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_IHDR(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[13];
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 width, height;
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int bit_depth, color_type, compression_type, filter_type;
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int interlace_type;
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_IHDR\n");
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IHDR)
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Out of place IHDR");
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* check the length */
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 13)
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Invalid IHDR chunk");
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_HAVE_IHDR;
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 13);
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_finish(png_ptr, 0);
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   width = png_get_uint_31(png_ptr, buf);
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   height = png_get_uint_31(png_ptr, buf + 4);
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   bit_depth = buf[8];
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   color_type = buf[9];
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   compression_type = buf[10];
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   filter_type = buf[11];
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   interlace_type = buf[12];
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* set internal variables */
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->width = width;
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->height = height;
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->bit_depth = (png_byte)bit_depth;
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->interlaced = (png_byte)interlace_type;
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->color_type = (png_byte)color_type;
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_MNG_FEATURES_SUPPORTED)
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->filter_type = (png_byte)filter_type;
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->compression_type = (png_byte)compression_type;
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* find number of channels */
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (png_ptr->color_type)
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_GRAY:
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_PALETTE:
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 1;
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_RGB:
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 3;
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_GRAY_ALPHA:
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 2;
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_COLOR_TYPE_RGB_ALPHA:
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->channels = 4;
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* set up other useful info */
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->pixel_depth = (png_byte)(png_ptr->bit_depth *
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->channels);
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->rowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->width);
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3,"bit_depth = %d\n", png_ptr->bit_depth);
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3,"channels = %d\n", png_ptr->channels);
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3,"rowbytes = %lu\n", png_ptr->rowbytes);
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth,
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      color_type, interlace_type, compression_type, filter_type);
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* read and check the palette */
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_PLTE(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_color palette[PNG_MAX_PALETTE_LENGTH];
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int num, i;
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_POINTER_INDEXING
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_colorp pal_ptr;
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_PLTE\n");
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before PLTE");
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid PLTE after IDAT");
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Duplicate PLTE chunk");
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_HAVE_PLTE;
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->color_type&PNG_COLOR_MASK_COLOR))
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr,
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        "Ignoring PLTE chunk in grayscale PNG");
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > 3*PNG_MAX_PALETTE_LENGTH || length % 3)
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
4618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Invalid palette chunk");
4628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
4638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
4648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
4658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
4668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
4678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_error(png_ptr, "Invalid palette chunk");
4688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
4698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   num = (int)length / 3;
4728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_POINTER_INDEXING
4748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
4758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[3];
4778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
4798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->red = buf[0];
4808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->green = buf[1];
4818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pal_ptr->blue = buf[2];
4828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < num; i++)
4858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
4868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[3];
4878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 3);
4898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* don't depend upon png_color being any order */
4908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].red = buf[0];
4918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].green = buf[1];
4928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      palette[i].blue = buf[2];
4938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
4948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* If we actually NEED the PLTE chunk (ie for a paletted image), we do
4978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      whatever the normal CRC configuration tells us.  However, if we
4988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      have an RGB image, the PLTE can be considered ancillary, so
4998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      we will act as though it is. */
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 0);
5058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
5078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
5088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* If we don't want to use the data from an ancillary chunk,
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         we have two options: an error abort, or a warning and we
5118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         ignore the data in this chunk (which should be OK, since
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         it's considered ancillary for a RGB or RGBA image). */
5138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_USE))
5148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
5158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
5168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
5178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_chunk_error(png_ptr, "CRC error");
5188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
5208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_chunk_warning(png_ptr, "CRC error");
5228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
5248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
5258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Otherwise, we (optionally) emit a warning and use the chunk. */
5268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (!(png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN))
5278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
5288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_chunk_warning(png_ptr, "CRC error");
5298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
5308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_PLTE(png_ptr, info_ptr, palette, num);
5348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_tRNS_SUPPORTED)
5368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
5378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
5398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
5408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans > (png_uint_16)num)
5418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
5428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect tRNS chunk length");
5438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->num_trans = (png_uint_16)num;
5448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
5458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (info_ptr->num_trans > (png_uint_16)num)
5468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
5478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Truncating incorrect info tRNS chunk length");
5488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            info_ptr->num_trans = (png_uint_16)num;
5498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
5508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
5518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
5578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_IEND(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_IEND\n");
5608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR) || !(png_ptr->mode & PNG_HAVE_IDAT))
5628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "No image in file");
5648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= (PNG_AFTER_IDAT | PNG_HAVE_IEND);
5678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 0)
5698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect IEND chunk length");
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_finish(png_ptr, length);
5738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   info_ptr =info_ptr; /* quiet compiler warnings about unused info_ptr */
5758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_gAMA_SUPPORTED)
5788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
5798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
5808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point igamma;
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
5838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   float file_gamma;
5848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[4];
5868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_gAMA\n");
5888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
5908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before gAMA");
5918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
5928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
5938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid gAMA after IDAT");
5948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
5958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
5968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
5988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
5998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place gAMA chunk");
6008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
6028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sRGB_SUPPORTED)
6038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
6048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
6068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate gAMA chunk");
6088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
6098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 4)
6138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect gAMA chunk length");
6158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
6168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
6208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
6218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   igamma = (png_fixed_point)png_get_uint_32(buf);
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* check for zero gamma */
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (igamma == 0)
6268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
6278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
6288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring gAMA chunk with gamma=0");
6298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
6308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
6318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sRGB_SUPPORTED)
6338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
6348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
6358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
6368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
6388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_CONSOLE_IO
6398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         fprintf(stderr, "gamma = (%d/100000)\n", (int)igamma);
6408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
6428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
6438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
6448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
6468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   file_gamma = (float)igamma / (float)100000.0;
6478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_READ_GAMMA_SUPPORTED
6488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_ptr->gamma = file_gamma;
6498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
6508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_set_gAMA(png_ptr, info_ptr, file_gamma);
6518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
6538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_gAMA_fixed(png_ptr, info_ptr, igamma);
6548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
6578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sBIT_SUPPORTED)
6598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
6608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
6618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t truelen;
6638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[4];
6648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_sBIT\n");
6668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   buf[0] = buf[1] = buf[2] = buf[3] = 0;
6688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
6708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sBIT");
6718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
6728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sBIT after IDAT");
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
6758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
6788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
6808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place sBIT chunk");
6818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sBIT))
6838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sBIT chunk");
6858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
6868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
6888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
6908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 3;
6918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
6928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = (png_size_t)png_ptr->channels;
6938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != truelen || length > 4)
6958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
6968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect sBIT chunk length");
6978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
6988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
6998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
7028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
7038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
7068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
7088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.green = buf[1];
7098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.blue = buf[2];
7108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.alpha = buf[3];
7118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
7138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.gray = buf[0];
7158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.red = buf[0];
7168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.green = buf[0];
7178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.blue = buf[0];
7188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->sig_bit.alpha = buf[1];
7198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sBIT(png_ptr, info_ptr, &(png_ptr->sig_bit));
7218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_cHRM_SUPPORTED)
7258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
7278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[4];
7298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   float white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y;
7318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
7338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_y_green, int_x_blue, int_y_blue;
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 uint_x, uint_y;
7368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_cHRM\n");
7388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
7408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before cHRM");
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
7428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM after IDAT");
7448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
7488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
7498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before cHRM");
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
7528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sRGB_SUPPORTED)
7538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      && !(info_ptr->valid & PNG_INFO_sRGB)
7548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
7568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate cHRM chunk");
7588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 32)
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect cHRM chunk length");
7658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
7668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
7708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_x = png_get_uint_32(buf);
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
7738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_y = png_get_uint_32(buf);
7748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (uint_x > 80000L || uint_y > 80000L ||
7768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      uint_x + uint_y > 100000L)
7778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM white point");
7798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 24);
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_white = (png_fixed_point)uint_x;
7838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_white = (png_fixed_point)uint_y;
7848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
7868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_x = png_get_uint_32(buf);
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_y = png_get_uint_32(buf);
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (uint_x + uint_y > 100000L)
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
7938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM red point");
7948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 16);
7958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
7968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_red = (png_fixed_point)uint_x;
7988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_red = (png_fixed_point)uint_y;
7998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_x = png_get_uint_32(buf);
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
8048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_y = png_get_uint_32(buf);
8058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (uint_x + uint_y > 100000L)
8078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM green point");
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 8);
8108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_green = (png_fixed_point)uint_x;
8138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_green = (png_fixed_point)uint_y;
8148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
8168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_x = png_get_uint_32(buf);
8178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 4);
8198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   uint_y = png_get_uint_32(buf);
8208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (uint_x + uint_y > 100000L)
8228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
8238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid cHRM blue point");
8248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, 0);
8258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
8278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_x_blue = (png_fixed_point)uint_x;
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int_y_blue = (png_fixed_point)uint_y;
8298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
8318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   white_x = (float)int_x_white / (float)100000.0;
8328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   white_y = (float)int_y_white / (float)100000.0;
8338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   red_x   = (float)int_x_red   / (float)100000.0;
8348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   red_y   = (float)int_y_red   / (float)100000.0;
8358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   green_x = (float)int_x_green / (float)100000.0;
8368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   green_y = (float)int_y_green / (float)100000.0;
8378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   blue_x  = (float)int_x_blue  / (float)100000.0;
8388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   blue_y  = (float)int_y_blue  / (float)100000.0;
8398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sRGB_SUPPORTED)
8428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
8438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
8448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
8458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_white, 32900,  1000) ||
8468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_red,   64000L, 1000) ||
8478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_red,   33000,  1000) ||
8488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_green, 30000,  1000) ||
8498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_green, 60000L, 1000) ||
8508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_x_blue,  15000,  1000) ||
8518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(int_y_blue,   6000,  1000))
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
8538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr,
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_CONSOLE_IO
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,"wx=%f, wy=%f, rx=%f, ry=%f\n",
8588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               white_x, white_y, red_x, red_y);
8598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,"gx=%f, gy=%f, bx=%f, by=%f\n",
8608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               green_x, green_y, blue_x, blue_y);
8618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,"wx=%ld, wy=%ld, rx=%ld, ry=%ld\n",
8638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int_x_white, int_y_white, int_x_red, int_y_red);
8648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fprintf(stderr,"gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int_x_green, int_y_green, int_x_blue, int_y_blue);
8668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_NO_CONSOLE_IO */
8688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
8698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, 0);
8708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
8728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
8738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
8758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_cHRM(png_ptr, info_ptr,
8768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      white_x, white_y, red_x, red_y, green_x, green_y, blue_x, blue_y);
8778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
8798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_cHRM_fixed(png_ptr, info_ptr,
8808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_x_white, int_y_white, int_x_red, int_y_red, int_x_green,
8818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int_y_green, int_x_blue, int_y_blue);
8828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
8848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
8858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sRGB_SUPPORTED)
8898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
8908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int intent;
8938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[1];
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_sRGB\n");
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sRGB");
8998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
9008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sRGB after IDAT");
9028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
9068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
9078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place sRGB chunk");
9088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
9108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sRGB chunk");
9128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 1)
9178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect sRGB chunk length");
9198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
9208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 1);
9248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
9258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   intent = buf[0];
9288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* check for bad intent */
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (intent >= PNG_sRGB_INTENT_LAST)
9308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unknown sRGB intent");
9328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_gAMA_SUPPORTED) && defined(PNG_READ_GAMMA_SUPPORTED)
9368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA))
9378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
9388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_fixed_point igamma;
9398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
9408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      igamma=info_ptr->int_gamma;
9418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
9428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_FLOATING_POINT_SUPPORTED
9438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      igamma=(png_fixed_point)(info_ptr->gamma * 100000.);
9448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
9458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
9478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
9488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr,
9498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           "Ignoring incorrect gAMA value when sRGB is also present");
9508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_CONSOLE_IO
9518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  ifdef PNG_FIXED_POINT_SUPPORTED
9528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         fprintf(stderr,"incorrect gamma=(%d/100000)\n",(int)png_ptr->int_gamma);
9538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  else
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    ifdef PNG_FLOATING_POINT_SUPPORTED
9558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         fprintf(stderr,"incorrect gamma=%f\n",png_ptr->gamma);
9568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#    endif
9578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#  endif
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
9598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
9618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_gAMA_SUPPORTED */
9628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_READ_cHRM_SUPPORTED
9648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
9658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM))
9668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (PNG_OUT_OF_RANGE(info_ptr->int_x_white, 31270,  1000) ||
9678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_white, 32900,  1000) ||
9688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_red,   64000L, 1000) ||
9698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_red,   33000,  1000) ||
9708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_green, 30000,  1000) ||
9718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_green, 60000L, 1000) ||
9728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_x_blue,  15000,  1000) ||
9738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          PNG_OUT_OF_RANGE(info_ptr->int_y_blue,   6000,  1000))
9748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
9758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr,
9768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              "Ignoring incorrect cHRM value when sRGB is also present");
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
9788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_FIXED_POINT_SUPPORTED */
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_cHRM_SUPPORTED */
9808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sRGB_gAMA_and_cHRM(png_ptr, info_ptr, intent);
9828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
9838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sRGB_SUPPORTED */
9848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_iCCP_SUPPORTED)
9868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
9878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
9888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
9898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
9908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp chunkdata;
9918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte compression_type;
9928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep pC;
9938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp profile;
9948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
9958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 profile_size, profile_length;
9968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_length, data_length;
9978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_iCCP\n");
9998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
10018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iCCP");
10028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
10038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid iCCP after IDAT");
10058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
10068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_PLTE)
10098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Should be an error, but we can cope with it */
10108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Out of place iCCP chunk");
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_iCCP))
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate iCCP chunk");
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "iCCP chunk too large to fit in memory");
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
10248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
10308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
10338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
10358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata[slength] = 0x00;
10398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (profile = chunkdata; *profile; profile++)
10418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop to find end of name */ ;
10428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ++profile;
10448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* there should be at least one zero (the compression type byte)
10468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      following the separator, and we should be on it  */
10478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( profile >= chunkdata + slength - 1)
10488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
10508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Malformed iCCP chunk");
10518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* compression_type should always be zero */
10558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   compression_type = *profile++;
10568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (compression_type)
10578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Ignoring nonzero compression type in iCCP chunk");
10598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      compression_type=0x00;  /* Reset it to zero (libpng-1.0.6 through 1.0.8
10608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                 wrote nonzero) */
10618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   prefix_length = profile - chunkdata;
10648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = png_decompress_chunk(png_ptr, compression_type, chunkdata,
10658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    slength, prefix_length, &data_length);
10668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   profile_length = data_length - prefix_length;
10688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ( prefix_length > data_length || profile_length < 4)
10708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Profile size field missing from iCCP chunk");
10738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Check the profile_size recorded in the first 32 bits of the ICC profile */
10778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   pC = (png_bytep)(chunkdata+prefix_length);
10788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   profile_size = ((*(pC  ))<<24) |
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  ((*(pC+1))<<16) |
10808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  ((*(pC+2))<< 8) |
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  ((*(pC+3))    );
10828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(profile_size < profile_length)
10848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      profile_length = profile_size;
10858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(profile_size > profile_length)
10878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
10888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
10898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
10908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
10918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
10928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_iCCP(png_ptr, info_ptr, chunkdata, compression_type,
10948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                chunkdata + prefix_length, profile_length);
10958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, chunkdata);
10968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_iCCP_SUPPORTED */
10988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sPLT_SUPPORTED)
11008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
11018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
11028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
11038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep chunkdata;
11058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep entry_start;
11068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_sPLT_t new_palette;
11078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_NO_POINTER_INDEXING
11088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_sPLT_entryp pp;
11098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int data_length, entry_size, i;
11118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
11138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_sPLT\n");
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
11178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sPLT");
11188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sPLT after IDAT");
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
11228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
11268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
11278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "sPLT chunk too large to fit in memory");
11298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
11308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
11318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
11338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = (png_bytep)png_malloc(png_ptr, length + 1);
11358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
11368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
11378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
11398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
11418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata[slength] = 0x00;
11458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (entry_start = chunkdata; *entry_start; entry_start++)
11478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop to find end of name */ ;
11488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ++entry_start;
11498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* a sample depth should follow the separator, and we should be on it  */
11518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (entry_start > chunkdata + slength - 2)
11528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
11548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "malformed sPLT chunk");
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.depth = *entry_start++;
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   entry_size = (new_palette.depth == 8 ? 6 : 10);
11608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   data_length = (slength - (entry_start - chunkdata));
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* integrity-check the data length */
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (data_length % entry_size)
11648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
11668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "sPLT chunk has bad length");
11678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
11688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.nentries = (png_int_32) ( data_length / entry_size);
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_uint_32) new_palette.nentries > (png_uint_32) (PNG_SIZE_MAX /
11728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_sizeof(png_sPLT_entry)))
11738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "sPLT chunk too long");
11758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
11768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
11788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
11798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (new_palette.entries == NULL)
11808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "sPLT chunk requires too much memory");
11828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
11838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
11848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef PNG_NO_POINTER_INDEXING
11868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_sPLT_entryp pp = new_palette.entries + i;
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (new_palette.depth == 8)
11918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
11928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->red = *entry_start++;
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->green = *entry_start++;
11948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->blue = *entry_start++;
11958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->alpha = *entry_start++;
11968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
11978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
11988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
11998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->red   = png_get_uint_16(entry_start); entry_start += 2;
12008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->green = png_get_uint_16(entry_start); entry_start += 2;
12018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->blue  = png_get_uint_16(entry_start); entry_start += 2;
12028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp->alpha = png_get_uint_16(entry_start); entry_start += 2;
12038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
12048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
12058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
12078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   pp = new_palette.entries;
12088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < new_palette.nentries; i++)
12098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (new_palette.depth == 8)
12128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
12138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].red   = *entry_start++;
12148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].green = *entry_start++;
12158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].blue  = *entry_start++;
12168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].alpha = *entry_start++;
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
12188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
12198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].red   = png_get_uint_16(entry_start); entry_start += 2;
12218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].green = png_get_uint_16(entry_start); entry_start += 2;
12228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].blue  = png_get_uint_16(entry_start); entry_start += 2;
12238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          pp[i].alpha = png_get_uint_16(entry_start); entry_start += 2;
12248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
12258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      pp->frequency = png_get_uint_16(entry_start); entry_start += 2;
12268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
12288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* discard all chunk data except the name and stash that */
12308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   new_palette.name = (png_charp)chunkdata;
12318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sPLT(png_ptr, info_ptr, &new_palette, 1);
12338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, chunkdata);
12358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, new_palette.entries);
12368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_sPLT_SUPPORTED */
12388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_tRNS_SUPPORTED)
12408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
12418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
12428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte readbuf[PNG_MAX_PALETTE_LENGTH];
12448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int bit_mask;
12458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_tRNS\n");
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* For non-indexed color, mask off any bits in the tRNS value that
12498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * exceed the bit depth.  Some creators were writing extra bits there.
12508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * This is not needed for indexed color. */
12518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   bit_mask = (1 << png_ptr->bit_depth) - 1;
12528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
12548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tRNS");
12558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
12568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid tRNS after IDAT");
12588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
12598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
12628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate tRNS chunk");
12648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
12658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
12668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
12698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[2];
12718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length != 2)
12738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
12748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
12758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
12768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 1;
12818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->trans_values.gray = png_get_uint_16(buf) & bit_mask;
12828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
12848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
12858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[6];
12868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length != 6)
12888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
12898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
12908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
12918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
12928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
12938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, (png_size_t)length);
12948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 1;
12958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->trans_values.red = png_get_uint_16(buf) & bit_mask;
12968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->trans_values.green = png_get_uint_16(buf + 2) & bit_mask;
12978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->trans_values.blue = png_get_uint_16(buf + 4) & bit_mask;
12988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
13008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->mode & PNG_HAVE_PLTE))
13028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         /* Should be an error, but we can cope with it. */
13048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Missing PLTE before tRNS");
13058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length > (png_uint_32)png_ptr->num_palette ||
13078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          length > PNG_MAX_PALETTE_LENGTH)
13088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Incorrect tRNS chunk length");
13108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
13128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (length == 0)
13148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Zero length tRNS chunk");
13168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_crc_finish(png_ptr, length);
13178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
13188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
13198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, readbuf, (png_size_t)length);
13208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = (png_uint_16)length;
13218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
13238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "tRNS chunk not allowed with alpha channel");
13258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
13308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_trans = 0;
13328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
13368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      &(png_ptr->trans_values));
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
13398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_bKGD_SUPPORTED)
13418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
13428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
13438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t truelen;
13458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[6];
13468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_bKGD\n");
13488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
13508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before bKGD");
13518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
13528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid bKGD after IDAT");
13548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE &&
13588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            !(png_ptr->mode & PNG_HAVE_PLTE))
13598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before bKGD");
13618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_bKGD))
13658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate bKGD chunk");
13678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
13728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 1;
13738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->color_type & PNG_COLOR_MASK_COLOR)
13748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 6;
13758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
13768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      truelen = 2;
13778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != truelen)
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect bKGD chunk length");
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
13828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
13848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, truelen);
13868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
13878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
13888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We convert the index value into RGB components so that we can allow
13908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * arbitrary RGB values for background when we have transparency, and
13918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * so it is easy to determine the RGB values of the background color
13928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    * from the info_ptr struct. */
13938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
13948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.index = buf[0];
13968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if(info_ptr->num_palette)
13978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          if(buf[0] > info_ptr->num_palette)
13998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          {
14008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             png_warning(png_ptr, "Incorrect bKGD chunk index value");
14018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             return;
14028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          }
14038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.red =
14048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].red;
14058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.green =
14068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].green;
14078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_ptr->background.blue =
14088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             (png_uint_16)png_ptr->palette[buf[0]].blue;
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (!(png_ptr->color_type & PNG_COLOR_MASK_COLOR)) /* GRAY */
14128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.red =
14148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.green =
14158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.blue =
14168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.gray = png_get_uint_16(buf);
14178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
14198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.red = png_get_uint_16(buf);
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.green = png_get_uint_16(buf + 2);
14228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->background.blue = png_get_uint_16(buf + 4);
14238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_bKGD(png_ptr, info_ptr, &(png_ptr->background));
14268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_hIST_SUPPORTED)
14308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
14318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
14328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unsigned int num, i;
14348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_16 readbuf[PNG_MAX_PALETTE_LENGTH];
14358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_hIST\n");
14378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
14398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before hIST");
14408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
14418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid hIST after IDAT");
14438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (!(png_ptr->mode & PNG_HAVE_PLTE))
14478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Missing PLTE before hIST");
14498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_hIST))
14538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate hIST chunk");
14558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   num = length / 2 ;
14608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (num != (unsigned int) png_ptr->num_palette || num >
14618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (unsigned int) PNG_MAX_PALETTE_LENGTH)
14628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect hIST chunk length");
14648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < num; i++)
14698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_byte buf[2];
14718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_read(png_ptr, buf, 2);
14738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      readbuf[i] = png_get_uint_16(buf);
14748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
14758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
14778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
14788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_hIST(png_ptr, info_ptr, readbuf);
14808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_pHYs_SUPPORTED)
14848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
14858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
14868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[9];
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 res_x, res_y;
14898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int unit_type;
14908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_pHYs\n");
14928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
14948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pHYs");
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
14968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
14978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pHYs after IDAT");
14988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
14998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pHYs))
15028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate pHYs chunk");
15048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 9)
15098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect pHYs chunk length");
15118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
15168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
15178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   res_x = png_get_uint_32(buf);
15208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   res_y = png_get_uint_32(buf + 4);
15218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unit_type = buf[8];
15228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_pHYs(png_ptr, info_ptr, res_x, res_y, unit_type);
15238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_oFFs_SUPPORTED)
15278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
15288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
15298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[9];
15318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 offset_x, offset_y;
15328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int unit_type;
15338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_oFFs\n");
15358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
15378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before oFFs");
15388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
15398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid oFFs after IDAT");
15418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_oFFs))
15458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate oFFs chunk");
15478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 9)
15528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect oFFs chunk length");
15548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 9);
15598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
15608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset_x = png_get_int_32(buf);
15638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   offset_y = png_get_int_32(buf + 4);
15648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   unit_type = buf[8];
15658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_oFFs(png_ptr, info_ptr, offset_x, offset_y, unit_type);
15668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
15678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
15688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_pCAL_SUPPORTED)
15708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* read the pCAL chunk (described in the PNG Extensions document) */
15718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
15728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
15738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
15748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp purpose;
15758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_int_32 X0, X1;
15768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte type, nparams;
15778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp buf, units, endptr;
15788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charpp params;
15798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
15808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int i;
15818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_pCAL\n");
15838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
15858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before pCAL");
15868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
15878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL after IDAT");
15898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_pCAL))
15938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate pCAL chunk");
15958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
15968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
15978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
15988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
15998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(2, "Allocating and reading pCAL chunk data (%lu bytes)\n",
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length + 1);
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   purpose = (png_charp)png_malloc_warn(png_ptr, length + 1);
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (purpose == NULL)
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL purpose.");
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)purpose, slength);
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
16118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, purpose);
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   purpose[slength] = 0x00; /* null terminate the last string */
16178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(3, "Finding end of pCAL purpose string\n");
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (buf = purpose; *buf; buf++)
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   endptr = purpose + slength;
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We need to have at least 12 bytes after the purpose string
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      in order to get the parameter information. */
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (endptr <= buf + 12)
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL data");
16298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, purpose);
16308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(3, "Reading pCAL X0, X1, type, nparams, and units\n");
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   X0 = png_get_int_32((png_bytep)buf+1);
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   X1 = png_get_int_32((png_bytep)buf+5);
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   type = buf[9];
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   nparams = buf[10];
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   units = buf + 11;
16398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(3, "Checking pCAL equation type and number of parameters\n");
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Check that we have the right number of parameters for known
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      equation types. */
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((type == PNG_EQUATION_LINEAR && nparams != 2) ||
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_BASE_E && nparams != 3) ||
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_ARBITRARY && nparams != 3) ||
16468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (type == PNG_EQUATION_HYPERBOLIC && nparams != 4))
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid pCAL parameters for equation type");
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, purpose);
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (type >= PNG_EQUATION_LAST)
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Unrecognized equation type for pCAL chunk");
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (buf = units; *buf; buf++)
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Empty loop to move past the units string. */ ;
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(3, "Allocating pCAL parameters array\n");
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   params = (png_charpp)png_malloc_warn(png_ptr, (png_uint_32)(nparams
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      *png_sizeof(png_charp))) ;
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (params == NULL)
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_free(png_ptr, purpose);
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "No memory for pCAL params.");
16678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* Get pointers to the start of each parameter string. */
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (i = 0; i < (int)nparams; i++)
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      buf++; /* Skip the null string terminator from previous parameter. */
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_debug1(3, "Reading pCAL parameter %d\n", i);
16768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++)
16778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         /* Empty loop to move past each parameter string */ ;
16788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* Make sure we haven't run out of data yet */
16808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (buf > endptr)
16818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
16828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Invalid pCAL data");
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_free(png_ptr, purpose);
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_free(png_ptr, params);
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
16868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_pCAL(png_ptr, info_ptr, purpose, X0, X1, type, nparams,
16908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      units, params);
16918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, purpose);
16938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, params);
16948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_sCAL_SUPPORTED)
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* read the sCAL chunk */
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
17028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp buffer, ep;
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   double width, height;
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp vp;
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp swidth, sheight;
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_sCAL\n");
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before sCAL");
17178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (png_ptr->mode & PNG_HAVE_IDAT)
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL after IDAT");
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sCAL))
17248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate sCAL chunk");
17268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
17278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(2, "Allocating and reading sCAL chunk data (%lu bytes)\n",
17318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length + 1);
17328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   buffer = (png_charp)png_malloc_warn(png_ptr, length + 1);
17338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (buffer == NULL)
17348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
17358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
17368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
17388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
17398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)buffer, slength);
17408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
17428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, buffer);
17448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
17458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   buffer[slength] = 0x00; /* null terminate the last string */
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ep = buffer + 1;        /* skip unit byte */
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   width = png_strtod(png_ptr, ep, &vp);
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (*vp)
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "malformed width string in sCAL chunk");
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
17598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
17608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   swidth = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
17618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (swidth == NULL)
17628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
17638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
17648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
17668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
17678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (ep = buffer; *ep; ep++)
17718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
17728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ep++;
17738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
17758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   height = png_strtod(png_ptr, ep, &vp);
17768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (*vp)
17778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "malformed height string in sCAL chunk");
17798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
17818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
17828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   sheight = (png_charp)png_malloc_warn(png_ptr, png_strlen(ep) + 1);
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (swidth == NULL)
17858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
17868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       return;
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
17908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (buffer + slength < ep
17948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
17958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      || width <= 0. || height <= 0.
17968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      )
17988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Invalid sCAL data");
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, buffer);
18018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, swidth);
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, sheight);
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FLOATING_POINT_SUPPORTED
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sCAL(png_ptr, info_ptr, buffer[0], width, height);
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_FIXED_POINT_SUPPORTED
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_sCAL_s(png_ptr, info_ptr, buffer[0], swidth, sheight);
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, buffer);
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_FIXED_POINT_SUPPORTED) && !defined(PNG_FLOATING_POINT_SUPPORTED)
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, swidth);
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, sheight);
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_tIME_SUPPORTED)
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_byte buf[7];
18308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_time mod_time;
18318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_tIME\n");
18338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
18358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Out of place tIME chunk");
18368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tIME))
18378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
18388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Duplicate tIME chunk");
18398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
18408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
18448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
18458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length != 7)
18478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
18488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Incorrect tIME chunk length");
18498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_crc_finish(png_ptr, length);
18508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, buf, 7);
18548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
18558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
18568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.second = buf[6];
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.minute = buf[5];
18598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.hour = buf[4];
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.day = buf[3];
18618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.month = buf[2];
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   mod_time.year = png_get_uint_16(buf);
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_set_tIME(png_ptr, info_ptr, &mod_time);
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_tEXt_SUPPORTED)
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Note: this does not properly handle chunks that are > 64K under DOS */
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
18728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
18738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
18748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp key;
18758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp text;
18768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
18778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength;
18788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
18798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_tEXt\n");
18818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
18838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before tEXt");
18848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
18868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
18878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
18898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
18908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
18918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "tEXt chunk too large to fit in memory");
18928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length - (png_uint_32)65535L;
18938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      length = (png_uint_32)65535L;
18948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
18958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
18968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   key = (png_charp)png_malloc_warn(png_ptr, length + 1);
18988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (key == NULL)
18998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "No memory to process text chunk.");
19018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
19028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
19048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)key, slength);
19058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, skip))
19078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, key);
19098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
19108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   key[slength] = 0x00;
19138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (text = key; *text; text++)
19158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop to find end of key */ ;
19168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text != key + slength)
19188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      text++;
19198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
19218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_32)png_sizeof(png_text));
19228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text_ptr == NULL)
19238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "Not enough memory to process text chunk.");
19258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_free(png_ptr, key);
19268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
19278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->compression = PNG_TEXT_COMPRESSION_NONE;
19298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->key = key;
19308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
19318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang = NULL;
19328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang_key = NULL;
19338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->itxt_length = 0;
19348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text = text;
19368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text_length = png_strlen(text);
19378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, key);
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, text_ptr);
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (ret)
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "Insufficient memory to process text chunk.");
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_zTXt_SUPPORTED)
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* note: this does not correctly handle chunks that are > 64K under DOS */
19498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
19508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
19518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
19538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp chunkdata;
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp text;
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_type;
19568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_len, data_len;
19588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_zTXt\n");
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
19618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before zTXt");
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
19648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
19658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
19698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr,"zTXt chunk too large to fit in memory");
19728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_crc_finish(png_ptr, length);
19738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
19748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
19788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (chunkdata == NULL)
19798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr,"Out of memory processing zTXt chunk.");
19818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
19828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
19848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
19858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
19868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
19898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata[slength] = 0x00;
19928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (text = chunkdata; *text; text++)
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
19958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* zTXt must have some text after the chunkdataword */
19978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text == chunkdata + slength - 1)
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Truncated zTXt chunk");
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_type = *(++text);
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if (comp_type != PNG_TEXT_COMPRESSION_zTXt)
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       {
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_warning(png_ptr, "Unknown compression type in zTXt chunk");
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          comp_type = PNG_TEXT_COMPRESSION_zTXt;
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       }
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       text++;        /* skip the compression_method byte */
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   prefix_len = text - chunkdata;
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = (png_charp)png_decompress_chunk(png_ptr, comp_type, chunkdata,
20168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                                    (png_size_t)length, prefix_len, &data_len);
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     (png_uint_32)png_sizeof(png_text));
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text_ptr == NULL)
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr,"Not enough memory to process zTXt chunk.");
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_free(png_ptr, chunkdata);
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->compression = comp_type;
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->key = chunkdata;
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_iTXt_SUPPORTED
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang = NULL;
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang_key = NULL;
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->itxt_length = 0;
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text = chunkdata + prefix_len;
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text_length = data_len;
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, text_ptr);
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, chunkdata);
20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (ret)
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_iTXt_SUPPORTED)
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* note: this does not correctly handle chunks that are > 64K under DOS */
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_textp text_ptr;
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp chunkdata;
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_charp key, lang, text, lang_key;
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_flag;
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int comp_type = 0;
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int ret;
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_size_t slength, prefix_len, data_len;
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_iTXt\n");
20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->mode & PNG_HAVE_IHDR))
20618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Missing IHDR before iTXt");
20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->mode |= PNG_AFTER_IDAT;
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* We will no doubt have problems with chunks even half this size, but
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      there is no hard and fast rule to tell us where to stop. */
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (length > (png_uint_32)65535L)
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr,"iTXt chunk too large to fit in memory");
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_crc_finish(png_ptr, length);
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (chunkdata == NULL)
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr, "No memory to process iTXt chunk.");
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   slength = (png_size_t)length;
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_read(png_ptr, (png_bytep)chunkdata, slength);
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_crc_finish(png_ptr, 0))
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunkdata[slength] = 0x00;
20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (lang = chunkdata; *lang; lang++)
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   lang++;        /* skip NUL separator */
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* iTXt must have a language tag (possibly empty), two compression bytes,
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      translated keyword (possibly empty), and possibly some text after the
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      keyword */
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (lang >= chunkdata + slength - 3)
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Truncated iTXt chunk");
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_flag = *lang++;
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       comp_type = *lang++;
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (lang_key = lang; *lang_key; lang_key++)
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   lang_key++;        /* skip NUL separator */
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   for (text = lang_key; *text; text++)
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      /* empty loop */ ;
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text++;        /* skip NUL separator */
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text >= chunkdata + slength)
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Malformed iTXt chunk");
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_free(png_ptr, chunkdata);
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   prefix_len = text - chunkdata;
21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   key=chunkdata;
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (comp_flag)
21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       chunkdata = png_decompress_chunk(png_ptr, comp_type, chunkdata,
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          (size_t)length, prefix_len, &data_len);
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
21348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       data_len=png_strlen(chunkdata + prefix_len);
21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr = (png_textp)png_malloc_warn(png_ptr,
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (png_uint_32)png_sizeof(png_text));
21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (text_ptr == NULL)
21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_warning(png_ptr,"Not enough memory to process iTXt chunk.");
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_free(png_ptr, chunkdata);
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     return;
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->compression = (int)comp_flag + 1;
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang_key = chunkdata+(lang_key-key);
21458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->lang = chunkdata+(lang-key);
21468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->itxt_length = data_len;
21478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text_length = 0;
21488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->key = chunkdata;
21498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   text_ptr->text = chunkdata + prefix_len;
21508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   ret=png_set_text_2(png_ptr, info_ptr, text_ptr, 1);
21528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, text_ptr);
21548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_free(png_ptr, chunkdata);
21558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (ret)
21568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
21578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* This function is called when we haven't found a handler for a
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunk.  If there isn't a problem with the chunk itself (ie bad
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   chunk name, CRC, or a critical chunk), the chunk is silently ignored
21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   -- unless the PNG_FLAG_UNKNOWN_CHUNKS_SUPPORTED flag is on in which
21648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   case it will be saved away to be written out later. */
21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_handle_unknown(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 skip = 0;
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_handle_unknown\n");
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->mode & PNG_HAVE_IDAT)
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      PNG_CONST PNG_IDAT;
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* not an IDAT */
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->mode |= PNG_AFTER_IDAT;
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_check_chunk_name(png_ptr, png_ptr->chunk_name);
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->chunk_name[0] & 0x20))
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           PNG_HANDLE_CHUNK_ALWAYS
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           && png_ptr->read_user_chunk_fn == NULL
21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        )
21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          png_chunk_error(png_ptr, "unknown critical chunk");
21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS) ||
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (png_ptr->read_user_chunk_fn != NULL))
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if (length > (png_uint_32)65535L)
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       {
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           png_warning(png_ptr, "unknown chunk too large to fit in memory");
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           skip = length - (png_uint_32)65535L;
22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           length = (png_uint_32)65535L;
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       }
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_strncpy((png_charp)png_ptr->unknown_chunk.name,
22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	 (png_charp)png_ptr->chunk_name,
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_sizeof((png_charp)png_ptr->chunk_name));
22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
22128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_ptr->unknown_chunk.size = (png_size_t)length;
22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if(png_ptr->read_user_chunk_fn != NULL)
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       {
22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          /* callback to user unknown chunk handler */
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          int ret;
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          ret = (*(png_ptr->read_user_chunk_fn))
22208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            (png_ptr, &png_ptr->unknown_chunk);
22218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          if (ret < 0)
22228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             png_chunk_error(png_ptr, "error in user chunk");
22238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          if (ret == 0)
22248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          {
22258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             if (!(png_ptr->chunk_name[0] & 0x20))
22268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
22278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     PNG_HANDLE_CHUNK_ALWAYS)
22288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                   png_chunk_error(png_ptr, "unknown critical chunk");
22298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             png_set_unknown_chunks(png_ptr, info_ptr,
22308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               &png_ptr->unknown_chunk, 1);
22318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          }
22328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       }
22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
22348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_set_unknown_chunks(png_ptr, info_ptr, &png_ptr->unknown_chunk, 1);
22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_free(png_ptr, png_ptr->unknown_chunk.data);
22378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       png_ptr->unknown_chunk.data = NULL;
22388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      skip = length;
22428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_crc_finish(png_ptr, skip);
22448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */
22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* This function is called to verify that a chunk name is valid.
22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This function can't have the "critical chunk check" incorporated
22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   into it, since in the future we will need to be able to call user
22538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   functions to handle unknown critical chunks after we check that
22548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the chunk name itself is valid. */
22558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define isnonalpha(c) ((c) < 65 || (c) > 122 || ((c) > 90 && (c) < 97))
22578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_check_chunk_name(png_structp png_ptr, png_bytep chunk_name)
22608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_check_chunk_name\n");
22628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (isnonalpha(chunk_name[0]) || isnonalpha(chunk_name[1]) ||
22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       isnonalpha(chunk_name[2]) || isnonalpha(chunk_name[3]))
22648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_chunk_error(png_ptr, "invalid chunk type");
22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Combines the row recently read in with the existing pixels in the
22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   row.  This routine takes care of alpha and transparency if requested.
22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This routine also handles the two methods of progressive display
22728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   of interlaced images, depending on the mask value.
22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   The mask value describes which pixels are to be combined with
22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the row.  The pattern always repeats every 8 pixels, so just 8
22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   bits are needed.  A one indicates the pixel is to be combined,
22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   a zero indicates the pixel is to be skipped.  This is in addition
22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   to any alpha or transparency value associated with the pixel.  If
22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   you want all pixels to be combined, pass 0xff (255) in mask.  */
22798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Optimized C version of utilities to read a PNG file
22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
22828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Based on code contributed by Nirav Chhatrapati, Intel Corp., 1998.
22838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Interface to libpng contributed by Gilles Vollant, 1999.
22848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * GNU C port by Greg Roelofs, 1999-2001.
22858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_OPTIMIZED_CODE_SUPPORTED)
22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_HAVE_MMX_COMBINE_ROW)
22908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                       P N G _ C O M B I N E _ R O W                       */
22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BPP2  2
22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BPP3  3 /* bytes per pixel (a.k.a. pixel_bytes) */
23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BPP4  4
23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BPP6  6 /* (defined only to help avoid cut-and-paste errors) */
23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define BPP8  8
23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Combines the row recently read in with the previous row.
23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This routine takes care of alpha and transparency if requested.
23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This routine also handles the two methods of progressive display
23078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   of interlaced images, depending on the mask value.
23088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   The mask value describes which pixels are to be combined with
23098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   the row.  The pattern always repeats every 8 pixels, so just 8
23108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   bits are needed.  A one indicates the pixel is to be combined; a
23118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   zero indicates the pixel is to be skipped.  This is in addition
23128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   to any alpha or transparency value associated with the pixel.
23138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   If you want all pixels to be combined, pass 0xff (255) in mask. */
23148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Use this routine for the x86 platform - it uses a faster MMX routine
23168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if the machine supports MMX. */
23178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_combine_row(png_structp png_ptr, png_bytep row, int mask)
23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_USE_LOCAL_ARRAYS)
23238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic PNG_CONST int FARDATA png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
23248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic PNG_CONST int FARDATA png_pass_inc[7]   = {8, 8, 4, 4, 2, 2, 1};
23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic PNG_CONST int FARDATA png_pass_width[7] = {8, 4, 4, 2, 2, 1, 1};
23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_combine_row (pngrutil.c OPTIMIZED)\n");
23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (mask == 0xff)
23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
23328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_debug(2,"mask == 0xff:  doing single png_memcpy()\n");
23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_memcpy(row, png_ptr->row_buf + 1,
23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       (png_size_t)PNG_ROWBYTES(png_ptr->row_info.pixel_depth,png_ptr->width));
23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else   /* (png_combine_row() is never called with mask == 0) */
23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (png_ptr->row_info.pixel_depth)
23398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         /* most common case:  combining 24-bit RGB */
23418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 24:       /* png_ptr->row_info.pixel_depth */
23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 i;
23488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 initial_val = BPP3 * png_pass_start[png_ptr->pass];
23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
23508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int stride = BPP3 * png_pass_inc[png_ptr->pass];
23518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
23528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int rep_bytes = BPP3 * png_pass_width[png_ptr->pass];
23538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
23548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
23558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int diff = (int) (png_ptr->width & 7); /* amount lost */
23568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 final_val = BPP3 * len;   /* GRR bugfix */
23578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr = png_ptr->row_buf + 1 + initial_val;
23598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr = row + initial_val;
23608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (i = initial_val; i < final_val; i += stride)
23628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
23648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
23658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
23668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
23678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (diff)  /* number of leftover pixels:  3 for pngtest */
23688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
23698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  final_val += diff*BPP3;
23708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (; i < final_val; i += stride)
23718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
23728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     if (rep_bytes > (int)(final_val-i))
23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        rep_bytes = (int)(final_val-i);
23748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(dstptr, srcptr, rep_bytes);
23758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     srcptr += stride;
23768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dstptr += stride;
23778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
23788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
23798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } /* end of else (_mmx_supported) */
23808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
23828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 24 bpp */
23838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 32:       /* png_ptr->row_info.pixel_depth */
23858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
23868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
23878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
23888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
23908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 i;
23918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 initial_val = BPP4 * png_pass_start[png_ptr->pass];
23928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int stride = BPP4 * png_pass_inc[png_ptr->pass];
23948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
23958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int rep_bytes = BPP4 * png_pass_width[png_ptr->pass];
23968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
23978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
23988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int diff = (int) (png_ptr->width & 7); /* amount lost */
23998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 final_val = BPP4 * len;   /* GRR bugfix */
24008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr = png_ptr->row_buf + 1 + initial_val;
24028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr = row + initial_val;
24038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (i = initial_val; i < final_val; i += stride)
24058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
24068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
24078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
24088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
24098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
24108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (diff)  /* number of leftover pixels:  3 for pngtest */
24118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
24128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  final_val += diff*BPP4;
24138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (; i < final_val; i += stride)
24148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
24158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     if (rep_bytes > (int)(final_val-i))
24168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        rep_bytes = (int)(final_val-i);
24178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(dstptr, srcptr, rep_bytes);
24188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     srcptr += stride;
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dstptr += stride;
24208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
24218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
24228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
24238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
24258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 32 bpp */
24268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 8:        /* png_ptr->row_info.pixel_depth */
24288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
24298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
24308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
24318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
24328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 i;
24338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 initial_val = png_pass_start[png_ptr->pass];
24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
24358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int stride = png_pass_inc[png_ptr->pass];
24368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int rep_bytes = png_pass_width[png_ptr->pass];
24388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
24398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
24408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int diff = (int) (png_ptr->width & 7); /* amount lost */
24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 final_val = len;  /* GRR bugfix */
24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr = png_ptr->row_buf + 1 + initial_val;
24448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr = row + initial_val;
24458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (i = initial_val; i < final_val; i += stride)
24478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
24488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
24498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
24508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
24518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
24528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (diff)  /* number of leftover pixels:  3 for pngtest */
24538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
24548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  final_val += diff /* *BPP1 */ ;
24558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (; i < final_val; i += stride)
24568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
24578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     if (rep_bytes > (int)(final_val-i))
24588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        rep_bytes = (int)(final_val-i);
24598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(dstptr, srcptr, rep_bytes);
24608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     srcptr += stride;
24618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dstptr += stride;
24628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
24638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
24648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
24658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
24678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 8 bpp */
24688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:        /* png_ptr->row_info.pixel_depth */
24708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
24718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp;
24728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp;
24738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_inc, s_start, s_end;
24748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m;
24758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
24768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
24778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = png_ptr->row_buf + 1;
24798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row;
24808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m = 0x80;
24818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
24828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
24838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
24848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 0;
24858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 7;
24868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = 1;
24878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
24888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
24898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
24908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
24918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 7;
24928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 0;
24938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = -1;
24948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
24958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
24978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < png_ptr->width; i++)
24998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
25018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  int value;
25038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x1;
25058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
25068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
25078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
25108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
25128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
25138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
25148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
25178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
25198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
25208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
25228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
25248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 1 bpp */
25258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:        /* png_ptr->row_info.pixel_depth */
25278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
25288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp;
25298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp;
25308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
25318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m;
25328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
25338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
25348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
25358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = png_ptr->row_buf + 1;
25378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row;
25388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m = 0x80;
25398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
25408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
25418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
25438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
25448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
25458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
25478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
25488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
25508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
25518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
25528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
25558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < png_ptr->width; i++)
25578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
25598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x3;
25618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
25628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
25638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
25668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
25678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
25688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
25698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
25708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
25718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
25738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
25748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
25758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
25768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
25778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
25788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
25798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 2 bpp */
25808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:        /* png_ptr->row_info.pixel_depth */
25828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
25838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp;
25848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp;
25858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
25868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m;
25878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
25888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
25898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
25908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
25918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = png_ptr->row_buf + 1;
25928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row;
25938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            m = 0x80;
25948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
25958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
25968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
25978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
25988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
25998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
26008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
26028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
26038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
26058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
26068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
26078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
26098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < png_ptr->width; i++)
26118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
26138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0xf;
26158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
26168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
26178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
26208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
26228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
26238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
26248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
26278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
26288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
26298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
26308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
26318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
26328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
26338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 4 bpp */
26348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 16:       /* png_ptr->row_info.pixel_depth */
26368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
26378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
26388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
26398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 i;
26428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 initial_val = BPP2 * png_pass_start[png_ptr->pass];
26438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
26448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int stride = BPP2 * png_pass_inc[png_ptr->pass];
26458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
26468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int rep_bytes = BPP2 * png_pass_width[png_ptr->pass];
26478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
26488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 len = png_ptr->width &~7;  /* reduce to mult of 8 */
26498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int diff = (int) (png_ptr->width & 7); /* amount lost */
26508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 final_val = BPP2 * len;   /* GRR bugfix */
26518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr = png_ptr->row_buf + 1 + initial_val;
26538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr = row + initial_val;
26548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (i = initial_val; i < final_val; i += stride)
26568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
26588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
26598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
26608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (diff)  /* number of leftover pixels:  3 for pngtest */
26628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
26638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  final_val += diff*BPP2;
26648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (; i < final_val; i += stride)
26658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
26668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     if (rep_bytes > (int)(final_val-i))
26678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        rep_bytes = (int)(final_val-i);
26688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(dstptr, srcptr, rep_bytes);
26698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     srcptr += stride;
26708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dstptr += stride;
26718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
26728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
26738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } /* end of else (_mmx_supported) */
26748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
26768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 16 bpp */
26778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 48:       /* png_ptr->row_info.pixel_depth */
26818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
26828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
26838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
26848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
26858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 i;
26868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 initial_val = BPP6 * png_pass_start[png_ptr->pass];
26878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
26888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int stride = BPP6 * png_pass_inc[png_ptr->pass];
26898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
26908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register int rep_bytes = BPP6 * png_pass_width[png_ptr->pass];
26918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                 /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
26928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_uint_32 len = png_ptr->width &~7; /* reduce to mult of 8 */
26938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int diff = (int) (png_ptr->width & 7); /* amount lost */
26948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               register png_uint_32 final_val = BPP6 * len;   /* GRR bugfix */
26958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr = png_ptr->row_buf + 1 + initial_val;
26978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr = row + initial_val;
26988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
26998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (i = initial_val; i < final_val; i += stride)
27008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
27018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
27028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
27038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
27048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
27058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (diff)  /* number of leftover pixels:  3 for pngtest */
27068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
27078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  final_val += diff*BPP6;
27088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (; i < final_val; i += stride)
27098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
27108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     if (rep_bytes > (int)(final_val-i))
27118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        rep_bytes = (int)(final_val-i);
27128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(dstptr, srcptr, rep_bytes);
27138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     srcptr += stride;
27148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dstptr += stride;
27158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
27168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
27178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
27198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 48 bpp */
27208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 64:       /* png_ptr->row_info.pixel_depth */
27228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
27238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep srcptr;
27248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dstptr;
27258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            register png_uint_32 i;
27268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 initial_val = BPP8 * png_pass_start[png_ptr->pass];
27278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              /* png.c:  png_pass_start[] = {0, 4, 0, 2, 0, 1, 0}; */
27288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            register int stride = BPP8 * png_pass_inc[png_ptr->pass];
27298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              /* png.c:  png_pass_inc[] = {8, 8, 4, 4, 2, 2, 1}; */
27308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            register int rep_bytes = BPP8 * png_pass_width[png_ptr->pass];
27318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project              /* png.c:  png_pass_width[] = {8, 4, 4, 2, 2, 1, 1}; */
27328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 len = png_ptr->width &~7;  /* reduce to mult of 8 */
27338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int diff = (int) (png_ptr->width & 7); /* amount lost */
27348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            register png_uint_32 final_val = BPP8 * len;   /* GRR bugfix */
27358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            srcptr = png_ptr->row_buf + 1 + initial_val;
27378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dstptr = row + initial_val;
27388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = initial_val; i < final_val; i += stride)
27408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(dstptr, srcptr, rep_bytes);
27428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               srcptr += stride;
27438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dstptr += stride;
27448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (diff)  /* number of leftover pixels:  3 for pngtest */
27468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
27478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               final_val += diff*BPP8;
27488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (; i < final_val; i += stride)
27498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
27508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (rep_bytes > (int)(final_val-i))
27518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     rep_bytes = (int)(final_val-i);
27528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dstptr, srcptr, rep_bytes);
27538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  srcptr += stride;
27548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dstptr += stride;
27558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
27568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
27578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
27598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }       /* end 64 bpp */
27608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default: /* png_ptr->row_info.pixel_depth != 1,2,4,8,16,24,32,48,64 */
27628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
27638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* this should never happen */
27648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Invalid row_info.pixel_depth in pngrutil");
27658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
27668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
27678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      } /* end switch (png_ptr->row_info.pixel_depth) */
27688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   } /* end if (non-trivial mask) */
27708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} /* end png_combine_row() */
27728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_HAVE_MMX_COMBINE_ROW */
27738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
27778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
27788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                 P N G _ D O _ R E A D _ I N T E R L A C E                 */
27798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
27808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
27818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_INTERLACING_SUPPORTED)
27838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_HAVE_MMX_READ_INTERLACE)
27848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* png_do_read_interlace() is called after any 16-bit to 8-bit conversion
27868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * has taken place.  [GRR: what other steps come before and/or after?]
27878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
27888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
27898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
27908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_do_read_interlace(png_structp png_ptr)
27918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
27928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_USE_LOCAL_ARRAYS)
27938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic PNG_CONST int FARDATA png_pass_inc[7]   = {8, 8, 4, 4, 2, 2, 1};
27948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
27958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_row_infop row_info = &(png_ptr->row_info);
27968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep row = png_ptr->row_buf + 1;
27978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int pass = png_ptr->pass;
27988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
27998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 transformations = png_ptr->transformations;
28008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
28018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1,"in png_do_read_interlace (pngrutil.c OPTIMIZED)\n");
28028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (row != NULL && row_info != NULL)
28048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
28058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_uint_32 final_width;
28068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      final_width = row_info->width * png_pass_inc[pass];
28088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (row_info->pixel_depth)
28108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
28118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:
28128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
28138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp, dp;
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            png_byte v;
28178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
28188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int j;
28198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = row + (png_size_t)((row_info->width - 1) >> 3);
28218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row + (png_size_t)((final_width - 1) >> 3);
28228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
28238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
28248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)((row_info->width + 7) & 7);
28268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)((final_width + 7) & 7);
28278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 7;
28288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
28298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -1;
28308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
28328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
28338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = 7 - (int)((row_info->width + 7) & 7);
28358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = 7 - (int)((final_width + 7) & 7);
28368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
28378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 7;
28388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 1;
28398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = row_info->width; i; i--)
28428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x1);
28448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < png_pass_inc[pass]; j++)
28458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
28468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - 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
28678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:
28688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
28698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp, dp;
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
28748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = row + (png_size_t)((row_info->width - 1) >> 2);
28758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row + (png_size_t)((final_width - 1) >> 2);
28768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
28778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
28788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (png_size_t)(((row_info->width + 3) & 3) << 1);
28808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (png_size_t)(((final_width + 3) & 3) << 1);
28818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
28828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
28838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
28848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
28868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
28878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (png_size_t)((3 - ((row_info->width + 3) & 3)) << 1);
28898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (png_size_t)((3 - ((final_width + 3) & 3)) << 1);
28908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
28918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
28928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
28938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
28948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
28958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = row_info->width; i; i--)
28968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
28978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v;
28988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
28998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x3);
29018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < png_pass_inc[pass]; j++)
29028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
29048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
29058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
29068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
29078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
29088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
29098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
29108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
29118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
29128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
29148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
29168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
29178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
29198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
29208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
29228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:
29258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
29268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp, dp;
29278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
29288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
29298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
29308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sp = row + (png_size_t)((row_info->width - 1) >> 1);
29328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row + (png_size_t)((final_width - 1) >> 1);
29338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
29348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
29358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
29368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (png_size_t)(((row_info->width + 1) & 1) << 2);
29378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (png_size_t)(((final_width + 1) & 1) << 2);
29388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
29398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
29408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
29418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
29438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
29448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
29458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (png_size_t)((1 - ((row_info->width + 1) & 1)) << 2);
29468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (png_size_t)((1 - ((final_width + 1) & 1)) << 2);
29478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
29488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
29498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
29508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = row_info->width; i; i--)
29538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
29548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v;
29558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
29568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0xf);
29588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < png_pass_inc[pass]; j++)
29598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
29618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
29628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
29638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
29648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
29658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
29668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
29678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
29688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
29698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
29718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
29728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
29738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
29748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
29758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
29768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
29778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
29788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
29798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
29808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       /*====================================================================*/
29828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default: /* 8-bit or larger (this is where the routine is modified) */
29848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
29858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sptr, dp;
29868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
29878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_size_t pixel_bytes;
29888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int width = (int)row_info->width;
29898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pixel_bytes = (row_info->pixel_depth >> 3);
29918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* point sptr at the last pixel in the pre-expanded row: */
29938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sptr = row + (width - 1) * pixel_bytes;
29948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* point dp at the last pixel position in the expanded row: */
29968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            dp = row + (final_width - 1) * pixel_bytes;
29978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
29988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* MMX not supported:  use modified C code - takes advantage
29998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             *   of inlining of png_memcpy for a constant */
30008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* GRR 19991007:  does it?  or should pixel_bytes in each
30018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             *   block be replaced with immediate value (e.g., 1)? */
30028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* GRR 19991017:  replaced with constants in each case */
30038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
30048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (pixel_bytes == 1)
30058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        *dp-- = *sptr;
30128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     --sptr;
30148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pixel_bytes == 3)
30178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
30218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, 3);
30238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, 3);
30268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= 3;
30278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= 3;
30298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pixel_bytes == 2)
30328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
30368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, 2);
30388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, 2);
30418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= 2;
30428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= 2;
30448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pixel_bytes == 4)
30478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
30518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, 4);
30538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_DEBUG) && defined(PNG_1_0_X)
30568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        if (dp < row || dp+3 > row+png_ptr->row_buf_size)
30578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        {
30588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           printf("dp out of bounds: row=%d, dp=%d, rp=%d\n",
30598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                             row, dp, row+png_ptr->row_buf_size);
30608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           printf("row_buf=%d\n",png_ptr->row_buf_size);
30618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        }
30628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
30638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, 4);
30648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= 4;
30658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= 4;
30678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pixel_bytes == 6)
30708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
30748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, 6);
30768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, 6);
30798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= 6;
30808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= 6;
30828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pixel_bytes == 8)
30858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
30868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
30878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
30888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
30898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
30908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, 8);
30918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
30928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
30938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, 8);
30948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= 8;
30958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
30968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= 8;
30978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
30988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
30998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else     /* GRR:  should never be reached */
31008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
31018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  for (i = width; i; i--)
31028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
31038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_byte v[8];
31048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     int j;
31058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     png_memcpy(v, sptr, pixel_bytes);
31068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     for (j = 0; j < png_pass_inc[pass]; j++)
31078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     {
31088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        png_memcpy(dp, v, pixel_bytes);
31098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        dp -= pixel_bytes;
31108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     }
31118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     sptr -= pixel_bytes;
31128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
31138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
31148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
31168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
31178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
31188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      } /* end switch (row_info->pixel_depth) */
31198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      row_info->width = final_width;
31218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
31238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
31248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} /* end png_do_read_interlace() */
31268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_HAVE_MMX_READ_INTERLACE */
31288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
31298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_HAVE_MMX_READ_FILTER_ROW)
31338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
31348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
31358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                   P N G _ R E A D _ F I L T E R _ R O W                   */
31368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*                                                                           */
31378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*===========================================================================*/
31388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Optimized png_read_filter_row routines */
31418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
31438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep
31448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   row, png_bytep prev_row, int filter)
31458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
31468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_DEBUG)
31478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   char filnm[10];
31488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
31498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_DEBUG)
31528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_read_filter_row (pngrutil.c OPTIMIZED)\n");
31538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (filter)
31548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
31558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 0:
31568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "none");
31578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 1:
31608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "sub-%s",
31618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "x86");
31628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 2:
31658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "up-%s",
31668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "x86");
31678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 3:
31708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "avg-%s",
31718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "x86");
31728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case 4:
31758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "Paeth-%s",
31768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             "x86");
31778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
31808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_snprintf(filnm, 10, "unknown");
31818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
31838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug2(0, "row_number=%5ld, %10s, ", png_ptr->row_number, filnm);
31848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(0, "row=0x%08lx, ", (unsigned long)row);
31858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug2(0, "pixdepth=%2d, bytes=%d, ", (int)row_info->pixel_depth,
31868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      (int)((row_info->pixel_depth + 7) >> 3));
31878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(0,"rowbytes=%8ld\n", row_info->rowbytes);
31888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_DEBUG */
31898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (filter)
31918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
31928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_NONE:
31938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
31948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
31958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_SUB:
31968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
31978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
31988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
31998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
32008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep rp = row + bpp;
32018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep lp = row;
32028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = bpp; i < istop; i++)
32048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
32068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
32078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
32088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
32098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
32108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_UP:
32128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
32138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
32148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 istop = row_info->rowbytes;
32158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep rp = row;
32168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep pp = prev_row;
32178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < istop; ++i)
32198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
32218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
32228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
32238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
32248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
32258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_AVG:
32278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
32288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
32298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep rp = row;
32308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep pp = prev_row;
32318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep lp = row;
32328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
32338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 istop = row_info->rowbytes - bpp;
32348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < bpp; i++)
32368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) +
32388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  ((int)(*pp++) >> 1)) & 0xff);
32398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
32408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
32418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < istop; i++)
32438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) +
32458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  ((int)(*pp++ + *lp++) >> 1)) & 0xff);
32468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
32478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
32488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
32498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
32508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_PAETH:
32528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
32538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
32548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep rp = row;
32558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep pp = prev_row;
32568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep lp = row;
32578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep cp = prev_row;
32588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
32598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 istop = row_info->rowbytes - bpp;
32608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < bpp; i++)
32628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
32648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
32658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
32668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < istop; i++)   /* use leftover rp,pp */
32688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
32698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int a, b, c, pa, pb, pc, p;
32708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               a = *lp++;
32728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               b = *pp++;
32738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               c = *cp++;
32748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               p = b - c;
32768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pc = a - c;
32778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_USE_ABS)
32798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pa = abs(p);
32808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pb = abs(pc);
32818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pc = abs(p + pc);
32828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
32838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pa = p < 0 ? -p : p;
32848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pb = pc < 0 ? -pc : pc;
32858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               pc = (p + pc) < 0 ? -(p + pc) : p + pc;
32868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
32878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               /*
32898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (pa <= pb && pa <= pc)
32908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     p = a;
32918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else if (pb <= pc)
32928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     p = b;
32938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
32948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     p = c;
32958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                */
32968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               p = (pa <= pb && pa <= pc) ? a : (pb <= pc) ? b : c;
32988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
32998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               *rp = (png_byte)(((int)(*rp) + p) & 0xff);
33008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               rp++;
33018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
33028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
33038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
33048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
33068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Ignoring bad row-filter type");
33078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         *row=0;
33088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
33098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
33108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
33118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_HAVE_MMX_READ_FILTER_ROW */
33138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_OPTIMIZED_CODE_SUPPORTED */
33148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_USE_PNGGCCRD) && !defined(PNG_USE_PNGVCRD)
33168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_OPTIMIZED_CODE_SUPPORTED)
33178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Use the unoptimized original C code.  This might be removed from a future
33188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * version of libpng if testing proves it to be worthless. */
33198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
33208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_combine_row(png_structp png_ptr, png_bytep row, int mask)
33218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
33228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1,"in png_combine_row NOT OPTIMIZED\n");
33238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (mask == 0xff)
33248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
33258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_memcpy(row, png_ptr->row_buf + 1,
33268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         PNG_ROWBYTES(png_ptr->row_info.pixel_depth, png_ptr->width));
33278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
33288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
33298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
33308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (png_ptr->row_info.pixel_depth)
33318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
33328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:
33338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
33348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
33358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
33368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_inc, s_start, s_end;
33378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
33388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
33398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
33408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
33418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
33438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
33448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
33458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 0;
33468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 7;
33478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = 1;
33488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
33498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
33508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
33518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
33528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 7;
33538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 0;
33548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = -1;
33558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
33568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
33588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
33608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
33618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
33628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
33638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  int value;
33648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x01;
33668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - shift)) & 0xff);
33678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
33688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
33698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
33718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
33728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
33738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
33748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
33758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
33768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
33778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
33788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
33808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
33818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
33828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
33838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
33848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
33858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
33868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:
33878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
33888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
33898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
33908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
33918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
33928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
33938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
33948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
33958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
33968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
33978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
33988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
33998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
34018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
34028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
34038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
34058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
34068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
34088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
34098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
34108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
34138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
34158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
34178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
34188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0x03;
34198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - shift)) & 0xff);
34208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
34218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
34228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
34248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
34258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
34268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
34278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
34288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
34298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
34308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
34318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
34328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
34338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
34348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
34358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
34378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
34388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:
34398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
34408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
34418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
34428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
34438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int m = 0x80;
34448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int shift;
34458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
34468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
34478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int value;
34488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
34508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->transformations & PNG_PACKSWAP)
34518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
34538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
34548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
34558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
34578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
34588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
34608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
34618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
34628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            shift = s_start;
34648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
34668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
34678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
34688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
34698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  value = (*sp >> shift) & 0xf;
34708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - shift)) & 0xff);
34718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(value << shift);
34728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
34738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (shift == s_end)
34758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
34768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift = s_start;
34778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp++;
34788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp++;
34798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
34808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
34818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  shift += s_inc;
34828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
34838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
34848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
34858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
34868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
34878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
34888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
34898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default:
34908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
34918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = png_ptr->row_buf + 1;
34928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row;
34938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_size_t pixel_bytes = (png_ptr->row_info.pixel_depth >> 3);
34948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
34958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 row_width = png_ptr->width;
34968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_byte m = 0x80;
34978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
34998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_width; i++)
35008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
35018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m & mask)
35028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
35038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dp, sp, pixel_bytes);
35048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
35058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sp += pixel_bytes;
35078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dp += pixel_bytes;
35088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (m == 1)
35108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m = 0x80;
35118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
35128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  m >>= 1;
35138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
35148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
35158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
35168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
35178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
35188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
35198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_READ_INTERLACING_SUPPORTED
35218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* OLD pre-1.0.9 interface:
35228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid png_do_read_interlace(png_row_infop row_info, png_bytep row, int pass,
35238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 transformations)
35248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
35258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
35268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_do_read_interlace(png_structp png_ptr)
35278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
35288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_row_infop row_info = &(png_ptr->row_info);
35298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep row = png_ptr->row_buf + 1;
35308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int pass = png_ptr->pass;
35318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 transformations = png_ptr->transformations;
35328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
35338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
35348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* offset to next interlace block */
35358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
35368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
35378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1,"in png_do_read_interlace (pngrutil.c NOT OPTIMIZED)\n");
35398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (row != NULL && row_info != NULL)
35408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
35418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_uint_32 final_width;
35428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      final_width = row_info->width * png_pass_inc[pass];
35448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      switch (row_info->pixel_depth)
35468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
35478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 1:
35488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
35498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 3);
35508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 3);
35518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
35528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
35538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
35548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_byte v;
35558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
35568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int j;
35578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
35598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
35608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
35618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sshift = (int)((row_info->width + 7) & 0x07);
35628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dshift = (int)((final_width + 7) & 0x07);
35638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 7;
35648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 0;
35658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = -1;
35668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
35678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
35688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
35698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
35708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                sshift = 7 - (int)((row_info->width + 7) & 0x07);
35718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                dshift = 7 - (int)((final_width + 7) & 0x07);
35728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_start = 0;
35738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_end = 7;
35748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s_inc = 1;
35758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
35768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
35778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
35788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
35798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x01);
35808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
35818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
35828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x7f7f >> (7 - dshift)) & 0xff);
35838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
35848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
35858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
35868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
35878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
35888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
35898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
35908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
35918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
35928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
35938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
35948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
35958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
35968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
35978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
35988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
35998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
36018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
36028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 2:
36038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
36048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_uint_32)((row_info->width - 1) >> 2);
36058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_uint_32)((final_width - 1) >> 2);
36068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
36078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
36088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
36098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
36108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
36128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
36138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)(((row_info->width + 3) & 0x03) << 1);
36158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)(((final_width + 3) & 0x03) << 1);
36168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 6;
36178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
36188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -2;
36198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
36218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
36228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)((3 - ((row_info->width + 3) & 0x03)) << 1);
36248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)((3 - ((final_width + 3) & 0x03)) << 1);
36258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
36268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 6;
36278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 2;
36288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
36318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v;
36338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
36348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               v = (png_byte)((*sp >> sshift) & 0x03);
36368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
36378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
36388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0x3f3f >> (6 - dshift)) & 0xff);
36398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
36408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
36418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
36428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
36438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
36448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
36458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
36468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
36478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
36488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
36498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
36508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
36518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
36528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
36538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
36548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
36558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
36578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
36588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         case 4:
36598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
36608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_size_t)((row_info->width - 1) >> 1);
36618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)((final_width - 1) >> 1);
36628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int sshift, dshift;
36638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int s_start, s_end, s_inc;
36648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
36658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
36668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACKSWAP_SUPPORTED)
36688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (transformations & PNG_PACKSWAP)
36698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)(((row_info->width + 1) & 0x01) << 2);
36718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)(((final_width + 1) & 0x01) << 2);
36728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 4;
36738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 0;
36748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = -4;
36758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            else
36778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
36788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sshift = (int)((1 - ((row_info->width + 1) & 0x01)) << 2);
36808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               dshift = (int)((1 - ((final_width + 1) & 0x01)) << 2);
36818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_start = 0;
36828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_end = 4;
36838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               s_inc = 4;
36848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
36858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
36878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
36888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v = (png_byte)((*sp >> sshift) & 0xf);
36898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
36908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
36918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
36928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
36938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp &= (png_byte)((0xf0f >> (4 - dshift)) & 0xff);
36948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  *dp |= (png_byte)(v << dshift);
36958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  if (dshift == s_end)
36968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  {
36978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift = s_start;
36988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dp--;
36998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  }
37008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  else
37018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     dshift += s_inc;
37028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
37038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (sshift == s_end)
37048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
37058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift = s_start;
37068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sp--;
37078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
37088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
37098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  sshift += s_inc;
37108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
37118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
37128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
37138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         default:
37148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
37158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_size_t pixel_bytes = (row_info->pixel_depth >> 3);
37168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep sp = row + (png_size_t)(row_info->width - 1) * pixel_bytes;
37178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_bytep dp = row + (png_size_t)(final_width - 1) * pixel_bytes;
37188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int jstop = png_pass_inc[pass];
37208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_uint_32 i;
37218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for (i = 0; i < row_info->width; i++)
37238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
37248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte v[8];
37258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               int j;
37268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_memcpy(v, sp, pixel_bytes);
37288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               for (j = 0; j < jstop; j++)
37298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               {
37308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_memcpy(dp, v, pixel_bytes);
37318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  dp -= pixel_bytes;
37328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               }
37338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               sp -= pixel_bytes;
37348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
37358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
37368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
37378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
37388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      row_info->width = final_width;
37398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth,final_width);
37408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
37418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
37428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   transformations = transformations; /* silence compiler warning */
37438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
37448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
37458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_INTERLACING_SUPPORTED */
37468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
37488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_filter_row(png_structp png_ptr, png_row_infop row_info, png_bytep row,
37498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_bytep prev_row, int filter)
37508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
37518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_read_filter_row (NOT OPTIMIZED)\n");
37528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug2(2,"row = %lu, filter = %d\n", png_ptr->row_number, filter);
37538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   switch (filter)
37548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
37558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_NONE:
37568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
37578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_SUB:
37588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
37598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
37608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
37618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
37628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row + bpp;
37638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
37648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = bpp; i < istop; i++)
37668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
37678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*lp++)) & 0xff);
37688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
37698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
37708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
37718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
37728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_UP:
37738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
37748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
37758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes;
37768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
37778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
37788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < istop; i++)
37808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
37818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
37828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
37838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
37848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
37858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
37868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_AVG:
37878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
37888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
37898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
37908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
37918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
37928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
37938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop = row_info->rowbytes - bpp;
37948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
37958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < bpp; i++)
37968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
37978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
37988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               ((int)(*pp++) / 2 )) & 0xff);
37998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
38008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
38018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < istop; i++)
38038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
38048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) +
38058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               (int)(*pp++ + *lp++) / 2 ) & 0xff);
38068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
38078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
38088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
38098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
38108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      case PNG_FILTER_VALUE_PAETH:
38118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
38128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 i;
38138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep rp = row;
38148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep pp = prev_row;
38158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep lp = row;
38168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_bytep cp = prev_row;
38178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
38188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_uint_32 istop=row_info->rowbytes - bpp;
38198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < bpp; i++)
38218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
38228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + (int)(*pp++)) & 0xff);
38238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
38248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
38258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         for (i = 0; i < istop; i++)   /* use leftover rp,pp */
38278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
38288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            int a, b, c, pa, pb, pc, p;
38298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            a = *lp++;
38318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            b = *pp++;
38328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            c = *cp++;
38338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = b - c;
38358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = a - c;
38368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_ABS
38388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pa = abs(p);
38398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pb = abs(pc);
38408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = abs(p + pc);
38418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
38428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pa = p < 0 ? -p : p;
38438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pb = pc < 0 ? -pc : pc;
38448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            pc = (p + pc) < 0 ? -(p + pc) : p + pc;
38458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
38468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /*
38488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (pa <= pb && pa <= pc)
38498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = a;
38508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else if (pb <= pc)
38518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = b;
38528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               else
38538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  p = c;
38548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             */
38558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p = (pa <= pb && pa <=pc) ? a : (pb <= pc) ? b : c;
38578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *rp = (png_byte)(((int)(*rp) + p) & 0xff);
38598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            rp++;
38608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
38618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
38628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
38638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      default:
38648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_warning(png_ptr, "Ignoring bad adaptive filter type");
38658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         *row=0;
38668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         break;
38678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
38688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
38698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !PNG_OPTIMIZED_CODE_SUPPORTED */
38708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* !PNG_USE_PNGGCCRD && !PNG_USE_PNGVCRD */
38718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
38738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_finish_row(png_structp png_ptr)
38748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
38758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
38768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
38778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* start of interlace block */
38798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
38808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* offset to next interlace block */
38828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
38838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* start of interlace block in the y direction */
38858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
38868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* offset to next interlace block in the y direction */
38888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
38898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
38908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_read_finish_row\n");
38928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->row_number++;
38938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->row_number < png_ptr->num_rows)
38948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return;
38958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
38968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->interlaced)
38978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
38988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->row_number = 0;
38998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_memset_check(png_ptr, png_ptr->prev_row, 0,
39008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->rowbytes + 1);
39018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      do
39028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
39038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->pass++;
39048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->pass >= 7)
39058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
39068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->iwidth = (png_ptr->width +
39078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_inc[png_ptr->pass] - 1 -
39088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_start[png_ptr->pass]) /
39098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_inc[png_ptr->pass];
39108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->irowbytes = PNG_ROWBYTES(png_ptr->pixel_depth,
39128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->iwidth) + 1;
39138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->transformations & PNG_INTERLACE))
39158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
39168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->num_rows = (png_ptr->height +
39178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_yinc[png_ptr->pass] - 1 -
39188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_ystart[png_ptr->pass]) /
39198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_pass_yinc[png_ptr->pass];
39208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(png_ptr->num_rows))
39218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               continue;
39228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
39238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else  /* if (png_ptr->transformations & PNG_INTERLACE) */
39248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
39258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      } while (png_ptr->iwidth == 0);
39268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->pass < 7)
39288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         return;
39298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
39308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
39328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
39338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
39348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      PNG_CONST PNG_IDAT;
39358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
39368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      char extra;
39378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      int ret;
39388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.next_out = (Byte *)&extra;
39408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_out = (uInt)1;
39418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      for(;;)
39428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
39438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->zstream.avail_in))
39448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
39458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            while (!png_ptr->idat_size)
39468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            {
39478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_byte chunk_length[4];
39488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_crc_finish(png_ptr, 0);
39508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_read_data(png_ptr, chunk_length, 4);
39528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->idat_size = png_get_uint_31(png_ptr, chunk_length);
39538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_reset_crc(png_ptr);
39548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_crc_read(png_ptr, png_ptr->chunk_name, 4);
39558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               if (png_memcmp(png_ptr->chunk_name, (png_bytep)png_IDAT, 4))
39568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                  png_error(png_ptr, "Not enough image data");
39578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
39598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->zstream.avail_in = (uInt)png_ptr->zbuf_size;
39608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->zstream.next_in = png_ptr->zbuf;
39618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (png_ptr->zbuf_size > png_ptr->idat_size)
39628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->zstream.avail_in = (uInt)png_ptr->idat_size;
39638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_crc_read(png_ptr, png_ptr->zbuf, png_ptr->zstream.avail_in);
39648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->idat_size -= png_ptr->zstream.avail_in;
39658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
39668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
39678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret == Z_STREAM_END)
39688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
39698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (!(png_ptr->zstream.avail_out) || png_ptr->zstream.avail_in ||
39708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_ptr->idat_size)
39718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               png_warning(png_ptr, "Extra compressed data");
39728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
39738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
39748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
39758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
39768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (ret != Z_OK)
39778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_error(png_ptr, png_ptr->zstream.msg ? png_ptr->zstream.msg :
39788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                      "Decompression Error");
39798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (!(png_ptr->zstream.avail_out))
39818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
39828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_warning(png_ptr, "Extra compressed data.");
39838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->mode |= PNG_AFTER_IDAT;
39848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
39858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
39868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
39878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
39898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->zstream.avail_out = 0;
39908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
39918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->idat_size || png_ptr->zstream.avail_in)
39938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_warning(png_ptr, "Extra compression data");
39948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   inflateReset(&png_ptr->zstream);
39968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
39978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->mode |= PNG_AFTER_IDAT;
39988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
39998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid /* PRIVATE */
40018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectpng_read_start_row(png_structp png_ptr)
40028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
40038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_USE_LOCAL_ARRAYS
40048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* arrays to facilitate easy interlacing - use pass (0 - 6) as index */
40058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* start of interlace block */
40078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_start[7] = {0, 4, 0, 2, 0, 1, 0};
40088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* offset to next interlace block */
40108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
40118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* start of interlace block in the y direction */
40138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_ystart[7] = {0, 0, 4, 0, 2, 0, 1};
40148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* offset to next interlace block in the y direction */
40168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
40178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
40188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   int max_pixel_depth;
40208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_uint_32 row_bytes;
40218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug(1, "in png_read_start_row\n");
40238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->zstream.avail_in = 0;
40248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_init_read_transformations(png_ptr);
40258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->interlaced)
40268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
40278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (!(png_ptr->transformations & PNG_INTERLACE))
40288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->num_rows = (png_ptr->height + png_pass_yinc[0] - 1 -
40298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_pass_ystart[0]) / png_pass_yinc[0];
40308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
40318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->num_rows = png_ptr->height;
40328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->iwidth = (png_ptr->width +
40348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_inc[png_ptr->pass] - 1 -
40358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_start[png_ptr->pass]) /
40368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_pass_inc[png_ptr->pass];
40378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         row_bytes = PNG_ROWBYTES(png_ptr->pixel_depth,png_ptr->iwidth) + 1;
40398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->irowbytes = (png_size_t)row_bytes;
40418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if((png_uint_32)png_ptr->irowbytes != row_bytes)
40428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            png_error(png_ptr, "Rowbytes overflow in png_read_start_row");
40438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
40448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   else
40458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
40468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->num_rows = png_ptr->height;
40478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->iwidth = png_ptr->width;
40488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->irowbytes = png_ptr->rowbytes + 1;
40498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
40508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   max_pixel_depth = png_ptr->pixel_depth;
40518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_PACK_SUPPORTED)
40538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
40548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      max_pixel_depth = 8;
40558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
40568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
40588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & PNG_EXPAND)
40598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
40608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
40618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
40628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
40638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
40648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
40658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 24;
40668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
40678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
40688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
40698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth < 8)
40708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 8;
40718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
40728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth *= 2;
40738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
40748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
40758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
40768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (png_ptr->num_trans)
40778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         {
40788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth *= 4;
40798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth /= 3;
40808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         }
40818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
40828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
40838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
40848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
40858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_FILLER_SUPPORTED)
40868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & (PNG_FILLER))
40878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
40888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
40898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         max_pixel_depth = 32;
40908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_GRAY)
40918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
40928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 8)
40938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 16;
40948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
40958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
40968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
40978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
40988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
40998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 32)
41008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
41018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
41028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
41038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
41048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
41058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
41088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (png_ptr->transformations & PNG_GRAY_TO_RGB)
41098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   {
41108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (
41118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_EXPAND_SUPPORTED)
41128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
41138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_FILLER_SUPPORTED)
41158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        (png_ptr->transformations & (PNG_FILLER)) ||
41168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
41188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
41198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 16)
41208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 32;
41218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
41228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
41238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
41248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else
41258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      {
41268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         if (max_pixel_depth <= 8)
41278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           {
41288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
41298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               max_pixel_depth = 32;
41308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             else
41318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project               max_pixel_depth = 24;
41328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           }
41338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB_ALPHA)
41348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 64;
41358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         else
41368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            max_pixel_depth = 48;
41378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      }
41388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   }
41398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_READ_USER_TRANSFORM_SUPPORTED) && \
41428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectdefined(PNG_USER_TRANSFORM_PTR_SUPPORTED)
41438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if(png_ptr->transformations & PNG_USER_TRANSFORM)
41448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     {
41458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       int user_pixel_depth=png_ptr->user_transform_depth*
41468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         png_ptr->user_transform_channels;
41478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project       if(user_pixel_depth > max_pixel_depth)
41488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         max_pixel_depth=user_pixel_depth;
41498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     }
41508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* align the width on the next larger 8 pixels.  Mainly used
41538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      for interlacing */
41548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   row_bytes = ((png_ptr->width + 7) & ~((png_uint_32)7));
41558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   /* calculate the maximum bytes needed, adding a byte and a pixel
41568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      for safety's sake */
41578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   row_bytes = PNG_ROWBYTES(max_pixel_depth,row_bytes) +
41588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      1 + ((max_pixel_depth + 7) >> 3);
41598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
41608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if (row_bytes > (png_uint_32)65536L)
41618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
41628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes+64);
41648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->row_buf = png_ptr->big_row_buf+32;
41658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(PNG_DEBUG) && defined(PNG_USE_PNGGCCRD) && defined(PNG_1_0_X)
41668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->row_buf_size = row_bytes;
41678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef PNG_MAX_MALLOC_64K
41708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
41718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "This image requires a row greater than 64KB");
41728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
41738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
41748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
41758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
41768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      png_ptr->rowbytes + 1));
41778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_memset_check(png_ptr, png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
41798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "width = %lu,\n", png_ptr->width);
41818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "height = %lu,\n", png_ptr->height);
41828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "iwidth = %lu,\n", png_ptr->iwidth);
41838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "num_rows = %lu\n", png_ptr->num_rows);
41848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "rowbytes = %lu,\n", png_ptr->rowbytes);
41858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_debug1(3, "irowbytes = %lu,\n", png_ptr->irowbytes);
41868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
41878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   png_ptr->flags |= PNG_FLAG_ROW_INIT;
41888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
41898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif /* PNG_READ_SUPPORTED */
4190