libwebp/libwebp-fix-transcode-of-loop-count-to-65535.patch
2020-03-13 22:25:17 +08:00

105 lines
3.5 KiB
Diff

From 4b282e13ad0cf7f1a3b4431788bddef1d6b11762 Mon Sep 17 00:00:00 2001
From: James Zern <jzern@google.com>
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
---
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 e74a915..a461ce2 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 c7a05c7..ee3e332 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 8063121..574e032 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 b61f273..caaed7a 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;
}
--
2.19.1