Index: libpng-1.2.31/pngpread.c
===================================================================
--- libpng-1.2.31.orig/pngpread.c
+++ libpng-1.2.31/pngpread.c
@@ -705,7 +705,6 @@ png_push_read_IDAT(png_structp png_ptr)
          save_size = png_ptr->save_buffer_size;
 
       png_calculate_crc(png_ptr, png_ptr->save_buffer_ptr, save_size);
-      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
          png_process_IDAT_data(png_ptr, png_ptr->save_buffer_ptr, save_size);
       png_ptr->idat_size -= save_size;
       png_ptr->buffer_size -= save_size;
@@ -727,7 +726,6 @@ png_push_read_IDAT(png_structp png_ptr)
          save_size = png_ptr->current_buffer_size;
 
       png_calculate_crc(png_ptr, png_ptr->current_buffer_ptr, save_size);
-      if (!(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
         png_process_IDAT_data(png_ptr, png_ptr->current_buffer_ptr, save_size);
 
       png_ptr->idat_size -= save_size;
@@ -753,57 +751,57 @@ void /* PRIVATE */
 png_process_IDAT_data(png_structp png_ptr, png_bytep buffer,
    png_size_t buffer_length)
 {
-   int ret;
-
-   if ((png_ptr->flags & PNG_FLAG_ZLIB_FINISHED) && buffer_length)
-      png_error(png_ptr, "Extra compression data");
-
    png_ptr->zstream.next_in = buffer;
    png_ptr->zstream.avail_in = (uInt)buffer_length;
-   for (;;)
+   while (png_ptr->zstream.avail_in > 0 &&
+         !(png_ptr->flags & PNG_FLAG_ZLIB_FINISHED))
    {
-      ret = inflate(&png_ptr->zstream, Z_PARTIAL_FLUSH);
-      if (ret != Z_OK)
+      int ret;
+
+      if (!(png_ptr->zstream.avail_out > 0))
       {
-         if (ret == Z_STREAM_END)
-         {
-            if (png_ptr->zstream.avail_in)
-               png_error(png_ptr, "Extra compressed data");
-            if (!(png_ptr->zstream.avail_out))
-            {
-               png_push_process_row(png_ptr);
-            }
-
-            png_ptr->mode |= PNG_AFTER_IDAT;
-            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-            break;
-         }
-         else if (ret == Z_BUF_ERROR)
-            break;
-         else
-            png_error(png_ptr, "Decompression Error");
+         png_ptr->zstream.avail_out =
+             (uInt) PNG_ROWBYTES(png_ptr->pixel_depth,
+             png_ptr->iwidth) + 1;
+         png_ptr->zstream.next_out = png_ptr->row_buf;
+      }
+
+      ret = inflate(&png_ptr->zstream, Z_SYNC_FLUSH);
+
+      if (ret != Z_OK && ret != Z_STREAM_END)
+      {
+        png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
+
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+            png_ptr->pass > 6)
+           png_warning(png_ptr, "Truncated compressed data in IDAT");
+        else
+           png_error(png_ptr, "Decompression error in IDAT");
+
+         return;
       }
-      if (!(png_ptr->zstream.avail_out))
+
+      if (png_ptr->zstream.next_out != png_ptr->row_buf)
       {
-         if ((
-#if defined(PNG_READ_INTERLACING_SUPPORTED)
-             png_ptr->interlaced && png_ptr->pass > 6) ||
-             (!png_ptr->interlaced &&
-#endif
-             png_ptr->row_number == png_ptr->num_rows))
+         if (png_ptr->row_number >= png_ptr->num_rows ||
+            png_ptr->pass > 6)
          {
-           if (png_ptr->zstream.avail_in)
-             png_warning(png_ptr, "Too much data in IDAT chunks");
+           png_warning(png_ptr, "Extra compressed data in IDAT");
            png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
-           break;
+           return;
          }
-         png_push_process_row(png_ptr);
-         png_ptr->zstream.avail_out = (uInt)png_ptr->irowbytes;
-         png_ptr->zstream.next_out = png_ptr->row_buf;
+
+        if (png_ptr->zstream.avail_out == 0)
+           png_push_process_row(png_ptr);
+
       }
-      else
-         break;
+
+      if (ret == Z_STREAM_END)
+        png_ptr->flags |= PNG_FLAG_ZLIB_FINISHED;
    }
+
+   if (png_ptr->zstream.avail_in > 0)
+     png_warning(png_ptr, "Extra compression data");
 }
 
 void /* PRIVATE */
Index: libpng-1.2.31/pngrutil.c
===================================================================
--- libpng-1.2.31.orig/pngrutil.c
+++ libpng-1.2.31/pngrutil.c
@@ -1792,6 +1792,7 @@ png_handle_sCAL(png_structp png_ptr, png
    if (png_ptr->chunkdata == NULL)
    {
       png_warning(png_ptr, "Out of memory while processing sCAL chunk");
+      png_crc_finish(png_ptr, length);
       return;
    }
    slength = (png_size_t)length;
@@ -1813,6 +1814,8 @@ png_handle_sCAL(png_structp png_ptr, png
    if (*vp)
    {
       png_warning(png_ptr, "malformed width string in sCAL chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
       return;
    }
 #else
@@ -1821,6 +1824,8 @@ png_handle_sCAL(png_structp png_ptr, png
    if (swidth == NULL)
    {
       png_warning(png_ptr, "Out of memory while processing sCAL chunk width");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
       return;
    }
    png_memcpy(swidth, ep, (png_size_t)png_strlen(ep));
@@ -1848,6 +1853,8 @@ png_handle_sCAL(png_structp png_ptr, png
    if (*vp)
    {
       png_warning(png_ptr, "malformed height string in sCAL chunk");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
       return;
    }
 #else
@@ -1856,6 +1863,9 @@ png_handle_sCAL(png_structp png_ptr, png
    if (sheight == NULL)
    {
       png_warning(png_ptr, "Out of memory while processing sCAL chunk height");
+      png_free(png_ptr, png_ptr->chunkdata);
+      png_ptr->chunkdata = NULL;
+      png_free(png_ptr, swidth);
       return;
    }
    png_memcpy(sheight, ep, (png_size_t)png_strlen(ep));
