From ad452735c363843a0764b7ba4b24eb52b705ecb2 Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 20 Mar 2013 12:41:29 -0700 Subject: [PATCH 1/3] WebPBitstreamFeatures: add has_animation field Change-Id: I3e181ce463b0e4833bfd29f8052b21ebe0bca977 --- src/dec/webp.c | 11 +++++++---- src/webp/decode.h | 9 +++++---- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/src/dec/webp.c b/src/dec/webp.c index ec05ff2f..10b2e264 100644 --- a/src/dec/webp.c +++ b/src/dec/webp.c @@ -276,6 +276,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, int* const width, int* const height, int* const has_alpha, + int* const has_animation, WebPHeaderStructure* const headers) { int found_riff = 0; int found_vp8x = 0; @@ -309,6 +310,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, return VP8_STATUS_BITSTREAM_ERROR; } if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG); + if (has_animation != NULL) *has_animation = !!(flags & ANIMATION_FLAG); if (found_vp8x && headers == NULL) { return VP8_STATUS_OK; // Return features from VP8X header. } @@ -371,9 +373,9 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { assert(headers != NULL); - // fill out headers, ignore width/height/has_alpha. + // fill out headers, ignore width/height/has_alpha/has_animation. return ParseHeadersInternal(headers->data, headers->data_size, - NULL, NULL, NULL, headers); + NULL, NULL, NULL, NULL, headers); } //------------------------------------------------------------------------------ @@ -625,10 +627,11 @@ static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, } DefaultFeatures(features); - // Only parse enough of the data to retrieve width/height/has_alpha. + // Only parse enough of the data to retrieve the features. return ParseHeadersInternal(data, data_size, &features->width, &features->height, - &features->has_alpha, NULL); + &features->has_alpha, &features->has_animation, + NULL); } //------------------------------------------------------------------------------ diff --git a/src/webp/decode.h b/src/webp/decode.h index 089ff66a..181eb186 100644 --- a/src/webp/decode.h +++ b/src/webp/decode.h @@ -392,9 +392,10 @@ WEBP_EXTERN(const WebPDecBuffer*) WebPIDecodedArea( // Features gathered from the bitstream struct WebPBitstreamFeatures { - int width; // Width in pixels, as read from the bitstream. - int height; // Height in pixels, as read from the bitstream. - int has_alpha; // True if the bitstream contains an alpha channel. + int width; // Width in pixels, as read from the bitstream. + int height; // Height in pixels, as read from the bitstream. + int has_alpha; // True if the bitstream contains an alpha channel. + int has_animation; // True if the bitstream is an animation. // Unused for now: int bitstream_version; // should be 0 for now. TODO(later) @@ -402,7 +403,7 @@ struct WebPBitstreamFeatures { // recommended. int rotate; // TODO(later) int uv_sampling; // should be 0 for now. TODO(later) - uint32_t pad[3]; // padding for later use + uint32_t pad[2]; // padding for later use }; // Internal, version-checked, entry point From 302efcdb41a83a648a9b92df5e26fc3b7b8841f0 Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 20 Mar 2013 12:59:29 -0700 Subject: [PATCH 2/3] Decode: return more meaningful error for animation VP8_STATUS_NOT_ENOUGH_DATA -> VP8_STATUS_UNSUPPORTED_FEATURE Change-Id: If5ee9fd2c99fc5502996d3c786848fd9cc118fe7 --- src/dec/webp.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/dec/webp.c b/src/dec/webp.c index 10b2e264..39d90188 100644 --- a/src/dec/webp.c +++ b/src/dec/webp.c @@ -372,10 +372,19 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, } VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { + VP8StatusCode status; + int has_animation = 0; assert(headers != NULL); - // fill out headers, ignore width/height/has_alpha/has_animation. - return ParseHeadersInternal(headers->data, headers->data_size, - NULL, NULL, NULL, NULL, headers); + // fill out headers, ignore width/height/has_alpha. + status = ParseHeadersInternal(headers->data, headers->data_size, + NULL, NULL, NULL, &has_animation, headers); + if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) { + // TODO(jzern): full support of animation frames will require API additions. + if (has_animation) { + status = VP8_STATUS_UNSUPPORTED_FEATURE; + } + } + return status; } //------------------------------------------------------------------------------ From a788644f93363b4f176ef1ec4c736763d42d8fe2 Mon Sep 17 00:00:00 2001 From: James Zern Date: Wed, 20 Mar 2013 13:05:04 -0700 Subject: [PATCH 3/3] dwebp: warn when decoding animated webp's the decode will fail; provide a bit more background info Change-Id: Iecccb09cf0fa9f8c1c3e87636a55e1f251dee023 --- examples/dwebp.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/dwebp.c b/examples/dwebp.c index d66a1069..a3dc615e 100644 --- a/examples/dwebp.c +++ b/examples/dwebp.c @@ -460,6 +460,13 @@ int main(int argc, const char *argv[]) { goto end; } + if (bitstream->has_animation) { + fprintf(stderr, + "Error! Decoding of an animated WebP file is not supported.\n" + " Use webpmux to extract the individual frames or\n" + " vwebp to view this image.\n"); + } + switch (format) { case PNG: #ifdef HAVE_WINCODEC_H