Merge "MUX API Updates"

This commit is contained in:
pascal massimino 2011-11-23 05:58:02 -08:00 committed by Gerrit Code Review
commit 113b312881
5 changed files with 779 additions and 374 deletions

View File

@ -73,7 +73,8 @@ metadata.
int copy_data = 0; int copy_data = 0;
WebPMux* mux = WebPMuxNew(); WebPMux* mux = WebPMuxNew();
// ... (Prepare image data). // ... (Prepare image data).
WebPMuxAddNamedData(mux, 1, "image", image_data, image_data_size, copy_data); WebPMuxSetImage(mux, image_data, image_data_size, alpha_data, alpha_size,
copy_data);
// ... (Prepare ICCP color profile data). // ... (Prepare ICCP color profile data).
WebPMuxSetColorProfile(mux, icc_data, icc_data_size, copy_data); WebPMuxSetColorProfile(mux, icc_data, icc_data_size, copy_data);
// ... (Prepare XMP metadata). // ... (Prepare XMP metadata).
@ -90,7 +91,8 @@ Example#2 (pseudo code): Get image & color profile data from a WebP file.
int copy_data = 0; int copy_data = 0;
// ... (Read data from file). // ... (Read data from file).
WebPMux* mux = WebPMuxCreate(data, data_size, copy_data); WebPMux* mux = WebPMuxCreate(data, data_size, copy_data);
WebPMuxGetNamedData(mux, "image", 1, &image_data, &image_data_size); WebPMuxGetImage(mux, &image_data, &image_data_size,
&alpha_data, &alpha_size);
// ... (Consume image_data; e.g. call WebPDecode() to decode the data). // ... (Consume image_data; e.g. call WebPDecode() to decode the data).
WebPMuxGetColorProfile(mux, &icc_data, &icc_data_size); WebPMuxGetColorProfile(mux, &icc_data, &icc_data_size);
// ... (Consume icc_data). // ... (Consume icc_data).

View File

