--- png.c +++ png.c @@ -4607,3 +4607,14 @@ #endif /* SIMPLIFIED READ/WRITE */ #endif /* READ || WRITE */ + +/* ANIMATED PNG SUPPORT */ +#ifdef PNG_APNG_SUPPORTED +int PNG_APNG_USED = 1; + +void PNGAPI +png_use_apng(int use) +{ + PNG_APNG_USED = use; +} +#endif /* APNG */ --- png.h +++ png.h @@ -3324,6 +3324,8 @@ PNG_EXPORT(267, void, png_write_frame_tail, (png_structp png_ptr, png_infop info_ptr)); #endif /* WRITE_APNG */ + +PNG_EXPORT(268, void, png_use_apng, (int use)); #endif /* APNG */ /* Maintainer: Put new public prototypes here ^, in libpng.3, in project @@ -3335,7 +3337,7 @@ */ #ifdef PNG_EXPORT_LAST_ORDINAL #ifdef PNG_APNG_SUPPORTED - PNG_EXPORT_LAST_ORDINAL(269); + PNG_EXPORT_LAST_ORDINAL(270); #else PNG_EXPORT_LAST_ORDINAL(249); #endif /* APNG */ --- pngpread.c +++ pngpread.c @@ -196,7 +196,7 @@ chunk_name = png_ptr->chunk_name; #ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->num_frames_read > 0 && + if (PNG_APNG_USED && png_ptr->num_frames_read > 0 && png_ptr->num_frames_read < info_ptr->num_frames) { if (chunk_name == png_IDAT) @@ -345,7 +345,8 @@ else if (chunk_name == png_IDAT) { #ifdef PNG_READ_APNG_SUPPORTED - png_have_info(png_ptr, info_ptr); + if (PNG_APNG_USED) + png_have_info(png_ptr, info_ptr); #endif png_ptr->idat_size = png_ptr->push_length; png_ptr->process_mode = PNG_READ_IDAT_MODE; @@ -494,13 +495,13 @@ #endif #ifdef PNG_READ_APNG_SUPPORTED - else if (chunk_name == png_acTL) + else if (PNG_APNG_USED && chunk_name == png_acTL) { PNG_PUSH_SAVE_BUFFER_IF_FULL png_handle_acTL(png_ptr, info_ptr, png_ptr->push_length); } - else if (chunk_name == png_fcTL) + else if (PNG_APNG_USED && chunk_name == png_fcTL) { PNG_PUSH_SAVE_BUFFER_IF_FULL png_handle_fcTL(png_ptr, info_ptr, png_ptr->push_length); @@ -640,7 +641,14 @@ /* TODO: this code can be commoned up with the same code in push_read */ #ifdef PNG_READ_APNG_SUPPORTED - PNG_PUSH_SAVE_BUFFER_IF_LT(12) + if (PNG_APNG_USED) + { + PNG_PUSH_SAVE_BUFFER_IF_LT(12) + } + else + { + PNG_PUSH_SAVE_BUFFER_IF_LT(8) + } #else PNG_PUSH_SAVE_BUFFER_IF_LT(8) #endif @@ -652,7 +660,7 @@ png_ptr->mode |= PNG_HAVE_CHUNK_HEADER; #ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0) + if (PNG_APNG_USED && png_ptr->chunk_name != png_fdAT && png_ptr->num_frames_read > 0) { if ((png_ptr->flags & PNG_FLAG_ZSTREAM_ENDED) != 0) { @@ -677,7 +685,7 @@ else #endif #ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->chunk_name != png_IDAT && png_ptr->num_frames_read == 0) + if (png_ptr->chunk_name != png_IDAT && (!PNG_APNG_USED || png_ptr->num_frames_read == 0)) #else if (png_ptr->chunk_name != png_IDAT) #endif @@ -688,9 +696,12 @@ png_error(png_ptr, "Not enough compressed data"); #ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->frame_end_fn != NULL) - (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); - png_ptr->num_frames_read++; + if (PNG_APNG_USED) + { + if (png_ptr->frame_end_fn != NULL) + (*(png_ptr->frame_end_fn))(png_ptr, png_ptr->num_frames_read); + png_ptr->num_frames_read++; + } #endif return; @@ -699,7 +710,7 @@ png_ptr->idat_size = png_ptr->push_length; #ifdef PNG_READ_APNG_SUPPORTED - if (png_ptr->num_frames_read > 0) + if (PNG_APNG_USED && png_ptr->num_frames_read > 0) { png_ensure_sequence_number(png_ptr, 4); png_ptr->idat_size -= 4; @@ -780,7 +791,7 @@ #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) == 0 && + if (PNG_APNG_USED && (png_ptr->apng_flags & PNG_APNG_APP) == 0 && png_ptr->num_frames_read > 0) { png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; --- pngpriv.h +++ pngpriv.h @@ -2197,6 +2197,10 @@ PNG_EMPTY); #endif +#ifdef PNG_APNG_SUPPORTED +extern int PNG_APNG_USED; +#endif + /* Maintainer: Put new private prototypes here ^ */ #include "pngdebug.h" --- pngread.c +++ pngread.c @@ -162,7 +162,8 @@ else if (chunk_name == png_IDAT) { #ifdef PNG_READ_APNG_SUPPORTED - png_have_info(png_ptr, info_ptr); + if (PNG_APNG_USED) + png_have_info(png_ptr, info_ptr); #endif png_ptr->idat_size = length; break; @@ -259,13 +260,13 @@ #endif #ifdef PNG_READ_APNG_SUPPORTED - else if (chunk_name == png_acTL) + else if (PNG_APNG_USED && chunk_name == png_acTL) png_handle_acTL(png_ptr, info_ptr, length); - else if (chunk_name == png_fcTL) + else if (PNG_APNG_USED && chunk_name == png_fcTL) png_handle_fcTL(png_ptr, info_ptr, length); - else if (chunk_name == png_fdAT) + else if (PNG_APNG_USED && chunk_name == png_fdAT) png_handle_fdAT(png_ptr, info_ptr, length); #endif --- pngrutil.c +++ pngrutil.c @@ -3342,7 +3342,7 @@ 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) + if (png_ptr->chunk_name == png_IDAT || (PNG_APNG_USED && png_ptr->chunk_name == png_fdAT)) #else if (png_ptr->chunk_name == png_IDAT) #endif @@ -4349,50 +4349,53 @@ uInt avail_in; png_bytep buffer; -#ifdef PNG_READ_APNG_SUPPORTED - png_uint_32 bytes_to_skip = 0; - - while (png_ptr->idat_size == 0 || bytes_to_skip != 0) + if (PNG_APNG_USED) { - png_crc_finish(png_ptr, bytes_to_skip); - bytes_to_skip = 0; + png_uint_32 bytes_to_skip = 0; - png_ptr->idat_size = png_read_chunk_header(png_ptr); - if (png_ptr->num_frames_read == 0) + while (png_ptr->idat_size == 0 || bytes_to_skip != 0) { - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); - } - else - { - if (png_ptr->chunk_name == png_IEND) - png_error(png_ptr, "Not enough image data"); - if (png_ptr->chunk_name != png_fdAT) + png_crc_finish(png_ptr, bytes_to_skip); + bytes_to_skip = 0; + + png_ptr->idat_size = png_read_chunk_header(png_ptr); + if (png_ptr->num_frames_read == 0) { - png_warning(png_ptr, "Skipped (ignored) a chunk " - "between APNG chunks"); - bytes_to_skip = png_ptr->idat_size; - continue; + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); } + else + { + if (png_ptr->chunk_name == png_IEND) + png_error(png_ptr, "Not enough image data"); + if (png_ptr->chunk_name != png_fdAT) + { + png_warning(png_ptr, "Skipped (ignored) a chunk " + "between APNG chunks"); + bytes_to_skip = png_ptr->idat_size; + continue; + } - png_ensure_sequence_number(png_ptr, png_ptr->idat_size); + png_ensure_sequence_number(png_ptr, png_ptr->idat_size); - png_ptr->idat_size -= 4; + png_ptr->idat_size -= 4; + } } } -#else - while (png_ptr->idat_size == 0) + else { - png_crc_finish(png_ptr, 0); + while (png_ptr->idat_size == 0) + { + png_crc_finish(png_ptr, 0); - png_ptr->idat_size = png_read_chunk_header(png_ptr); - /* This is an error even in the 'check' case because the code just - * consumed a non-IDAT header. - */ - if (png_ptr->chunk_name != png_IDAT) - png_error(png_ptr, "Not enough image data"); + png_ptr->idat_size = png_read_chunk_header(png_ptr); + /* This is an error even in the 'check' case because the code just + * consumed a non-IDAT header. + */ + if (png_ptr->chunk_name != png_IDAT) + png_error(png_ptr, "Not enough image data"); + } } -#endif /* READ_APNG */ avail_in = png_ptr->IDAT_read_size; @@ -4457,7 +4460,8 @@ png_ptr->mode |= PNG_AFTER_IDAT; png_ptr->flags |= PNG_FLAG_ZSTREAM_ENDED; #ifdef PNG_READ_APNG_SUPPORTED - png_ptr->num_frames_read++; + if (PNG_APNG_USED) + png_ptr->num_frames_read++; #endif if (png_ptr->zstream.avail_in > 0 || png_ptr->idat_size > 0) --- pngwrite.c +++ pngwrite.c @@ -129,7 +129,7 @@ * flag here too. */ #ifdef PNG_WRITE_APNG_SUPPORTED - if ((info_ptr->valid & PNG_INFO_acTL) != 0) + if (PNG_APNG_USED && (info_ptr->valid & PNG_INFO_acTL) != 0) png_write_acTL(png_ptr, info_ptr->num_frames, info_ptr->num_plays); #endif #ifdef PNG_GAMMA_SUPPORTED @@ -370,7 +370,7 @@ png_error(png_ptr, "No IDATs written into file"); #ifdef PNG_WRITE_APNG_SUPPORTED - if (png_ptr->num_frames_written != png_ptr->num_frames_to_write) + if (PNG_APNG_USED && png_ptr->num_frames_written != png_ptr->num_frames_to_write) png_error(png_ptr, "Not enough frames written"); #endif --- pngwutil.c +++ pngwutil.c @@ -1010,7 +1010,7 @@ if (size > 0) #ifdef PNG_WRITE_APNG_SUPPORTED { - if (png_ptr->num_frames_written == 0) + if (!PNG_APNG_USED || png_ptr->num_frames_written == 0) #endif png_write_complete_chunk(png_ptr, png_IDAT, data, size); #ifdef PNG_WRITE_APNG_SUPPORTED @@ -1067,7 +1067,7 @@ if (size > 0) #ifdef PNG_WRITE_APNG_SUPPORTED { - if (png_ptr->num_frames_written == 0) + if (!PNG_APNG_USED || png_ptr->num_frames_written == 0) #endif png_write_complete_chunk(png_ptr, png_IDAT, data, size); #ifdef PNG_WRITE_APNG_SUPPORTED --- scripts/symbols.def +++ scripts/symbols.def @@ -273,3 +273,4 @@ png_set_progressive_frame_fn @267 png_write_frame_head @268 png_write_frame_tail @269 + png_use_apng @270