From 9f761cfae9beb5f1dec882c4e032cbeba57127f8 Mon Sep 17 00:00:00 2001 From: Vikas Arora Date: Wed, 28 Sep 2011 09:16:09 +0530 Subject: [PATCH] Changed function signature for WebPMuxCreate Changed function signature of method WebPMuxCreate and few other minor nits. Header file has been re-organised to have declaration of set/get/Delete methods for different use-cases (Metadata, ColorProfile etc) in one place instead of declaring all Set methods together followed by Get & Delete. Change-Id: I52f6dffd216b1c343423d55a5b45fa1b9b9c1347 --- src/mux/mux.c | 256 +++++++++++++++-------------- src/webp/mux.h | 425 ++++++++++++++++++++++++++++++++----------------- 2 files changed, 416 insertions(+), 265 deletions(-) diff --git a/src/mux/mux.c b/src/mux/mux.c index b549e4f1..12f13034 100644 --- a/src/mux/mux.c +++ b/src/mux/mux.c @@ -7,7 +7,8 @@ // // RIFF container manipulation // -// Author: Urvang (urvang@google.com) +// Authors: Urvang (urvang@google.com) +// Vikas (vikasa@google.com) #include #include @@ -50,8 +51,6 @@ struct WebPMux { WebPChunk* vp8x_; WebPChunk* unknown_; - - WebPChunk mux_; // Final assembly of chunks. }; //------------------------------------------------------------------------------ @@ -344,7 +343,6 @@ static int WebPMuxRelease(WebPMux* const mux) { DeleteAllChunks(&mux->images_); DeleteAllChunks(&mux->meta_); DeleteAllChunks(&mux->unknown_); - ReleaseChunk(&mux->mux_); return 1; } @@ -381,8 +379,6 @@ static void PutLE32(uint8_t* const data, uint32_t val) { static WebPMuxError AssignData(WebPChunk* chunk, const uint8_t* data, uint32_t data_size, WebPImageInfo* image_info, int copy_data, uint32_t tag) { - WebPMuxError err = WEBP_MUX_OK; - // For internally allocated chunks, always copy data & make it owner of data. if ((tag == kChunks[VP8X_ID].chunkTag) || (tag == kChunks[LOOP_ID].chunkTag)) { @@ -419,7 +415,7 @@ static WebPMuxError AssignData(WebPChunk* chunk, const uint8_t* data, chunk->tag_ = tag; - return err; + return WEBP_MUX_OK; } static WebPMuxError RecordChunk(WebPChunk* chunk, const uint8_t* data, @@ -510,48 +506,133 @@ static WebPMuxError WebPMuxAddChunk(WebPMux* const mux, uint32_t nth, return MuxSet(mux, id, nth, data, size, image_info, copy_data); } -WebPMuxError WebPMuxCreate(WebPMux* const mux, const uint8_t* data, - uint32_t size, int copy_data) { +static int IsNotCompatible(int feature, int num_items) { + return (feature != 0) != (num_items > 0); +} + +static WebPMuxError WebPMuxValidate(const WebPMux* const mux) { + int num_iccp; + int num_meta; + int num_loop_chunks; + int num_frames; + int num_tiles; + int num_vp8x; + int num_images; + uint32_t flags; + WebPMuxError err; + + // Verify mux is not NULL. + if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT; + + // Verify mux has at least one image. + if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT; + + err = WebPMuxGetFeatures(mux, &flags); + if (err != WEBP_MUX_OK) return err; + + // At most one color profile chunk. + err = WebPMuxNumNamedElements(mux, kChunks[ICCP_ID].chunkName, &num_iccp); + if (err != WEBP_MUX_OK) return err; + if (num_iccp > 1) return WEBP_MUX_INVALID_ARGUMENT; + + // ICCP_FLAG and color profile chunk is consistent. + if (IsNotCompatible(flags & ICCP_FLAG, num_iccp)) { + return WEBP_MUX_INVALID_ARGUMENT; + } + + // At most one XMP metadata. + err = WebPMuxNumNamedElements(mux, kChunks[META_ID].chunkName, &num_meta); + if (err != WEBP_MUX_OK) return err; + if (num_meta > 1) return WEBP_MUX_INVALID_ARGUMENT; + + // META_FLAG and XMP metadata chunk is consistent. + if (IsNotCompatible(flags & META_FLAG, num_meta)) { + return WEBP_MUX_INVALID_ARGUMENT; + } + + // At most one loop chunk. + err = WebPMuxNumNamedElements(mux, kChunks[LOOP_ID].chunkName, + &num_loop_chunks); + if (err != WEBP_MUX_OK) return err; + if (num_loop_chunks > 1) return WEBP_MUX_INVALID_ARGUMENT; + + // Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent. + err = WebPMuxNumNamedElements(mux, kChunks[FRAME_ID].chunkName, &num_frames); + if (err != WEBP_MUX_OK) return err; + if ((flags & ANIMATION_FLAG) && + ((num_loop_chunks == 0) || (num_frames == 0))) { + return WEBP_MUX_INVALID_ARGUMENT; + } else if (((num_loop_chunks == 1) || (num_frames > 0)) && + !(flags & ANIMATION_FLAG)) { + return WEBP_MUX_INVALID_ARGUMENT; + } + + // Tiling: TILE_FLAG and tile chunk(s) are consistent. + err = WebPMuxNumNamedElements(mux, kChunks[TILE_ID].chunkName, &num_tiles); + if (err != WEBP_MUX_OK) return err; + if (IsNotCompatible(flags & TILE_FLAG, num_tiles)) { + return WEBP_MUX_INVALID_ARGUMENT; + } + + // Verify either VP8X chunk is present OR there is only one elem in + // mux->images_. + err = WebPMuxNumNamedElements(mux, kChunks[VP8X_ID].chunkName, &num_vp8x); + if (err != WEBP_MUX_OK) return err; + err = WebPMuxNumNamedElements(mux, kChunks[IMAGE_ID].chunkName, &num_images); + if (err != WEBP_MUX_OK) return err; + + if (num_vp8x > 1) { + return WEBP_MUX_INVALID_ARGUMENT; + } else if ((num_vp8x == 0) && (num_images != 1)) { + return WEBP_MUX_INVALID_ARGUMENT; + } + + return WEBP_MUX_OK; +} + +WebPMux* WebPMuxCreate(const uint8_t* data, uint32_t size, int copy_data) { uint32_t mux_size; uint32_t tag; const uint8_t* end; TAG_ID id; - - if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT; + WebPMux* mux; // Sanity checks on size and leading bytes. + if (data == NULL) return NULL; if (size < RIFF_HEADER_SIZE + CHUNK_HEADER_SIZE) { - return WEBP_MUX_INVALID_ARGUMENT; + return NULL; } if (GetLE32(data + 0) != mktag('R', 'I', 'F', 'F') || GetLE32(data + 8) != mktag('W', 'E', 'B', 'P')) { - return WEBP_MUX_BAD_DATA; + return NULL; } mux_size = CHUNK_HEADER_SIZE + GetLE32(data + 4); if (mux_size > size) { - return WEBP_MUX_BAD_DATA; + return NULL; } tag = GetLE32(data + RIFF_HEADER_SIZE); if (tag != kChunks[IMAGE_ID].chunkTag && tag != kChunks[VP8X_ID].chunkTag) { // First chunk should be either VP8X or VP8. - return WEBP_MUX_BAD_DATA; + return NULL; } end = data + mux_size; data += RIFF_HEADER_SIZE; mux_size -= RIFF_HEADER_SIZE; - // TODO(urvang): Add a call to WebPMuxInit() here to empty mux (next CL). + mux = WebPMuxNew(); + if (mux == NULL) return NULL; // Loop over chunks. while (data != end) { - WebPMuxError err = WEBP_MUX_OK; WebPChunk chunk; WebPChunk** chunk_list; uint32_t data_size; InitChunk(&chunk); - err = RecordChunk(&chunk, data, mux_size, copy_data); - if (err != WEBP_MUX_OK) return err; + if (RecordChunk(&chunk, data, mux_size, copy_data) != WEBP_MUX_OK) { + WebPMuxDelete(mux); + return NULL; + } data_size = ChunkDiskSize(&chunk); @@ -559,15 +640,26 @@ WebPMuxError WebPMuxCreate(WebPMux* const mux, const uint8_t* data, chunk_list = GetListFromId(mux, id); if (chunk_list == NULL) chunk_list = (WebPChunk**)&mux->unknown_; - err = SetNthChunk(&chunk, chunk_list, 0); - if (err != WEBP_MUX_OK) return err; + if (SetNthChunk(&chunk, chunk_list, 0) != WEBP_MUX_OK) { + WebPMuxDelete(mux); + return NULL; + } data += data_size; mux_size -= data_size; } - return WEBP_MUX_OK; + + // Validate mux. + if (WebPMuxValidate(mux) != WEBP_MUX_OK) { + WebPMuxDelete(mux); + return NULL; + } + return mux; } +//------------------------------------------------------------------------------ +// Set API(s). + WebPMuxError WebPMuxSetMetadata(WebPMux* const mux, const uint8_t* data, uint32_t size, int copy_data) { WebPMuxError err; @@ -623,6 +715,9 @@ WebPMuxError WebPMuxSetLoopCount(WebPMux* const mux, uint32_t loop_count) { return err; } +//------------------------------------------------------------------------------ +// Helper functions. + // Find out absolute indices or frame/chunk and image chunks // given overall index 'nth'. // isFrame = true -> This is for a frame. @@ -738,6 +833,9 @@ static WebPMuxError WebPMuxAddFrameTileInternal(WebPMux* const mux, return err; } +//------------------------------------------------------------------------------ +// Add API(s). + WebPMuxError WebPMuxAddFrame(WebPMux* const mux, uint32_t nth, const uint8_t* data, uint32_t size, uint32_t x_offset, uint32_t y_offset, @@ -769,6 +867,9 @@ WebPMuxError WebPMuxAddNamedData(WebPMux* const mux, uint32_t nth, copy_data); } +//------------------------------------------------------------------------------ +// Delete API(s). + static WebPMuxError WebPMuxDeleteNamedData(WebPMux* const mux, uint32_t nth, const char* const tag) { TAG_ID id; @@ -828,90 +929,6 @@ WebPMuxError WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth) { return WebPMuxDeleteFrameTileInternal(mux, nth, kChunks[TILE_ID].chunkName); } -static int IsNotCompatible(int feature, int num_items) { - return (feature != 0) != (num_items > 0); -} - -static WebPMuxError WebPMuxValidate(const WebPMux* mux) { - int num_iccp; - int num_meta; - int num_loop_chunks; - int num_frames; - int num_tiles; - int num_vp8x; - int num_images; - uint32_t flags; - WebPMuxError err; - - // Verify mux is not NULL. - if (mux == NULL) return WEBP_MUX_INVALID_ARGUMENT; - - // Verify mux has at least one image. - if (mux->images_ == NULL) return WEBP_MUX_INVALID_ARGUMENT; - - err = WebPMuxGetFeatures(mux, &flags); - if (err != WEBP_MUX_OK) return err; - - // At most one color profile chunk. - err = WebPMuxNumNamedElements(mux, kChunks[ICCP_ID].chunkName, &num_iccp); - if (err != WEBP_MUX_OK) return err; - if (num_iccp > 1) return WEBP_MUX_INVALID_ARGUMENT; - - // ICCP_FLAG and color profile chunk is consistent. - if (IsNotCompatible(flags & ICCP_FLAG, num_iccp)) { - return WEBP_MUX_INVALID_ARGUMENT; - } - - // At most one XMP metadata. - err = WebPMuxNumNamedElements(mux, kChunks[META_ID].chunkName, &num_meta); - if (err != WEBP_MUX_OK) return err; - if (num_meta > 1) return WEBP_MUX_INVALID_ARGUMENT; - - // META_FLAG and XMP metadata chunk is consistent. - if (IsNotCompatible(flags & META_FLAG, num_meta)) { - return WEBP_MUX_INVALID_ARGUMENT; - } - - // At most one loop chunk. - err = WebPMuxNumNamedElements(mux, kChunks[LOOP_ID].chunkName, - &num_loop_chunks); - if (err != WEBP_MUX_OK) return err; - if (num_loop_chunks > 1) return WEBP_MUX_INVALID_ARGUMENT; - - // Animation: ANIMATION_FLAG, loop chunk and frame chunk(s) are consistent. - err = WebPMuxNumNamedElements(mux, kChunks[FRAME_ID].chunkName, &num_frames); - if (err != WEBP_MUX_OK) return err; - if ((flags & ANIMATION_FLAG) && - ((num_loop_chunks == 0) || (num_frames == 0))) { - return WEBP_MUX_INVALID_ARGUMENT; - } else if (((num_loop_chunks == 1) || (num_frames > 0)) && - !(flags & ANIMATION_FLAG)) { - return WEBP_MUX_INVALID_ARGUMENT; - } - - // Tiling: TILE_FLAG and tile chunk(s) are consistent. - err = WebPMuxNumNamedElements(mux, kChunks[TILE_ID].chunkName, &num_tiles); - if (err != WEBP_MUX_OK) return err; - if (IsNotCompatible(flags & TILE_FLAG, num_tiles)) { - return WEBP_MUX_INVALID_ARGUMENT; - } - - // Verify either VP8X chunk is present OR there is only one elem in - // mux->images_. - err = WebPMuxNumNamedElements(mux, kChunks[VP8X_ID].chunkName, &num_vp8x); - if (err != WEBP_MUX_OK) return err; - err = WebPMuxNumNamedElements(mux, kChunks[IMAGE_ID].chunkName, &num_images); - if (err != WEBP_MUX_OK) return err; - - if (num_vp8x > 1) { - return WEBP_MUX_INVALID_ARGUMENT; - } else if ((num_vp8x == 0) && (num_images != 1)) { - return WEBP_MUX_INVALID_ARGUMENT; - } - - return WEBP_MUX_OK; -} - //------------------------------------------------------------------------------ // Assembly of the WebP RIFF file. @@ -943,7 +960,7 @@ static uint8_t* EmitChunks(const WebPChunk* chunk_list, uint8_t* dst) { return dst; } -static WebPMuxError GetImageCanvasHeightWidth(WebPMux* const mux, +static WebPMuxError GetImageCanvasHeightWidth(const WebPMux* const mux, uint32_t flags, uint32_t* width, uint32_t* height) { @@ -954,6 +971,7 @@ static WebPMuxError GetImageCanvasHeightWidth(WebPMux* const mux, assert(mux != NULL); assert(mux->images_ != NULL); + assert(width && height); image_chunk = mux->images_; @@ -1098,7 +1116,6 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux, uint8_t** output_data, if (err != WEBP_MUX_OK) return err; // Allocate data. - ReleaseChunk(&mux->mux_); size = ChunksListDiskSize(mux->vp8x_) + ChunksListDiskSize(mux->iccp_) + ChunksListDiskSize(mux->loop_) + ChunksListDiskSize(mux->images_) + ChunksListDiskSize(mux->meta_) + ChunksListDiskSize(mux->unknown_) @@ -1131,8 +1148,6 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux, uint8_t** output_data, } // Finalize. - mux->mux_.data_ = data; - mux->mux_.payload_size_ = size; *output_data = data; *output_size = size; @@ -1156,7 +1171,7 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux, uint8_t** output_data, } \ } -static WebPMuxError MuxGet(const WebPMux* mux, TAG_ID id, uint32_t nth, +static WebPMuxError MuxGet(const WebPMux* const mux, TAG_ID id, uint32_t nth, const uint8_t** data, uint32_t* data_size) { assert(mux != NULL); *data = NULL; @@ -1173,7 +1188,7 @@ static WebPMuxError MuxGet(const WebPMux* mux, TAG_ID id, uint32_t nth, } #undef SWITCH_ID_LIST -WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) { +WebPMuxError WebPMuxGetFeatures(const WebPMux* const mux, uint32_t* flags) { const uint8_t* data; uint32_t data_size; WebPMuxError err; @@ -1195,7 +1210,7 @@ WebPMuxError WebPMuxGetFeatures(const WebPMux* mux, uint32_t* flags) { return WEBP_MUX_OK; } -WebPMuxError WebPMuxGetMetadata(const WebPMux* mux, const uint8_t** data, +WebPMuxError WebPMuxGetMetadata(const WebPMux* const mux, const uint8_t** data, uint32_t* size) { if (mux == NULL || data == NULL || size == NULL) { return WEBP_MUX_INVALID_ARGUMENT; @@ -1204,8 +1219,8 @@ WebPMuxError WebPMuxGetMetadata(const WebPMux* mux, const uint8_t** data, return MuxGet(mux, META_ID, 1, data, size); } -WebPMuxError WebPMuxGetColorProfile(const WebPMux* mux, const uint8_t** data, - uint32_t* size) { +WebPMuxError WebPMuxGetColorProfile(const WebPMux* const mux, + const uint8_t** data, uint32_t* size) { if (mux == NULL || data == NULL || size == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } @@ -1213,7 +1228,8 @@ WebPMuxError WebPMuxGetColorProfile(const WebPMux* mux, const uint8_t** data, return MuxGet(mux, ICCP_ID, 1, data, size); } -WebPMuxError WebPMuxGetLoopCount(const WebPMux* mux, uint32_t* loop_count) { +WebPMuxError WebPMuxGetLoopCount(const WebPMux* const mux, + uint32_t* loop_count) { const uint8_t* data; uint32_t data_size; WebPMuxError err; @@ -1229,7 +1245,7 @@ WebPMuxError WebPMuxGetLoopCount(const WebPMux* mux, uint32_t* loop_count) { return WEBP_MUX_OK; } -WebPMuxError WebPMuxGetFrame(const WebPMux* mux, uint32_t nth, +WebPMuxError WebPMuxGetFrame(const WebPMux* const mux, uint32_t nth, const uint8_t** data, uint32_t* size, uint32_t* x_offset, uint32_t* y_offset, uint32_t* duration) { @@ -1255,7 +1271,7 @@ WebPMuxError WebPMuxGetFrame(const WebPMux* mux, uint32_t nth, return WebPMuxGetNamedData(mux, kChunks[IMAGE_ID].chunkName, nth, data, size); } -WebPMuxError WebPMuxGetTile(const WebPMux* mux, uint32_t nth, +WebPMuxError WebPMuxGetTile(const WebPMux* const mux, uint32_t nth, const uint8_t** data, uint32_t* size, uint32_t* x_offset, uint32_t* y_offset) { const uint8_t* tile_data; @@ -1279,7 +1295,7 @@ WebPMuxError WebPMuxGetTile(const WebPMux* mux, uint32_t nth, return WebPMuxGetNamedData(mux, kChunks[IMAGE_ID].chunkName, nth, data, size); } -WebPMuxError WebPMuxNumNamedElements(const WebPMux* mux, const char* tag, +WebPMuxError WebPMuxNumNamedElements(const WebPMux* const mux, const char* tag, int* num_elements) { TAG_ID id; WebPChunk** chunk_list; @@ -1300,7 +1316,7 @@ WebPMuxError WebPMuxNumNamedElements(const WebPMux* mux, const char* tag, return WEBP_MUX_OK; } -WebPMuxError WebPMuxGetNamedData(const WebPMux* mux, const char* tag, +WebPMuxError WebPMuxGetNamedData(const WebPMux* const mux, const char* tag, uint32_t nth, const uint8_t** data, uint32_t* size) { TAG_ID id; diff --git a/src/webp/mux.h b/src/webp/mux.h index 298fd8c2..9e884b1a 100644 --- a/src/webp/mux.h +++ b/src/webp/mux.h @@ -7,7 +7,40 @@ // // RIFF container manipulation for WEBP images. // -// Author: Urvang (urvang@google.com) +// Authors: Urvang (urvang@google.com) +// Vikas (vikasa@google.com) + +// This API allows manipulation of WebP container images containing features +// like Color profile, XMP metadata, Animation & Tiling. +// +// Code Example#1: Creating a MUX with image data, color profile & XMP metadata. +// +// int copy_data = 0; +// WebPMux* mux = WebPMuxNew(); +// // ... (Prepare image data). +// WebPMuxAddNamedData(mux, 1, "image", image_data, image_data_size, +// copy_data); +// // ... (Prepare ICCP color profile data). +// WebPMuxSetColorProfile(mux, icc_data, icc_data_size, copy_data); +// // ... (Prepare XMP metadata). +// WebPMuxSetMetadata(mux, xmp_data, xmp_data_size, copy_data); +// // Get data from mux in WebP RIFF format. +// WebPMuxAssemble(mux, &output_data, &output_data_size); +// WebPMuxDelete(mux); +// // ... (Consume output_data; e.g. write output_data to file). +// free(output_data); +// +// Code Example#2: Get image & color profile data from a WebP file. +// +// int copy_data = 0; +// // ... (Read data from file). +// WebPMux* mux = WebPMuxCreate(data, data_size, copy_data); +// WebPMuxGetNamedData(mux, "image", 1, &image_data, &image_data_size); +// // ... (Consume image_data; e.g. call WebPDecode() to decode the data). +// WebPMuxGetColorProfile(mux, &icc_data, &icc_data_size); +// // ... (Consume icc_data). +// WebPMuxDelete(mux); +// free(data); #ifndef WEBP_WEBP_MUX_H_ #define WEBP_WEBP_MUX_H_ @@ -48,27 +81,36 @@ typedef struct WebPMux WebPMux; // main opaque object. WEBP_EXTERN(WebPMux*) WebPMuxNew(void); // Deletes the mux object. +// Parameters: +// mux - (in/out) object to be deleted WEBP_EXTERN(void) WebPMuxDelete(WebPMux* const mux); //------------------------------------------------------------------------------ -// Writing +// Mux creation. // Creates a mux object from raw data given in WebP RIFF format. -// WebPMuxNew() should be called before calling this function. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// Parameters: +// data - (in) the raw data in WebP RIFF format +// size - (in) size of raw 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_BAD_DATA - if data cannot be read as a mux object. -// WEBP_MUX_MEMORY_ERROR - on memory allocation error. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxCreate(WebPMux* const mux, const uint8_t* data, - uint32_t size, int copy_data); +// A pointer to the mux object created from given data - on success. +// NULL - In case of invalid data or memory error. +WEBP_EXTERN(WebPMux*) WebPMuxCreate(const uint8_t* data, uint32_t size, + int copy_data); + +//------------------------------------------------------------------------------ +// XMP Metadata. // Sets the XMP metadata in the mux object. Any existing metadata chunk(s) will // be removed. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// Parameters: +// mux - (in/out) object to which the XMP metadata is to be added +// data - (in) the XMP metadata data to be added +// size - (in) size of the XMP metadata 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. @@ -77,10 +119,40 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetMetadata(WebPMux* const mux, const uint8_t* data, uint32_t size, int copy_data); +// Gets a reference to the XMP metadata in the mux object. +// The caller should NOT free the returned data. +// Parameters: +// mux - (in) object from which the XMP metadata is to be fetched +// data - (out) the returned XMP metadata +// size - (out) size of the returned XMP metadata +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either of mux, data or size is NULL +// WEBP_MUX_NOT_FOUND - if metadata is not present in mux object. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(const WebPMux* const mux, + const uint8_t** data, + uint32_t* size); + +// Deletes the XMP metadata in the mux object. +// Parameters: +// mux - (in/out) object from which XMP metadata is to be deleted +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL +// WEBP_MUX_NOT_FOUND - If mux does not contain metadata. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* const mux); + +//------------------------------------------------------------------------------ +// ICC Color Profile. + // Sets the color profile in the mux object. Any existing color profile chunk(s) // will be removed. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// Parameters: +// mux - (in/out) object to which the color profile is to be added +// data - (in) the color profile data to be added +// size - (in) size of the color profile 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 @@ -89,20 +161,44 @@ WEBP_EXTERN(WebPMuxError) WebPMuxSetColorProfile(WebPMux* const mux, const uint8_t* data, uint32_t size, int copy_data); -// Sets the animation loop count in the mux object. Any existing loop count -// value(s) will be removed. +// Gets a reference to the color profile in the mux object. +// The caller should NOT free the returned data. +// Parameters: +// mux - (in) object from which the color profile data is to be fetched +// data - (out) the returned color profile data +// size - (out) size of the returned color profile data +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either of mux, data or size is NULL +// WEBP_MUX_NOT_FOUND - if color profile is not present in mux object. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(const WebPMux* const mux, + const uint8_t** data, + uint32_t* size); + +// Deletes the color profile in the mux object. +// Parameters: +// mux - (in/out) object from which color profile is to be deleted // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL -// WEBP_MUX_MEMORY_ERROR - on memory allocation error. +// WEBP_MUX_NOT_FOUND - If mux does not contain color profile. // WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* const mux, - uint32_t loop_count); +WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux); + +//------------------------------------------------------------------------------ +// Animation. // Adds an animation frame to the mux object. // nth=0 has a special meaning - last position. -// duration is in milliseconds. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// Parameters: +// 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. +// data - (in) the raw VP8 image data corresponding to frame image +// size - (in) size of frame chunk data +// x_offset - (in) x-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) +// 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_NOT_FOUND - If we have less than (nth-1) frames before adding. @@ -113,10 +209,80 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddFrame(WebPMux* const mux, uint32_t nth, uint32_t x_offset, uint32_t y_offset, uint32_t duration, int copy_data); +// Gets a reference to the nth animation frame from 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 the info is to be fetched +// nth - (in) index of the frame in the mux object +// data - (out) the returned image data +// size - (out) size of the returned image data +// x_offset - (out) x-offset of the returned frame +// y_offset - (out) y-offset of the returned frame +// duration - (out) duration of the returned frame (in milliseconds) +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either mux, data, size, x_offset, +// y_offset, or duration is NULL +// WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. +// WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(const WebPMux* const mux, + uint32_t nth, + const uint8_t** data, uint32_t* size, + uint32_t* x_offset, + uint32_t* y_offset, + uint32_t* duration); + +// Deletes an animation frame from the mux object. +// nth=0 has a special meaning - last position. +// Parameters: +// mux - (in/out) object from which a frame is to be deleted +// nth - (in) The position from which the frame is to be deleted +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL +// WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object +// before deletion. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxDeleteFrame(WebPMux* const mux, uint32_t nth); + +// Sets the animation loop count in the mux object. Any existing loop count +// value(s) will be removed. +// Parameters: +// mux - (in/out) object in which loop chunk is to be set/added +// loop_count - (in) animation loop count value. +// Note that loop_count of zero denotes infinite loop. +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL +// WEBP_MUX_MEMORY_ERROR - on memory allocation error. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxSetLoopCount(WebPMux* const mux, + uint32_t loop_count); + +// Gets the animation loop count from the mux object. +// Parameters: +// mux - (in) object from which the loop count is to be fetched +// loop_count - (out) the loop_count value present in the LOOP chunk +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either of mux or loop_count is NULL +// WEBP_MUX_NOT_FOUND - if loop chunk is not present in mux object. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* const mux, + uint32_t* loop_count); + +//------------------------------------------------------------------------------ +// Tiling. + // Adds a tile to the mux object. // nth=0 has a special meaning - last position. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// Parameters: +// mux - (in/out) object to which a 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 +// size - (in) size of tile chunk data +// x_offset - (in) x-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 +// value 0 indicates data will NOT be copied. // Returns: // WEBP_MUX_INVALID_ARGUMENT - if mux is NULL or data is NULL // WEBP_MUX_NOT_FOUND - If we have less than (nth-1) tiles before adding. @@ -127,10 +293,52 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddTile(WebPMux* const mux, uint32_t nth, uint32_t x_offset, uint32_t y_offset, int copy_data); +// Gets a reference to the nth tile from 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 the info is to be fetched +// nth - (in) index of the tile in the mux object +// data - (out) the returned image data +// size - (out) size of the returned image data +// x_offset - (out) x-offset of the returned tile +// y_offset - (out) y-offset of the returned tile +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either mux, data, size, x_offset or +// y_offset is NULL +// WEBP_MUX_NOT_FOUND - if there are less than nth tiles in the mux object. +// WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(const WebPMux* const mux, uint32_t nth, + const uint8_t** data, uint32_t* size, + uint32_t* x_offset, + uint32_t* y_offset); + +// Deletes a tile from the mux object. +// nth=0 has a special meaning - last position +// Parameters: +// mux - (in/out) object from which a tile is to be deleted +// nth - (in) The position from which the tile is to be deleted +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL +// WEBP_MUX_NOT_FOUND - If there are less than nth tiles in the mux object +// before deletion. +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth); + +//------------------------------------------------------------------------------ +// Misc Utilities. + // Adds a chunk with given tag at nth position. // nth=0 has a special meaning - last position. -// copy_data - value 1 indicates given data WILL copied to the mux object, and -// value 0 indicates data will NOT be copied. +// 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. @@ -141,42 +349,60 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAddNamedData(WebPMux* const mux, uint32_t nth, const uint8_t* data, uint32_t size, int copy_data); -// Deletes the XMP metadata in the mux object. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL -// WEBP_MUX_NOT_FOUND - If mux does not contain metadata. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxDeleteMetadata(WebPMux* const mux); - -// Deletes the color profile in the mux object. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL -// WEBP_MUX_NOT_FOUND - If mux does not contain color profile. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxDeleteColorProfile(WebPMux* const mux); - -// Deletes an animation frame from the mux object. +// 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 mux is NULL -// WEBP_MUX_NOT_FOUND - If there are less than nth frames in the mux object -// before deletion. +// 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) WebPMuxDeleteFrame(WebPMux* const mux, uint32_t nth); +WEBP_EXTERN(WebPMuxError) WebPMuxGetNamedData(const WebPMux* const mux, + const char* tag, uint32_t nth, + const uint8_t** data, + uint32_t* size); -// Deletes a tile from the mux object. -// nth=0 has a special meaning - last position +// Gets the feature flags from the mux object. +// Parameters: +// mux - (in) object from which the features are to be fetched +// flags - (out) the flags specifying which features are present in the +// mux object. This will be an OR of various flag values. +// Enum 'FeatureFlags' can be used to test for individual flag values. // Returns: -// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL -// WEBP_MUX_NOT_FOUND - If there are less than nth tiles in the mux object -// before deletion. +// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 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_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxDeleteTile(WebPMux* const mux, uint32_t nth); +WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* const mux, + uint32_t* flags); + +// Gets number of chunks having tag value tag in the mux object. +// Parameters: +// mux - (in) object from which the info is to be fetched +// tag - (in) tag name specifying the type of chunk +// num_elements - (out) number of chunks corresponding to the specified tag +// Returns: +// WEBP_MUX_INVALID_ARGUMENT - if either mux, tag or num_elements is NULL +// WEBP_MUX_OK - on success. +WEBP_EXTERN(WebPMuxError) WebPMuxNumNamedElements(const WebPMux* const mux, + const char* tag, + int* num_elements); // Assembles all chunks in WebP RIFF format and returns in output_data. // This function also validates the mux object. -// This function does NOT free the mux object. The caller function should free -// the mux object and output_data after output_data has been consumed. +// The content of '*output_data' is allocated using malloc(), and NOT +// owned by the 'mux' object. +// It MUST be deallocated by the caller by calling free(). +// Parameters: +// mux - (in/out) object whose chunks are to be assembled +// output_data - (out) byte array where assembled WebP data is returned +// output_size - (out) size of returned data // Returns: // WEBP_MUX_BAD_DATA - if mux object is invalid. // WEBP_MUX_INVALID_ARGUMENT - if either mux, output_data or output_size is @@ -187,97 +413,6 @@ WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* const mux, uint8_t** output_data, uint32_t* output_size); -//------------------------------------------------------------------------------ -// Reading - -// Gets the feature flags from the mux object. -// Use enum 'FeatureFlags' to test for individual features. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if mux is NULL 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_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetFeatures(const WebPMux* mux, - uint32_t* flags); - -// Gets a reference to the XMP metadata in the mux object. -// The caller should not free the returned data. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either of mux, data or size is NULL -// WEBP_MUX_NOT_FOUND - if metadata is not present in mux object. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetMetadata(const WebPMux* mux, - const uint8_t** data, - uint32_t* size); - -// Gets a reference to the color profile in the mux object. -// The caller should not free the returned data. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either of mux, data or size is NULL -// WEBP_MUX_NOT_FOUND - if color profile is not present in mux object. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetColorProfile(const WebPMux* mux, - const uint8_t** data, - uint32_t* size); - -// Gets the animation loop count from the mux object. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either of mux or loop_count is NULL -// WEBP_MUX_NOT_FOUND - if loop chunk is not present in mux object. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetLoopCount(const WebPMux* mux, - uint32_t* loop_count); - -// Gets a reference to the nth animation frame from the mux object. -// nth=0 has a special meaning - last position. -// duration is in milliseconds. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either mux, data, size, x_offset, -// y_offset, or duration is NULL -// WEBP_MUX_NOT_FOUND - if there are less than nth frames in the mux object. -// WEBP_MUX_BAD_DATA - if nth frame chunk in mux is invalid. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetFrame(const WebPMux* mux, uint32_t nth, - const uint8_t** data, uint32_t* size, - uint32_t* x_offset, - uint32_t* y_offset, - uint32_t* duration); - -// Gets a reference to the nth tile from the mux object. -// The caller should not free the returned data. -// nth=0 has a special meaning - last position. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either mux, data, size, x_offset or -// y_offset is NULL -// WEBP_MUX_NOT_FOUND - if there are less than nth tiles in the mux object. -// WEBP_MUX_BAD_DATA - if nth tile chunk in mux is invalid. -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxGetTile(const WebPMux* mux, uint32_t nth, - const uint8_t** data, uint32_t* size, - uint32_t* x_offset, - uint32_t* y_offset); - -// Gets number of chunks having tag value tag in the mux object. -// Returns: -// WEBP_MUX_INVALID_ARGUMENT - if either mux, tag or num_elements is NULL -// WEBP_MUX_OK - on success. -WEBP_EXTERN(WebPMuxError) WebPMuxNumNamedElements(const WebPMux* mux, - const char* tag, - int* num_elements); - -// 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. -// 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* mux, - const char* tag, uint32_t nth, - const uint8_t** data, - uint32_t* size); - //------------------------------------------------------------------------------ #if defined(__cplusplus) || defined(c_plusplus)