src/3rdparty/libpng/pngrutil.c
changeset 30 5dc02b23752f
parent 0 1918ee327afb
--- a/src/3rdparty/libpng/pngrutil.c	Wed Jun 23 19:07:03 2010 +0300
+++ b/src/3rdparty/libpng/pngrutil.c	Tue Jul 06 15:10:48 2010 +0300
@@ -1,8 +1,8 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.2.38 [July 16, 2009]
- * Copyright (c) 1998-2009 Glenn Randers-Pehrson
+ * Last changed in libpng 1.4.0 [January 3, 2010]
+ * Copyright (c) 1998-2010 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
@@ -14,57 +14,21 @@
  * libpng itself during the course of reading an image.
  */
 
-#define PNG_INTERNAL
+#define PNG_NO_PEDANTIC_WARNINGS
 #include "png.h"
-#if defined(PNG_READ_SUPPORTED)
-
-#if defined(_WIN32_WCE) && (_WIN32_WCE<0x500)
-#  define WIN32_WCE_OLD
-#endif
-
-#ifdef PNG_FLOATING_POINT_SUPPORTED
-#  if defined(WIN32_WCE_OLD)
-/* The strtod() function is not supported on WindowsCE */
-__inline double png_strtod(png_structp png_ptr, PNG_CONST char *nptr, char **endptr)
-{
-   double result = 0;
-   int len;
-   wchar_t *str, *end;
-
-   len = MultiByteToWideChar(CP_ACP, 0, nptr, -1, NULL, 0);
-   str = (wchar_t *)png_malloc(png_ptr, len * png_sizeof(wchar_t));
-   if ( NULL != str )
-   {
-      MultiByteToWideChar(CP_ACP, 0, nptr, -1, str, len);
-      result = wcstod(str, &end);
-      len = WideCharToMultiByte(CP_ACP, 0, end, -1, NULL, 0, NULL, NULL);
-      *endptr = (char *)nptr + (png_strlen(nptr) - len + 1);
-      png_free(png_ptr, str);
-   }
-   return result;
-}
-#  else
+#ifdef PNG_READ_SUPPORTED
+#include "pngpriv.h"
+
 #    define png_strtod(p,a,b) strtod(a,b)
-#  endif
-#endif
-
 png_uint_32 PNGAPI
 png_get_uint_31(png_structp png_ptr, png_bytep buf)
 {
-#ifdef PNG_READ_BIG_ENDIAN_SUPPORTED
    png_uint_32 i = png_get_uint_32(buf);
-#else
-   /* Avoid an extra function call by inlining the result. */
-   png_uint_32 i = ((png_uint_32)(*buf) << 24) +
-      ((png_uint_32)(*(buf + 1)) << 16) +
-      ((png_uint_32)(*(buf + 2)) << 8) +
-      (png_uint_32)(*(buf + 3));
-#endif
    if (i > PNG_UINT_31_MAX)
-     png_error(png_ptr, "PNG unsigned integer out of range.");
+     png_error(png_ptr, "PNG unsigned integer out of range");
    return (i);
 }
-#ifndef PNG_READ_BIG_ENDIAN_SUPPORTED
+#ifndef PNG_USE_READ_MACROS
 /* Grab an unsigned 32-bit integer from a buffer in big-endian format. */
 png_uint_32 PNGAPI
 png_get_uint_32(png_bytep buf)
@@ -101,7 +65,7 @@
 
    return (i);
 }
-#endif /* PNG_READ_BIG_ENDIAN_SUPPORTED */
+#endif /* PNG_USE_READ_MACROS */
 
 /* Read the chunk header (length + type name).
  * Put the type name into png_ptr->chunk_name, and return the length.
@@ -112,6 +76,13 @@
    png_byte buf[8];
    png_uint_32 length;
 
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that the chunk header is being read.
+    * PNG_IO_CHUNK_HDR requires a single I/O call.
+    */
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_HDR;
+#endif
+
    /* Read the length and the chunk name */
    png_read_data(png_ptr, buf, 8);
    length = png_get_uint_31(png_ptr, buf);
@@ -129,6 +100,13 @@
    /* Check to see if chunk name is valid */
    png_check_chunk_name(png_ptr, png_ptr->chunk_name);
 
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that chunk data will (possibly) be read.
+    * PNG_IO_CHUNK_DATA does NOT require a specific number of I/O calls.
+    */
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_DATA;
+#endif
+
    return length;
 }
 
@@ -173,7 +151,8 @@
       }
       else
       {
-         png_chunk_error(png_ptr, "CRC error");
+         png_chunk_benign_error(png_ptr, "CRC error");
+         return (0);
       }
       return (1);
    }
@@ -203,6 +182,12 @@
          need_crc = 0;
    }
 
