diff --git a/README.mux b/README.mux index c440c348..9eec6319 100644 --- a/README.mux +++ b/README.mux @@ -81,10 +81,10 @@ profile & XMP metadata. // ... (Prepare XMP metadata). WebPMuxSetMetadata(mux, &xmp, copy_data); // Get data from mux in WebP RIFF format. - WebPMuxAssemble(mux, &output_data, &output_data_size); + WebPMuxAssemble(mux, &output_data); WebPMuxDelete(mux); - // ... (Consume output_data; e.g. write output_data to file). - free(output_data); + // ... (Consume output_data; e.g. write output_data.bytes_ to file). + WebPDataClear(&output_data); Example#2 (pseudo code): Get image & color profile data from a WebP file. diff --git a/examples/webpmux.c b/examples/webpmux.c index 55dfb28f..8f46de2a 100644 --- a/examples/webpmux.c +++ b/examples/webpmux.c @@ -135,12 +135,6 @@ static int WebPDataCopy(const WebPData* const src, WebPData* const dst) { return 1; } -// Frees data allocated by WebPDataCopy. -static void WebPDataFree(WebPData* const webpdata) { - free((void*)webpdata->bytes_); - memset(webpdata, 0, sizeof(*webpdata)); -} - #define RETURN_IF_ERROR(ERR_MSG) \ if (err != WEBP_MUX_OK) { \ fprintf(stderr, ERR_MSG); \ @@ -370,8 +364,8 @@ static int ReadImage(const char* filename, if (!ok) { fprintf(stderr, "Error allocating storage for image (%zu bytes) " "and alpha (%zu bytes) data\n", image.size_, alpha.size_); - WebPDataFree(image_ptr); - WebPDataFree(alpha_ptr); + WebPDataClear(image_ptr); + WebPDataClear(alpha_ptr); } } else { fprintf(stderr, "Failed to extract image data from file %s. Error: %d\n", @@ -399,17 +393,15 @@ static int WriteData(const char* filename, const WebPData* const webpdata) { } static int WriteWebP(WebPMux* const mux, const char* filename) { - WebPData webpdata; int ok; - - const WebPMuxError err = WebPMuxAssemble( - mux, (uint8_t**)&webpdata.bytes_, &webpdata.size_); + WebPData webp_data; + const WebPMuxError err = WebPMuxAssemble(mux, &webp_data); if (err != WEBP_MUX_OK) { fprintf(stderr, "Error (%d) assembling the WebP file.\n", err); return 0; } - ok = WriteData(filename, &webpdata); - WebPDataFree(&webpdata); + ok = WriteData(filename, &webp_data); + WebPDataClear(&webp_data); return ok; } @@ -862,14 +854,14 @@ static int Process(const WebPMuxConfig* config) { ok = ParseFrameArgs(feature->args_[index].params_, &x_offset, &y_offset, &duration); if (!ok) { - WebPDataFree(&image); - WebPDataFree(&alpha); + WebPDataClear(&image); + WebPDataClear(&alpha); ERROR_GOTO1("ERROR: Could not parse frame properties.\n", Err2); } err = WebPMuxSetFrame(mux, 0, &image, &alpha, x_offset, y_offset, duration, 1); - WebPDataFree(&image); - WebPDataFree(&alpha); + WebPDataClear(&image); + WebPDataClear(&alpha); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR#%d: Could not add a frame at index %d.\n", err, index, Err2); @@ -893,13 +885,13 @@ static int Process(const WebPMuxConfig* config) { ok = ParseTileArgs(feature->args_[index].params_, &x_offset, &y_offset); if (!ok) { - WebPDataFree(&image); - WebPDataFree(&alpha); + WebPDataClear(&image); + WebPDataClear(&alpha); ERROR_GOTO1("ERROR: Could not parse tile properties.\n", Err2); } err = WebPMuxSetTile(mux, 0, &image, &alpha, x_offset, y_offset, 1); - WebPDataFree(&image); - WebPDataFree(&alpha); + WebPDataClear(&image); + WebPDataClear(&alpha); if (err != WEBP_MUX_OK) { ERROR_GOTO3("ERROR#%d: Could not add a tile at index %d.\n", err, index, Err2); diff --git a/src/mux/muxedit.c b/src/mux/muxedit.c index 01376fb9..283014b3 100644 --- a/src/mux/muxedit.c +++ b/src/mux/muxedit.c @@ -270,7 +270,8 @@ WebPMuxError WebPMuxSetImage(WebPMux* const mux, // Add image chunk. ChunkInit(&chunk); - err = ChunkAssignDataImageInfo(&chunk, &image_raw, NULL, copy_data, image_tag); + err = ChunkAssignDataImageInfo(&chunk, &image_raw, NULL, copy_data, + image_tag); if (err != WEBP_MUX_OK) return err; err = ChunkSetNth(&chunk, &wpi.img_, 1); if (err != WEBP_MUX_OK) return err; @@ -645,7 +646,7 @@ static WebPMuxError CreateVP8XChunk(WebPMux* const mux) { } WebPMuxError WebPMuxAssemble(WebPMux* const mux, - uint8_t** output_data, size_t* output_size) { + WebPData* const assembled_data) { size_t size = 0; uint8_t* data = NULL; uint8_t* dst = NULL; @@ -653,13 +654,10 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux, int num_loop_chunks; WebPMuxError err; - if (mux == NULL || output_data == NULL || output_size == NULL) { + if (mux == NULL || assembled_data == NULL) { return WEBP_MUX_INVALID_ARGUMENT; } - *output_data = NULL; - *output_size = 0; - // Remove LOOP chunk if unnecessary. err = WebPMuxNumNamedElements(mux, kChunks[IDX_LOOP].name, &num_loop_chunks); @@ -715,8 +713,8 @@ WebPMuxError WebPMuxAssemble(WebPMux* const mux, } // Finalize. - *output_data = data; - *output_size = size; + assembled_data->bytes_ = data; + assembled_data->size_ = size; return err; } diff --git a/src/mux/muxinternal.c b/src/mux/muxinternal.c index 6dc7a34b..6fefedfd 100644 --- a/src/mux/muxinternal.c +++ b/src/mux/muxinternal.c @@ -225,6 +225,16 @@ uint8_t* ChunkListEmit(const WebPChunk* chunk_list, uint8_t* dst) { return dst; } +//------------------------------------------------------------------------------ +// Life of a WebPData object. + +void WebPDataClear(WebPData* const webp_data) { + if (webp_data != NULL) { + free((void*)webp_data->bytes_); + memset(webp_data, 0, sizeof(*webp_data)); + } +} + //------------------------------------------------------------------------------ // Life of a MuxImage object. diff --git a/src/webp/mux.h b/src/webp/mux.h index d96dacca..aa589411 100644 --- a/src/webp/mux.h +++ b/src/webp/mux.h @@ -24,10 +24,10 @@ // // ... (Prepare XMP metadata). // WebPMuxSetMetadata(mux, &xmp, copy_data); // // Get data from mux in WebP RIFF format. -// WebPMuxAssemble(mux, &output_data, &output_data_size); +// WebPMuxAssemble(mux, &output_data); // WebPMuxDelete(mux); -// // ... (Consume output_data; e.g. write output_data to file). -// free(output_data); +// // ... (Consume output_data; e.g. write output_data.bytes_ to file). +// WebPDataClear(&output_data); // // Code Example#2: Get image & color profile data from a WebP file. // @@ -88,6 +88,13 @@ typedef struct { size_t size_; } WebPData; +//------------------------------------------------------------------------------ +// Life of a WebPData object. + +// Clears the contents of the 'webp_data' object by calling free(). Does not +// deallocate the object itself. +WEBP_EXTERN(void) WebPDataClear(WebPData* const webp_data); + //------------------------------------------------------------------------------ // Life of a Mux object @@ -138,7 +145,7 @@ static WEBP_INLINE WebPMux* WebPMuxCreate(const WebPData* const bitstream, // Parameters: // mux - (in/out) object in which the image is to be set // image - (in) the image data. The data can be either a VP8/VP8L -// bitstream or a single-image WebP file (non-animated & non-tiled) +// bitstream or a single-image WebP file (non-animated & non-tiled) // alpha - (in) the alpha data of the image (if present) // copy_data - (in) value 1 indicates given data WILL copied to the mux, and // value 0 indicates data will NOT be copied. @@ -438,15 +445,15 @@ WEBP_EXTERN(WebPMuxError) WebPMuxNumNamedElements(const WebPMux* const mux, const char* name, int* num_elements); -// Assembles all chunks in WebP RIFF format and returns in output_data. +// Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. // This function also validates the mux object. -// 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(). +// Note: The content of 'assembled_data' will be ignored and overwritten. +// Also, the content of 'assembled_data' is allocated using malloc(), and NOT +// owned by the 'mux' object. It MUST be deallocated by the caller by calling +// WebPDataClear(). // 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 +// assembled_data - (out) assembled WebP data // Returns: // WEBP_MUX_BAD_DATA - if mux object is invalid. // WEBP_MUX_INVALID_ARGUMENT - if either mux, output_data or output_size is @@ -454,8 +461,7 @@ WEBP_EXTERN(WebPMuxError) WebPMuxNumNamedElements(const WebPMux* const mux, // WEBP_MUX_MEMORY_ERROR - on memory allocation error. // WEBP_MUX_OK - on success WEBP_EXTERN(WebPMuxError) WebPMuxAssemble(WebPMux* const mux, - uint8_t** output_data, - size_t* output_size); + WebPData* const assembled_data); //------------------------------------------------------------------------------