From 86c0031eb2c24f78d4dcfc5dab752ebc9f511607 Mon Sep 17 00:00:00 2001 From: Pascal Massimino Date: Wed, 21 Aug 2013 21:56:35 +0000 Subject: [PATCH] add a 'format' field to WebPBitstreamFeatures Change-Id: I79a688e4c34fb77527127bbdf4bc844efa6aa9a4 --- examples/dwebp.c | 16 ++++++++++++---- src/dec/webp.c | 17 ++++++++++++----- src/webp/decode.h | 4 ++-- 3 files changed, 26 insertions(+), 11 deletions(-) diff --git a/examples/dwebp.c b/examples/dwebp.c index 702d9ae7..eb40b747 100644 --- a/examples/dwebp.c +++ b/examples/dwebp.c @@ -573,6 +573,10 @@ static const char* const kStatusMessages[] = { "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" }; +static const char* const kFormatType[] = { + "unspecified", "lossy", "lossless" +}; + int main(int argc, const char *argv[]) { int ok = 0; const char *in_file = NULL; @@ -741,14 +745,18 @@ int main(int argc, const char *argv[]) { } if (out_file != NULL) { - fprintf(stderr, "Decoded %s. Dimensions: %d x %d%s. Now saving...\n", + fprintf(stderr, "Decoded %s. Dimensions: %d x %d %s. Format: %s. " + "Now saving...\n", in_file, output_buffer->width, output_buffer->height, - bitstream->has_alpha ? " (with alpha)" : ""); + bitstream->has_alpha ? " (with alpha)" : "", + kFormatType[bitstream->format]); ok = SaveOutput(output_buffer, format, out_file); } else { - fprintf(stderr, "File %s can be decoded (dimensions: %d x %d)%s.\n", + fprintf(stderr, "File %s can be decoded " + "(dimensions: %d x %d %s. Format: %s).\n", in_file, output_buffer->width, output_buffer->height, - bitstream->has_alpha ? " (with alpha)" : ""); + bitstream->has_alpha ? " (with alpha)" : "", + kFormatType[bitstream->format]); fprintf(stderr, "Nothing written; " "use -o flag to save the result as e.g. PNG.\n"); } diff --git a/src/dec/webp.c b/src/dec/webp.c index 6e060fbd..21d16070 100644 --- a/src/dec/webp.c +++ b/src/dec/webp.c @@ -285,6 +285,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, int* const height, int* const has_alpha, int* const has_animation, + int* const format, WebPHeaderStructure* const headers) { int canvas_width = 0; int canvas_height = 0; @@ -292,6 +293,9 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, int image_height = 0; int found_riff = 0; int found_vp8x = 0; + int animation_present = 0; + int fragments_present = 0; + VP8StatusCode status; WebPHeaderStructure hdrs; @@ -312,8 +316,6 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, // Skip over VP8X. { uint32_t flags = 0; - int animation_present; - int fragments_present; status = ParseVP8X(&data, &data_size, &found_vp8x, &canvas_width, &canvas_height, &flags); if (status != VP8_STATUS_OK) { @@ -328,6 +330,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, } if (has_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG); if (has_animation != NULL) *has_animation = animation_present; + if (format != NULL) *format = 0; // default = undefined if (found_vp8x && (animation_present || fragments_present) && headers == NULL) { @@ -359,6 +362,10 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data, return VP8_STATUS_BITSTREAM_ERROR; } + if (format != NULL && !(animation_present || fragments_present)) { + *format = hdrs.is_lossless ? 2 : 1; + } + if (!hdrs.is_lossless) { if (data_size < VP8_FRAME_HEADER_SIZE) { return VP8_STATUS_NOT_ENOUGH_DATA; @@ -405,7 +412,8 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) { assert(headers != NULL); // fill out headers, ignore width/height/has_alpha. status = ParseHeadersInternal(headers->data, headers->data_size, - NULL, NULL, NULL, &has_animation, headers); + NULL, NULL, NULL, &has_animation, + NULL, 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) { @@ -652,7 +660,6 @@ uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, static void DefaultFeatures(WebPBitstreamFeatures* const features) { assert(features != NULL); memset(features, 0, sizeof(*features)); - features->bitstream_version = 0; } static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, @@ -666,7 +673,7 @@ static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, return ParseHeadersInternal(data, data_size, &features->width, &features->height, &features->has_alpha, &features->has_animation, - NULL); + &features->format, NULL); } //------------------------------------------------------------------------------ diff --git a/src/webp/decode.h b/src/webp/decode.h index 141f8618..404dae18 100644 --- a/src/webp/decode.h +++ b/src/webp/decode.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define WEBP_DECODER_ABI_VERSION 0x0201 // MAJOR(8b) + MINOR(8b) +#define WEBP_DECODER_ABI_VERSION 0x0202 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. @@ -404,9 +404,9 @@ struct WebPBitstreamFeatures { 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. + int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless // Unused for now: - int bitstream_version; // should be 0 for now. TODO(later) int no_incremental_decoding; // if true, using incremental decoding is not // recommended. int rotate; // TODO(later)