From a4df4aae735998b9b090c74c1ede13899a8aa1b9 Mon Sep 17 00:00:00 2001 From: Skal Date: Tue, 15 Oct 2019 23:16:51 +0200 Subject: [PATCH] Expose WebPMalloc() in addition to WebPFree() and use it at various places, including for WebPData. This is an API change! Change-Id: Ic041323a1179c465292a4f981a86c4c34635d243 --- examples/anim_util.c | 18 +++++++++--------- examples/cwebp.c | 5 +++-- examples/dwebp.c | 8 ++++---- examples/example_util.c | 4 ++-- examples/gifdec.c | 4 ++-- examples/webpmux.c | 4 ++-- src/utils/utils.c | 9 +++++++-- src/webp/decode.h | 5 +---- src/webp/encode.h | 5 +---- src/webp/mux.h | 12 ++++++------ src/webp/mux_types.h | 10 +++++----- src/webp/types.h | 18 +++++++++++++++++- 12 files changed, 59 insertions(+), 43 deletions(-) diff --git a/examples/anim_util.c b/examples/anim_util.c index 8eff8b11..b6ee97b2 100644 --- a/examples/anim_util.c +++ b/examples/anim_util.c @@ -60,15 +60,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) { !CheckSizeForOverflow(total_frame_size)) { return 0; } - mem = (uint8_t*)malloc((size_t)total_size); - frames = (DecodedFrame*)malloc((size_t)total_frame_size); + mem = (uint8_t*)WebPMalloc((size_t)total_size); + frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size); if (mem == NULL || frames == NULL) { - free(mem); - free(frames); + WebPFree(mem); + WebPFree(frames); return 0; } - free(image->raw_mem); + WebPFree(image->raw_mem); image->num_frames = num_frames; image->frames = frames; for (i = 0; i < num_frames; ++i) { @@ -82,8 +82,8 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) { void ClearAnimatedImage(AnimatedImage* const image) { if (image != NULL) { - free(image->raw_mem); - free(image->frames); + WebPFree(image->raw_mem); + WebPFree(image->frames); image->num_frames = 0; image->frames = NULL; image->raw_mem = NULL; @@ -165,7 +165,7 @@ static int DumpFrame(const char filename[], const char dump_folder[], base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1; max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name) + strlen("_frame_") + strlen(".pam") + 8; - file_name = (W_CHAR*)malloc(max_len * sizeof(*file_name)); + file_name = (W_CHAR*)WebPMalloc(max_len * sizeof(*file_name)); if (file_name == NULL) goto End; if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam", @@ -197,7 +197,7 @@ static int DumpFrame(const char filename[], const char dump_folder[], ok = 1; End: if (f != NULL) fclose(f); - free(file_name); + WebPFree(file_name); return ok; } diff --git a/examples/cwebp.c b/examples/cwebp.c index 35c832a4..aa96caf5 100644 --- a/examples/cwebp.c +++ b/examples/cwebp.c @@ -128,7 +128,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic, static void AllocExtraInfo(WebPPicture* const pic) { const int mb_w = (pic->width + 15) / 16; const int mb_h = (pic->height + 15) / 16; - pic->extra_info = (uint8_t*)malloc(mb_w * mb_h * sizeof(*pic->extra_info)); + pic->extra_info = + (uint8_t*)WebPMalloc(mb_w * mb_h * sizeof(*pic->extra_info)); } static void PrintByteCount(const int bytes[4], int total_size, @@ -1168,7 +1169,7 @@ int main(int argc, const char* argv[]) { Error: WebPMemoryWriterClear(&memory_writer); - free(picture.extra_info); + WebPFree(picture.extra_info); MetadataFree(&metadata); WebPPictureFree(&picture); WebPPictureFree(&original_picture); diff --git a/examples/dwebp.c b/examples/dwebp.c index e9a0e66a..cc75cb77 100644 --- a/examples/dwebp.c +++ b/examples/dwebp.c @@ -132,7 +132,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config, format == RGB_565) ? 2 : 4; uint32_t stride = bpp * w + 7; // <- just for exercising - external_buffer = (uint8_t*)malloc(stride * h); + external_buffer = (uint8_t*)WebPMalloc(stride * h); if (external_buffer == NULL) return NULL; output_buffer->u.RGBA.stride = stride; output_buffer->u.RGBA.size = stride * h; @@ -145,7 +145,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config, uint32_t total_size = stride * h * (has_alpha ? 2 : 1) + 2 * uv_stride * (h + 1) / 2; assert(format >= YUV && format <= YUVA); - external_buffer = (uint8_t*)malloc(total_size); + external_buffer = (uint8_t*)WebPMalloc(total_size); if (external_buffer == NULL) return NULL; tmp = external_buffer; output_buffer->u.YUVA.y = tmp; @@ -412,8 +412,8 @@ int main(int argc, const char* argv[]) { } Exit: WebPFreeDecBuffer(output_buffer); - free((void*)external_buffer); - free((void*)data); + WebPFree((void*)external_buffer); + WebPFree((void*)data); FREE_WARGV_AND_RETURN(ok ? 0 : -1); } diff --git a/examples/example_util.c b/examples/example_util.c index a1c84988..b0436541 100644 --- a/examples/example_util.c +++ b/examples/example_util.c @@ -75,7 +75,7 @@ static void ResetCommandLineArguments(int argc, const char* argv[], void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) { if (args != NULL) { if (args->own_argv_) { - free((void*)args->argv_); + WebPFree((void*)args->argv_); WebPDataClear(&args->argv_data_); } ResetCommandLineArguments(0, NULL, args); @@ -102,7 +102,7 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[], return 0; } args->own_argv_ = 1; - args->argv_ = (const char**)malloc(MAX_ARGC * sizeof(*args->argv_)); + args->argv_ = (const char**)WebPMalloc(MAX_ARGC * sizeof(*args->argv_)); if (args->argv_ == NULL) return 0; argc = 0; diff --git a/examples/gifdec.c b/examples/gifdec.c index 4219352f..99ee9966 100644 --- a/examples/gifdec.c +++ b/examples/gifdec.c @@ -137,7 +137,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index, } dst = sub_image.argb; - tmp = (uint8_t*)malloc(rect.width * sizeof(*tmp)); + tmp = (uint8_t*)WebPMalloc(rect.width * sizeof(*tmp)); if (tmp == NULL) goto End; if (image_desc->Interlace) { // Interlaced image. @@ -168,7 +168,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index, End: if (!ok) picture->error_code = sub_image.error_code; WebPPictureFree(&sub_image); - free(tmp); + WebPFree(tmp); return ok; } diff --git a/examples/webpmux.c b/examples/webpmux.c index ccea83ae..49eff514 100644 --- a/examples/webpmux.c +++ b/examples/webpmux.c @@ -1045,7 +1045,7 @@ static int Process(const Config* config) { int* durations = NULL; WebPMux* new_mux = DuplicateMuxHeader(mux); if (new_mux == NULL) goto Err2; - durations = (int*)malloc((size_t)num_frames * sizeof(*durations)); + durations = (int*)WebPMalloc((size_t)num_frames * sizeof(*durations)); if (durations == NULL) goto Err2; for (i = 0; i < num_frames; ++i) durations[i] = -1; @@ -1103,7 +1103,7 @@ static int Process(const Config* config) { new_mux = NULL; Err3: - free(durations); + WebPFree(durations); WebPMuxDelete(new_mux); if (!ok) goto Err2; } diff --git a/src/utils/utils.c b/src/utils/utils.c index 44d5c14f..764f752b 100644 --- a/src/utils/utils.c +++ b/src/utils/utils.c @@ -216,9 +216,14 @@ void WebPSafeFree(void* const ptr) { free(ptr); } -// Public API function. +// Public API functions. + +void* WebPMalloc(size_t size) { + return WebPSafeMalloc(1, size); +} + void WebPFree(void* ptr) { - free(ptr); + WebPSafeFree(ptr); } //------------------------------------------------------------------------------ diff --git a/src/webp/decode.h b/src/webp/decode.h index ae8bfe84..80dd0ef0 100644 --- a/src/webp/decode.h +++ b/src/webp/decode.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define WEBP_DECODER_ABI_VERSION 0x0208 // MAJOR(8b) + MINOR(8b) +#define WEBP_DECODER_ABI_VERSION 0x0209 // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. @@ -91,9 +91,6 @@ WEBP_EXTERN uint8_t* WebPDecodeYUV(const uint8_t* data, size_t data_size, uint8_t** u, uint8_t** v, int* stride, int* uv_stride); -// Releases memory returned by the WebPDecode*() functions above. -WEBP_EXTERN void WebPFree(void* ptr); - // These five functions are variants of the above ones, that decode the image // directly into a pre-allocated buffer 'output_buffer'. The maximum storage // available in this buffer is indicated by 'output_buffer_size'. If this diff --git a/src/webp/encode.h b/src/webp/encode.h index a68518c0..655166e7 100644 --- a/src/webp/encode.h +++ b/src/webp/encode.h @@ -20,7 +20,7 @@ extern "C" { #endif -#define WEBP_ENCODER_ABI_VERSION 0x020e // MAJOR(8b) + MINOR(8b) +#define WEBP_ENCODER_ABI_VERSION 0x020f // MAJOR(8b) + MINOR(8b) // Note: forward declaring enumerations is not allowed in (strict) C and C++, // the types are left here for reference. @@ -79,9 +79,6 @@ WEBP_EXTERN size_t WebPEncodeLosslessBGRA(const uint8_t* bgra, int width, int height, int stride, uint8_t** output); -// Releases memory returned by the WebPEncode*() functions above. -WEBP_EXTERN void WebPFree(void* ptr); - //------------------------------------------------------------------------------ // Coding parameters diff --git a/src/webp/mux.h b/src/webp/mux.h index 66096a92..7d27489a 100644 --- a/src/webp/mux.h +++ b/src/webp/mux.h @@ -57,7 +57,7 @@ extern "C" { WebPMuxGetChunk(mux, "ICCP", &icc_profile); // ... (Consume icc_data). WebPMuxDelete(mux); - free(data); + WebPFree(data); */ // Note: forward declaring enumerations is not allowed in (strict) C and C++, @@ -245,7 +245,7 @@ WEBP_EXTERN WebPMuxError WebPMuxPushFrame( WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data); // Gets the nth frame from the mux object. -// The content of 'frame->bitstream' is allocated using malloc(), and NOT +// The content of 'frame->bitstream' is allocated using WebPMalloc(), and NOT // owned by the 'mux' object. It MUST be deallocated by the caller by calling // WebPDataClear(). // nth=0 has a special meaning - last position. @@ -376,10 +376,10 @@ WEBP_EXTERN WebPMuxError WebPMuxNumChunks(const WebPMux* mux, // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'. // This function also validates the mux object. // 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(). It's always safe to call WebPDataClear() upon return, -// even in case of error. +// Also, the content of 'assembled_data' is allocated using WebPMalloc(), and +// NOT owned by the 'mux' object. It MUST be deallocated by the caller by +// calling WebPDataClear(). It's always safe to call WebPDataClear() upon +// return, even in case of error. // Parameters: // mux - (in/out) object whose chunks are to be assembled // assembled_data - (out) assembled WebP data diff --git a/src/webp/mux_types.h b/src/webp/mux_types.h index ceea77df..2fe81958 100644 --- a/src/webp/mux_types.h +++ b/src/webp/mux_types.h @@ -14,7 +14,6 @@ #ifndef WEBP_WEBP_MUX_TYPES_H_ #define WEBP_WEBP_MUX_TYPES_H_ -#include // free() #include // memset() #include "./types.h" @@ -56,6 +55,7 @@ typedef enum WebPMuxAnimBlend { // Data type used to describe 'raw' data, e.g., chunk data // (ICC profile, metadata) and WebP compressed image data. +// 'bytes' memory must be allocated using WebPMalloc() and such. struct WebPData { const uint8_t* bytes; size_t size; @@ -68,11 +68,11 @@ static WEBP_INLINE void WebPDataInit(WebPData* webp_data) { } } -// Clears the contents of the 'webp_data' object by calling free(). Does not -// deallocate the object itself. +// Clears the contents of the 'webp_data' object by calling WebPFree(). +// Does not deallocate the object itself. static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { if (webp_data != NULL) { - free((void*)webp_data->bytes); + WebPFree((void*)webp_data->bytes); WebPDataInit(webp_data); } } @@ -83,7 +83,7 @@ static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) { if (src == NULL || dst == NULL) return 0; WebPDataInit(dst); if (src->bytes != NULL && src->size != 0) { - dst->bytes = (uint8_t*)malloc(src->size); + dst->bytes = (uint8_t*)WebPMalloc(src->size); if (dst->bytes == NULL) return 0; memcpy((void*)dst->bytes, src->bytes, src->size); dst->size = src->size; diff --git a/src/webp/types.h b/src/webp/types.h index 0ce2622e..47f7f2b0 100644 --- a/src/webp/types.h +++ b/src/webp/types.h @@ -7,7 +7,7 @@ // be found in the AUTHORS file in the root of the source tree. // ----------------------------------------------------------------------------- // -// Common types +// Common types + memory wrappers // // Author: Skal (pascal.massimino@gmail.com) @@ -49,4 +49,20 @@ typedef long long int int64_t; // Macro to check ABI compatibility (same major revision number) #define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) +#ifdef __cplusplus +extern "C" { +#endif + +// Allocates 'size' bytes of memory. Returns NULL upon error. Memory +// must be deallocated by calling WebPFree(). This function is made available +// by the core 'libwebp' library. +WEBP_EXTERN void* WebPMalloc(size_t size); + +// Releases memory returned by the WebPDecode*() functions (from decode.h). +WEBP_EXTERN void WebPFree(void* ptr); + +#ifdef __cplusplus +} // extern "C" +#endif + #endif // WEBP_WEBP_TYPES_H_