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:
skal
2014-03-27 23:27:32 +01:00
committed by Gerrit Code Review
parent 51f406a5d7
commit af93bdd6bc
32 changed files with 168 additions and 134 deletions

View File

@ -16,13 +16,14 @@
#include "./vp8i.h"
#include "./vp8li.h"
#include "../utils/quant_levels_dec.h"
#include "../utils/utils.h"
#include "../webp/format_constants.h"
//------------------------------------------------------------------------------
// ALPHDecoder object.
ALPHDecoder* ALPHNew(void) {
ALPHDecoder* const dec = (ALPHDecoder*)calloc(1, sizeof(*dec));
ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
return dec;
}
@ -30,7 +31,7 @@ void ALPHDelete(ALPHDecoder* const dec) {
if (dec != NULL) {
VP8LDelete(dec->vp8l_dec_);
dec->vp8l_dec_ = NULL;
free(dec);
WebPSafeFree(dec);
}
}
@ -158,4 +159,3 @@ const uint8_t* VP8DecompressAlphaRows(VP8Decoder* const dec,
// Return a pointer to the current decoded row.
return dec->alpha_plane_ + row * width;
}

View File

@ -216,8 +216,9 @@ int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
if (buffer != NULL) {
if (!buffer->is_external_memory)
free(buffer->private_memory);
if (!buffer->is_external_memory) {
WebPSafeFree(buffer->private_memory);
}
buffer->private_memory = NULL;
}
}

View File