+#ifdef PNG_IO_STATE_SUPPORTED
+   /* Inform the I/O callback that the chunk CRC is being read */
+   /* PNG_IO_CHUNK_CRC requires the I/O to be done at once */
+   png_ptr->io_state = PNG_IO_READING | PNG_IO_CHUNK_CRC;
+#endif
+
    png_read_data(png_ptr, crc_bytes, 4);
 
    if (need_crc)
@@ -228,7 +213,7 @@
                               png_size_t chunklength,
                               png_size_t prefix_size, png_size_t *newlength)
 {
-   static PNG_CONST char msg[] = "Error decoding compressed text";
+   static PNG_CONST char msg[] = "Error decoding compressed chunk";
    png_charp text;
    png_size_t text_size;
 
@@ -290,7 +275,7 @@
                   png_free(png_ptr, png_ptr->chunkdata);
                   png_ptr->chunkdata = NULL;
                   png_error(png_ptr,
-                    "Not enough memory to decompress chunk.");
+                    "Not enough memory to decompress chunk");
                }
                png_memcpy(text + prefix_size, png_ptr->zbuf,
                     text_size - prefix_size);
@@ -302,16 +287,30 @@
                png_charp tmp;
 
                tmp = text;
-               text = (png_charp)png_malloc_warn(png_ptr,
-                  (png_uint_32)(text_size +
-                  png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+               if ((png_ptr->user_chunk_cache_max != 0) &&
+                  (--png_ptr->user_chunk_cache_max == 0))
+               {
+                  png_warning(png_ptr, "No space in chunk cache");
+                  text = NULL;
+               }
+
+               else
+               {
+#endif
+                  text = (png_charp)png_malloc_warn(png_ptr,
+                     (png_size_t)(text_size +
+                      png_ptr->zbuf_size - png_ptr->zstream.avail_out + 1));
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+               }
+#endif
                if (text == NULL)
                {
                   png_free(png_ptr, tmp);
                   png_free(png_ptr, png_ptr->chunkdata);
                   png_ptr->chunkdata = NULL;
                   png_error(png_ptr,
-                    "Not enough memory to decompress chunk..");
+                    "Not enough memory to decompress chunk");
                }
                png_memcpy(text, tmp, text_size);
                png_free(png_ptr, tmp);
@@ -331,7 +330,7 @@
       }
       if (ret != Z_STREAM_END)
       {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+#ifdef PNG_STDIO_SUPPORTED
          char umsg[52];
 
          if (ret == Z_BUF_ERROR)
@@ -362,7 +361,7 @@
               {
                 png_free(png_ptr, png_ptr->chunkdata);
                 png_ptr->chunkdata = NULL;
-                png_error(png_ptr, "Not enough memory for text.");
+                png_error(png_ptr, "Not enough memory for text");
               }
             png_memcpy(text, png_ptr->chunkdata, prefix_size);
          }
@@ -378,7 +377,7 @@
    }
    else /* if (comp_type != PNG_COMPRESSION_TYPE_BASE) */
    {
-#if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE)
+#ifdef PNG_STDIO_SUPPORTED
       char umsg[50];
 
       png_snprintf(umsg, 50, "Unknown zTXt compression type %d", comp_type);
@@ -430,7 +429,7 @@
    png_ptr->bit_depth = (png_byte)bit_depth;
    png_ptr->interlaced = (png_byte)interlace_type;
    png_ptr->color_type = (png_byte)color_type;
-#if defined(PNG_MNG_FEATURES_SUPPORTED)
+#ifdef PNG_MNG_FEATURES_SUPPORTED
    png_ptr->filter_type = (png_byte)filter_type;
 #endif
    png_ptr->compression_type = (png_byte)compression_type;
@@ -473,7 +472,7 @@
 {
    png_color palette[PNG_MAX_PALETTE_LENGTH];
    int num, i;
-#ifndef PNG_NO_POINTER_INDEXING
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
    png_colorp pal_ptr;
 #endif
 
@@ -501,7 +500,7 @@
       png_crc_finish(png_ptr, length);
       return;
    }
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    if (png_ptr->color_type != PNG_COLOR_TYPE_PALETTE)
    {
       png_crc_finish(png_ptr, length);
@@ -526,7 +525,7 @@
 
    num = (int)length / 3;
 
-#ifndef PNG_NO_POINTER_INDEXING
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
    for (i = 0, pal_ptr = palette; i < num; i++, pal_ptr++)
    {
       png_byte buf[3];
@@ -554,13 +553,13 @@
     * have an RGB image, the PLTE can be considered ancillary, so
     * we will act as though it is.
     */
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
 #endif
    {
       png_crc_finish(png_ptr, 0);
    }
-#if !defined(PNG_READ_OPT_PLTE_SUPPORTED)
+#ifndef PNG_READ_OPT_PLTE_SUPPORTED
    else if (png_crc_error(png_ptr))  /* Only if we have a CRC error */
    {
       /* If we don't want to use the data from an ancillary chunk,
@@ -571,7 +570,7 @@
       {
          if (png_ptr->flags & PNG_FLAG_CRC_ANCILLARY_NOWARN)
          {
-            png_chunk_error(png_ptr, "CRC error");
+            png_chunk_benign_error(png_ptr, "CRC error");
          }
          else
          {
@@ -589,7 +588,7 @@
 
    png_set_PLTE(png_ptr, info_ptr, palette, num);
 
-#if defined(PNG_READ_tRNS_SUPPORTED)
+#ifdef PNG_READ_tRNS_SUPPORTED
    if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
       if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_tRNS))
@@ -631,7 +630,7 @@
    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
 }
 
-#if defined(PNG_READ_gAMA_SUPPORTED)
+#ifdef PNG_READ_gAMA_SUPPORTED
 void /* PRIVATE */
 png_handle_gAMA(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -656,7 +655,7 @@
       png_warning(png_ptr, "Out of place gAMA chunk");
 
    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_gAMA)
-#if defined(PNG_READ_sRGB_SUPPORTED)
+#ifdef PNG_READ_sRGB_SUPPORTED
       && !(info_ptr->valid & PNG_INFO_sRGB)
 #endif
       )
@@ -686,13 +685,13 @@
          return;
       }
 
-#if defined(PNG_READ_sRGB_SUPPORTED)
+#ifdef PNG_READ_sRGB_SUPPORTED
    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_sRGB))
       if (PNG_OUT_OF_RANGE(igamma, 45500L, 500))
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_CONSOLE_IO_SUPPORTED
          fprintf(stderr, "gamma = (%d/100000)", (int)igamma);
 #endif
          return;
