Merge "Expose WebPMalloc() in addition to WebPFree()"

This commit is contained in:
Pascal Massimino 2019-10-16 05:48:18 +00:00 committed by Gerrit Code Review
commit 2fa2552db1
12 changed files with 59 additions and 43 deletions

View File

@ -60,15 +60,15 @@ static int AllocateFrames(AnimatedImage* const image, uint32_t num_frames) {
!CheckSizeForOverflow(total_frame_size)) { !CheckSizeForOverflow(total_frame_size)) {
return 0; return 0;
} }
mem = (uint8_t*)malloc((size_t)total_size); mem = (uint8_t*)WebPMalloc((size_t)total_size);
frames = (DecodedFrame*)malloc((size_t)total_frame_size); frames = (DecodedFrame*)WebPMalloc((size_t)total_frame_size);
if (mem == NULL || frames == NULL) { if (mem == NULL || frames == NULL) {
free(mem); WebPFree(mem);
free(frames); WebPFree(frames);
return 0; return 0;
} }
free(image->raw_mem); WebPFree(image->raw_mem);
image->num_frames = num_frames; image->num_frames = num_frames;
image->frames = frames; image->frames = frames;
for (i = 0; i < num_frames; ++i) { 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) { void ClearAnimatedImage(AnimatedImage* const image) {
if (image != NULL) { if (image != NULL) {
free(image->raw_mem); WebPFree(image->raw_mem);
free(image->frames); WebPFree(image->frames);
image->num_frames = 0; image->num_frames = 0;
image->frames = NULL; image->frames = NULL;
image->raw_mem = 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; base_name = (base_name == NULL) ? (const W_CHAR*)filename : base_name + 1;
max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name) max_len = WSTRLEN(dump_folder) + 1 + WSTRLEN(base_name)
+ strlen("_frame_") + strlen(".pam") + 8; + 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 (file_name == NULL) goto End;
if (WSNPRINTF(file_name, max_len, "%s/%s_frame_%d.pam", 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; ok = 1;
End: End:
if (f != NULL) fclose(f); if (f != NULL) fclose(f);
free(file_name); WebPFree(file_name);
return ok; return ok;
} }

View File

@ -128,7 +128,8 @@ static int ReadPicture(const char* const filename, WebPPicture* const pic,
static void AllocExtraInfo(WebPPicture* const pic) { static void AllocExtraInfo(WebPPicture* const pic) {
const int mb_w = (pic->width + 15) / 16; const int mb_w = (pic->width + 15) / 16;
const int mb_h = (pic->height + 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, static void PrintByteCount(const int bytes[4], int total_size,
@ -1168,7 +1169,7 @@ int main(int argc, const char* argv[]) {
Error: Error:
WebPMemoryWriterClear(&memory_writer); WebPMemoryWriterClear(&memory_writer);
free(picture.extra_info); WebPFree(picture.extra_info);
MetadataFree(&metadata); MetadataFree(&metadata);
WebPPictureFree(&picture); WebPPictureFree(&picture);
WebPPictureFree(&original_picture); WebPPictureFree(&original_picture);

View File

@ -132,7 +132,7 @@ static uint8_t* AllocateExternalBuffer(WebPDecoderConfig* config,
format == RGB_565) ? 2 format == RGB_565) ? 2
: 4; : 4;
uint32_t stride = bpp * w + 7; // <- just for exercising 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; if (external_buffer == NULL) return NULL;
output_buffer->u.RGBA.stride = stride; output_buffer->u.RGBA.stride = stride;
output_buffer->u.RGBA.size = stride * h; 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) uint32_t total_size = stride * h * (has_alpha ? 2 : 1)
+ 2 * uv_stride * (h + 1) / 2; + 2 * uv_stride * (h + 1) / 2;
assert(format >= YUV && format <= YUVA); 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; if (external_buffer == NULL) return NULL;
tmp = external_buffer; tmp = external_buffer;
output_buffer->u.YUVA.y = tmp; output_buffer->u.YUVA.y = tmp;
@ -412,8 +412,8 @@ int main(int argc, const char* argv[]) {
} }
Exit: Exit:
WebPFreeDecBuffer(output_buffer); WebPFreeDecBuffer(output_buffer);
free((void*)external_buffer); WebPFree((void*)external_buffer);
free((void*)data); WebPFree((void*)data);
FREE_WARGV_AND_RETURN(ok ? 0 : -1); FREE_WARGV_AND_RETURN(ok ? 0 : -1);
} }

View File

@ -75,7 +75,7 @@ static void ResetCommandLineArguments(int argc, const char* argv[],
void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) { void ExUtilDeleteCommandLineArguments(CommandLineArguments* const args) {
if (args != NULL) { if (args != NULL) {
if (args->own_argv_) { if (args->own_argv_) {
free((void*)args->argv_); WebPFree((void*)args->argv_);
WebPDataClear(&args->argv_data_); WebPDataClear(&args->argv_data_);
} }
ResetCommandLineArguments(0, NULL, args); ResetCommandLineArguments(0, NULL, args);
@ -102,7 +102,7 @@ int ExUtilInitCommandLineArguments(int argc, const char* argv[],
return 0; return 0;
} }
args->own_argv_ = 1; 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; if (args->argv_ == NULL) return 0;
argc = 0; argc = 0;

View File

@ -137,7 +137,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
} }
dst = sub_image.argb; 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 (tmp == NULL) goto End;
if (image_desc->Interlace) { // Interlaced image. if (image_desc->Interlace) { // Interlaced image.
@ -168,7 +168,7 @@ int GIFReadFrame(GifFileType* const gif, int transparent_index,
End: End:
if (!ok) picture->error_code = sub_image.error_code; if (!ok) picture->error_code = sub_image.error_code;
WebPPictureFree(&sub_image); WebPPictureFree(&sub_image);
free(tmp); WebPFree(tmp);
return ok; return ok;
} }

View File

@ -1045,7 +1045,7 @@ static int Process(const Config* config) {
int* durations = NULL; int* durations = NULL;
WebPMux* new_mux = DuplicateMuxHeader(mux); WebPMux* new_mux = DuplicateMuxHeader(mux);
if (new_mux == NULL) goto Err2; 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; if (durations == NULL) goto Err2;
for (i = 0; i < num_frames; ++i) durations[i] = -1; for (i = 0; i < num_frames; ++i) durations[i] = -1;
@ -1103,7 +1103,7 @@ static int Process(const Config* config) {
new_mux = NULL; new_mux = NULL;
Err3: Err3:
free(durations); WebPFree(durations);
WebPMuxDelete(new_mux); WebPMuxDelete(new_mux);
if (!ok) goto Err2; if (!ok) goto Err2;
} }

View File

@ -216,9 +216,14 @@ void WebPSafeFree(void* const ptr) {
free(ptr); free(ptr);
} }
// Public API function. // Public API functions.
void* WebPMalloc(size_t size) {
return WebPSafeMalloc(1, size);
}
void WebPFree(void* ptr) { void WebPFree(void* ptr) {
free(ptr); WebPSafeFree(ptr);
} }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------

View File

@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #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++, // Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference. // 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, uint8_t** u, uint8_t** v,
int* stride, int* uv_stride); 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 // These five functions are variants of the above ones, that decode the image
// directly into a pre-allocated buffer 'output_buffer'. The maximum storage // directly into a pre-allocated buffer 'output_buffer'. The maximum storage
// available in this buffer is indicated by 'output_buffer_size'. If this // available in this buffer is indicated by 'output_buffer_size'. If this

View File

@ -20,7 +20,7 @@
extern "C" { extern "C" {
#endif #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++, // Note: forward declaring enumerations is not allowed in (strict) C and C++,
// the types are left here for reference. // 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, int width, int height, int stride,
uint8_t** output); uint8_t** output);
// Releases memory returned by the WebPEncode*() functions above.
WEBP_EXTERN void WebPFree(void* ptr);
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Coding parameters // Coding parameters

View File

@ -57,7 +57,7 @@ extern "C" {
WebPMuxGetChunk(mux, "ICCP", &icc_profile); WebPMuxGetChunk(mux, "ICCP", &icc_profile);
// ... (Consume icc_data). // ... (Consume icc_data).
WebPMuxDelete(mux); WebPMuxDelete(mux);
free(data); WebPFree(data);
*/ */
// Note: forward declaring enumerations is not allowed in (strict) C and C++, // 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); WebPMux* mux, const WebPMuxFrameInfo* frame, int copy_data);
// Gets the nth frame from the mux object. // 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 // owned by the 'mux' object. It MUST be deallocated by the caller by calling
// WebPDataClear(). // WebPDataClear().
// nth=0 has a special meaning - last position. // 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'. // Assembles all chunks in WebP RIFF format and returns in 'assembled_data'.
// This function also validates the mux object. // This function also validates the mux object.
// Note: The content of 'assembled_data' will be ignored and overwritten. // Note: The content of 'assembled_data' will be ignored and overwritten.
// Also, the content of 'assembled_data' is allocated using malloc(), and NOT // Also, the content of 'assembled_data' is allocated using WebPMalloc(), and
// owned by the 'mux' object. It MUST be deallocated by the caller by calling // NOT owned by the 'mux' object. It MUST be deallocated by the caller by
// WebPDataClear(). It's always safe to call WebPDataClear() upon return, // calling WebPDataClear(). It's always safe to call WebPDataClear() upon
// even in case of error. // return, even in case of error.
// Parameters: // Parameters:
// mux - (in/out) object whose chunks are to be assembled // mux - (in/out) object whose chunks are to be assembled
// assembled_data - (out) assembled WebP data // assembled_data - (out) assembled WebP data

View File

@ -14,7 +14,6 @@
#ifndef WEBP_WEBP_MUX_TYPES_H_ #ifndef WEBP_WEBP_MUX_TYPES_H_
#define WEBP_WEBP_MUX_TYPES_H_ #define WEBP_WEBP_MUX_TYPES_H_
#include <stdlib.h> // free()
#include <string.h> // memset() #include <string.h> // memset()
#include "./types.h" #include "./types.h"
@ -56,6 +55,7 @@ typedef enum WebPMuxAnimBlend {
// Data type used to describe 'raw' data, e.g., chunk data // Data type used to describe 'raw' data, e.g., chunk data
// (ICC profile, metadata) and WebP compressed image data. // (ICC profile, metadata) and WebP compressed image data.
// 'bytes' memory must be allocated using WebPMalloc() and such.
struct WebPData { struct WebPData {
const uint8_t* bytes; const uint8_t* bytes;
size_t size; 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 // Clears the contents of the 'webp_data' object by calling WebPFree().
// deallocate the object itself. // Does not deallocate the object itself.
static WEBP_INLINE void WebPDataClear(WebPData* webp_data) { static WEBP_INLINE void WebPDataClear(WebPData* webp_data) {
if (webp_data != NULL) { if (webp_data != NULL) {
free((void*)webp_data->bytes); WebPFree((void*)webp_data->bytes);
WebPDataInit(webp_data); WebPDataInit(webp_data);
} }
} }
@ -83,7 +83,7 @@ static WEBP_INLINE int WebPDataCopy(const WebPData* src, WebPData* dst) {
if (src == NULL || dst == NULL) return 0; if (src == NULL || dst == NULL) return 0;
WebPDataInit(dst); WebPDataInit(dst);
if (src->bytes != NULL && src->size != 0) { 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; if (dst->bytes == NULL) return 0;
memcpy((void*)dst->bytes, src->bytes, src->size); memcpy((void*)dst->bytes, src->bytes, src->size);
dst->size = src->size; dst->size = src->size;

View File

@ -7,7 +7,7 @@
// be found in the AUTHORS file in the root of the source tree. // 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) // 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) // Macro to check ABI compatibility (same major revision number)
#define WEBP_ABI_IS_INCOMPATIBLE(a, b) (((a) >> 8) != ((b) >> 8)) #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_ #endif // WEBP_WEBP_TYPES_H_