fix blinking animation on chromium
[platform/upstream/libpng.git] / pngpread.c
index 2eaeca0..d12b6d3 100644 (file)
@@ -202,42 +202,29 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
       if (chunk_name == png_IDAT)
       {
          /* Discard trailing IDATs for the first frame */
-         if (png_ptr->mode & PNG_HAVE_fcTL || png_ptr->num_frames_read > 1)
+         if ((png_ptr->mode & PNG_HAVE_fcTL) != 0 ||
+             png_ptr->num_frames_read > 1)
             png_error(png_ptr, "out of place IDAT");
 
-         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-         {
-            png_push_save_buffer(png_ptr);
-            return;
-         }
-
+         PNG_PUSH_SAVE_BUFFER_IF_FULL
+         png_crc_finish(png_ptr, png_ptr->push_length);
          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-         return;
       }
+
       else if (chunk_name == png_fdAT)
       {
-         if (png_ptr->buffer_size < 4)
-         {
-            png_push_save_buffer(png_ptr);
-            return;
-         }
-
+         PNG_PUSH_SAVE_BUFFER_IF_LT(4)
          png_ensure_sequence_number(png_ptr, 4);
 
-         if (!(png_ptr->mode & PNG_HAVE_fcTL))
+         if ((png_ptr->mode & PNG_HAVE_fcTL) == 0)
          {
             /* Discard trailing fdATs for frames other than the first */
             if (png_ptr->num_frames_read < 2)
                png_error(png_ptr, "out of place fdAT");
 
-            if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-            {
-               png_push_save_buffer(png_ptr);
-               return;
-            }
-
+            PNG_PUSH_SAVE_BUFFER_IF_FULL
+            png_crc_finish(png_ptr, png_ptr->push_length);
             png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-            return;
          }
 
          else
@@ -246,25 +233,18 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
             png_ptr->idat_size = png_ptr->push_length - 4;
             png_ptr->mode |= PNG_HAVE_IDAT;
             png_ptr->process_mode = PNG_READ_IDAT_MODE;
-
-            return;
          }
       }
 
       else if (chunk_name == png_fcTL)
       {
-         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-         {
-            png_push_save_buffer(png_ptr);
-            return;
-         }
-
+         PNG_PUSH_SAVE_BUFFER_IF_FULL
          png_read_reset(png_ptr);
          png_ptr->mode &= ~PNG_HAVE_fcTL;
 
          png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
 
-         if (!(png_ptr->mode & PNG_HAVE_fcTL))
+         if ((png_ptr->mode & PNG_HAVE_fcTL) == 0)
             png_error(png_ptr, "missing required fcTL chunk");
 
          png_read_reinit(png_ptr, info_ptr);
@@ -274,21 +254,24 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
             (*(png_ptr->frame_info_fn))(png_ptr, png_ptr->num_frames_read);
 
          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
+      }
 
-         return;
+      else if (chunk_name == png_IEND)
+      {
+         PNG_PUSH_SAVE_BUFFER_IF_FULL
+         png_warning(png_ptr, "Number of actual frames fewer than expected");
+         png_crc_finish(png_ptr, png_ptr->push_length);
+         png_ptr->process_mode = PNG_READ_DONE_MODE;
+         png_push_have_end(png_ptr, info_ptr);
       }
 
       else
       {
-         if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-         {
-            png_push_save_buffer(png_ptr);
-            return;
-         }
+         PNG_PUSH_SAVE_BUFFER_IF_FULL
          png_warning(png_ptr, "Skipped (ignored) a chunk "
                               "between APNG chunks");
+         png_crc_finish(png_ptr, png_ptr->push_length);
          png_ptr->mode &= ~PNG_HAVE_CHUNK_HEADER;
-         return;
       }
 
       return;
@@ -512,23 +495,13 @@ png_push_read_chunk(png_structrp png_ptr, png_inforp info_ptr)
 #ifdef PNG_READ_APNG_SUPPORTED
    else if (chunk_name == png_acTL)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length);
    }
 
    else if (chunk_name == png_fcTL)
    {
-      if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-      {
-         png_push_save_buffer(png_ptr);
-         return;
-      }
-
+      PNG_PUSH_SAVE_BUFFER_IF_FULL
       png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length);
    }
 
@@ -681,7 +654,7 @@ png_push_read_IDAT(png_structrp png_ptr)
 #ifdef PNG_READ_APNG_SUPPORTED
       if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0)
       {
-          if (png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED)
+          if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) != 0)
           {
               png_ptr->process_mode = PNG_READ_CHUNK_MODE;
               if (png_ptr->frame_end_fn != NULL)
@@ -693,11 +666,7 @@ png_push_read_IDAT(png_structrp png_ptr)
           {
               if (png_ptr->chunk_name == png_IEND)
                   png_error(png_ptr, "Not enough image data");
-              if (png_ptr->push_length + 4 > png_ptr->buffer_size)
-              {
-                 png_push_save_buffer(png_ptr);
-                 return;
-              }
+              PNG_PUSH_SAVE_BUFFER_IF_FULL
               png_warning(png_ptr, "Skipping (ignoring) a chunk between "
                                    "APNG chunks");
               png_crc_finish(png_ptr, png_ptr->push_length);
@@ -811,7 +780,8 @@ png_process_IDAT_data(png_structrp png_ptr, png_bytep buffer,
 
 #ifdef PNG_READ_APNG_SUPPORTED
    /* If the app is not APNG-aware, decode only the first frame */
-   if (!(png_ptr->apng_flags & PNG_APNG_APP) && png_ptr->num_frames_read > 0)
+   if ((png_ptr->apng_flags & PNG_APNG_APP) == 0 &&
+      png_ptr->num_frames_read > 0)
    {
      png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED;
      return;