[devel] Fixed a number of problems with 64-bit compilation reported by Visual

Studio 2010 (John Bowler).
diff --git a/ANNOUNCE b/ANNOUNCE
index 1b4d397..9443eca 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
 
-Libpng 1.5.0beta47 - August 28, 2010
+Libpng 1.5.0beta47 - September 11, 2010
 
 This is not intended to be a public release.  It will be replaced
 within a few weeks by a public version or by another test version.
@@ -226,7 +226,7 @@
     offset of the png_ptr->rowbuf pointer into png_ptr->big_row_buf.
   Added more blank lines for readability.
 
-version 1.5.0beta25 [August 28, 2010]
+version 1.5.0beta25 [September 11, 2010]
   In pngpread.c: png_push_have_row() add check for new_row > height
   Removed the now-redundant check for out-of-bounds new_row from example.c
 
@@ -393,7 +393,9 @@
   Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options.
   Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project.
 
-Version 1.5.0beta47 [August 28, 2010]
+Version 1.5.0beta47 [September 11, 2010]
+  Fixed a number of problems with 64-bit compilation reported by Visual
+    Studio 2010 (John Bowler).
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net:
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index 24ebee6..542bcc9 100644
--- a/CHANGES
+++ b/CHANGES
@@ -3030,7 +3030,9 @@
   Added PNG_READ_16BIT, PNG_WRITE_16BIT, and PNG_16BIT options.
   Added reference to scripts/pnglibconf.h.prebuilt in the visualc71 project.
 
-Version 1.5.0beta47 [August 28, 2010]
+Version 1.5.0beta47 [September 11, 2010]
+  Fixed a number of problems with 64-bit compilation reported by Visual
+    Studio 2010 (John Bowler).
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/example.c b/example.c
index db44428..943dbaa 100644
--- a/example.c
+++ b/example.c
@@ -2,7 +2,7 @@
 #if 0 /* in case someone actually tries to compile this */
 
 /* example.c - an example of using libpng
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 2010]
  * This file has been placed in the public domain by the authors.
  * Maintained 1998-2010 Glenn Randers-Pehrson
  * Maintained 1996, 1997 Andreas Dilger)
diff --git a/png.c b/png.c
index 53a5de2..8eb214f 100644
--- a/png.c
+++ b/png.c
@@ -1,7 +1,7 @@
 
 /* png.c - location for general purpose libpng functions
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -560,13 +560,13 @@
 #else
 #  ifdef __STDC__
    return PNG_STRING_NEWLINE \
-     "libpng version 1.5.0beta47 - August 28, 2010" PNG_STRING_NEWLINE \
+     "libpng version 1.5.0beta47 - September 11, 2010" PNG_STRING_NEWLINE \
      "Copyright (c) 1998-2010 Glenn Randers-Pehrson" PNG_STRING_NEWLINE \
      "Copyright (c) 1996-1997 Andreas Dilger" PNG_STRING_NEWLINE \
      "Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc." \
      PNG_STRING_NEWLINE;
 #  else
-      return "libpng version 1.5.0beta47 - August 28, 2010\
+      return "libpng version 1.5.0beta47 - September 11, 2010\
       Copyright (c) 1998-2010 Glenn Randers-Pehrson\
       Copyright (c) 1996-1997 Andreas Dilger\
       Copyright (c) 1995-1996 Guy Eric Schalnat, Group 42, Inc.";
diff --git a/png.h b/png.h
index c6cb703..6243993 100644
--- a/png.h
+++ b/png.h
@@ -1,7 +1,7 @@
 
 /* png.h - header file for PNG reference library
  *
- * libpng version 1.5.0beta47 - August 28, 2010
+ * libpng version 1.5.0beta47 - September 11, 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.)
@@ -11,7 +11,7 @@
  * Authors and maintainers:
  *   libpng versions 0.71, May 1995, through 0.88, January 1996: Guy Schalnat
  *   libpng versions 0.89c, June 1996, through 0.96, May 1997: Andreas Dilger
- *   libpng versions 0.97, January 1998, through 1.5.0beta47 - August 28, 2010: Glenn
+ *   libpng versions 0.97, January 1998, through 1.5.0beta47 - September 11, 2010: Glenn
  *   See also "Contributing Authors", below.
  *
  * Note about libpng version numbers:
@@ -172,7 +172,7 @@
  *
  * This code is released under the libpng license.
  *
- * libpng versions 1.2.6, August 15, 2004, through 1.5.0beta47, August 28, 2010, are
+ * libpng versions 1.2.6, August 15, 2004, through 1.5.0beta47, September 11, 2010, are
  * Copyright (c) 2004, 2006-2010 Glenn Randers-Pehrson, and are
  * distributed according to the same disclaimer and license as libpng-1.2.5
  * with the following individual added to the list of Contributing Authors:
@@ -284,7 +284,7 @@
  * Y2K compliance in libpng:
  * =========================
  *
- *    August 28, 2010
+ *    September 11, 2010
  *
  *    Since the PNG Development group is an ad-hoc body, we can't make
  *    an official declaration.
@@ -348,7 +348,7 @@
 /* Version information for png.h - this should match the version in png.c */
 #define PNG_LIBPNG_VER_STRING "1.5.0beta47"
 #define PNG_HEADER_VERSION_STRING \
