From fffefd18c3cf7321a4f47961016c42daf5784477 Mon Sep 17 00:00:00 2001 From: Urvang Joshi Date: Thu, 2 May 2013 13:54:25 -0700 Subject: [PATCH] Add GetCanvasSize() method to mux Change-Id: If910f5024f4c301a92e6c2e8ee9c315a103c5df7 --- NEWS | 1 + examples/webpmux.c | 7 ++++++- src/mux/muxi.h | 6 ++++++ src/mux/muxinternal.c | 4 ++++ src/mux/muxread.c | 32 ++++++++++++++++++++++++++++++++ src/webp/mux.h | 23 ++++++++++++++++++++--- 6 files changed, 69 insertions(+), 4 deletions(-) diff --git a/NEWS b/NEWS index 3f956e00..0c48beb1 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,6 @@ - Next version: * Add incremental decoding support for images containing ALPH and ICCP chunks. + * New function: WebPMuxGetCanvasSize - 3/20/13: version 0.3.0 This is a binary compatible release. diff --git a/examples/webpmux.c b/examples/webpmux.c index 0ba4ca76..689a624d 100644 --- a/examples/webpmux.c +++ b/examples/webpmux.c @@ -180,9 +180,14 @@ static const char* ErrorString(WebPMuxError err) { } while (0) static WebPMuxError DisplayInfo(const WebPMux* mux) { + int width, height; uint32_t flag; - WebPMuxError err = WebPMuxGetFeatures(mux, &flag); + WebPMuxError err = WebPMuxGetCanvasSize(mux, &width, &height); + RETURN_IF_ERROR("Failed to retrieve canvas width/height.\n"); + printf("Canvas size: %d x %d\n", width, height); + + err = WebPMuxGetFeatures(mux, &flag); #ifndef WEBP_EXPERIMENTAL_FEATURES if (flag & FRAGMENTS_FLAG) err = WEBP_MUX_INVALID_ARGUMENT; #endif diff --git a/src/mux/muxi.h b/src/mux/muxi.h index 97b7f43d..bbdc60f6 100644 --- a/src/mux/muxi.h +++ b/src/mux/muxi.h @@ -236,6 +236,12 @@ WebPChunk** MuxGetChunkListFromId(const WebPMux* mux, WebPChunkId id); // Validates that the given mux has a single image. WebPMuxError MuxValidateForImage(const WebPMux* const mux); +// Get the canvas width and height after validating that VP8X/VP8/VP8L chunk and +// canvas size are valid. This method can be used for validation-only purposes +// by passing 'width' and 'height' to be NULL. +WebPMuxError MuxGetCanvasSize(const WebPMux* const mux, int* width, + int* height); + // Validates the given mux object. WebPMuxError MuxValidate(const WebPMux* const mux); diff --git a/src/mux/muxinternal.c b/src/mux/muxinternal.c index 3fa91f7d..573d3ac2 100644 --- a/src/mux/muxinternal.c +++ b/src/mux/muxinternal.c @@ -503,6 +503,10 @@ WebPMuxError MuxValidate(const WebPMux* const mux) { // Verify mux has at least one image. if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT; + // Validate that VP8X/VP8/VP8L chunk and canvas size are valid. + err = MuxGetCanvasSize(mux, NULL, NULL); + if (err != WEBP_MUX_OK) return err; + err = WebPMuxGetFeatures(mux, &flags); if (err != WEBP_MUX_OK) return err; diff --git a/src/mux/muxread.c b/src/mux/muxread.c index 0e074fb2..1b5ac223 100644 --- a/src/mux/muxread.c +++ b/src/mux/muxread.c @@ -260,6 +260,38 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data, //------------------------------------------------------------------------------ // Get API(s). +WebPMuxError MuxGetCanvasSize(const WebPMux* const mux, int* width, + int* height) { + int w, h; + WebPData data; + assert(mux != NULL); + + // Check if VP8X chunk is present. + if (MuxGet(mux, IDX_VP8X, 1, &data) == WEBP_MUX_OK) { + if (data.size < VP8X_CHUNK_SIZE) return WEBP_MUX_BAD_DATA; + w = GetLE24(data.bytes + 4) + 1; + h = GetLE24(data.bytes + 7) + 1; + } else { // Single image case. + WebPMuxError err = MuxValidateForImage(mux); + if (err != WEBP_MUX_OK) return err; + err = MuxGetImageWidthHeight(mux->images_->img_, &w, &h); + if (err != WEBP_MUX_OK) return err; + } + if (w * (uint64_t)h >= MAX_IMAGE_AREA) return WEBP_MUX_BAD_DATA; + + if (width) *width = w; + if (height) *height = h; + return WEBP_MUX_OK; +} + +WebPMuxError WebPMuxGetCanvasSize(const WebPMux* mux, int* width, int* height) { + if (mux == NULL || width == NULL || height == NULL) { + return WEBP_MUX_INVALID_ARGUMENT; + } + return MuxGetCanvasSize(mux, width, height); +} + + WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) { WebPData data; diff --git a/src/webp/mux.h b/src/webp/mux.h index f869a2dc..01b9bc8b 100644 --- a/src/webp/mux.h +++ b/src/webp/mux.h @@ -51,7 +51,7 @@ extern "C" { #endif -#define WEBP_MUX_ABI_VERSION 0x0100 // MAJOR(8b) + MINOR(8b) +#define WEBP_MUX_ABI_VERSION 0x0101 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. @@ -303,7 +303,25 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams( //------------------------------------------------------------------------------ // Misc Utilities. +// Gets the canvas size from the mux object. +// Note: This method assumes that VP8X chunk, if present, is up-to-date. That +// is, the mux object hasn't been modified since the last call to +// WebPMuxAssemble() or WebMuxCreate(). +// Parameters: +// mux - (in) object from which the canvas size is to be fetched +// width - (out) canvas width +// height - (out) canvas height +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if mux, width or height is NULL +// WEBP_MUX_BAD_DATA - if VP8X/VP8/VP8L chunk or canvas size is invalid. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetCanvasSize(const WebPMux* mux, + int* width, int* height); + // Gets the feature flags from the mux object. +// Note: This method assumes that VP8X chunk, if present, is up-to-date. That +// is, the mux object hasn't been modified since the last call to +// WebPMuxAssemble() or WebMuxCreate(). // Parameters: // mux - (in) object from which the features are to be fetched // flags - (out) the flags specifying which features are present in the @@ -311,8 +329,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetAnimationParams( // Enum 'WebPFeatureFlags' can be used to test individual flag values. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux or flags is NULL -// WEBP_MUX_NOT_FOUND - if VP8X chunk is not present in mux object. -// WEBP_MUX_BAD_DATA - if VP8X chunk in mux is invalid. +// WEBP_MUX_BAD_DATA - if VP8X/VP8L chunk in mux is invalid. // WEBP_MUX_OK - on success. WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags);