mirror of
https://github.com/webmproject/libwebp.git
synced 2025-07-13 06:24:27 +02:00
use WebPSafe[CM]alloc/WebPSafeFree instead of [cm]alloc/free
there's still some malloc/free in the external example This is an encoder API change because of the introduction of WebPMemoryWriterClear() for symmetry reasons. The MemoryWriter object should probably go in examples/ instead of being in the main lib, though. mux_types.h stil contain some inlined free()/malloc() that are harder to remove (we need to put them in the libwebputils lib and make sure link is ok). Left as a TODO for now. Also: WebPDecodeRGB*() function are still returning a pointer that needs to be free()'d. We should call WebPSafeFree() on these, but it means exposing the whole mechanism. TODO(later). Change-Id: Iad2c9060f7fa6040e3ba489c8b07f4caadfab77b
This commit is contained in:
@ -17,6 +17,7 @@
|
||||
#include "./vp8enci.h"
|
||||
#include "../utils/filters.h"
|
||||
#include "../utils/quant_levels.h"
|
||||
#include "../utils/utils.h"
|
||||
#include "../webp/format_constants.h"
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
@ -34,7 +35,7 @@
|
||||
//
|
||||
// 'output' corresponds to the buffer containing compressed alpha data.
|
||||
// This buffer is allocated by this method and caller should call
|
||||
// free(*output) when done.
|
||||
// WebPSafeFree(*output) when done.
|
||||
// 'output_size' corresponds to size of this compressed alpha buffer.
|
||||
//
|
||||
// Returns 1 on successfully encoding the alpha and
|
||||
@ -231,7 +232,7 @@ static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height,
|
||||
GetFilterMap(alpha, width, height, filter, effort_level);
|
||||
InitFilterTrial(&best);
|
||||
if (try_map != FILTER_TRY_NONE) {
|
||||
uint8_t* filtered_alpha = (uint8_t*)malloc(data_size);
|
||||
uint8_t* filtered_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
|
||||
if (filtered_alpha == NULL) return 0;
|
||||
|
||||
for (filter = WEBP_FILTER_NONE; ok && try_map; ++filter, try_map >>= 1) {
|
||||
@ -248,7 +249,7 @@ static int ApplyFiltersAndEncode(const uint8_t* alpha, int width, int height,
|
||||
}
|
||||
}
|
||||
}
|
||||
free(filtered_alpha);
|
||||
WebPSafeFree(filtered_alpha);
|
||||
} else {
|
||||
ok = EncodeAlphaInternal(alpha, width, height, method, WEBP_FILTER_NONE,
|
||||
reduce_levels, effort_level, NULL, &best);
|
||||
@ -298,7 +299,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
||||
filter = WEBP_FILTER_NONE;
|
||||
}
|
||||
|
||||
quant_alpha = (uint8_t*)malloc(data_size);
|
||||
quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
|
||||
if (quant_alpha == NULL) {
|
||||
return 0;
|
||||
}
|
||||
@ -325,7 +326,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
||||
}
|
||||
}
|
||||
|
||||
free(quant_alpha);
|
||||
WebPSafeFree(quant_alpha);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -346,7 +347,7 @@ static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) {
|
||||
return 0;
|
||||
}
|
||||
if (alpha_size != (uint32_t)alpha_size) { // Sanity check.
|
||||
free(alpha_data);
|
||||
WebPSafeFree(alpha_data);
|
||||
return 0;
|
||||
}
|
||||
enc->alpha_data_size_ = (uint32_t)alpha_size;
|
||||
@ -401,7 +402,7 @@ int VP8EncDeleteAlpha(VP8Encoder* const enc) {
|
||||
ok = WebPWorkerSync(worker); // finish anything left in flight
|
||||
WebPWorkerEnd(worker); // still need to end the worker, even if !ok
|
||||
}
|
||||
free(enc->alpha_data_);
|
||||
WebPSafeFree(enc->alpha_data_);
|
||||
enc->alpha_data_ = NULL;
|
||||
enc->alpha_data_size_ = 0;
|
||||
enc->has_alpha_ = 0;
|
||||
|
@ -63,7 +63,7 @@ static void SmoothSegmentMap(VP8Encoder* const enc) {
|
||||
mb->segment_ = tmp[x + y * w];
|
||||
}
|
||||
}
|
||||
free(tmp);
|
||||
WebPSafeFree(tmp);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
@ -89,7 +89,7 @@ void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs) {
|
||||
|
||||
void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs) {
|
||||
if (refs != NULL) {
|
||||
free(refs->refs);
|
||||
WebPSafeFree(refs->refs);
|
||||
VP8LInitBackwardRefs(refs);
|
||||
}
|
||||
}
|
||||
@ -116,13 +116,13 @@ static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) {
|
||||
|
||||
static HashChain* HashChainNew(int size) {
|
||||
int i;
|
||||
HashChain* const p = (HashChain*)malloc(sizeof(*p));
|
||||
HashChain* const p = (HashChain*)WebPSafeMalloc(1ULL, sizeof(*p));
|
||||
if (p == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_));
|
||||
if (p->chain_ == NULL) {
|
||||
free(p);
|
||||
WebPSafeFree(p);
|
||||
return NULL;
|
||||
}
|
||||
for (i = 0; i < size; ++i) {
|
||||
@ -136,8 +136,8 @@ static HashChain* HashChainNew(int size) {
|
||||
|
||||
static void HashChainDelete(HashChain* const p) {
|
||||
if (p != NULL) {
|
||||
free(p->chain_);
|
||||
free(p);
|
||||
WebPSafeFree(p->chain_);
|
||||
WebPSafeFree(p);
|
||||
}
|
||||
}
|
||||
|
||||
@ -490,7 +490,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||
const int use_color_cache = (cache_bits > 0);
|
||||
float* const cost =
|
||||
(float*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost));
|
||||
CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model));
|
||||
CostModel* cost_model = (CostModel*)WebPSafeMalloc(1ULL, sizeof(*cost_model));
|
||||
HashChain* hash_chain = HashChainNew(pix_count);
|
||||
VP8LColorCache hashers;
|
||||
const double mul0 = (recursive_cost_model != 0) ? 1.0 : 0.68;
|
||||
@ -597,8 +597,8 @@ static int BackwardReferencesHashChainDistanceOnly(
|
||||
Error:
|
||||
if (cc_init) VP8LColorCacheClear(&hashers);
|
||||
HashChainDelete(hash_chain);
|
||||
free(cost_model);
|
||||
free(cost);
|
||||
WebPSafeFree(cost_model);
|
||||
WebPSafeFree(cost);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -724,7 +724,7 @@ static int BackwardReferencesTraceBackwards(int xsize, int ysize,
|
||||
}
|
||||
ok = 1;
|
||||
Error:
|
||||
free(dist_array);
|
||||
WebPSafeFree(dist_array);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -768,7 +768,8 @@ int VP8LGetBackwardReferences(int width, int height,
|
||||
|
||||
{
|
||||
double bit_cost_lz77, bit_cost_rle;
|
||||
VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
|
||||
VP8LHistogram* const histo =
|
||||
(VP8LHistogram*)WebPSafeMalloc(1ULL, sizeof(*histo));
|
||||
if (histo == NULL) goto Error1;
|
||||
// Evaluate lz77 coding
|
||||
VP8LHistogramCreate(histo, &refs_lz77, cache_bits);
|
||||
@ -778,7 +779,7 @@ int VP8LGetBackwardReferences(int width, int height,
|
||||
bit_cost_rle = VP8LHistogramEstimateBits(histo);
|
||||
// Decide if LZ77 is useful.
|
||||
lz77_is_useful = (bit_cost_lz77 < bit_cost_rle);
|
||||
free(histo);
|
||||
WebPSafeFree(histo);
|
||||
}
|
||||
|
||||
// Choose appropriate backward reference.
|
||||
|
@ -162,7 +162,7 @@ static int Record(int bit, proba_t* const stats) {
|
||||
return bit;
|
||||
}
|
||||
|
||||
// We keep the table free variant around for reference, in case.
|
||||
// We keep the table-free variant around for reference, in case.
|
||||
#define USE_LEVEL_CODE_TABLE
|
||||
|
||||
// Simulate block coding, but only record statistics.
|
||||
|
@ -723,7 +723,8 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
// bin_map[n][num_histo + 1] ... bin_map[n][bin_depth - 1] = un-used indices.
|
||||
const int bin_depth = histo_image_raw_size + 1;
|
||||
int16_t* bin_map = NULL;
|
||||
VP8LHistogram* const histos = (VP8LHistogram*)malloc(2 * sizeof(*histos));
|
||||
VP8LHistogram* const histos =
|
||||
(VP8LHistogram*)WebPSafeMalloc(2ULL, sizeof(*histos));
|
||||
VP8LHistogramSet* const init_histo =
|
||||
VP8LAllocateHistogramSet(histo_image_raw_size, cache_bits);
|
||||
|
||||
@ -760,8 +761,8 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
ok = 1;
|
||||
|
||||
Error:
|
||||
free(bin_map);
|
||||
free(init_histo);
|
||||
free(histos);
|
||||
WebPSafeFree(bin_map);
|
||||
WebPSafeFree(init_histo);
|
||||
WebPSafeFree(histos);
|
||||
return ok;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ typedef struct {
|
||||
} VP8LHistogram;
|
||||
|
||||
// Collection of histograms with fixed capacity, allocated as one
|
||||
// big memory chunk. Can be destroyed by simply calling 'free()'.
|
||||
// big memory chunk. Can be destroyed by calling WebPSafeFree().
|
||||
typedef struct {
|
||||
int size; // number of slots currently in use
|
||||
int max_size; // maximum capacity
|
||||
|
@ -14,6 +14,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "./vp8enci.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
@ -39,6 +40,5 @@ int VP8EncFinishLayer(VP8Encoder* const enc) {
|
||||
}
|
||||
|
||||
void VP8EncDeleteLayer(VP8Encoder* enc) {
|
||||
free(enc->layer_data_);
|
||||
WebPSafeFree(enc->layer_data_);
|
||||
}
|
||||
|
||||
|
@ -175,7 +175,7 @@ static void WebPPictureGrabSpecs(const WebPPicture* const src,
|
||||
// the other YUV(A) buffer.
|
||||
static int PictureAllocARGB(WebPPicture* const picture) {
|
||||
WebPPicture tmp;
|
||||
free(picture->memory_argb_);
|
||||
WebPSafeFree(picture->memory_argb_);
|
||||
PictureResetARGB(picture);
|
||||
picture->use_argb = 1;
|
||||
WebPPictureGrabSpecs(picture, &tmp);
|
||||
@ -191,8 +191,8 @@ static int PictureAllocARGB(WebPPicture* const picture) {
|
||||
// Release memory owned by 'picture' (both YUV and ARGB buffers).
|
||||
void WebPPictureFree(WebPPicture* picture) {
|
||||
if (picture != NULL) {
|
||||
free(picture->memory_);
|
||||
free(picture->memory_argb_);
|
||||
WebPSafeFree(picture->memory_);
|
||||
WebPSafeFree(picture->memory_argb_);
|
||||
PictureResetYUVA(picture);
|
||||
PictureResetARGB(picture);
|
||||
}
|
||||
@ -504,7 +504,7 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
|
||||
AlphaMultiplyARGB(&tmp, 1);
|
||||
}
|
||||
WebPPictureFree(pic);
|
||||
free(work);
|
||||
WebPSafeFree(work);
|
||||
*pic = tmp;
|
||||
return 1;
|
||||
}
|
||||
@ -538,7 +538,7 @@ int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
if (w->size > 0) {
|
||||
memcpy(new_mem, w->mem, w->size);
|
||||
}
|
||||
free(w->mem);
|
||||
WebPSafeFree(w->mem);
|
||||
w->mem = new_mem;
|
||||
// down-cast is ok, thanks to WebPSafeMalloc
|
||||
w->max_size = (size_t)next_max_size;
|
||||
@ -550,6 +550,15 @@ int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||
return 1;
|
||||
}
|
||||
|
||||
void WebPMemoryWriterClear(WebPMemoryWriter* writer) {
|
||||
if (writer != NULL) {
|
||||
WebPSafeFree(writer->mem);
|
||||
writer->mem = NULL;
|
||||
writer->size = 0;
|
||||
writer->max_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Detection of non-trivial transparency
|
||||
|
||||
@ -1323,7 +1332,7 @@ static size_t Encode(const uint8_t* rgba, int width, int height, int stride,
|
||||
ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic);
|
||||
WebPPictureFree(&pic);
|
||||
if (!ok) {
|
||||
free(wrt.mem);
|
||||
WebPMemoryWriterClear(&wrt);
|
||||
*output = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "./cost.h"
|
||||
#include "./vp8enci.h"
|
||||
#include "../utils/utils.h"
|
||||
|
||||
#if !defined(DISABLE_TOKEN_BUFFER)
|
||||
|
||||
@ -51,7 +52,7 @@ void VP8TBufferClear(VP8TBuffer* const b) {
|
||||
const VP8Tokens* p = b->pages_;
|
||||
while (p != NULL) {
|
||||
const VP8Tokens* const next = p->next_;
|
||||
free((void*)p);
|
||||
WebPSafeFree((void*)p);
|
||||
p = next;
|
||||
}
|
||||
VP8TBufferInit(b);
|
||||
@ -59,7 +60,8 @@ void VP8TBufferClear(VP8TBuffer* const b) {
|
||||
}
|
||||
|
||||
static int TBufferNewPage(VP8TBuffer* const b) {
|
||||
VP8Tokens* const page = b->error_ ? NULL : (VP8Tokens*)malloc(sizeof(*page));
|
||||
VP8Tokens* const page =
|
||||
b->error_ ? NULL : (VP8Tokens*)WebPSafeMalloc(1ULL, sizeof(*page));
|
||||
if (page == NULL) {
|
||||
b->error_ = 1;
|
||||
return 0;
|
||||
@ -228,7 +230,7 @@ int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
|
||||
VP8PutBit(bw, bit, probas[token & 0x3fffu]);
|
||||
}
|
||||
}
|
||||
if (final_pass) free((void*)p);
|
||||
if (final_pass) WebPSafeFree((void*)p);
|
||||
p = next;
|
||||
}
|
||||
if (final_pass) b->pages_ = NULL;
|
||||
|
@ -108,7 +108,7 @@ static int AnalyzeEntropy(const uint32_t* argb,
|
||||
|
||||
VP8LHistogram* nonpredicted = NULL;
|
||||
VP8LHistogram* predicted =
|
||||
(VP8LHistogram*)malloc(2 * sizeof(*predicted));
|
||||
(VP8LHistogram*)WebPSafeMalloc(2ULL, sizeof(*predicted));
|
||||
if (predicted == NULL) return 0;
|
||||
nonpredicted = predicted + 1;
|
||||
|
||||
@ -135,7 +135,7 @@ static int AnalyzeEntropy(const uint32_t* argb,
|
||||
}
|
||||
*nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
|
||||
*predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
|
||||
free(predicted);
|
||||
WebPSafeFree(predicted);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -228,7 +228,7 @@ static int GetHuffBitLengthsAndCodes(
|
||||
|
||||
End:
|
||||
if (!ok) {
|
||||
free(mem_buf);
|
||||
WebPSafeFree(mem_buf);
|
||||
// If one VP8LCreateHuffmanTree() above fails, we need to clean up behind.
|
||||
memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
|
||||
}
|
||||
@ -362,7 +362,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
||||
}
|
||||
ok = 1;
|
||||
End:
|
||||
free(tokens);
|
||||
WebPSafeFree(tokens);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -503,9 +503,9 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
||||
ok = 1;
|
||||
|
||||
Error:
|
||||
free(histogram_image);
|
||||
WebPSafeFree(histogram_image);
|
||||
VP8LClearBackwardRefs(&refs);
|
||||
free(huffman_codes[0].codes);
|
||||
WebPSafeFree(huffman_codes[0].codes);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -532,8 +532,8 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
||||
|
||||
if (histogram_image == NULL || histogram_symbols == NULL) {
|
||||
free(histogram_image);
|
||||
free(histogram_symbols);
|
||||
WebPSafeFree(histogram_image);
|
||||
WebPSafeFree(histogram_symbols);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -559,7 +559,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
goto Error;
|
||||
}
|
||||
// Free combined histograms.
|
||||
free(histogram_image);
|
||||
WebPSafeFree(histogram_image);
|
||||
histogram_image = NULL;
|
||||
|
||||
// Color Cache parameters.
|
||||
@ -593,7 +593,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
VP8LSubSampleSize(width, histogram_bits),
|
||||
VP8LSubSampleSize(height, histogram_bits),
|
||||
quality);
|
||||
free(histogram_argb);
|
||||
WebPSafeFree(histogram_argb);
|
||||
if (!ok) goto Error;
|
||||
}
|
||||
}
|
||||
@ -614,14 +614,14 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
ok = 1;
|
||||
|
||||
Error:
|
||||
free(histogram_image);
|
||||
WebPSafeFree(histogram_image);
|
||||
|
||||
VP8LClearBackwardRefs(&refs);
|
||||
if (huffman_codes != NULL) {
|
||||
free(huffman_codes->codes);
|
||||
free(huffman_codes);
|
||||
WebPSafeFree(huffman_codes->codes);
|
||||
WebPSafeFree(huffman_codes);
|
||||
}
|
||||
free(histogram_symbols);
|
||||
WebPSafeFree(histogram_symbols);
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -637,7 +637,8 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
||||
int i;
|
||||
const uint32_t* const argb = enc->argb_;
|
||||
double bit_cost_before, bit_cost_after;
|
||||
VP8LHistogram* const histo = (VP8LHistogram*)malloc(sizeof(*histo));
|
||||
VP8LHistogram* const histo =
|
||||
(VP8LHistogram*)WebPSafeMalloc(1ULL, sizeof(*histo));
|
||||
if (histo == NULL) return 0;
|
||||
|
||||
VP8LHistogramInit(histo, 1);
|
||||
@ -656,7 +657,7 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
||||
++histo->blue_[((c >> 0) - green) & 0xff];
|
||||
}
|
||||
bit_cost_after = VP8LHistogramEstimateBits(histo);
|
||||
free(histo);
|
||||
WebPSafeFree(histo);
|
||||
|
||||
// Check if subtracting green yields low entropy.
|
||||
enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
|
||||
@ -907,7 +908,7 @@ static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
|
||||
}
|
||||
|
||||
Error:
|
||||
free(row);
|
||||
WebPSafeFree(row);
|
||||
return err;
|
||||
}
|
||||
|
||||
@ -944,7 +945,7 @@ static void FinishEncParams(VP8LEncoder* const enc) {
|
||||
|
||||
static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
|
||||
const WebPPicture* const picture) {
|
||||
VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc));
|
||||
VP8LEncoder* const enc = (VP8LEncoder*)WebPSafeCalloc(1ULL, sizeof(*enc));
|
||||
if (enc == NULL) {
|
||||
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||
return NULL;
|
||||
@ -959,9 +960,9 @@ static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
|
||||
|
||||
static void VP8LEncoderDelete(VP8LEncoder* enc) {
|
||||
if (enc != NULL) {
|
||||
free(enc->argb_);
|
||||
WebPSafeFree(enc->argb_);
|
||||
WebPSafeFree(enc);
|
||||
}
|
||||
free(enc);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -269,7 +269,7 @@ static int DeleteVP8Encoder(VP8Encoder* enc) {
|
||||
VP8EncDeleteLayer(enc);
|
||||
#endif
|
||||
VP8TBufferClear(&enc->tokens_);
|
||||
free(enc);
|
||||
WebPSafeFree(enc);
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
Reference in New Issue
Block a user