-     " libpng version 1.5.0beta47 - August 28, 2010\n"
+     " libpng version 1.5.0beta47 - September 11, 2010\n"
 
 #define PNG_LIBPNG_VER_SONUM   15
 #define PNG_LIBPNG_VER_DLLNUM  15
diff --git a/pngconf.h b/pngconf.h
index dadfdf4..ae9ed16 100644
--- a/pngconf.h
+++ b/pngconf.h
@@ -1,7 +1,7 @@
 
 /* pngconf.h - machine configurable file for libpng
  *
- * libpng version 1.5.0beta47 - August 28, 2010
+ * libpng version 1.5.0beta47 - September 11, 2010
  *
  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
diff --git a/pngdebug.h b/pngdebug.h
index 332c89e..2ade470 100644
--- a/pngdebug.h
+++ b/pngdebug.h
@@ -5,7 +5,7 @@
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng version 1.5.0 - August 28, 2010
+ * Last changed in libpng version 1.5.0 - September 11, 2010
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
diff --git a/pngerror.c b/pngerror.c
index 5a1fdfe..3aebc4d 100644
--- a/pngerror.c
+++ b/pngerror.c
@@ -1,7 +1,7 @@
 
 /* pngerror.c - stub functions for i/o and memory allocation
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngget.c b/pngget.c
index c66c97e..5a66176 100644
--- a/pngget.c
+++ b/pngget.c
@@ -1,7 +1,7 @@
 
 /* pngget.c - retrieval of values from info struct
  *
- * Last changed in libpng 1.4.1 [August 28, 2010]
+ * Last changed in libpng 1.4.1 [September 11, 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.)
diff --git a/pnginfo.h b/pnginfo.h
index b9a678f..c87bfa2 100644
--- a/pnginfo.h
+++ b/pnginfo.h
@@ -5,7 +5,7 @@
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng version 1.5.0 - August 28, 2010
+ * Last changed in libpng version 1.5.0 - September 11, 2010
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
diff --git a/pngmem.c b/pngmem.c
index 6ff0382..b643eae 100644
--- a/pngmem.c
+++ b/pngmem.c
@@ -1,7 +1,7 @@
 
 /* pngmem.c - stub functions for memory allocation
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngpread.c b/pngpread.c
index 7a15194..ddd5d25 100644
--- a/pngpread.c
+++ b/pngpread.c
@@ -1,7 +1,7 @@
 
 /* pngpread.c - read a png file in push mode
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -582,34 +582,47 @@
 {
    if (png_ptr->skip_length && png_ptr->save_buffer_size)
    {
-      png_size_t save_size;
+      png_size_t save_size = png_ptr->current_buffer_size;
+      png_uint_32 skip_length = png_ptr->skip_length;
 
-      if (png_ptr->skip_length < (png_uint_32)png_ptr->save_buffer_size)
-         save_size = (png_size_t)png_ptr->skip_length;
+      /* We want the smaller of 'skip_length' and 'current_buffer_size', but
+       * they are of different types and we don't know which variable has the
+       * fewest bits.  Carefully select the smaller and cast it to the type of
+       * the larger - this cannot overflow.  Do not cast in the following test
+       * - it will break on either 16 or 64 bit platforms.
+       */
+      if (skip_length < save_size)
+         save_size = (png_size_t)skip_length;
 
       else
-         save_size = png_ptr->save_buffer_size;
+         skip_length = (png_uint_32)save_size;
 
       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
 
-      png_ptr->skip_length -= save_size;
+      png_ptr->skip_length -= skip_length;
       png_ptr->buffer_size -= save_size;
       png_ptr->save_buffer_size -= save_size;
       png_ptr->save_buffer_ptr += save_size;
    }
    if (png_ptr->skip_length && png_ptr->current_buffer_size)
    {
-      png_size_t save_size;
+      png_size_t save_size = png_ptr->current_buffer_size;
+      png_uint_32 skip_length = png_ptr->skip_length;
 
-      if (png_ptr->skip_length < (png_uint_32)png_ptr->current_buffer_size)
-         save_size = (png_size_t)png_ptr->skip_length;
+      /* We want the smaller of 'skip_length' and 'current_buffer_size', but
+       * they are of different types and we don't know which variable has the
+       * fewest bits.  Carefully select the smaller and cast it to the type of
+       * the larger - this cannot overflow.
+       */
+      if (skip_length < save_size)
+         save_size = (png_size_t)skip_length;
 
       else
-         save_size = png_ptr->current_buffer_size;
+         skip_length = (png_uint_32)save_size;
 
       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
 
-      png_ptr->skip_length -= save_size;
+      png_ptr->skip_length -= skip_length;
       png_ptr->buffer_size -= save_size;
       png_ptr->current_buffer_size -= save_size;
       png_ptr->current_buffer_ptr += save_size;
@@ -771,49 +784,52 @@
    }
    if (png_ptr->idat_size && png_ptr->save_buffer_size)
    {
-      png_size_t save_size;
+      png_size_t save_size = png_ptr->save_buffer_size;
+      png_uint_32 idat_size = png_ptr->idat_size;
 
-      if (png_ptr->idat_size < (png_uint_32)png_ptr->save_buffer_size)
-      {
-         save_size = (png_size_t)png_ptr->idat_size;
-
-         /* Check for overflow */
-         if ((png_uint_32)save_size != png_ptr->idat_size)
-            png_error(png_ptr, "save_size overflowed in pngpread");
-      }
+      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+       * are of different types and we don't know which variable has the fewest
+       * bits.  Carefully select the smaller and cast it to the type of the
+       * larger - this cannot overflow.  Do not cast in the following test - it
+       * will break on either 16 or 64 bit platforms.
+       */
+      if (idat_size < save_size)
+         save_size = (png_size_t)idat_size;
 
       else
-         save_size = png_ptr->save_buffer_size;
+         idat_size = (png_uint_32)save_size;
 
       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
 
       png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
 
-      png_ptr->idat_size -= save_size;
+      png_ptr->idat_size -= idat_size;
       png_ptr->buffer_size -= save_size;
       png_ptr->save_buffer_size -= save_size;
       png_ptr->save_buffer_ptr += save_size;
    }