@ -50,6 +50,9 @@ document describes additional support for:
* **Animation.** An image may have pauses between frames, making it * **Animation.** An image may have pauses between frames, making it
an animation. an animation.
* **Transparency.** An image may have transparency, i.e., an alpha channel for
each frame/tile.
Files not using these new features are backward compatible with the Files not using these new features are backward compatible with the
original format. Use of these features will produce files that are not original format. Use of these features will produce files that are not
compatible with older programs. compatible with older programs.
@ -215,6 +218,10 @@ multiple frames. Data for each frame consists of:
present at the beginning of data for an image that's represented as present at the beginning of data for an image that's represented as
multiple tile images. multiple tile images.
* An optional "ALPH" chunk with alpha bitstream of the tile. It **MUST** be
present for an image containing transparency. It **MUST NOT** be present
in non-transparent images.
* A "VP8 " chunk with the bitstream of the tile. * A "VP8 " chunk with the bitstream of the tile.
All chunks **MUST** be placed in the same order as listed above (except All chunks **MUST** be placed in the same order as listed above (except
@ -228,8 +235,8 @@ position, a decoder can choose to stop searching for it. The rule of
ignoring late chunks should make programs that need to do a full search ignoring late chunks should make programs that need to do a full search
give the same results as the ones stopping early. give the same results as the ones stopping early.
**Example:** An example layout of a non-animated, tiled image may look **Example:** An example layout of a non-animated, tiled image without
as follows: transparency may look as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RIFF/WEBP RIFF/WEBP
@ -246,17 +253,20 @@ RIFF/WEBP
+- META (XMP metadata) +- META (XMP metadata)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
**Example:** An example layout of an animated image may look as follows: **Example:** An example layout of an animated image with transparency may look
as follows:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
RIFF/WEBP RIFF/WEBP
+- VP8X (descriptions of features used) +- VP8X (descriptions of features used)
+- LOOP (animation control parameters) +- LOOP (animation control parameters)
+- FRM (first animation frame parameters) +- FRM (first animation frame parameters)
+- ALPH (alpha bitstream - first image frame)
+- VP8 (bitstream - first image frame) +- VP8 (bitstream - first image frame)
+- FRM (second animation frame parameters) +- FRM (second animation frame parameters)
+- ALPH (alpha bitstream - second image frame)
+- VP8 (bitstream - second image frame) +- VP8 (bitstream - second image frame)
+- META(XMP metadata) +- META (XMP metadata)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -272,14 +282,20 @@ pseudocode:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
assert not VP8X.flags.haveAnimation assert not VP8X.flags.haveAnimation
canvas ← new black image of size VP8X.canvasWidth x VP8X.canvasHeight. canvas ← new black image of size
VP8X.canvasWidth x VP8X.canvasHeight.
tile_params.tileCanvasX = tile_params.tileCanvasY = 0 tile_params.tileCanvasX = tile_params.tileCanvasY = 0
for chunk in data_for_all_frames: for chunk in data_for_all_frames:
if chunk.tag == "TILE": if chunk.tag == "TILE":
assert No other TILE chunk after the last "VP8 " chunk assert No other TILE chunk after the last "VP8 " chunk
assert No ALPH chunk after the last "VP8 " chunk
tile_params = chunk tile_params = chunk
if chunk.tag == "ALPH":
assert No other ALPH chunk after the last "VP8 " chunk
tile_params.alpha = alpha_data
if chunk.tag == "VP8 ": if chunk.tag == "VP8 ":
render image in chunk in canvas with top-left corner in (tile_params.tileCanvasX, tile_params.tileCanvasY) using the isometry in VP8X.flags.rotationAndSymmetry. render image in chunk in canvas with top-left corner in
(tile_params.tileCanvasX, tile_params.tileCanvasY).
tile_params.tileCanvasX = tile_params.tileCanvasY = 0 tile_params.tileCanvasX = tile_params.tileCanvasY = 0
Ignore unknown chunks Ignore unknown chunks
canvas contains the decoded canvas. canvas contains the decoded canvas.
@ -290,7 +306,8 @@ pseudocode:
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
assert VP8X.flags.haveAnimation assert VP8X.flags.haveAnimation
canvas ← new black image of size VP8X.canvasWidth x VP8X.canvasHeight. canvas ← new black image of size
VP8X.canvasWidth x VP8X.canvasHeight.
if LOOP.loopCount==0: if LOOP.loopCount==0:
LOOP.loopCount=∞ LOOP.loopCount=∞
current_FRM ← nil current_FRM ← nil
@ -298,15 +315,24 @@ for LOOP.loop = 0, ..., LOOP.loopCount-1
assert First chunk in data_for_all_frames is a FRM assert First chunk in data_for_all_frames is a FRM
for chunk in data_for_all_frames: for chunk in data_for_all_frames:
if chunk.tag == "FRM ": if chunk.tag == "FRM ":
assert No other FRM chunk after the last "VP8 " chunk
assert No ALPH chunk after the last "VP8 " chunk
if current_FRM != nil: if current_FRM != nil:
Show the contents of canvas for current_FRM.frameDuration*10ms. Show the contents of canvas for
current_FRM.frameDuration * 1ms.
current_FRM = chunk current_FRM = chunk
if chunk.tag == "ALPH":
assert No other ALPH chunk after the last "VP8 " chunk
tile_params.alpha = alpha_data
if chunk.tag == "VP8 ": if chunk.tag == "VP8 ":
assert tile_params.tileCanvasX >= current_FRM.frameX assert tile_params.tileCanvasX >= current_FRM.frameX
assert tile_params.tileCanvasY >= current_FRM.frameY assert tile_params.tileCanvasY >= current_FRM.frameY
assert tile_params.tileCanvasX + chunk.tileWidth >= current_FRM.frameX + current_FRM.frameWidth assert tile_params.tileCanvasX + chunk.tileWidth >=
assert tile_params.tileCanvasY + chunk.tileHeight >= current_FRM.frameX + current_FRM.frameHeight current_FRM.frameX + current_FRM.frameWidth
render image in chunk in canvas with top-left corner in (tile_params.tileCanvasX, tile_params.tileCanvasY) using the isometry in VP8X.flags.rotationAndSymmetry. assert tile_params.tileCanvasY + chunk.tileHeight >=
current_FRM.frameX + current_FRM.frameHeight
render image in chunk in canvas with top-left corner in
(tile_params.tileCanvasX, tile_params.tileCanvasY).
tile_params.tileCanvasX = tile_params.tileCanvasY = 0 tile_params.tileCanvasX = tile_params.tileCanvasY = 0
Ignore unknown chunks Ignore unknown chunks
canvas contains the decoded canvas. canvas contains the decoded canvas.
@ -482,6 +508,31 @@ constraints:
_tileCanvasY + tileHeight == canvasHeight_ **MUST** be true. _tileCanvasY + tileHeight == canvasHeight_ **MUST** be true.
### ALPH Chunks (Alpha Bitstreams)
This optional chunk contains encoded alpha data for a single tile. Either
**ALL or NONE** of the tiles must contain this chunk.
The alpha channel can be encoded either losslessly or with lossy preprocessing
(quantization). After the optional preprocessing, the alpha values are encoded
with a lossless compression method like zlib. Work is in progress to improve the
compression gain further by exploring alternate compression methods and hence,
the bit-stream for the Alpha-chunk is still experimental and expected to change.
The contents of such a chunk are as follows:
* Byte 0: The _compression method_ used. Currently two methods are
supported:
* 0 --> No compression
* 1 --> Zlib compression.
* Byte 1: _Reserved_. **Should** be 0.
* Byte 2 onwards: _Encoded alpha bitstream_.
### ICCP Chunk (Color Profile) ### ICCP Chunk (Color Profile)
An optional "ICCP" chunk contains an ICC profile. There **SHOULD** be An optional "ICCP" chunk contains an ICC profile. There **SHOULD** be
@ -525,4 +576,4 @@ specification. Such chunks **MUST** be ignored, but preserved. Writers
[vp8spec]: http://tools.ietf.org/html/draft-bankoski-vp8-bitstream [vp8spec]: http://tools.ietf.org/html/draft-bankoski-vp8-bitstream
[xmpspec]: http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf [xmpspec]: http://www.adobe.com/content/dam/Adobe/en/devnet/xmp/pdfs/XMPSpecificationPart1.pdf
[metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf [metadata]: http://www.metadataworkinggroup.org/pdf/mwg_guidance.pdf

View File

@ -191,8 +191,8 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
fprintf(stderr, "No.: x_offset y_offset duration\n"); fprintf(stderr, "No.: x_offset y_offset duration\n");
for (i = 1; i <= nFrames; i++) { for (i = 1; i <= nFrames; i++) {
err = WebPMuxGetFrame(mux, i, &data, &size, &x_offset, &y_offset, err = WebPMuxGetFrame(mux, i, &data, &size, NULL, NULL,
&duration); &x_offset, &y_offset, &duration);
assert(err == WEBP_MUX_OK); assert(err == WEBP_MUX_OK);
fprintf(stderr, "%3d: %8d %8d %8d\n", i, x_offset, y_offset, duration); fprintf(stderr, "%3d: %8d %8d %8d\n", i, x_offset, y_offset, duration);
} }
@ -209,7 +209,8 @@ static WebPMuxError DisplayInfo(const WebPMux* mux) {
uint32_t x_offset, y_offset; uint32_t x_offset, y_offset;
fprintf(stderr, "No.: x_offset y_offset\n"); fprintf(stderr, "No.: x_offset y_offset\n");
for (i = 1; i <= nTiles; i++) { for (i = 1; i <= nTiles; i++) {
err = WebPMuxGetTile(mux, i, &data, &size, &x_offset, &y_offset); err = WebPMuxGetTile(mux, i, &data, &size, NULL, NULL,
&x_offset, &y_offset);
assert(err == WEBP_MUX_OK); assert(err == WEBP_MUX_OK);
fprintf(stderr, "%3d: %8d %8d\n", i, x_offset, y_offset); fprintf(stderr, "%3d: %8d %8d\n", i, x_offset, y_offset);
} }
@ -350,45 +351,6 @@ static int ReadFile(const char* const filename, WebPMux** mux) {
return 0; return 0;
} }
static int ReadImageData(const char* filename, int image_index,
const uint8_t** data_ptr, uint32_t* size_ptr) {
uint32_t size = 0;
void* data = NULL;
WebPMux* mux;
WebPMuxError err;
int ok = 1;
if (!ReadData(filename, &data, &size)) return 0;
mux = WebPMuxCreate((const uint8_t*)data, size, 1);
free(data);
if (mux == NULL) {
fprintf(stderr, "Failed to create mux object from file %s.\n",
filename);
return 0;
}
err = WebPMuxGetNamedData(mux, "image", image_index, (const uint8_t**)&data,
&size);
if (err == WEBP_MUX_OK) {
*size_ptr = size;
*data_ptr = (uint8_t*)malloc(*size_ptr);
if (*data_ptr != NULL) {
memcpy((void*)*data_ptr, data, (size_t)size);
} else {
err = WEBP_MUX_MEMORY_ERROR;
fprintf(stderr, "Failed to allocate %d bytes to extract image data from"
" file %s. Error: %d\n", size, filename, err);
ok = 0;
}
} else {
fprintf(stderr, "Failed to extract image data from file %s. Error: %d\n",
filename, err);
ok = 0;
}
WebPMuxDelete(mux);
return ok;
}
static int WriteData(const char* filename, void* data, uint32_t size) { static int WriteData(const char* filename, void* data, uint32_t size) {
int ok = 0; int ok = 0;
FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout; FILE* fout = strcmp(filename, "-") ? fopen(filename, "wb") : stdout;
@ -770,13 +732,14 @@ static int GetFrameTile(const WebPMux* mux,
} }
if (isFrame) { if (isFrame) {
err = WebPMuxGetFrame(mux, num, &data, &size, &x_offset, &y_offset, err = WebPMuxGetFrame(mux, num, &data, &size, NULL, NULL,
&duration); &x_offset, &y_offset, &duration);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet); ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet);
} }
} else { } else {
err = WebPMuxGetTile(mux, num, &data, &size, &x_offset, &y_offset); err = WebPMuxGetTile(mux, num, &data, &size, NULL, NULL,
&x_offset, &y_offset);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet); ERROR_GOTO3("ERROR#%d: Could not get frame %ld.\n", err, num, ErrGet);
} }
@ -787,7 +750,7 @@ static int GetFrameTile(const WebPMux* mux,
err = WEBP_MUX_MEMORY_ERROR; err = WEBP_MUX_MEMORY_ERROR;
ERROR_GOTO2("ERROR#%d: Could not allocate a mux object.\n", err, ErrGet); ERROR_GOTO2("ERROR#%d: Could not allocate a mux object.\n", err, ErrGet);
} }
err = WebPMuxAddNamedData(mux_single, 0, "image", data, size, 1); err = WebPMuxSetImage(mux_single, data, size, NULL, 0, 1);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO2("ERROR#%d: Could not create single image mux object.\n", err, ERROR_GOTO2("ERROR#%d: Could not create single image mux object.\n", err,
ErrGet); ErrGet);
@ -870,8 +833,8 @@ static int Process(const WebPMuxConfig* config) {
ERROR_GOTO2("ERROR#%d: Could not set loop count.\n", err, Err2); ERROR_GOTO2("ERROR#%d: Could not set loop count.\n", err, Err2);
} }
} else if (feature->args_[index].subtype_ == SUBTYPE_FRM) { } else if (feature->args_[index].subtype_ == SUBTYPE_FRM) {
ok = ReadImageData(feature->args_[index].filename_, 1, ok = ReadData(feature->args_[index].filename_,
&data, &size); (void**)&data, &size);
if (!ok) goto Err2; if (!ok) goto Err2;
ok = ParseFrameArgs(feature->args_[index].params_, ok = ParseFrameArgs(feature->args_[index].params_,
&x_offset, &y_offset, &duration); &x_offset, &y_offset, &duration);
@ -879,8 +842,8 @@ static int Process(const WebPMuxConfig* config) {
free((void*)data); free((void*)data);
ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2); ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2);
} }
err = WebPMuxAddFrame(mux, 0, data, size, x_offset, y_offset, err = WebPMuxAddFrame(mux, 0, data, size, NULL, 0,
duration, 1); x_offset, y_offset, duration, 1);
free((void*)data); free((void*)data);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n", ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n",
@ -899,8 +862,8 @@ static int Process(const WebPMuxConfig* config) {
WEBP_MUX_MEMORY_ERROR, Err2); WEBP_MUX_MEMORY_ERROR, Err2);
} }
for (index = 0; index < feature->arg_count_; ++index) { for (index = 0; index < feature->arg_count_; ++index) {
ok = ReadImageData(feature->args_[index].filename_, 1, ok = ReadData(feature->args_[index].filename_,
&data, &size); (void**)&data, &size);
if (!ok) goto Err2; if (!ok) goto Err2;
ok = ParseTileArgs(feature->args_[index].params_, &x_offset, ok = ParseTileArgs(feature->args_[index].params_, &x_offset,
&y_offset); &y_offset);
@ -908,7 +871,8 @@ static int Process(const WebPMuxConfig* config) {
free((void*)data); free((void*)data);
ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2); ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2);
} }
err = WebPMuxAddTile(mux, 0, data, size, x_offset, y_offset, 1); err = WebPMuxAddTile(mux, 0, data, size, NULL, 0,
x_offset, y_offset, 1);
free((void*)data); free((void*)data);
if (err != WEBP_MUX_OK) { if (err != WEBP_MUX_OK) {
ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n", ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n",

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@
// int copy_data = 0; // int copy_data = 0;
// WebPMux* mux = WebPMuxNew(); // WebPMux* mux = WebPMuxNew();
// // ... (Prepare image data). // // ... (Prepare image data).
// WebPMuxAddNamedData(mux, 1, "image", image_data, image_data_size, // WebPMuxSetImage(mux, image_data, image_data_size, alpha_data, alpha_size,
// copy_data); // copy_data);
// // ... (Prepare ICCP color profile data). // // ... (Prepare ICCP color profile data).
// WebPMuxSetColorProfile(mux, icc_data, icc_data_size, copy_data); // WebPMuxSetColorProfile(mux, icc_data, icc_data_size, copy_data);
// // ... (Prepare XMP metadata). // // ... (Prepare XMP metadata).
@ -35,7 +35,8 @@
// int copy_data = 0; // int copy_data = 0;
// // ... (Read data from file). // // ... (Read data from file).
// WebPMux* mux = WebPMuxCreate(data, data_size, copy_data); // WebPMux* mux = WebPMuxCreate(data, data_size, copy_data);
// WebPMuxGetNamedData(mux, "image", 1, &image_data, &image_data_size); // WebPMuxGetImage(mux, &image_data, &image_data_size,
// &alpha_data, &alpha_size);
// // ... (Consume image_data; e.g. call WebPDecode() to decode the data). // // ... (Consume image_data; e.g. call WebPDecode() to decode the data).
// WebPMuxGetColorProfile(mux, &icc_data, &icc_data_size); // WebPMuxGetColorProfile(mux, &icc_data, &icc_data_size);
// // ... (Consume icc_data). // // ... (Consume icc_data).
@ -67,7 +68,8 @@ typedef enum {
TILE_FLAG = 0x00000001, TILE_FLAG = 0x00000001,
ANIMATION_FLAG = 0x00000002, ANIMATION_FLAG = 0x00000002,
ICCP_FLAG = 0x00000004, ICCP_FLAG = 0x00000004,
META_FLAG = 0x00000008 META_FLAG = 0x00000008,
ALPHA_FLAG = 0x00000010
} FeatureFlags; } FeatureFlags;
typedef struct WebPMux WebPMux; // main opaque object. typedef struct WebPMux WebPMux; // main opaque object.
@ -100,6 +102,57 @@ WEBP_EXTERN(void) WebPMuxDelete(WebPMux* const mux);
WEBP_EXTERN(WebPMux*) WebPMuxCreate(const uint8_t* data, uint32_t size, WEBP_EXTERN(WebPMux*) WebPMuxCreate(const uint8_t* data, uint32_t size,
int copy_data); int copy_data);
//------------------------------------------------------------------------------
// Single Image.
// Sets the image in the mux object. Any existing images (including frame/tile)
// will be removed.
// Parameters:
// mux - (in/out) object in which the image is to be set
// data - (in) the image data to be set. The data can be either a VP8
// bitstream or a single-image WebP file (non-animated & non-tiled)
// size - (in) size of the image data
// alpha_data - (in) the alpha data corresponding to the image (if present)
// alpha_size - (in) size of alpha chunk data
// copy_data - (in) value 1 indicates given data WILL copied to the mux, and
// value 0 indicates data will NOT be copied.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or data is NULL.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxSetImage(WebPMux* const mux,
const uint8_t* data, uint32_t size,
const uint8_t* alpha_data,
uint32_t alpha_size, int copy_data);
// Gets a reference to the image in the mux object.
// The caller should NOT free the returned data.
// Parameters:
// mux - (in) object from which the image is to be fetched
// data - (out) the returned image data
// size - (out) size of the returned image data
// alpha_data - (in) the returned alpha data of the image (if present)
// alpha_size - (in) size of alpha chunk data
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if either of mux, data or size is NULL
// OR if mux contains animation/tiling.
// WEBP_MUX_NOT_FOUND - if image is not present in mux object.
// WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetImage(const WebPMux* const mux,
const uint8_t** data, uint32_t* size,
const uint8_t** alpha_data,
uint32_t* alpha_size);
// Deletes the image in the mux object.
// Parameters:
// mux - (in/out) object from which the image is to be deleted
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL
// OR if mux contains animation/tiling.
// WEBP_MUX_NOT_FOUND - if image is not present in mux object.
// WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxDeleteImage(WebPMux* const mux);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// XMP Metadata. // XMP Metadata.
@ -192,8 +245,12 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux);
// Parameters: // Parameters:
// mux - (in/out) object to which an animation frame is to be added // mux - (in/out) object to which an animation frame is to be added
// nth - (in) The position at which the frame is to be added. // nth - (in) The position at which the frame is to be added.
// data - (in) the raw VP8 image data corresponding to frame image // data - (in) the raw VP8 image data corresponding to frame image. The data
// can be either a VP8 bitstream or a single-image WebP file
// (non-animated & non-tiled)
// size - (in) size of frame chunk data // size - (in) size of frame chunk data
// alpha_data - (in) the alpha data corresponding to frame image (if present)
// alpha_size - (in) size of alpha chunk data
// x_offset - (in) x-offset of the frame to be added // x_offset - (in) x-offset of the frame to be added
// y_offset - (in) y-offset of the frame to be added // y_offset - (in) y-offset of the frame to be added
// duration - (in) duration of the frame to be added (in milliseconds) // duration - (in) duration of the frame to be added (in milliseconds)
@ -206,9 +263,22 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux);
// WEBP_MUX_OK - on success. // WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxAddFrame(WebPMux* const mux, uint32_t nth, WEBP_EXTERN(WebPMuxError) WebPMuxAddFrame(WebPMux* const mux, uint32_t nth,
const uint8_t* data, uint32_t size, const uint8_t* data, uint32_t size,
const uint8_t* alpha_data,
uint32_t alpha_size,
uint32_t x_offset, uint32_t y_offset, uint32_t x_offset, uint32_t y_offset,
uint32_t duration, int copy_data); uint32_t duration, int copy_data);
// TODO(urvang): Create a struct as follows to reduce argument list size:
// typedef struct {
// int nth;
// uint8_t* data;
// uint32_t data_size;
// uint8_t* alpha;
// uint32_t alpha_size;
// uint32_t x_offset, y_offset;
// uint32_t duration;
// } FrameInfo;
// Gets a reference to the nth animation frame from the mux object. // Gets a reference to the nth animation frame from the mux object.
// The caller should NOT free the returned data. // The caller should NOT free the returned data.
// nth=0 has a special meaning - last position. // nth=0 has a special meaning - last position.
@ -217,6 +287,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddFrame(WebPMux* const mux, uint32_t nth,
// nth - (in) index of the frame in the mux object // nth - (in) index of the frame in the mux object
// data - (out) the returned image data // data - (out) the returned image data
// size - (out) size of the returned image data // size - (out) size of the returned image data
// alpha_data - (in) the alpha data corresponding to frame image (if present)
// alpha_size - (in) size of alpha chunk data
// x_offset - (out) x-offset of the returned frame // x_offset - (out) x-offset of the returned frame
// y_offset - (out) y-offset of the returned frame // y_offset - (out) y-offset of the returned frame
// duration - (out) duration of the returned frame (in milliseconds) // duration - (out) duration of the returned frame (in milliseconds)
@ -229,6 +301,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddFrame(WebPMux* const mux, uint32_t nth,
WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(const WebPMux* const mux, WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(const WebPMux* const mux,
uint32_t nth, uint32_t nth,
const uint8_t** data, uint32_t* size, const uint8_t** data, uint32_t* size,
const uint8_t** alpha_data,
uint32_t* alpha_size,
uint32_t* x_offset, uint32_t* x_offset,
uint32_t* y_offset, uint32_t* y_offset,
uint32_t* duration); uint32_t* duration);
@ -277,8 +351,12 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* const mux,
// Parameters: // Parameters:
// mux - (in/out) object to which a tile is to be added // mux - (in/out) object to which a tile is to be added
// nth - (in) The position at which the tile is to be added. // nth - (in) The position at which the tile is to be added.
// data - (in) the raw VP8 image data corresponding to tile image // data - (in) the raw VP8 image data corresponding to tile image. The data
// can be either a VP8 bitstream or a single-image WebP file
// (non-animated & non-tiled)
// size - (in) size of tile chunk data // size - (in) size of tile chunk data
// alpha_data - (in) the alpha data corresponding to tile image (if present)
// alpha_size - (in) size of alpha chunk data
// x_offset - (in) x-offset of the tile to be added // x_offset - (in) x-offset of the tile to be added
// y_offset - (in) y-offset of the tile to be added // y_offset - (in) y-offset of the tile to be added
// copy_data - (in) value 1 indicates given data WILL copied to the mux, and // copy_data - (in) value 1 indicates given data WILL copied to the mux, and
@ -290,6 +368,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* const mux,
// WEBP_MUX_OK - on success. // WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxAddTile(WebPMux* const mux, uint32_t nth, WEBP_EXTERN(WebPMuxError) WebPMuxAddTile(WebPMux* const mux, uint32_t nth,
const uint8_t* data, uint32_t size, const uint8_t* data, uint32_t size,
const uint8_t* alpha_data,
uint32_t alpha_size,
uint32_t x_offset, uint32_t y_offset, uint32_t x_offset, uint32_t y_offset,
int copy_data); int copy_data);
@ -301,6 +381,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddTile(WebPMux* const mux, uint32_t nth,
// nth - (in) index of the tile in the mux object // nth - (in) index of the tile in the mux object
// data - (out) the returned image data // data - (out) the returned image data
// size - (out) size of the returned image data // size - (out) size of the returned image data
// alpha_data - (in) the alpha data corresponding to tile image (if present)
// alpha_size - (in) size of alpha chunk data
// x_offset - (out) x-offset of the returned tile // x_offset - (out) x-offset of the returned tile
// y_offset - (out) y-offset of the returned tile // y_offset - (out) y-offset of the returned tile
// Returns: // Returns:
@ -311,6 +393,8 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddTile(WebPMux* const mux, uint32_t nth,
// WEBP_MUX_OK - on success. // WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(const WebPMux* const mux, uint32_t nth, WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(const WebPMux* const mux, uint32_t nth,
const uint8_t** data, uint32_t* size, const uint8_t** data, uint32_t* size,
const uint8_t** alpha_data,
uint32_t* alpha_size,
uint32_t* x_offset, uint32_t* x_offset,
uint32_t* y_offset); uint32_t* y_offset);
@ -329,45 +413,6 @@ WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Misc Utilities. // Misc Utilities.
// Adds a chunk with given tag at nth position.
// nth=0 has a special meaning - last position.
// Parameters:
// mux - (in/out) object to which a chunk is to be added
// nth - (in) The position at which the chunk is to be added.
// tag - (in) tag name specifying the type of chunk
// data - (in) the chunk data
// size - (in) size of tile chunk data
// copy_data - (in) value 1 indicates given data WILL copied to the mux, and
// value 0 indicates data will NOT be copied.
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if either mux, tag or data is NULL
// WEBP_MUX_INVALID_PARAMETER - if tag is invalid.
// WEBP_MUX_MEMORY_ERROR - on memory allocation error.
// WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxAddNamedData(WebPMux* const mux, uint32_t nth,
const char* const tag,
const uint8_t* data,
uint32_t size, int copy_data);
// Gets a reference to the nth chunk having tag value tag in the mux object.
// The caller should NOT free the returned data.
// nth=0 has a special meaning - last position.
// Parameters:
// mux - (in) object from which a chunk is to be fetched
// tag - (in) tag name specifying which type of chunk is to be fetched
// nth - (in) chunk index corresponding to the specified tag to be fetched
// data - (out) raw data of the chunk returned
// size - (out) size of the returned data
// Returns:
// WEBP_MUX_INVALID_ARGUMENT - if either mux, tag, data or size is NULL
// WEBP_MUX_NOT_FOUND - If there are less than nth named elements in the mux
// object.
// WEBP_MUX_OK - on success.
WEBP_EXTERN(WebPMuxError) WebPMuxGetNamedData(const WebPMux* const mux,
const char* tag, uint32_t nth,
const uint8_t** data,
uint32_t* size);
// Gets the feature flags from the mux object. // Gets the feature flags from the mux object.
// Parameters: // Parameters:
// mux - (in) object from which the features are to be fetched // mux - (in) object from which the features are to be fetched