@@ -712,7 +711,7 @@
 }
 #endif
 
-#if defined(PNG_READ_sBIT_SUPPORTED)
+#ifdef PNG_READ_sBIT_SUPPORTED
 void /* PRIVATE */
 png_handle_sBIT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -778,7 +777,7 @@
 }
 #endif
 
-#if defined(PNG_READ_cHRM_SUPPORTED)
+#ifdef PNG_READ_cHRM_SUPPORTED
 void /* PRIVATE */
 png_handle_cHRM(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -806,7 +805,7 @@
       png_warning(png_ptr, "Missing PLTE before cHRM");
 
    if (info_ptr != NULL && (info_ptr->valid & PNG_INFO_cHRM)
-#if defined(PNG_READ_sRGB_SUPPORTED)
+#ifdef PNG_READ_sRGB_SUPPORTED
       && !(info_ptr->valid & PNG_INFO_sRGB)
 #endif
       )
@@ -858,7 +857,7 @@
    blue_y  = (float)int_y_blue  / (float)100000.0;
 #endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED)
+#ifdef PNG_READ_sRGB_SUPPORTED
    if ((info_ptr != NULL) && (info_ptr->valid & PNG_INFO_sRGB))
       {
       if (PNG_OUT_OF_RANGE(int_x_white, 31270,  1000) ||
@@ -872,7 +871,7 @@
          {
             png_warning(png_ptr,
               "Ignoring incorrect cHRM value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_CONSOLE_IO_SUPPORTED
 #ifdef PNG_FLOATING_POINT_SUPPORTED
             fprintf(stderr, "wx=%f, wy=%f, rx=%f, ry=%f\n",
                white_x, white_y, red_x, red_y);
@@ -884,7 +883,7 @@
             fprintf(stderr, "gx=%ld, gy=%ld, bx=%ld, by=%ld\n",
                int_x_green, int_y_green, int_x_blue, int_y_blue);
 #endif
-#endif /* PNG_NO_CONSOLE_IO */
+#endif /* PNG_CONSOLE_IO_SUPPORTED */
          }
          return;
       }
@@ -902,7 +901,7 @@
 }
 #endif
 
-#if defined(PNG_READ_sRGB_SUPPORTED)
+#ifdef PNG_READ_sRGB_SUPPORTED
 void /* PRIVATE */
 png_handle_sRGB(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -964,7 +963,7 @@
       {
          png_warning(png_ptr,
            "Ignoring incorrect gAMA value when sRGB is also present");
-#ifndef PNG_NO_CONSOLE_IO
+#ifdef PNG_CONSOLE_IO_SUPPORTED
 #  ifdef PNG_FIXED_POINT_SUPPORTED
          fprintf(stderr, "incorrect gamma=(%d/100000)\n",
             (int)png_ptr->int_gamma);
@@ -1000,7 +999,7 @@
 }
 #endif /* PNG_READ_sRGB_SUPPORTED */
 
-#if defined(PNG_READ_iCCP_SUPPORTED)
+#ifdef PNG_READ_iCCP_SUPPORTED
 void /* PRIVATE */
 png_handle_iCCP(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 /* Note: this does not properly handle chunks that are > 64K under DOS */
@@ -1109,7 +1108,7 @@
    {
       png_free(png_ptr, png_ptr->chunkdata);
       png_ptr->chunkdata = NULL;
-      png_warning(png_ptr, "Ignoring truncated iCCP profile.");
+      png_warning(png_ptr, "Ignoring truncated iCCP profile");
       return;
    }
 
@@ -1120,14 +1119,14 @@
 }
 #endif /* PNG_READ_iCCP_SUPPORTED */
 
-#if defined(PNG_READ_sPLT_SUPPORTED)
+#ifdef PNG_READ_sPLT_SUPPORTED
 void /* PRIVATE */
 png_handle_sPLT(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 /* Note: this does not properly handle chunks that are > 64K under DOS */
 {
    png_bytep entry_start;
    png_sPLT_t new_palette;
-#ifdef PNG_NO_POINTER_INDEXING
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
    png_sPLT_entryp pp;
 #endif
    int data_length, entry_size, i;
@@ -1136,6 +1135,23 @@
 
    png_debug(1, "in png_handle_sPLT");
 
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for sPLT");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Missing IHDR before sPLT");
@@ -1210,10 +1226,10 @@
        return;
    }
 
-#ifndef PNG_NO_POINTER_INDEXING
+#ifdef PNG_POINTER_INDEXING_SUPPORTED
    for (i = 0; i < new_palette.nentries; i++)
    {
-      png_sPLT_entryp pp = new_palette.entries + i;
+      pp = new_palette.entries + i;
 
       if (new_palette.depth == 8)
       {
@@ -1265,7 +1281,7 @@
 }
 #endif /* PNG_READ_sPLT_SUPPORTED */
 
-#if defined(PNG_READ_tRNS_SUPPORTED)
+#ifdef PNG_READ_tRNS_SUPPORTED
 void /* PRIVATE */
 png_handle_tRNS(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1301,7 +1317,7 @@
 
       png_crc_read(png_ptr, buf, 2);
       png_ptr->num_trans = 1;
-      png_ptr->trans_values.gray = png_get_uint_16(buf);
+      png_ptr->trans_color.gray = png_get_uint_16(buf);
    }
    else if (png_ptr->color_type == PNG_COLOR_TYPE_RGB)
    {
@@ -1315,9 +1331,9 @@
       }
       png_crc_read(png_ptr, buf, (png_size_t)length);
       png_ptr->num_trans = 1;
-      png_ptr->trans_values.red = png_get_uint_16(buf);
-      png_ptr->trans_values.green = png_get_uint_16(buf + 2);
-      png_ptr->trans_values.blue = png_get_uint_16(buf + 4);
+      png_ptr->trans_color.red = png_get_uint_16(buf);
+      png_ptr->trans_color.green = png_get_uint_16(buf + 2);
+      png_ptr->trans_color.blue = png_get_uint_16(buf + 4);
    }
    else if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
    {
@@ -1356,11 +1372,11 @@
    }
 
    png_set_tRNS(png_ptr, info_ptr, readbuf, png_ptr->num_trans,
-      &(png_ptr->trans_values));
+      &(png_ptr->trans_color));
 }
 #endif
 
-#if defined(PNG_READ_bKGD_SUPPORTED)
+#ifdef PNG_READ_bKGD_SUPPORTED
 void /* PRIVATE */
 png_handle_bKGD(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1449,7 +1465,7 @@
 }
 #endif
 
-#if defined(PNG_READ_hIST_SUPPORTED)
+#ifdef PNG_READ_hIST_SUPPORTED
 void /* PRIVATE */
 png_handle_hIST(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1503,7 +1519,7 @@
 }
 #endif
 
-#if defined(PNG_READ_pHYs_SUPPORTED)
+#ifdef PNG_READ_pHYs_SUPPORTED
 void /* PRIVATE */
 png_handle_pHYs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1546,7 +1562,7 @@
 }
 #endif
 