+
    if (png_ptr->idat_size && png_ptr->current_buffer_size)
    {
-      png_size_t save_size;
+      png_size_t save_size = png_ptr->current_buffer_size;
+      png_uint_32 idat_size = png_ptr->idat_size;
 
-      if (png_ptr->idat_size < (png_uint_32)png_ptr->current_buffer_size)
-      {
-         save_size = (png_size_t)png_ptr->idat_size;
+      /* We want the smaller of 'idat_size' and 'current_buffer_size', but they
+       * are of different types and we don't know which variable has the fewest
+       * bits.  Carefully select the smaller and cast it to the type of the
+       * larger - this cannot overflow.
+       */
+      if (idat_size < save_size)
+         save_size = (png_size_t)idat_size;
 
-         /* Check for overflow */
-         if ((png_uint_32)save_size != png_ptr->idat_size)
-            png_error(png_ptr, "save_size overflowed in pngpread");
-      }
       else
-         save_size = png_ptr->current_buffer_size;
+         idat_size = (png_uint_32)save_size;
 
       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
 
       png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
 
-      png_ptr->idat_size -= save_size;
+      png_ptr->idat_size -= idat_size;
       png_ptr->buffer_size -= save_size;
       png_ptr->current_buffer_size -= save_size;
       png_ptr->current_buffer_ptr += save_size;
diff --git a/pngpriv.h b/pngpriv.h
index e5acf45..8bbb11b 100644
--- a/pngpriv.h
+++ b/pngpriv.h
@@ -1,7 +1,7 @@
 
 /* pngpriv.h - private declarations for use inside libpng
  *
- * libpng version 1.5.0beta47 - August 28, 2010
+ * libpng version 1.5.0beta47 - September 11, 2010
  * For conditions of distribution and use, see copyright notice in png.h
  * Copyright (c) 1998-2010 Glenn Randers-Pehrson
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
@@ -349,6 +349,18 @@
 #define PNG_FLAG_CRC_MASK           (PNG_FLAG_CRC_ANCILLARY_MASK | \
                                      PNG_FLAG_CRC_CRITICAL_MASK)
 
+/* zlib.h declares a magic type 'uInt' that limits the amount of data that zlib
+ * can handle at once.  This type need be no larger than 16 bits (so maximum of
+ * 65535), this define allows us to discover how big it is, but limited by the
+ * maximuum for png_size_t.  The value can be overriden in a library build
+ * (pngusr.h, or set it in CPPFLAGS) and it works to set it to a considerably
+ * lower value (e.g. 255 works).  A lower value may help memory usage (slightly)
+ * and may even improve performance on some systems (and degrade it on others.)
+ */
+#ifndef ZLIB_IO_MAX
+#  define ZLIB_IO_MAX ((uInt)-1)
+#endif
+
 /* Save typing and make code easier to understand */
 
 #define PNG_COLOR_DIST(c1, c2) (abs((int)((c1).red) - (int)((c2).red)) + \
diff --git a/pngread.c b/pngread.c
index 4bd8172..612f550 100644
--- a/pngread.c
+++ b/pngread.c
@@ -1,7 +1,7 @@
 
 /* pngread.c - read a PNG file
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngrio.c b/pngrio.c
index dfef308..e30d818 100644
--- a/pngrio.c
+++ b/pngrio.c
@@ -1,7 +1,7 @@
 
 /* pngrio.c - functions for data input
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngrtran.c b/pngrtran.c
index 565f62c..5269c6d 100644
--- a/pngrtran.c
+++ b/pngrtran.c
@@ -1,7 +1,7 @@
 
 /* pngrtran.c - transforms the data in a row for PNG readers
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -1545,7 +1545,7 @@
       png_do_quantize(&(png_ptr->row_info), png_ptr->row_buf + 1,
           png_ptr->palette_lookup, png_ptr->quantize_index);
 
-      if (png_ptr->row_info.rowbytes == (png_uint_32)0)
+      if (png_ptr->row_info.rowbytes == 0)
          png_error(png_ptr, "png_do_quantize returned rowbytes=0");
    }
 #endif /* PNG_READ_QUANTIZE_SUPPORTED */
@@ -1614,7 +1614,7 @@
              (png_ptr,                    /* png_ptr */
              &(png_ptr->row_info),     /* row_info: */
                 /*  png_uint_32 width;       width of row */
-                /*  png_uint_32 rowbytes;    number of bytes in row */
+                /*  png_size_t rowbytes;     number of bytes in row */
                 /*  png_byte color_type;     color type of pixels */
                 /*  png_byte bit_depth;      bit depth of samples */
                 /*  png_byte channels;       number of channels (1-4) */
@@ -1788,8 +1788,8 @@
          case 2:
          {
             png_bytep bp;
-            png_uint_32 i;
-            png_uint_32 istop = row_info->rowbytes;
+            png_size_t i;
+            png_size_t istop = row_info->rowbytes;
 
             for (bp = row, i = 0; i < istop; i++)
             {
@@ -1802,8 +1802,8 @@
          case 4:
          {
             png_bytep bp = row;
-            png_uint_32 i;
-            png_uint_32 istop = row_info->rowbytes;
+            png_size_t i;
+            png_size_t istop = row_info->rowbytes;
             png_byte mask = (png_byte)((((int)0xf0 >> shift[0]) & (int)0xf0) |
                 (png_byte)((int)0xf >> shift[0]));
 
diff --git a/pngrutil.c b/pngrutil.c
index 1bd8a0b..de4ac7a 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -1,7 +1,7 @@
 
 /* pngrutil.c - utilities to read a PNG file
  *
- * Last changed in libpng 1.4.1 [August 28, 2010]
+ * Last changed in libpng 1.4.1 [September 11, 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.)
@@ -241,13 +241,46 @@
 {
    png_size_t count = 0;
 
+   /* zlib can't necessarily handle more than 65535 bytes at once (i.e. it can't
+    * even necessarily handle 65536 bytes) because the type uInt is "16 bits or
+    * more".  Consequently it is necessary to chunk the input to zlib.  This
+    * code uses ZLIB_IO_MAX, from pngpriv.h, as the maximum (the maximum value
+    * that can be stored in a uInt.)  It is possible to set ZLIB_IO_MAX to a
+    * lower value in pngpriv.h and this may sometimes have a performance
+    * advantage, because it forces access of the input data to be separated from
+    * at least some of the use by some period of time.
+    */
    png_ptr->zstream.next_in = data;
-   png_ptr->zstream.avail_in = size;
+   /* avail_in is set below from 'size' */
+   png_ptr->zstream.avail_in = 0;
 
    while (1)
    {
       int ret, avail;
 
+      /* The setting of 'avail_in' used to be outside the loop, by setting it
+       * inside it is possible to chunk the input to zlib and simply rely on
+       * zlib to advance the 'next_in' pointer.  This allows arbitrary amounts o
+       * data to be passed through zlib at the unavoidable cost of requiring a
+       * window save (memcpy of up to 32768 output bytes) every ZLIB_IO_MAX
+       * input bytes.
+       */
+      if (png_ptr->zstream.avail_in == 0 && size > 0)
+      {
+         if (size <= ZLIB_IO_MAX)
+         {
+            /* The value is less than ZLIB_IO_MAX so the cast is safe: */
+            png_ptr->zstream.avail_in = (uInt)size;
+            size = 0;
+         }
+   
+         else
+         {
+            png_ptr->zstream.avail_in = ZLIB_IO_MAX;
+            size -= ZLIB_IO_MAX;
+         }
+      }
+
       /* Reset the output buffer each time round - we empty it
        * after every inflate call.
        */
@@ -1033,7 +1066,8 @@
    png_bytep pC;
    png_charp profile;
    png_uint_32 skip = 0;
-   png_uint_32 profile_size, profile_length;
+   png_uint_32 profile_size;
+   png_alloc_size_t profile_length;
    png_size_t slength, prefix_length, data_length;
 
    png_debug(1, "in png_handle_iCCP");
@@ -1128,9 +1162,13 @@
                   ((*(pC + 2)) <<  8) |
                   ((*(pC + 3))      );
 
+   /* NOTE: the following guarantees that 'profile_length' fits into 32 bits,
+    * because profile_size is a 32 bit value.
+    */
    if (profile_size < profile_length)
       profile_length = profile_size;
 
+   /* And the following guarantees that profile_size == profile_length. */
    if (profile_size > profile_length)
    {
       png_free(png_ptr, png_ptr->chunkdata);
@@ -1153,7 +1191,7 @@
 
    png_set_iCCP(png_ptr, info_ptr, png_ptr->chunkdata,
        compression_type, (png_bytep)png_ptr->chunkdata + prefix_length,
-       profile_length);
+       profile_size);
    png_free(png_ptr, png_ptr->chunkdata);
    png_ptr->chunkdata = NULL;
 }
@@ -1169,7 +1207,8 @@
 #ifdef PNG_POINTER_INDEXING_SUPPORTED
    png_sPLT_entryp pp;
 #endif
-   int data_length, entry_size, i;
+   png_uint_32 data_length;
+   int entry_size, i;
    png_uint_32 skip = 0;
    png_size_t slength;
 
@@ -1214,6 +1253,11 @@
 
    png_free(png_ptr, png_ptr->chunkdata);
    png_ptr->chunkdata = (png_charp)png_malloc(png_ptr, length + 1);
+
+   /* WARNING: this may break if size_t is less than 32 bits; it is assumed
+    * that the PNG_MAX_MALLOC_64K test is enabled in this case, but this is a
+    * potential breakage point if the types in pngconf.h aren't exactly right.
+    */
    slength = (png_size_t)length;
    png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength);
 
@@ -1243,7 +1287,12 @@
 
    new_palette.depth = *entry_start++;
    entry_size = (new_palette.depth == 8 ? 6 : 10);
-   data_length = (slength - (entry_start - (png_bytep)png_ptr->chunkdata));
+   /* This must fit in a png_uint_32 because it is derived from the original
+    * chunk data length (and use 'length', not 'slength' here for clarity -
+    * they are guaranteed to be the same, see the tests above.)
+    */
+   data_length = length - (png_uint_32)(entry_start -
+      (png_bytep)png_ptr->chunkdata);
 
    /* Integrity-check the data length */
    if (data_length % entry_size)
@@ -1254,13 +1303,12 @@
       return;
    }
 
-   new_palette.nentries = (png_int_32) ( data_length / entry_size);
-   if ((png_uint_32) new_palette.nentries >
-       (png_uint_32) (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
+   if ((data_length / entry_size) > (PNG_SIZE_MAX / png_sizeof(png_sPLT_entry)))
    {
        png_warning(png_ptr, "sPLT chunk too long");
        return;
    }
+   new_palette.nentries = (png_int_32) ( data_length / entry_size);
 
    new_palette.entries = (png_sPLT_entryp)png_malloc_warn(
        png_ptr, new_palette.nentries * png_sizeof(png_sPLT_entry));
@@ -2969,9 +3017,9 @@
 
       case PNG_FILTER_VALUE_SUB:
       {
-         png_uint_32 i;
-         png_uint_32 istop = row_info->rowbytes;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
+         png_size_t i;
+         png_size_t istop = row_info->rowbytes;
+         unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
          png_bytep rp = row + bpp;
          png_bytep lp = row;
 
@@ -2984,8 +3032,8 @@
       }
       case PNG_FILTER_VALUE_UP:
       {
-         png_uint_32 i;
-         png_uint_32 istop = row_info->rowbytes;
+         png_size_t i;
+         png_size_t istop = row_info->rowbytes;
          png_bytep rp = row;
          png_const_bytep pp = prev_row;
 
@@ -2998,12 +3046,12 @@
       }
       case PNG_FILTER_VALUE_AVG:
       {
-         png_uint_32 i;
+         png_size_t i;
          png_bytep rp = row;
          png_const_bytep pp = prev_row;
          png_bytep lp = row;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
-         png_uint_32 istop = row_info->rowbytes - bpp;
+         unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+         png_size_t istop = row_info->rowbytes - bpp;
 
          for (i = 0; i < bpp; i++)
          {
@@ -3022,13 +3070,13 @@
       }
       case PNG_FILTER_VALUE_PAETH:
       {
-         png_uint_32 i;
+         png_size_t i;
          png_bytep rp = row;
          png_const_bytep pp = prev_row;
          png_bytep lp = row;
          png_const_bytep cp = prev_row;
-         png_uint_32 bpp = (row_info->pixel_depth + 7) >> 3;
-         png_uint_32 istop=row_info->rowbytes - bpp;
+         unsigned int bpp = (row_info->pixel_depth + 7) >> 3;
+         png_size_t istop=row_info->rowbytes - bpp;
 
          for (i = 0; i < bpp; i++)
          {
@@ -3112,8 +3160,7 @@
    {
       png_ptr->row_number = 0;
 
-      png_memset(png_ptr->prev_row, 0,
-          png_ptr->rowbytes + 1);
+      png_memset(png_ptr->prev_row, 0, png_ptr->rowbytes + 1);
 
       do
       {
@@ -3427,19 +3474,18 @@
    }
 
 #ifdef PNG_MAX_MALLOC_64K
-   if ((png_uint_32)png_ptr->rowbytes + 1 > (png_uint_32)65536L)
+   if (png_ptr->rowbytes > 65535)
       png_error(png_ptr, "This image requires a row greater than 64KB");
 
 #endif
-   if ((png_uint_32)png_ptr->rowbytes > (png_uint_32)(PNG_SIZE_MAX - 1))
+   if (png_ptr->rowbytes > (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)(
-          png_ptr->rowbytes + 1));
+      png_ptr->prev_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
 
       png_ptr->old_prev_row_size = png_ptr->rowbytes + 1;
    }
diff --git a/pngset.c b/pngset.c
index cb071cd..1020f0b 100644
--- a/pngset.c
+++ b/pngset.c
@@ -1,7 +1,7 @@
 
 /* pngset.c - storage of image information into info struct
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -1116,17 +1116,28 @@
 #endif
 
 void PNGAPI
-png_set_compression_buffer_size(png_structp png_ptr,
-    png_size_t size)
+png_set_compression_buffer_size(png_structp png_ptr, png_size_t size)
 {
     if (png_ptr == NULL)
        return;
 
     png_free(png_ptr, png_ptr->zbuf);
-    png_ptr->zbuf_size = size;
+    if (size > ZLIB_IO_MAX)
+    {
+        png_warning(png_ptr, "Attempt to set buffer size beyond max ignored");
+        png_ptr->zbuf_size = ZLIB_IO_MAX;
+        size = ZLIB_IO_MAX; /* must fit */
+    }
+    else
+        png_ptr->zbuf_size = (uInt)size;
+
     png_ptr->zbuf = (png_bytep)png_malloc(png_ptr, size);
+    /* The following ensures a relatively safe failure if this gets called while
+     * the buffer is actually in use.
+     */
     png_ptr->zstream.next_out = png_ptr->zbuf;
-    png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
+    png_ptr->zstream.avail_out = 0;
+    png_ptr->zstream.avail_in = 0;
 }
 
 void PNGAPI
@@ -1170,8 +1181,7 @@
    png_alloc_size_t user_chunk_malloc_max)
 {
     if (png_ptr)
-       png_ptr->user_chunk_malloc_max =
-          (png_size_t)user_chunk_malloc_max;
+       png_ptr->user_chunk_malloc_max = user_chunk_malloc_max;
 }
 #endif /* ?PNG_SET_USER_LIMITS_SUPPORTED */
 
diff --git a/pngstruct.h b/pngstruct.h
index 63d5780..67d84b4 100644
--- a/pngstruct.h
+++ b/pngstruct.h
@@ -5,7 +5,7 @@
  * (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger)
  * (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.)
  *
- * Last changed in libpng version 1.5.0 - August 28, 2010
+ * Last changed in libpng version 1.5.0 - September 11, 2010
  *
  * This code is released under the libpng license.
  * For conditions of distribution and use, see the disclaimer
@@ -63,7 +63,7 @@
 
    z_stream zstream;          /* pointer to decompression structure (below) */
    png_bytep zbuf;            /* buffer for zlib */
-   png_size_t zbuf_size;      /* size of zbuf */
+   uInt zbuf_size;            /* size of zbuf (typically 65536) */
    int zlib_level;            /* holds zlib compression level */
    int zlib_method;           /* holds zlib compression method */
    int zlib_window_bits;      /* holds zlib compression window bits */
@@ -284,7 +284,7 @@
    /* Total memory that a zTXt, sPLT, iTXt, iCCP, or unknown chunk
     * can occupy when decompressed.  0 means unlimited.
     */
-   png_uint_32 user_chunk_malloc_max;
+   png_alloc_size_t user_chunk_malloc_max;
 #endif
 
 /* New member added in libpng-1.0.25 and 1.2.17 */
@@ -294,8 +294,8 @@
 #endif
 
 /* New members added in libpng-1.2.26 */
-  png_uint_32 old_big_row_buf_size;
-  png_uint_32 old_prev_row_size;
+  png_size_t old_big_row_buf_size;
+  png_size_t old_prev_row_size;
 
 /* New member added in libpng-1.2.30 */
   png_charp chunkdata;  /* buffer for reading chunk data */
diff --git a/pngtest.c b/pngtest.c
index e1f0992..9a9ae17 100644
--- a/pngtest.c
+++ b/pngtest.c
@@ -1,7 +1,7 @@
 
 /* pngtest.c - a simple test program to test libpng
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngtrans.c b/pngtrans.c
index ddf938e..0f93691 100644
--- a/pngtrans.c
+++ b/pngtrans.c
@@ -1,7 +1,7 @@
 
 /* pngtrans.c - transforms the data in a row (used by both readers and writers)
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -217,8 +217,8 @@
    if (row_info->color_type == PNG_COLOR_TYPE_GRAY)
    {
       png_bytep rp = row;
-      png_uint_32 i;
-      png_uint_32 istop = row_info->rowbytes;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i++)
       {
@@ -231,8 +231,8 @@
       row_info->bit_depth == 8)
    {
       png_bytep rp = row;
-      png_uint_32 i;
-      png_uint_32 istop = row_info->rowbytes;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i += 2)
       {
@@ -246,8 +246,8 @@
       row_info->bit_depth == 16)
    {
       png_bytep rp = row;
-      png_uint_32 i;
-      png_uint_32 istop = row_info->rowbytes;
+      png_size_t i;
+      png_size_t istop = row_info->rowbytes;
 
       for (i = 0; i < istop; i += 4)
       {
diff --git a/pngvalid.c b/pngvalid.c
index 64f5dc9..0ecccf2 100644
--- a/pngvalid.c
+++ b/pngvalid.c
@@ -1,7 +1,7 @@
 
 /* pngvalid.c - validate libpng by constructing then reading png files.
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 2010]
  * Copyright (c) 2010 Glenn Randers-Pehrson
  * Written by John C. Bowler
  *
@@ -3559,6 +3559,9 @@
       else if (strcmp(*argv, "--speed") == 0)
          pm.this.speed = 1, pm.ngammas = (sizeof gammas)/(sizeof gammas[0]);
 
+      else if (strcmp(*argv, "--nogamma") == 0)
+         pm.ngammas = 0;
+
       else if (strcmp(*argv, "--progressive-read") == 0)
          pm.this.progressive = 1;
 
diff --git a/pngwio.c b/pngwio.c
index a3009a3..d3ab072 100644
--- a/pngwio.c
+++ b/pngwio.c
@@ -1,7 +1,7 @@
 
 /* pngwio.c - functions for data output
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -50,7 +50,7 @@
 void PNGCBAPI
 png_default_write_data(png_structp png_ptr, png_bytep data, png_size_t length)
 {
-   png_uint_32 check;
+   png_size_t check;
 
    if (png_ptr == NULL)
       return;
diff --git a/pngwrite.c b/pngwrite.c
index 260b1f5..87633c5 100644
--- a/pngwrite.c
+++ b/pngwrite.c
@@ -1,7 +1,7 @@
 
 /* pngwrite.c - general routines to write a PNG file
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
diff --git a/pngwtran.c b/pngwtran.c
index df7ba93..f4b4898 100644
--- a/pngwtran.c
+++ b/pngwtran.c
@@ -1,7 +1,7 @@
 
 /* pngwtran.c - transforms the data in a row for PNG writers
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -34,7 +34,7 @@
             (png_ptr,                    /* png_ptr */
             &(png_ptr->row_info),           /* row_info: */
                /*  png_uint_32 width;       width of row */
-               /*  png_uint_32 rowbytes;    number of bytes in row */
+               /*  png_size_t rowbytes;     number of bytes in row */
                /*  png_byte color_type;     color type of pixels */
                /*  png_byte bit_depth;      bit depth of samples */
                /*  png_byte channels;       number of channels (1-4) */
@@ -279,9 +279,9 @@
       if (row_info->bit_depth < 8)
       {
          png_bytep bp = row;
-         png_uint_32 i;
+         png_size_t i;
          png_byte mask;
-         png_uint_32 row_bytes = row_info->rowbytes;
+         png_size_t row_bytes = row_info->rowbytes;
 
          if (bit_depth->gray == 1 && row_info->bit_depth == 2)
             mask = 0x55;
diff --git a/pngwutil.c b/pngwutil.c
index 4e16820..8026ac6 100644
--- a/pngwutil.c
+++ b/pngwutil.c
@@ -1,7 +1,7 @@
 
 /* pngwutil.c - utilities to write a PNG file
  *
- * Last changed in libpng 1.5.0 [August 28, 2010]
+ * Last changed in libpng 1.5.0 [September 11, 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.)
@@ -197,7 +197,7 @@
 typedef struct
 {
    png_const_bytep input;   /* The uncompressed input data */
-   int input_len;   /* Its length */
+   png_size_t input_len;   /* Its length */
    int num_output_ptr; /* Number of output pointers used */
    int max_output_ptr; /* Size of output_ptr */
    png_bytep *output_ptr; /* Array of pointers to output */
@@ -396,7 +396,7 @@
    /* Handle the no-compression case */
    if (comp->input)
    {
-      png_write_chunk_data(png_ptr, comp->input, (png_size_t)comp->input_len);
+      png_write_chunk_data(png_ptr, comp->input, comp->input_len);
 
       return;
    }
@@ -1766,8 +1766,7 @@
    /* Set up filtering buffer, if using this filter */
    if (png_ptr->do_filter & PNG_FILTER_SUB)
    {
-      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr,
-          (png_alloc_size_t)(png_ptr->rowbytes + 1));
+      png_ptr->sub_row = (png_bytep)png_malloc(png_ptr, png_ptr->rowbytes + 1);
 
       png_ptr->sub_row[0] = PNG_FILTER_VALUE_SUB;
    }
@@ -1782,7 +1781,7 @@
       if (png_ptr->do_filter & PNG_FILTER_UP)
       {
          png_ptr->up_row = (png_bytep)png_malloc(png_ptr,
-             (png_size_t)(png_ptr->rowbytes + 1));
+            png_ptr->rowbytes + 1);
 
          png_ptr->up_row[0] = PNG_FILTER_VALUE_UP;
       }
@@ -1790,7 +1789,7 @@
       if (png_ptr->do_filter & PNG_FILTER_AVG)
       {
          png_ptr->avg_row = (png_bytep)png_malloc(png_ptr,
-             (png_alloc_size_t)(png_ptr->rowbytes + 1));
+             png_ptr->rowbytes + 1);
 
          png_ptr->avg_row[0] = PNG_FILTER_VALUE_AVG;
       }
@@ -1798,7 +1797,7 @@
       if (png_ptr->do_filter & PNG_FILTER_PAETH)
       {
          png_ptr->paeth_row = (png_bytep)png_malloc(png_ptr,
-             (png_size_t)(png_ptr->rowbytes + 1));
+             png_ptr->rowbytes + 1);
 
          png_ptr->paeth_row[0] = PNG_FILTER_VALUE_PAETH;
       }
@@ -2149,7 +2148,7 @@
    png_bytep prev_row, row_buf;
    png_uint_32 mins, bpp;
    png_byte filter_to_do = png_ptr->do_filter;
-   png_uint_32 row_bytes = row_info->rowbytes;
+   png_size_t row_bytes = row_info->rowbytes;
 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
    int num_p_filters = (int)png_ptr->num_prev_filters;
 #endif
@@ -2203,7 +2202,7 @@
    {
       png_bytep rp;
       png_uint_32 sum = 0;
-      png_uint_32 i;
+      png_size_t i;
       int v;
 
       for (i = 0, rp = row_buf + 1; i < row_bytes; i++, rp++)
@@ -2258,7 +2257,7 @@
    /* It's the only filter so no testing is needed */
    {
       png_bytep rp, lp, dp;
-      png_uint_32 i;
+      png_size_t i;
 
       for (i = 0, rp = row_buf + 1, dp = png_ptr->sub_row + 1; i < bpp;
            i++, rp++, dp++)
@@ -2279,7 +2278,7 @@
    {
       png_bytep rp, dp, lp;
       png_uint_32 sum = 0, lmins = mins;
-      png_uint_32 i;
+      png_size_t i;
       int v;
 
 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
@@ -2384,7 +2383,7 @@
    if (filter_to_do == PNG_FILTER_UP)
    {
       png_bytep rp, dp, pp;
-      png_uint_32 i;
+      png_size_t i;
 
       for (i = 0, rp = row_buf + 1, dp = png_ptr->up_row + 1,
           pp = prev_row + 1; i < row_bytes;
@@ -2399,7 +2398,7 @@
    {
       png_bytep rp, dp, pp;
       png_uint_32 sum = 0, lmins = mins;
-      png_uint_32 i;
+      png_size_t i;
       int v;
 
 
@@ -2513,7 +2512,7 @@
    {
       png_bytep rp, dp, pp, lp;
       png_uint_32 sum = 0, lmins = mins;
-      png_uint_32 i;
+      png_size_t i;
       int v;
 
 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
@@ -2614,7 +2613,7 @@
    if (filter_to_do == PNG_FILTER_PAETH)
    {
       png_bytep rp, dp, pp, cp, lp;
-      png_uint_32 i;
+      png_size_t i;
 
       for (i = 0, rp = row_buf + 1, dp = png_ptr->paeth_row + 1,
           pp = prev_row + 1; i < bpp; i++)
@@ -2654,7 +2653,7 @@
    {
       png_bytep rp, dp, pp, cp, lp;
       png_uint_32 sum = 0, lmins = mins;
-      png_uint_32 i;
+      png_size_t i;
       int v;
 
 #ifdef PNG_WRITE_WEIGHTED_FILTER_SUPPORTED
@@ -2807,18 +2806,45 @@
 void /* PRIVATE */
 png_write_filtered_row(png_structp png_ptr, png_bytep filtered_row)
 {
+   png_size_t avail;
+
    png_debug(1, "in png_write_filtered_row");
 
    png_debug1(2, "filter = %d", filtered_row[0]);
    /* Set up the zlib input buffer */
 
    png_ptr->zstream.next_in = filtered_row;
-   png_ptr->zstream.avail_in = (uInt)png_ptr->row_info.rowbytes + 1;
+   png_ptr->zstream.avail_in = 0;
+   avail = png_ptr->row_info.rowbytes + 1;
    /* Repeat until we have compressed all the data */
    do
    {
       int ret; /* Return of zlib */
 
+      /* Record the number of bytes available - zlib supports at least 65535
+       * bytes at one step, depending on the size of the zlib type 'uInt', the
+       * maximum size zlib can write at once is ZLIB_IO_MAX (from pngpriv.h).
+       * Use this because on 16 bit systems 'rowbytes' can be up to 65536 (i.e.
+       * one more than 16 bits) and, in this case 'rowbytes+1' can overflow a
+       * uInt.  ZLIB_IO_MAX can be safely reduced to cause zlib to be called
+       * with smaller chunks of data.
+       */
+      if (png_ptr->zstream.avail_in == 0)
+      {
+         if (avail > ZLIB_IO_MAX)
+         {
+            png_ptr->zstream.avail_in  = ZLIB_IO_MAX;
+            avail -= ZLIB_IO_MAX;
+         }
+
+         else
+         {
+            /* So this will fit in the available uInt space: */
+            png_ptr->zstream.avail_in = (uInt)avail;
+            avail = 0;
+         }
+      }
+
       /* Compress the data */
       ret = deflate(&png_ptr->zstream, Z_NO_FLUSH);
 
@@ -2841,7 +2867,7 @@
          png_ptr->zstream.avail_out = (uInt)png_ptr->zbuf_size;
       }
    /* Repeat until all data has been compressed */
-   } while (png_ptr->zstream.avail_in);
+   } while (avail > 0 || png_ptr->zstream.avail_in > 0);
 
    /* Swap the current and previous rows */
    if (png_ptr->prev_row != NULL)