[libpng16] Calculate our own zlib windowBits when decoding rather than

trusting the CMF bytes in the PNG datastream.
diff --git a/ANNOUNCE b/ANNOUNCE
index dab805a..9094afe 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -1,5 +1,5 @@
 
-Libpng 1.6.3beta04 - April 30, 2013
+Libpng 1.6.3beta04 - May 6, 2013
 
 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.
@@ -41,7 +41,9 @@
   Avoid dereferencing NULL pointer possibly returned from
      png_create_write_struct() (Andrew Church).
 
-Version 1.6.3beta04 [April 30, 2013]
+Version 1.6.3beta04 [May 6, 2013]
+  Calculate our own zlib windowBits when decoding rather than trusting the
+    CMF bytes in the PNG datastream.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/CHANGES b/CHANGES
index 841ed3c..6c56b0d 100644
--- a/CHANGES
+++ b/CHANGES
@@ -4485,6 +4485,7 @@
   Corrected a misplaced closing bracket in contrib/libtests/pngvalid.c
     (Flavio Medeiros).
   Corrected length written to uncompressed iTXt chunks (Samuli Suominen).
+    Bug was introduced in libpng-1.6.0.
 
 Version 1.6.2rc01 [April 18, 2013]
   Added contrib/tools/fixitxt.c, to repair the erroneous iTXt chunk length
@@ -4523,7 +4524,9 @@
   Avoid dereferencing NULL pointer possibly returned from
      png_create_write_struct() (Andrew Church).
 
-Version 1.6.3beta04 [April 30, 2013]
+Version 1.6.3beta04 [May 6, 2013]
+  Calculate our own zlib windowBits when decoding rather than trusting the
+    CMF bytes in the PNG datastream.
 
 Send comments/corrections/commendations to png-mng-implement at lists.sf.net
 (subscription required; visit
diff --git a/pngrutil.c b/pngrutil.c
index 01c3679..9c10e26 100644
--- a/pngrutil.c
+++ b/pngrutil.c
@@ -18,8 +18,6 @@
 
 #ifdef PNG_READ_SUPPORTED
 
-#define png_strtod(p,a,b) strtod(a,b)
-
 png_uint_32 PNGAPI
 png_get_uint_31(png_const_structrp png_ptr, png_const_bytep buf)
 {
@@ -4165,6 +4163,75 @@
 }
 #endif /* PNG_SEQUENTIAL_READ_SUPPORTED */
 
+#ifdef PNG_READ_OPTIMIZE_WINDOWBITS_SUPPORTED
+/* This is the code to to select a windowBits value to match the smallest
+ * possible sliding window needed to contain the entire uncompressed image.
+ */
+static unsigned int
+required_window_bits(png_alloc_size_t data_size)
+{
+   unsigned int windowBits = 15;
+   if (data_size <= 16384) /* else windowBits must be 15 */
+   {
+      unsigned int half_z_window_size = 1U << (windowBits-1);  /* 16384 */
+
+      do
+      {
+         half_z_window_size >>= 1;
+         --windowBits;
+      }
+      while (windowBits > 8 && data_size <= half_z_window_size);
+   }
+   return windowBits;
+}
+/* This is used below to find the size of an image to pass to png_deflate_claim,
+ * so it only needs to be accurate if the size is less than 16384 bytes (the
+ * point at which a lower LZ window size can be used.)
+ *
+ * To do: merge this with png_image_size() in pngwutil.c and put the result
+ * in png.c as a PNG_INTERNAL_FUNCTION.
+ */
+static png_alloc_size_t
+png_read_image_size(png_structrp png_ptr)
+{
+   /* Only return sizes up to the maximum of a png_uint_32, do this by limiting
+    * the width and height used to 15 bits.
+    */
+   png_uint_32 h = png_ptr->height;
+
+   if (png_ptr->rowbytes < 32768 && h < 32768)
+   {
+      if (png_ptr->interlaced)
+      {
+         /* Interlacing makes the image larger because of the replication of
+          * both the filter byte and the padding to a byte boundary.
+          */
+         png_uint_32 w = png_ptr->width;
+         unsigned int pd = png_ptr->pixel_depth;
+         png_alloc_size_t cb_base;
+         int pass;
+
+         for (cb_base=0, pass=0; pass<=6; ++pass)
+         {
+            png_uint_32 pw = PNG_PASS_COLS(w, pass);
+
+            if (pw > 0)
+               cb_base += (PNG_ROWBYTES(pd, pw)+1) * PNG_PASS_ROWS(h, pass);
+         }
+
+         return cb_base;
+      }
+
+      else
+         return (png_ptr->rowbytes+1) * h;
+   }
+
+   else
+      return 0xffffffffU;
+}
+
+#endif /* PNG_READ_OPTIMIZE_WINDOWBITS_SUPPORTED */
+
 void /* PRIVATE */
 png_read_start_row(png_structrp png_ptr)
 {
@@ -4449,14 +4516,20 @@
       png_free(png_ptr, buffer);
    }
 
-   /* Finally claim the zstream for the inflate of the IDAT data, use the bits
-    * value from the stream (note that this will result in a fatal error if the
-    * IDAT stream has a bogus deflate header window_bits value, but this should
-    * not be happening any longer!)
+   /* Finally claim the zstream for the inflate of the IDAT data, using the
+    * windowBts predicted from the uncompressed data size, not the value from
+    * the stream.  If READ_OPTIMIZE_WINDOWBITS_SUPPORTED is not defined, then
+    * simply use a 32kbyte window (windowBits=15).
     */
-   if (png_inflate_claim(png_ptr, png_IDAT, 0) != Z_OK)
+#ifdef PNG_READ_OPTIMIZE_WINDOWBITS_SUPPORTED
+   if (png_inflate_claim(png_ptr, png_IDAT,
+      required_window_bits(png_read_image_size(png_ptr))) != Z_OK)
+#else
+   if (png_inflate_claim(png_ptr, png_IDAT, 15) != Z_OK)
+#endif
       png_error(png_ptr, png_ptr->zstream.msg);
 
    png_ptr->flags |= PNG_FLAG_ROW_INIT;
 }
+
 #endif /* PNG_READ_SUPPORTED */