-#if defined(PNG_READ_oFFs_SUPPORTED)
+#ifdef PNG_READ_oFFs_SUPPORTED
 void /* PRIVATE */
 png_handle_oFFs(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1589,7 +1605,7 @@
 }
 #endif
 
-#if defined(PNG_READ_pCAL_SUPPORTED)
+#ifdef PNG_READ_pCAL_SUPPORTED
 /* Read the pCAL chunk (described in the PNG Extensions document) */
 void /* PRIVATE */
 png_handle_pCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -1624,7 +1640,7 @@
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
      {
-       png_warning(png_ptr, "No memory for pCAL purpose.");
+       png_warning(png_ptr, "No memory for pCAL purpose");
        return;
      }
    slength = (png_size_t)length;
@@ -1685,12 +1701,12 @@
 
    png_debug(3, "Allocating pCAL parameters array");
    params = (png_charpp)png_malloc_warn(png_ptr,
-      (png_uint_32)(nparams * png_sizeof(png_charp))) ;
+      (png_size_t)(nparams * png_sizeof(png_charp)));
    if (params == NULL)
      {
        png_free(png_ptr, png_ptr->chunkdata);
        png_ptr->chunkdata = NULL;
-       png_warning(png_ptr, "No memory for pCAL params.");
+       png_warning(png_ptr, "No memory for pCAL params");
        return;
      }
 
