add a 'format' field to WebPBitstreamFeatures

Change-Id: I79a688e4c34fb77527127bbdf4bc844efa6aa9a4
This commit is contained in:
Pascal Massimino 2013-08-21 21:56:35 +00:00 committed by James Zern
parent dde91fde96
commit 86c0031eb2
3 changed files with 26 additions and 11 deletions

View File

@ -573,6 +573,10 @@ static const char* const kStatusMessages[] = {
"UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA" "UNSUPPORTED_FEATURE", "SUSPENDED", "USER_ABORT", "NOT_ENOUGH_DATA"
}; };
static const char* const kFormatType[] = {
"unspecified", "lossy", "lossless"
};
int main(int argc, const char *argv[]) { int main(int argc, const char *argv[]) {
int ok = 0; int ok = 0;
const char *in_file = NULL; const char *in_file = NULL;
@ -741,14 +745,18 @@ int main(int argc, const char *argv[]) {
} }
if (out_file != NULL) { 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, 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); ok = SaveOutput(output_buffer, format, out_file);
} else { } 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, 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; " fprintf(stderr, "Nothing written; "
"use -o flag to save the result as e.g. PNG.\n"); "use -o flag to save the result as e.g. PNG.\n");
} }

View File

@ -285,6 +285,7 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
int* const height, int* const height,
int* const has_alpha, int* const has_alpha,
int* const has_animation, int* const has_animation,
int* const format,
WebPHeaderStructure* const headers) { WebPHeaderStructure* const headers) {
int canvas_width = 0; int canvas_width = 0;
int canvas_height = 0; int canvas_height = 0;
@ -292,6 +293,9 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
int image_height = 0; int image_height = 0;
int found_riff = 0; int found_riff = 0;
int found_vp8x = 0; int found_vp8x = 0;
int animation_present = 0;
int fragments_present = 0;
VP8StatusCode status; VP8StatusCode status;
WebPHeaderStructure hdrs; WebPHeaderStructure hdrs;
@ -312,8 +316,6 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
// Skip over VP8X. // Skip over VP8X.
{ {
uint32_t flags = 0; uint32_t flags = 0;
int animation_present;
int fragments_present;
status = ParseVP8X(&data, &data_size, &found_vp8x, status = ParseVP8X(&data, &data_size, &found_vp8x,
&canvas_width, &canvas_height, &flags); &canvas_width, &canvas_height, &flags);
if (status != VP8_STATUS_OK) { 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_alpha != NULL) *has_alpha = !!(flags & ALPHA_FLAG);
if (has_animation != NULL) *has_animation = animation_present; if (has_animation != NULL) *has_animation = animation_present;
if (format != NULL) *format = 0; // default = undefined
if (found_vp8x && (animation_present || fragments_present) && if (found_vp8x && (animation_present || fragments_present) &&
headers == NULL) { headers == NULL) {
@ -359,6 +362,10 @@ static VP8StatusCode ParseHeadersInternal(const uint8_t* data,
return VP8_STATUS_BITSTREAM_ERROR; return VP8_STATUS_BITSTREAM_ERROR;
} }
if (format != NULL && !(animation_present || fragments_present)) {
*format = hdrs.is_lossless ? 2 : 1;
}
if (!hdrs.is_lossless) { if (!hdrs.is_lossless) {
if (data_size < VP8_FRAME_HEADER_SIZE) { if (data_size < VP8_FRAME_HEADER_SIZE) {
return VP8_STATUS_NOT_ENOUGH_DATA; return VP8_STATUS_NOT_ENOUGH_DATA;
@ -405,7 +412,8 @@ VP8StatusCode WebPParseHeaders(WebPHeaderStructure* const headers) {
assert(headers != NULL); assert(headers != NULL);
// fill out headers, ignore width/height/has_alpha. // fill out headers, ignore width/height/has_alpha.
status = ParseHeadersInternal(headers->data, headers->data_size, 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) { if (status == VP8_STATUS_OK || status == VP8_STATUS_NOT_ENOUGH_DATA) {
// TODO(jzern): full support of animation frames will require API additions. // TODO(jzern): full support of animation frames will require API additions.
if (has_animation) { if (has_animation) {
@ -652,7 +660,6 @@ uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size,
static void DefaultFeatures(WebPBitstreamFeatures* const features) { static void DefaultFeatures(WebPBitstreamFeatures* const features) {
assert(features != NULL); assert(features != NULL);
memset(features, 0, sizeof(*features)); memset(features, 0, sizeof(*features));
features->bitstream_version = 0;
} }
static VP8StatusCode GetFeatures(const uint8_t* const data, size_t data_size, 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, return ParseHeadersInternal(data, data_size,
&features->width, &features->height, &features->width, &features->height,
&features->has_alpha, &features->has_animation, &features->has_alpha, &features->has_animation,
NULL); &features->format, NULL);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #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++, // Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference. // the types are left here for reference.
@ -404,9 +404,9 @@ struct WebPBitstreamFeatures {
int height; // Height 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_alpha; // True if the bitstream contains an alpha channel.
int has_animation; // True if the bitstream is an animation. int has_animation; // True if the bitstream is an animation.
int format; // 0 = undefined (/mixed), 1 = lossy, 2 = lossless
// Unused for now: // Unused for now:
int bitstream_version; // should be 0 for now. TODO(later)
int no_incremental_decoding; // if true, using incremental decoding is not int no_incremental_decoding; // if true, using incremental decoding is not
// recommended. // recommended.
int rotate; // TODO(later) int rotate; // TODO(later)