From b7d209a448b9387b2df0ffe4b7913b950bbfab77 Mon Sep 17 00:00:00 2001 From: Urvang Joshi Date: Thu, 11 Sep 2014 14:35:21 -0700 Subject: [PATCH] gif2webp: Handle frames with missing graphic control extension According to the GIF spec (http://www.w3.org/Graphics/GIF/spec-gif89a.txt), this block is optional, and its scope is only the first graphic rendering block that follows. The spec doesn't mention what default values of frame dimensions, offsets, duration and transparent index to use in such a case, though. So, we use the defaults used by GIF reader in Chromium: https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/platform/image-decoders/gif/GIFImageReader.h&l=186 (cherry picked from commit d51f3e40698284ffc4831e7d8de7ae59d453f41d) Change-Id: Iecc6967847192483770e85ac15fe2835cd01ce7b --- examples/gif2webp.c | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/examples/gif2webp.c b/examples/gif2webp.c index 395068b9..e0381f7f 100644 --- a/examples/gif2webp.c +++ b/examples/gif2webp.c @@ -46,7 +46,18 @@ //------------------------------------------------------------------------------ -static int transparent_index = -1; // Index of transparent color in the map. +static int transparent_index; // Index of transparent color in the map. + +static void ResetFrameInfo(WebPMuxFrameInfo* const info) { + WebPDataInit(&info->bitstream); + info->x_offset = 0; + info->y_offset = 0; + info->duration = 0; + info->id = WEBP_CHUNK_ANMF; + info->dispose_method = WEBP_MUX_DISPOSE_NONE; + info->blend_method = WEBP_MUX_BLEND; + transparent_index = -1; // Opaque frame by default. +} static void SanitizeKeyFrameIntervals(size_t* const kmin_ptr, size_t* const kmax_ptr) { @@ -278,10 +289,7 @@ int main(int argc, const char *argv[]) { size_t kmax = 0; int allow_mixed = 0; // If true, each frame can be lossy or lossless. - memset(&info, 0, sizeof(info)); - info.id = WEBP_CHUNK_ANMF; - info.dispose_method = WEBP_MUX_DISPOSE_BACKGROUND; - info.blend_method = WEBP_MUX_BLEND; + ResetFrameInfo(&info); if (!WebPConfigInit(&config) || !WebPPictureInit(&frame)) { fprintf(stderr, "Error! Version mismatch!\n"); @@ -492,6 +500,11 @@ int main(int argc, const char *argv[]) { goto End; } is_first_frame = 0; + + // In GIF, graphic control extensions are optional for a frame, so we + // may not get one before reading the next frame. To handle this case, + // we reset frame properties to reasonable defaults for the next frame. + ResetFrameInfo(&info); break; } case EXTENSION_RECORD_TYPE: {