@@ -1723,7 +1739,7 @@
 }
 #endif
 
-#if defined(PNG_READ_sCAL_SUPPORTED)
+#ifdef PNG_READ_sCAL_SUPPORTED
 /* Read the sCAL chunk */
 void /* PRIVATE */
 png_handle_sCAL(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -1793,7 +1809,7 @@
       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
       return;
    }
-   png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
+   png_memcpy(swidth, ep, png_strlen(ep));
 #endif
 #endif
 
@@ -1828,7 +1844,7 @@
       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
       return;
    }
-   png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
+   png_memcpy(sheight, ep, png_strlen(ep));
 #endif
 #endif
 
@@ -1866,7 +1882,7 @@
 }
 #endif
 
-#if defined(PNG_READ_tIME_SUPPORTED)
+#ifdef PNG_READ_tIME_SUPPORTED
 void /* PRIVATE */
 png_handle_tIME(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
 {
@@ -1909,7 +1925,7 @@
 }
 #endif
 
-#if defined(PNG_READ_tEXt_SUPPORTED)
+#ifdef PNG_READ_tEXt_SUPPORTED
 /* Note: this does not properly handle chunks that are > 64K under DOS */
 void /* PRIVATE */
 png_handle_tEXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -1923,6 +1939,22 @@
 
    png_debug(1, "in png_handle_tEXt");
 
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for tEXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Missing IHDR before tEXt");
@@ -1944,7 +1976,7 @@
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
    {
-     png_warning(png_ptr, "No memory to process text chunk.");
+     png_warning(png_ptr, "No memory to process text chunk");
      return;
    }
    slength = (png_size_t)length;
@@ -1968,10 +2000,10 @@
       text++;
 
    text_ptr = (png_textp)png_malloc_warn(png_ptr,
-      (png_uint_32)png_sizeof(png_text));
+      png_sizeof(png_text));
    if (text_ptr == NULL)
    {
-     png_warning(png_ptr, "Not enough memory to process text chunk.");
+     png_warning(png_ptr, "Not enough memory to process text chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
@@ -1992,11 +2024,11 @@
    png_ptr->chunkdata = NULL;
    png_free(png_ptr, text_ptr);
    if (ret)
-     png_warning(png_ptr, "Insufficient memory to process text chunk.");
+     png_warning(png_ptr, "Insufficient memory to process text chunk");
 }
 #endif
 
-#if defined(PNG_READ_zTXt_SUPPORTED)
+#ifdef PNG_READ_zTXt_SUPPORTED
 /* Note: this does not correctly handle chunks that are > 64K under DOS */
 void /* PRIVATE */
 png_handle_zTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -2009,6 +2041,22 @@
 
    png_debug(1, "in png_handle_zTXt");
 
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for zTXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Missing IHDR before zTXt");
@@ -2031,7 +2079,7 @@
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
    {
-     png_warning(png_ptr, "Out of memory processing zTXt chunk.");
+     png_warning(png_ptr, "Out of memory processing zTXt chunk");
      return;
    }
    slength = (png_size_t)length;
@@ -2072,10 +2120,10 @@
      (png_size_t)length, prefix_len, &data_len);
 
    text_ptr = (png_textp)png_malloc_warn(png_ptr,
-      (png_uint_32)png_sizeof(png_text));
+      png_sizeof(png_text));
    if (text_ptr == NULL)
    {
-     png_warning(png_ptr, "Not enough memory to process zTXt chunk.");
+     png_warning(png_ptr, "Not enough memory to process zTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
@@ -2096,11 +2144,11 @@
    png_free(png_ptr, png_ptr->chunkdata);
    png_ptr->chunkdata = NULL;
    if (ret)
-     png_error(png_ptr, "Insufficient memory to store zTXt chunk.");
+     png_error(png_ptr, "Insufficient memory to store zTXt chunk");
 }
 #endif
 
-#if defined(PNG_READ_iTXt_SUPPORTED)
+#ifdef PNG_READ_iTXt_SUPPORTED
 /* Note: this does not correctly handle chunks that are > 64K under DOS */
 void /* PRIVATE */
 png_handle_iTXt(png_structp png_ptr, png_infop info_ptr, png_uint_32 length)
@@ -2114,6 +2162,22 @@
 
    png_debug(1, "in png_handle_iTXt");
 
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for iTXt");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
 
    if (!(png_ptr->mode & PNG_HAVE_IHDR))
       png_error(png_ptr, "Missing IHDR before iTXt");
@@ -2136,7 +2200,7 @@
    png_ptr->chunkdata = (png_charp)png_malloc_warn(png_ptr, length + 1);
    if (png_ptr->chunkdata == NULL)
    {
-     png_warning(png_ptr, "No memory to process iTXt chunk.");
+     png_warning(png_ptr, "No memory to process iTXt chunk");
      return;
    }
    slength = (png_size_t)length;
@@ -2204,10 +2268,10 @@
    else
        data_len = png_strlen(png_ptr->chunkdata + prefix_len);
    text_ptr = (png_textp)png_malloc_warn(png_ptr,
-      (png_uint_32)png_sizeof(png_text));
+      png_sizeof(png_text));
    if (text_ptr == NULL)
    {
-     png_warning(png_ptr, "Not enough memory to process iTXt chunk.");
+     png_warning(png_ptr, "Not enough memory to process iTXt chunk");
      png_free(png_ptr, png_ptr->chunkdata);
      png_ptr->chunkdata = NULL;
      return;
@@ -2226,7 +2290,7 @@
    png_free(png_ptr, png_ptr->chunkdata);
    png_ptr->chunkdata = NULL;
    if (ret)
-     png_error(png_ptr, "Insufficient memory to store iTXt chunk.");
+     png_error(png_ptr, "Insufficient memory to store iTXt chunk");
 }
 #endif
 