@ -549,7 +549,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
if (needed != (size_t)needed) return 0; // check for overflow
if (needed > dec->mem_size_) {
free(dec->mem_);
WebPSafeFree(dec->mem_);
dec->mem_size_ = 0;
dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
if (dec->mem_ == NULL) {

View File

@ -188,7 +188,7 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
if (new_buf == NULL) return 0;
memcpy(new_buf, old_base, current_size);
free(mem->buf_);
WebPSafeFree(mem->buf_);
mem->buf_ = new_buf;
mem->buf_size_ = (size_t)extra_size;
mem->start_ = new_mem_start;
@ -230,8 +230,8 @@ static void InitMemBuffer(MemBuffer* const mem) {
static void ClearMemBuffer(MemBuffer* const mem) {
assert(mem);
if (mem->mode_ == MEM_MODE_APPEND) {
free(mem->buf_);
free((void*)mem->part0_buf_);
WebPSafeFree(mem->buf_);
WebPSafeFree((void*)mem->part0_buf_);
}
}
@ -373,7 +373,7 @@ static int CopyParts0Data(WebPIDecoder* const idec) {
assert(psize <= mem->part0_size_); // Format limit: no need for runtime check
if (mem->mode_ == MEM_MODE_APPEND) {
// We copy and grab ownership of the partition #0 data.
uint8_t* const part0_buf = (uint8_t*)malloc(psize);
uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, psize);
if (part0_buf == NULL) {
return 0;
}
@ -573,7 +573,7 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
// Public functions
WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(*idec));
WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
if (idec == NULL) {
return NULL;
}
@ -632,7 +632,7 @@ void WebPIDelete(WebPIDecoder* idec) {
}
ClearMemBuffer(&idec->mem_);
WebPFreeDecBuffer(&idec->output_);
free(idec);
WebPSafeFree(idec);
}
//------------------------------------------------------------------------------

View File

@ -17,6 +17,7 @@
#include "./webpi.h"
#include "../dsp/dsp.h"
#include "../dsp/yuv.h"
#include "../utils/utils.h"
//------------------------------------------------------------------------------
// Main YUV<->RGB conversion functions
@ -324,7 +325,7 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
if (has_alpha) {
tmp_size += work_size;
}
p->memory = calloc(1, tmp_size * sizeof(*work));
p->memory = WebPSafeCalloc(1ULL, tmp_size * sizeof(*work));
if (p->memory == NULL) {
return 0; // memory error
}
@ -492,7 +493,7 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
const size_t work_size = 2 * out_width; // scratch memory for one rescaler
int32_t* work; // rescalers work area
uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
size_t tmp_size1, tmp_size2;
size_t tmp_size1, tmp_size2, total_size;
tmp_size1 = 3 * work_size;
tmp_size2 = 3 * out_width;
@ -500,7 +501,8 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
tmp_size1 += work_size;
tmp_size2 += out_width;
}
p->memory = calloc(1, tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp));
total_size = tmp_size1 * sizeof(*work) + tmp_size2 * sizeof(*tmp);
p->memory = WebPSafeCalloc(1ULL, total_size);
if (p->memory == NULL) {
return 0; // memory error
}
@ -564,7 +566,7 @@ static int CustomSetup(VP8Io* io) {
if (io->fancy_upsampling) {
#ifdef FANCY_UPSAMPLING
const int uv_width = (io->mb_w + 1) >> 1;
p->memory = malloc(io->mb_w + 2 * uv_width);
p->memory = WebPSafeMalloc(1ULL, (size_t)(io->mb_w + 2 * uv_width));
if (p->memory == NULL) {
return 0; // memory error.
}
@ -620,7 +622,7 @@ static int CustomPut(const VP8Io* io) {
static void CustomTeardown(const VP8Io* io) {
WebPDecParams* const p = (WebPDecParams*)io->opaque;
free(p->memory);
WebPSafeFree(p->memory);
p->memory = NULL;
}

View File

@ -18,6 +18,7 @@
#include "./vp8li.h"
#include "./webpi.h"
#include "../utils/bit_reader.h"
#include "../utils/utils.h"
//------------------------------------------------------------------------------
@ -44,7 +45,7 @@ int VP8InitIoInternal(VP8Io* const io, int version) {
}
VP8Decoder* VP8New(void) {
VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec));
VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
if (dec != NULL) {
SetOk(dec);
WebPWorkerInit(&dec->worker_);
@ -68,7 +69,7 @@ const char* VP8StatusMessage(VP8Decoder* const dec) {
void VP8Delete(VP8Decoder* const dec) {
if (dec != NULL) {
VP8Clear(dec);
free(dec);
WebPSafeFree(dec);
}
}
@ -689,7 +690,7 @@ void VP8Clear(VP8Decoder* const dec) {
}
ALPHDelete(dec->alph_dec_);
dec->alph_dec_ = NULL;
free(dec->mem_);
WebPSafeFree(dec->mem_);
dec->mem_ = NULL;
dec->mem_size_ = 0;
memset(&dec->br_, 0, sizeof(dec->br_));

View File

@ -285,7 +285,7 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
if (ok) {
ok = HuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size);
}
free(code_lengths);
WebPSafeFree(code_lengths);
}
ok = ok && !br->error_;
if (!ok) {
@ -304,7 +304,7 @@ static void DeleteHtreeGroups(HTreeGroup* htree_groups, int num_htree_groups) {
HuffmanTreeRelease(&htrees[j]);
}
}
free(htree_groups);
WebPSafeFree(htree_groups);
}
}
@ -368,7 +368,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
return 1;
Error:
free(huffman_image);
WebPSafeFree(huffman_image);
DeleteHtreeGroups(htree_groups, num_htree_groups);
return 0;
}
@ -933,7 +933,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
// VP8LTransform
static void ClearTransform(VP8LTransform* const transform) {
free(transform->data_);
WebPSafeFree(transform->data_);
transform->data_ = NULL;
}
@ -957,7 +957,7 @@ static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
}
for (; i < 4 * final_num_colors; ++i)
new_data[i] = 0; // black tail.
free(transform->data_);
WebPSafeFree(transform->data_);
transform->data_ = new_color_map;
}
return 1;
@ -1027,7 +1027,7 @@ static void InitMetadata(VP8LMetadata* const hdr) {
static void ClearMetadata(VP8LMetadata* const hdr) {
assert(hdr);
free(hdr->huffman_image_);
WebPSafeFree(hdr->huffman_image_);
DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_);
VP8LColorCacheClear(&hdr->color_cache_);
InitMetadata(hdr);
@ -1037,7 +1037,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
// VP8LDecoder
VP8LDecoder* VP8LNew(void) {
VP8LDecoder* const dec = (VP8LDecoder*)calloc(1, sizeof(*dec));
VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
if (dec == NULL) return NULL;
dec->status_ = VP8_STATUS_OK;
dec->action_ = READ_DIM;
@ -1053,7 +1053,7 @@ void VP8LClear(VP8LDecoder* const dec) {
if (dec == NULL) return;
ClearMetadata(&dec->hdr_);
free(dec->pixels_);
WebPSafeFree(dec->pixels_);
dec->pixels_ = NULL;
for (i = 0; i < dec->next_transform_; ++i) {
ClearTransform(&dec->transforms_[i]);
@ -1061,7 +1061,7 @@ void VP8LClear(VP8LDecoder* const dec) {
dec->next_transform_ = 0;
dec->transforms_seen_ = 0;
free(dec->rescaler_memory);
WebPSafeFree(dec->rescaler_memory);
dec->rescaler_memory = NULL;
dec->output_ = NULL; // leave no trace behind
@ -1070,7 +1070,7 @@ void VP8LClear(VP8LDecoder* const dec) {
void VP8LDelete(VP8LDecoder* const dec) {
if (dec != NULL) {
VP8LClear(dec);
free(dec);
WebPSafeFree(dec);
}
}
@ -1157,7 +1157,7 @@ static int DecodeImageStream(int xsize, int ysize,
End:
if (!ok) {
free(data);
WebPSafeFree(data);
ClearMetadata(hdr);
// If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the
// status appropriately.