 +
 +    png_ptr->next_seq_num++;
 +}
-+#endif /* READ_APNG */
++#endif /* PNG_READ_APNG_SUPPORTED */
 +
  #ifdef PNG_READ_UNKNOWN_CHUNKS_SUPPORTED
  /* Utility function for png_handle_unknown; set up png_ptr::unknown_chunk */
  static int
-@@ -3162,7 +3341,11 @@
-    if (PNG_USER_CHUNK_MALLOC_MAX < limit)
-       limit = PNG_USER_CHUNK_MALLOC_MAX;
- # endif
-+#ifdef PNG_READ_APNG_SUPPORTED
-+   if (png_ptr->chunk_name == png_IDAT || png_ptr->chunk_name == png_fdAT)
-+#else
-    if (png_ptr->chunk_name == png_IDAT)
-+#endif
-    {
-       png_alloc_size_t idat_limit = PNG_UINT_31_MAX;
-       size_t row_factor =
-@@ -4166,6 +4349,38 @@
+@@ -4165,7 +4343,38 @@
+       {
           uInt avail_in;
           png_bytep buffer;
- 
 +#ifdef PNG_READ_APNG_SUPPORTED
 +         png_uint_32 bytes_to_skip = 0;
 +

+            else
+               png_write_fdAT(png_ptr, data, size);
+         }
+#endif /* WRITE_APNG */
+
          png_ptr->mode |= PNG_HAVE_IDAT;
 
          png_ptr->zstream.next_out = data;
@@ -1050,7 +1065,17 @@
 #endif
 
          if (size > 0)
+#ifdef PNG_WRITE_APNG_SUPPORTED
+         {
+            if (png_ptr->num_frames_written == 0)
+#endif
             png_write_complete_chunk(png_ptr, png_IDAT, data, size);
+#ifdef PNG_WRITE_APNG_SUPPORTED
+            else
+               png_write_fdAT(png_ptr, data, size);
+         }
+#endif /* WRITE_APNG */
+
          png_ptr->zstream.avail_out = 0;
          png_ptr->zstream.next_out = NULL;
          png_ptr->mode |= PNG_HAVE_IDAT | PNG_AFTER_IDAT;
@@ -1885,6 +1910,82 @@
 }
 #endif
 

+        if (png_ptr->chunk_name == png_IDAT)
+        {
+            /* discard trailing IDATs for the first frame */
+            if (have_chunk_after_DAT || png_ptr->num_frames_read > 1)
+                png_error(png_ptr, "png_read_frame_head(): out of place IDAT");
+            png_crc_finish(png_ptr, length);
+        }
