From 2108fad5ce6c8c16546d888672a9332e37845b45 Mon Sep 17 00:00:00 2001 From: "jiyong.min" Date: Tue, 29 Dec 2020 07:47:57 +0900 Subject: [PATCH] fix blinking animation on chromium - Cause: Parsing 'IEND' chunk was missed. - Solution: APNG Chromium patch has been applied. Add to parse 'IEND' chunk. (https://sourceforge.net/projects/apng/) Change-Id: Idfb952919580b52616a72ac9c9854309fa9ae46a --- pngpread.c | 84 ++++++++++++++++++++------------------------------------------ 1 file changed, 27 insertions(+), 57 deletions(-) diff --git a/pngpread.c b/pngpread.c index 2eaeca0..d12b6d3 100644 --- a/pngpread.c +++ b/pngpread.c @@ -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; -- 2.7.4