@@ -2242,22 +2306,36 @@
 
    png_debug(1, "in png_handle_unknown");
 
+#ifdef PNG_SET_USER_LIMITS_SUPPORTED
+   if (png_ptr->user_chunk_cache_max != 0)
+   {
+      if (png_ptr->user_chunk_cache_max == 1)
+      {
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+      if (--png_ptr->user_chunk_cache_max == 1)
+      {
+         png_warning(png_ptr, "No space in chunk cache for unknown chunk");
+         png_crc_finish(png_ptr, length);
+         return;
+      }
+   }
+#endif
 
    if (png_ptr->mode & PNG_HAVE_IDAT)
    {
-#ifdef PNG_USE_LOCAL_ARRAYS
-      PNG_CONST PNG_IDAT;
-#endif
+      PNG_IDAT;
       if (png_memcmp(png_ptr->chunk_name, png_IDAT, 4))  /* Not an IDAT */
          png_ptr->mode |= PNG_AFTER_IDAT;
    }
 
    if (!(png_ptr->chunk_name[0] & 0x20))
    {
-#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
       if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
            PNG_HANDLE_CHUNK_ALWAYS
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
            && png_ptr->read_user_chunk_fn == NULL
 #endif
         )
@@ -2265,9 +2343,9 @@
           png_chunk_error(png_ptr, "unknown critical chunk");
    }
 
-#if defined(PNG_READ_UNKNOWN_CHUNKS_SUPPORTED)
+#ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
    if ((png_ptr->flags & PNG_FLAG_KEEP_UNKNOWN_CHUNKS)
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
        || (png_ptr->read_user_chunk_fn != NULL)
 #endif
         )
@@ -2292,7 +2370,7 @@
          png_ptr->unknown_chunk.data = (png_bytep)png_malloc(png_ptr, length);
          png_crc_read(png_ptr, (png_bytep)png_ptr->unknown_chunk.data, length);
        }
