From af0e4fbb0669026659983691a15dad23a9f196c1 Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 9 May 2018 17:36:13 -0700 Subject: [PATCH] gif2webp: fix transcode of loop count=65535 with loop_compatibility disabled (the default), non-zero loop counts will be incremented by 1 for browser rendering compatibility. the max, 65535, is a special case as the muxer will fail if it is exceeded; avoid increasing the limit in this case. this isn't 100% correct, but should be close enough given the high number of iterations. BUG=webp:382 Change-Id: Icde3e98a58e9ee89604a72fafda30ab71060dec5 --- examples/anim_diff.c | 14 ++++++++++++-- examples/anim_util.c | 2 ++ examples/anim_util.h | 6 ++++++ examples/gif2webp.c | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/examples/anim_diff.c b/examples/anim_diff.c index e74a915f..a461ce2a 100644 --- a/examples/anim_diff.c +++ b/examples/anim_diff.c @@ -143,8 +143,18 @@ static int CompareAnimatedImagePair(const AnimatedImage* const img1, if (!ok) return 0; // These are fatal failures, can't proceed. if (is_multi_frame_image) { // Checks relevant for multi-frame images only. - ok = CompareValues(img1->loop_count, img2->loop_count, - "Loop count mismatch") && ok; + int max_loop_count_workaround = 0; + // Transcodes to webp increase the gif loop count by 1 for compatibility. + // When the gif has the maximum value the webp value will be off by one. + if ((img1->format == ANIM_GIF && img1->loop_count == 65536 && + img2->format == ANIM_WEBP && img2->loop_count == 65535) || + (img1->format == ANIM_WEBP && img1->loop_count == 65535 && + img2->format == ANIM_GIF && img2->loop_count == 65536)) { + max_loop_count_workaround = 1; + } + ok = (max_loop_count_workaround || + CompareValues(img1->loop_count, img2->loop_count, + "Loop count mismatch")) && ok; ok = CompareBackgroundColor(img1->bgcolor, img2->bgcolor, premultiply) && ok; } diff --git a/examples/anim_util.c b/examples/anim_util.c index c7a05c7c..ee3e3326 100644 --- a/examples/anim_util.c +++ b/examples/anim_util.c @@ -275,6 +275,7 @@ static int ReadAnimatedWebP(const char filename[], prev_frame_timestamp = timestamp; } ok = dump_ok; + if (ok) image->format = ANIM_WEBP; End: WebPAnimDecoderDelete(dec); @@ -687,6 +688,7 @@ static int ReadAnimatedGIF(const char filename[], AnimatedImage* const image, } } } + image->format = ANIM_GIF; DGifCloseFile(gif, NULL); return 1; } diff --git a/examples/anim_util.h b/examples/anim_util.h index 8063121f..574e032d 100644 --- a/examples/anim_util.h +++ b/examples/anim_util.h @@ -22,6 +22,11 @@ extern "C" { #endif +typedef enum { + ANIM_GIF, + ANIM_WEBP +} AnimatedFileFormat; + typedef struct { uint8_t* rgba; // Decoded and reconstructed full frame. int duration; // Frame duration in milliseconds. @@ -29,6 +34,7 @@ typedef struct { } DecodedFrame; typedef struct { + AnimatedFileFormat format; uint32_t canvas_width; uint32_t canvas_height; uint32_t bgcolor; diff --git a/examples/gif2webp.c b/examples/gif2webp.c index b61f273e..caaed7a6 100644 --- a/examples/gif2webp.c +++ b/examples/gif2webp.c @@ -478,7 +478,7 @@ int main(int argc, const char *argv[]) { stored_loop_count = 1; loop_count = 1; } - } else if (loop_count > 0) { + } else if (loop_count > 0 && loop_count < 65535) { // adapt GIF's semantic to WebP's (except in the infinite-loop case) loop_count += 1; }