-#if defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+#ifdef PNG_READ_USER_CHUNKS_SUPPORTED
        if (png_ptr->read_user_chunk_fn != NULL)
        {
           /* Callback to user unknown chunk handler */
@@ -2304,7 +2382,7 @@
           if (ret == 0)
           {
              if (!(png_ptr->chunk_name[0] & 0x20))
-#if defined(PNG_HANDLE_AS_UNKNOWN_SUPPORTED)
+#ifdef PNG_HANDLE_AS_UNKNOWN_SUPPORTED
                 if (png_handle_as_unknown(png_ptr, png_ptr->chunk_name) !=
                      PNG_HANDLE_CHUNK_ALWAYS)
 #endif
@@ -2325,7 +2403,7 @@
 
    png_crc_finish(png_ptr, skip);
 
-#if !defined(PNG_READ_USER_CHUNKS_SUPPORTED)
+#ifndef PNG_READ_USER_CHUNKS_SUPPORTED
    info_ptr = info_ptr; /* Quiet compiler warnings about unused info_ptr */
 #endif
 }
@@ -2383,7 +2461,7 @@
             png_uint_32 i;
             png_uint_32 row_width = png_ptr->width;
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (png_ptr->transformations & PNG_PACKSWAP)
             {
                 s_start = 0;
@@ -2438,7 +2516,7 @@
             png_uint_32 row_width = png_ptr->width;
             int value;
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (png_ptr->transformations & PNG_PACKSWAP)
             {
                s_start = 0;
@@ -2490,7 +2568,7 @@
             png_uint_32 row_width = png_ptr->width;
             int value;
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (png_ptr->transformations & PNG_PACKSWAP)
             {
                s_start = 0;
@@ -2573,11 +2651,9 @@
    png_bytep row = png_ptr->row_buf + 1;
    int pass = png_ptr->pass;
    png_uint_32 transformations = png_ptr->transformations;
-#ifdef PNG_USE_LOCAL_ARRAYS
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
    /* Offset to next interlace block */
    PNG_CONST int png_pass_inc[7] = {8, 8, 4, 4, 2, 2, 1};
-#endif
 
    png_debug(1, "in png_do_read_interlace");
    if (row != NULL && row_info != NULL)
@@ -2599,7 +2675,7 @@
             png_uint_32 i;
             int j;
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (transformations & PNG_PACKSWAP)
             {
                 sshift = (int)((row_info->width + 7) & 0x07);
@@ -2652,7 +2728,7 @@
             int jstop = png_pass_inc[pass];
             png_uint_32 i;
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (transformations & PNG_PACKSWAP)
             {
                sshift = (int)(((row_info->width + 3) & 0x03) << 1);
@@ -2708,7 +2784,7 @@
             png_uint_32 i;
             int jstop = png_pass_inc[pass];
 
-#if defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifdef PNG_READ_PACKSWAP_SUPPORTED
             if (transformations & PNG_PACKSWAP)
             {
                sshift = (int)(((row_info->width + 1) & 0x01) << 2);
@@ -2782,7 +2858,7 @@
       row_info->width = final_width;
       row_info->rowbytes = PNG_ROWBYTES(row_info->pixel_depth, final_width);
    }
-#if !defined(PNG_READ_PACKSWAP_SUPPORTED)
+#ifndef PNG_READ_PACKSWAP_SUPPORTED
    transformations = transformations; /* Silence compiler warning */
 #endif
 }
@@ -2911,11 +2987,10 @@
    }
 }
 
-#ifndef PNG_NO_SEQUENTIAL_READ_SUPPORTED
+#ifdef PNG_SEQUENTIAL_READ_SUPPORTED
 void /* PRIVATE */
 png_read_finish_row(png_structp png_ptr)
 {
-#ifdef PNG_USE_LOCAL_ARRAYS
 #ifdef PNG_READ_INTERLACING_SUPPORTED
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
@@ -2931,7 +3006,6 @@
    /* Offset to next interlace block in the y direction */
    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 #endif /* PNG_READ_INTERLACING_SUPPORTED */
-#endif
 
    png_debug(1, "in png_read_finish_row");
    png_ptr->row_number++;
@@ -2942,7 +3016,7 @@
    if (png_ptr->interlaced)
    {
       png_ptr->row_number = 0;
-      png_memset_check(png_ptr, png_ptr->prev_row, 0,
+      png_memset(png_ptr->prev_row, 0,
          png_ptr->rowbytes + 1);
       do
       {
@@ -2977,9 +3051,7 @@
 
    if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    {
-#ifdef PNG_USE_LOCAL_ARRAYS
-      PNG_CONST PNG_IDAT;
-#endif
+      PNG_IDAT;
       char extra;
       int ret;
 
@@ -3026,7 +3098,7 @@
 
          if (!(png_ptr->zstream.avail_out))
          {
-            png_warning(png_ptr, "Extra compressed data.");
+            png_warning(png_ptr, "Extra compressed data");
             png_ptr->mode |= PNG_AFTER_IDAT;
             png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
             break;
@@ -3043,12 +3115,11 @@
 
    png_ptr->mode |= PNG_AFTER_IDAT;
 }
-#endif /* PNG_NO_SEQUENTIAL_READ_SUPPORTED */
+#endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
 
 void /* PRIVATE */
 png_read_start_row(png_structp png_ptr)
 {
-#ifdef PNG_USE_LOCAL_ARRAYS
 #ifdef PNG_READ_INTERLACING_SUPPORTED
    /* Arrays to facilitate easy interlacing - use pass (0 - 6) as index */
 
@@ -3064,7 +3135,6 @@
    /* Offset to next interlace block in the y direction */
    PNG_CONST int png_pass_yinc[7] = {8, 8, 8, 4, 4, 2, 2};
 #endif
-#endif
 
    int max_pixel_depth;
    png_size_t row_bytes;
@@ -3098,12 +3168,12 @@
    }
    max_pixel_depth = png_ptr->pixel_depth;
 
-#if defined(PNG_READ_PACK_SUPPORTED)
+#ifdef PNG_READ_PACK_SUPPORTED
    if ((png_ptr->transformations & PNG_PACK) && png_ptr->bit_depth < 8)
       max_pixel_depth = 8;
 #endif
 
-#if defined(PNG_READ_EXPAND_SUPPORTED)
+#ifdef PNG_READ_EXPAND_SUPPORTED
    if (png_ptr->transformations & PNG_EXPAND)
    {
       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
@@ -3131,7 +3201,7 @@
    }
 #endif
 
-#if defined(PNG_READ_FILLER_SUPPORTED)
+#ifdef PNG_READ_FILLER_SUPPORTED
    if (png_ptr->transformations & (PNG_FILLER))
    {
       if (png_ptr->color_type == PNG_COLOR_TYPE_PALETTE)
@@ -3153,14 +3223,14 @@
    }
 #endif
 
-#if defined(PNG_READ_GRAY_TO_RGB_SUPPORTED)
+#ifdef PNG_READ_GRAY_TO_RGB_SUPPORTED
    if (png_ptr->transformations & PNG_GRAY_TO_RGB)
    {
       if (
-#if defined(PNG_READ_EXPAND_SUPPORTED)
+#ifdef PNG_READ_EXPAND_SUPPORTED
         (png_ptr->num_trans && (png_ptr->transformations & PNG_EXPAND)) ||
 #endif
-#if defined(PNG_READ_FILLER_SUPPORTED)
+#ifdef PNG_READ_FILLER_SUPPORTED
         (png_ptr->transformations & (PNG_FILLER)) ||
 #endif
         png_ptr->color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
@@ -3212,33 +3282,47 @@
       png_error(png_ptr, "This image requires a row greater than 64KB");
 #endif
 
-   if (row_bytes + 64 > png_ptr->old_big_row_buf_size)
+   if (row_bytes + 48 > png_ptr->old_big_row_buf_size)
    {
      png_free(png_ptr, png_ptr->big_row_buf);
-     png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr, row_bytes + 64);
      if (png_ptr->interlaced)
-       png_memset(png_ptr->big_row_buf, 0, row_bytes + 64);
+        png_ptr->big_row_buf = (png_bytep)png_calloc(png_ptr,
+            row_bytes + 48);
+     else
+        png_ptr->big_row_buf = (png_bytep)png_malloc(png_ptr,
+            row_bytes + 48);
+     png_ptr->old_big_row_buf_size = row_bytes + 48;
+
+#ifdef PNG_ALIGNED_MEMORY_SUPPORTED
+     /* Use 16-byte aligned memory for row_buf with at least 16 bytes
+      * of padding before and after row_buf.
+      */
+     png_ptr->row_buf = png_ptr->big_row_buf + 32
+         - (((png_alloc_size_t)&(png_ptr->big_row_buf[0]) + 15) % 16);
+     png_ptr->old_big_row_buf_size = row_bytes + 48;
+#else
+     /* Use 32 bytes of padding before and 16 bytes after row_buf. */
      png_ptr->row_buf = png_ptr->big_row_buf + 32;
-     png_ptr->old_big_row_buf_size = row_bytes + 64;
+#endif
+     png_ptr->old_big_row_buf_size = row_bytes + 48;
    }
 
 #ifdef PNG_MAX_MALLOC_64K
-   if ((png_uint_32)row_bytes + 1 > (png_uint_32)65536L)
+   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
       png_error(png_ptr, "This image requires a row greater than 64KB");
 #endif
-   if ((png_uint_32)row_bytes > (png_uint_32)(PNG_SIZE_MAX - 1))
-      png_error(png_ptr, "Row has too many bytes to allocate in memory.");
-
-   if (row_bytes + 1 > png_ptr->old_prev_row_size)
+   if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
+      png_error(png_ptr, "Row has too many bytes to allocate in memory");
+
+   if (png_ptr->rowbytes + 1 > png_ptr->old_prev_row_size)
    {
       png_free(png_ptr, png_ptr->prev_row);
       png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, (png_uint_32)(
-        row_bytes + 1));
-      png_memset_check(png_ptr, png_ptr->prev_row, 0, row_bytes + 1);
-      png_ptr->old_prev_row_size = row_bytes + 1;
+        png_ptr->rowbytes + 1));
+      png_ptr->old_prev_row_size = png_ptr->rowbytes + 1;
    }
 
-   png_ptr->rowbytes = row_bytes;
+   png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 
    png_debug1(3, "width = %lu,", png_ptr->width);
    png_debug1(3, "height = %lu,", png_ptr->height);