mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-20 04:18:26 +01: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:
parent
51f406a5d7
commit
af93bdd6bc
7
README
7
README
@ -443,15 +443,20 @@ The encoding flow looks like:
|
|||||||
|
|
||||||
// Set up a byte-output write method. WebPMemoryWriter, for instance.
|
// Set up a byte-output write method. WebPMemoryWriter, for instance.
|
||||||
WebPMemoryWriter wrt;
|
WebPMemoryWriter wrt;
|
||||||
|
WebPMemoryWriterInit(&wrt); // initialize 'wrt'
|
||||||
|
|
||||||
pic.writer = MyFileWriter;
|
pic.writer = MyFileWriter;
|
||||||
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
|
pic.custom_ptr = my_opaque_structure_to_make_MyFileWriter_work;
|
||||||
// initialize 'wrt' here...
|
|
||||||
|
|
||||||
// Compress!
|
// Compress!
|
||||||
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
|
int ok = WebPEncode(&config, &pic); // ok = 0 => error occurred!
|
||||||
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
|
WebPPictureFree(&pic); // must be called independently of the 'ok' result.
|
||||||
|
|
||||||
// output data should have been handled by the writer at that point.
|
// output data should have been handled by the writer at that point.
|
||||||
|
// -> compressed data is the memory buffer described by wrt.mem / wrt.size
|
||||||
|
|
||||||
|
// deallocate the memory used by compressed data
|
||||||
|
WebPMemoryWriterClear(&wrt);
|
||||||
|
|
||||||
-------------------------------------- END PSEUDO EXAMPLE
|
-------------------------------------- END PSEUDO EXAMPLE
|
||||||
|
|
||||||
|
@ -1121,7 +1121,7 @@ int main(int argc, const char *argv[]) {
|
|||||||
return_value = 0;
|
return_value = 0;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(memory_writer.mem);
|
WebPMemoryWriterClear(&memory_writer);
|
||||||
free(picture.extra_info);
|
free(picture.extra_info);
|
||||||
MetadataFree(&metadata);
|
MetadataFree(&metadata);
|
||||||
WebPPictureFree(&picture);
|
WebPPictureFree(&picture);
|
||||||
|
@ -469,10 +469,10 @@ static int SetFrame(const WebPConfig* const config, int allow_mixed,
|
|||||||
// TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should
|
// TODO(later): Perhaps a rough SSIM/PSNR produced by the encoder should
|
||||||
// also be a criteria, in addition to sizes.
|
// also be a criteria, in addition to sizes.
|
||||||
if (mem1.size <= mem2.size) {
|
if (mem1.size <= mem2.size) {
|
||||||
free(mem2.mem);
|
WebPMemoryWriterClear(&mem2);
|
||||||
GetEncodedData(&mem1, encoded_data);
|
GetEncodedData(&mem1, encoded_data);
|
||||||
} else {
|
} else {
|
||||||
free(mem1.mem);
|
WebPMemoryWriterClear(&mem1);
|
||||||
GetEncodedData(&mem2, encoded_data);
|
GetEncodedData(&mem2, encoded_data);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -481,8 +481,8 @@ static int SetFrame(const WebPConfig* const config, int allow_mixed,
|
|||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
Err:
|
Err:
|
||||||
free(mem1.mem);
|
WebPMemoryWriterClear(&mem1);
|
||||||
free(mem2.mem);
|
WebPMemoryWriterClear(&mem2);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,13 +16,14 @@
|
|||||||
#include "./vp8i.h"
|
#include "./vp8i.h"
|
||||||
#include "./vp8li.h"
|
#include "./vp8li.h"
|
||||||
#include "../utils/quant_levels_dec.h"
|
#include "../utils/quant_levels_dec.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
#include "../webp/format_constants.h"
|
#include "../webp/format_constants.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// ALPHDecoder object.
|
// ALPHDecoder object.
|
||||||
|
|
||||||
ALPHDecoder* ALPHNew(void) {
|
ALPHDecoder* ALPHNew(void) {
|
||||||
ALPHDecoder* const dec = (ALPHDecoder*)calloc(1, sizeof(*dec));
|
ALPHDecoder* const dec = (ALPHDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||||
return dec;
|
return dec;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,7 +31,7 @@ void ALPHDelete(ALPHDecoder* const dec) {
|
|||||||
if (dec != NULL) {
|
if (dec != NULL) {
|
||||||
VP8LDelete(dec->vp8l_dec_);
|
VP8LDelete(dec->vp8l_dec_);
|
||||||
dec->vp8l_dec_ = NULL;
|
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 a pointer to the current decoded row.
|
||||||
return dec->alpha_plane_ + row * width;
|
return dec->alpha_plane_ + row * width;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,8 +216,9 @@ int WebPInitDecBufferInternal(WebPDecBuffer* buffer, int version) {
|
|||||||
|
|
||||||
void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
|
void WebPFreeDecBuffer(WebPDecBuffer* buffer) {
|
||||||
if (buffer != NULL) {
|
if (buffer != NULL) {
|
||||||
if (!buffer->is_external_memory)
|
if (!buffer->is_external_memory) {
|
||||||
free(buffer->private_memory);
|
WebPSafeFree(buffer->private_memory);
|
||||||
|
}
|
||||||
buffer->private_memory = NULL;
|
buffer->private_memory = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -549,7 +549,7 @@ static int AllocateMemory(VP8Decoder* const dec) {
|
|||||||
|
|
||||||
if (needed != (size_t)needed) return 0; // check for overflow
|
if (needed != (size_t)needed) return 0; // check for overflow
|
||||||
if (needed > dec->mem_size_) {
|
if (needed > dec->mem_size_) {
|
||||||
free(dec->mem_);
|
WebPSafeFree(dec->mem_);
|
||||||
dec->mem_size_ = 0;
|
dec->mem_size_ = 0;
|
||||||
dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
|
dec->mem_ = WebPSafeMalloc(needed, sizeof(uint8_t));
|
||||||
if (dec->mem_ == NULL) {
|
if (dec->mem_ == NULL) {
|
||||||
|
@ -188,7 +188,7 @@ static int AppendToMemBuffer(WebPIDecoder* const idec,
|
|||||||
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
(uint8_t*)WebPSafeMalloc(extra_size, sizeof(*new_buf));
|
||||||
if (new_buf == NULL) return 0;
|
if (new_buf == NULL) return 0;
|
||||||
memcpy(new_buf, old_base, current_size);
|
memcpy(new_buf, old_base, current_size);
|
||||||
free(mem->buf_);
|
WebPSafeFree(mem->buf_);
|
||||||
mem->buf_ = new_buf;
|
mem->buf_ = new_buf;
|
||||||
mem->buf_size_ = (size_t)extra_size;
|
mem->buf_size_ = (size_t)extra_size;
|
||||||
mem->start_ = new_mem_start;
|
mem->start_ = new_mem_start;
|
||||||
@ -230,8 +230,8 @@ static void InitMemBuffer(MemBuffer* const mem) {
|
|||||||
static void ClearMemBuffer(MemBuffer* const mem) {
|
static void ClearMemBuffer(MemBuffer* const mem) {
|
||||||
assert(mem);
|
assert(mem);
|
||||||
if (mem->mode_ == MEM_MODE_APPEND) {
|
if (mem->mode_ == MEM_MODE_APPEND) {
|
||||||
free(mem->buf_);
|
WebPSafeFree(mem->buf_);
|
||||||
free((void*)mem->part0_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
|
assert(psize <= mem->part0_size_); // Format limit: no need for runtime check
|
||||||
if (mem->mode_ == MEM_MODE_APPEND) {
|
if (mem->mode_ == MEM_MODE_APPEND) {
|
||||||
// We copy and grab ownership of the partition #0 data.
|
// 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) {
|
if (part0_buf == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -573,7 +573,7 @@ static VP8StatusCode IDecode(WebPIDecoder* idec) {
|
|||||||
// Public functions
|
// Public functions
|
||||||
|
|
||||||
WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
|
WebPIDecoder* WebPINewDecoder(WebPDecBuffer* output_buffer) {
|
||||||
WebPIDecoder* idec = (WebPIDecoder*)calloc(1, sizeof(*idec));
|
WebPIDecoder* idec = (WebPIDecoder*)WebPSafeCalloc(1ULL, sizeof(*idec));
|
||||||
if (idec == NULL) {
|
if (idec == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -632,7 +632,7 @@ void WebPIDelete(WebPIDecoder* idec) {
|
|||||||
}
|
}
|
||||||
ClearMemBuffer(&idec->mem_);
|
ClearMemBuffer(&idec->mem_);
|
||||||
WebPFreeDecBuffer(&idec->output_);
|
WebPFreeDecBuffer(&idec->output_);
|
||||||
free(idec);
|
WebPSafeFree(idec);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
12
src/dec/io.c
12
src/dec/io.c
@ -17,6 +17,7 @@
|
|||||||
#include "./webpi.h"
|
#include "./webpi.h"
|
||||||
#include "../dsp/dsp.h"
|
#include "../dsp/dsp.h"
|
||||||
#include "../dsp/yuv.h"
|
#include "../dsp/yuv.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Main YUV<->RGB conversion functions
|
// Main YUV<->RGB conversion functions
|
||||||
@ -324,7 +325,7 @@ static int InitYUVRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
if (has_alpha) {
|
if (has_alpha) {
|
||||||
tmp_size += work_size;
|
tmp_size += work_size;
|
||||||
}
|
}
|
||||||
p->memory = calloc(1, tmp_size * sizeof(*work));
|
p->memory = WebPSafeCalloc(1ULL, tmp_size * sizeof(*work));
|
||||||
if (p->memory == NULL) {
|
if (p->memory == NULL) {
|
||||||
return 0; // memory error
|
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
|
const size_t work_size = 2 * out_width; // scratch memory for one rescaler
|
||||||
int32_t* work; // rescalers work area
|
int32_t* work; // rescalers work area
|
||||||
uint8_t* tmp; // tmp storage for scaled YUV444 samples before RGB conversion
|
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_size1 = 3 * work_size;
|
||||||
tmp_size2 = 3 * out_width;
|
tmp_size2 = 3 * out_width;
|
||||||
@ -500,7 +501,8 @@ static int InitRGBRescaler(const VP8Io* const io, WebPDecParams* const p) {
|
|||||||
tmp_size1 += work_size;
|
tmp_size1 += work_size;
|
||||||
tmp_size2 += out_width;
|
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) {
|
if (p->memory == NULL) {
|
||||||
return 0; // memory error
|
return 0; // memory error
|
||||||
}
|
}
|
||||||
@ -564,7 +566,7 @@ static int CustomSetup(VP8Io* io) {
|
|||||||
if (io->fancy_upsampling) {
|
if (io->fancy_upsampling) {
|
||||||
#ifdef FANCY_UPSAMPLING
|
#ifdef FANCY_UPSAMPLING
|
||||||
const int uv_width = (io->mb_w + 1) >> 1;
|
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) {
|
if (p->memory == NULL) {
|
||||||
return 0; // memory error.
|
return 0; // memory error.
|
||||||
}
|
}
|
||||||
@ -620,7 +622,7 @@ static int CustomPut(const VP8Io* io) {
|
|||||||
|
|
||||||
static void CustomTeardown(const VP8Io* io) {
|
static void CustomTeardown(const VP8Io* io) {
|
||||||
WebPDecParams* const p = (WebPDecParams*)io->opaque;
|
WebPDecParams* const p = (WebPDecParams*)io->opaque;
|
||||||
free(p->memory);
|
WebPSafeFree(p->memory);
|
||||||
p->memory = NULL;
|
p->memory = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "./vp8li.h"
|
#include "./vp8li.h"
|
||||||
#include "./webpi.h"
|
#include "./webpi.h"
|
||||||
#include "../utils/bit_reader.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* VP8New(void) {
|
||||||
VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec));
|
VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||||
if (dec != NULL) {
|
if (dec != NULL) {
|
||||||
SetOk(dec);
|
SetOk(dec);
|
||||||
WebPWorkerInit(&dec->worker_);
|
WebPWorkerInit(&dec->worker_);
|
||||||
@ -68,7 +69,7 @@ const char* VP8StatusMessage(VP8Decoder* const dec) {
|
|||||||
void VP8Delete(VP8Decoder* const dec) {
|
void VP8Delete(VP8Decoder* const dec) {
|
||||||
if (dec != NULL) {
|
if (dec != NULL) {
|
||||||
VP8Clear(dec);
|
VP8Clear(dec);
|
||||||
free(dec);
|
WebPSafeFree(dec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -689,7 +690,7 @@ void VP8Clear(VP8Decoder* const dec) {
|
|||||||
}
|
}
|
||||||
ALPHDelete(dec->alph_dec_);
|
ALPHDelete(dec->alph_dec_);
|
||||||
dec->alph_dec_ = NULL;
|
dec->alph_dec_ = NULL;
|
||||||
free(dec->mem_);
|
WebPSafeFree(dec->mem_);
|
||||||
dec->mem_ = NULL;
|
dec->mem_ = NULL;
|
||||||
dec->mem_size_ = 0;
|
dec->mem_size_ = 0;
|
||||||
memset(&dec->br_, 0, sizeof(dec->br_));
|
memset(&dec->br_, 0, sizeof(dec->br_));
|
||||||
|
@ -285,7 +285,7 @@ static int ReadHuffmanCode(int alphabet_size, VP8LDecoder* const dec,
|
|||||||
if (ok) {
|
if (ok) {
|
||||||
ok = HuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size);
|
ok = HuffmanTreeBuildImplicit(tree, code_lengths, alphabet_size);
|
||||||
}
|
}
|
||||||
free(code_lengths);
|
WebPSafeFree(code_lengths);
|
||||||
}
|
}
|
||||||
ok = ok && !br->error_;
|
ok = ok && !br->error_;
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
@ -304,7 +304,7 @@ static void DeleteHtreeGroups(HTreeGroup* htree_groups, int num_htree_groups) {
|
|||||||
HuffmanTreeRelease(&htrees[j]);
|
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;
|
return 1;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(huffman_image);
|
WebPSafeFree(huffman_image);
|
||||||
DeleteHtreeGroups(htree_groups, num_htree_groups);
|
DeleteHtreeGroups(htree_groups, num_htree_groups);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -933,7 +933,7 @@ static int DecodeImageData(VP8LDecoder* const dec, uint32_t* const data,
|
|||||||
// VP8LTransform
|
// VP8LTransform
|
||||||
|
|
||||||
static void ClearTransform(VP8LTransform* const transform) {
|
static void ClearTransform(VP8LTransform* const transform) {
|
||||||
free(transform->data_);
|
WebPSafeFree(transform->data_);
|
||||||
transform->data_ = NULL;
|
transform->data_ = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -957,7 +957,7 @@ static int ExpandColorMap(int num_colors, VP8LTransform* const transform) {
|
|||||||
}
|
}
|
||||||
for (; i < 4 * final_num_colors; ++i)
|
for (; i < 4 * final_num_colors; ++i)
|
||||||
new_data[i] = 0; // black tail.
|
new_data[i] = 0; // black tail.
|
||||||
free(transform->data_);
|
WebPSafeFree(transform->data_);
|
||||||
transform->data_ = new_color_map;
|
transform->data_ = new_color_map;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
@ -1027,7 +1027,7 @@ static void InitMetadata(VP8LMetadata* const hdr) {
|
|||||||
static void ClearMetadata(VP8LMetadata* const hdr) {
|
static void ClearMetadata(VP8LMetadata* const hdr) {
|
||||||
assert(hdr);
|
assert(hdr);
|
||||||
|
|
||||||
free(hdr->huffman_image_);
|
WebPSafeFree(hdr->huffman_image_);
|
||||||
DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_);
|
DeleteHtreeGroups(hdr->htree_groups_, hdr->num_htree_groups_);
|
||||||
VP8LColorCacheClear(&hdr->color_cache_);
|
VP8LColorCacheClear(&hdr->color_cache_);
|
||||||
InitMetadata(hdr);
|
InitMetadata(hdr);
|
||||||
@ -1037,7 +1037,7 @@ static void ClearMetadata(VP8LMetadata* const hdr) {
|
|||||||
// VP8LDecoder
|
// VP8LDecoder
|
||||||
|
|
||||||
VP8LDecoder* VP8LNew(void) {
|
VP8LDecoder* VP8LNew(void) {
|
||||||
VP8LDecoder* const dec = (VP8LDecoder*)calloc(1, sizeof(*dec));
|
VP8LDecoder* const dec = (VP8LDecoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
|
||||||
if (dec == NULL) return NULL;
|
if (dec == NULL) return NULL;
|
||||||
dec->status_ = VP8_STATUS_OK;
|
dec->status_ = VP8_STATUS_OK;
|
||||||
dec->action_ = READ_DIM;
|
dec->action_ = READ_DIM;
|
||||||
@ -1053,7 +1053,7 @@ void VP8LClear(VP8LDecoder* const dec) {
|
|||||||
if (dec == NULL) return;
|
if (dec == NULL) return;
|
||||||
ClearMetadata(&dec->hdr_);
|
ClearMetadata(&dec->hdr_);
|
||||||
|
|
||||||
free(dec->pixels_);
|
WebPSafeFree(dec->pixels_);
|
||||||
dec->pixels_ = NULL;
|
dec->pixels_ = NULL;
|
||||||
for (i = 0; i < dec->next_transform_; ++i) {
|
for (i = 0; i < dec->next_transform_; ++i) {
|
||||||
ClearTransform(&dec->transforms_[i]);
|
ClearTransform(&dec->transforms_[i]);
|
||||||
@ -1061,7 +1061,7 @@ void VP8LClear(VP8LDecoder* const dec) {
|
|||||||
dec->next_transform_ = 0;
|
dec->next_transform_ = 0;
|
||||||
dec->transforms_seen_ = 0;
|
dec->transforms_seen_ = 0;
|
||||||
|
|
||||||
free(dec->rescaler_memory);
|
WebPSafeFree(dec->rescaler_memory);
|
||||||
dec->rescaler_memory = NULL;
|
dec->rescaler_memory = NULL;
|
||||||
|
|
||||||
dec->output_ = NULL; // leave no trace behind
|
dec->output_ = NULL; // leave no trace behind
|
||||||
@ -1070,7 +1070,7 @@ void VP8LClear(VP8LDecoder* const dec) {
|
|||||||
void VP8LDelete(VP8LDecoder* const dec) {
|
void VP8LDelete(VP8LDecoder* const dec) {
|
||||||
if (dec != NULL) {
|
if (dec != NULL) {
|
||||||
VP8LClear(dec);
|
VP8LClear(dec);
|
||||||
free(dec);
|
WebPSafeFree(dec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1157,7 +1157,7 @@ static int DecodeImageStream(int xsize, int ysize,
|
|||||||
End:
|
End:
|
||||||
|
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
free(data);
|
WebPSafeFree(data);
|
||||||
ClearMetadata(hdr);
|
ClearMetadata(hdr);
|
||||||
// If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the
|
// If not enough data (br.eos_) resulted in BIT_STREAM_ERROR, update the
|
||||||
// status appropriately.
|
// status appropriately.
|
||||||
|
@ -289,7 +289,7 @@ static ParseStatus NewFrame(const MemBuffer* const mem,
|
|||||||
if (actual_size < min_size) return PARSE_ERROR;
|
if (actual_size < min_size) return PARSE_ERROR;
|
||||||
if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
|
if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
*frame = (Frame*)calloc(1, sizeof(**frame));
|
*frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(**frame));
|
||||||
return (*frame == NULL) ? PARSE_ERROR : PARSE_OK;
|
return (*frame == NULL) ? PARSE_ERROR : PARSE_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -317,7 +317,7 @@ static ParseStatus ParseAnimationFrame(
|
|||||||
(bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE;
|
(bits & 1) ? WEBP_MUX_DISPOSE_BACKGROUND : WEBP_MUX_DISPOSE_NONE;
|
||||||
frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND;
|
frame->blend_method_ = (bits & 2) ? WEBP_MUX_NO_BLEND : WEBP_MUX_BLEND;
|
||||||
if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) {
|
if (frame->width_ * (uint64_t)frame->height_ >= MAX_IMAGE_AREA) {
|
||||||
free(frame);
|
WebPSafeFree(frame);
|
||||||
return PARSE_ERROR;
|
return PARSE_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -333,7 +333,7 @@ static ParseStatus ParseAnimationFrame(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!added_frame) free(frame);
|
if (!added_frame) WebPSafeFree(frame);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -368,7 +368,7 @@ static ParseStatus ParseFragment(WebPDemuxer* const dmux,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!added_fragment) free(frame);
|
if (!added_fragment) WebPSafeFree(frame);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
#endif // WEBP_EXPERIMENTAL_FEATURES
|
#endif // WEBP_EXPERIMENTAL_FEATURES
|
||||||
@ -379,7 +379,7 @@ static ParseStatus ParseFragment(WebPDemuxer* const dmux,
|
|||||||
// Returns true on success, false otherwise.
|
// Returns true on success, false otherwise.
|
||||||
static int StoreChunk(WebPDemuxer* const dmux,
|
static int StoreChunk(WebPDemuxer* const dmux,
|
||||||
size_t start_offset, uint32_t size) {
|
size_t start_offset, uint32_t size) {
|
||||||
Chunk* const chunk = (Chunk*)calloc(1, sizeof(*chunk));
|
Chunk* const chunk = (Chunk*)WebPSafeCalloc(1ULL, sizeof(*chunk));
|
||||||
if (chunk == NULL) return 0;
|
if (chunk == NULL) return 0;
|
||||||
|
|
||||||
chunk->data_.offset_ = start_offset;
|
chunk->data_.offset_ = start_offset;
|
||||||
@ -427,7 +427,7 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
|||||||
if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
|
if (SizeIsInvalid(mem, min_size)) return PARSE_ERROR;
|
||||||
if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
|
if (MemDataSize(mem) < min_size) return PARSE_NEED_MORE_DATA;
|
||||||
|
|
||||||
frame = (Frame*)calloc(1, sizeof(*frame));
|
frame = (Frame*)WebPSafeCalloc(1ULL, sizeof(*frame));
|
||||||
if (frame == NULL) return PARSE_ERROR;
|
if (frame == NULL) return PARSE_ERROR;
|
||||||
|
|
||||||
// For the single image case we allow parsing of a partial frame, but we need
|
// For the single image case we allow parsing of a partial frame, but we need
|
||||||
@ -458,7 +458,7 @@ static ParseStatus ParseSingleImage(WebPDemuxer* const dmux) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!image_added) free(frame);
|
if (!image_added) WebPSafeFree(frame);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -729,7 +729,7 @@ WebPDemuxer* WebPDemuxInternal(const WebPData* data, int allow_partial,
|
|||||||
partial = (mem.buf_size_ < mem.riff_end_);
|
partial = (mem.buf_size_ < mem.riff_end_);
|
||||||
if (!allow_partial && partial) return NULL;
|
if (!allow_partial && partial) return NULL;
|
||||||
|
|
||||||
dmux = (WebPDemuxer*)calloc(1, sizeof(*dmux));
|
dmux = (WebPDemuxer*)WebPSafeCalloc(1ULL, sizeof(*dmux));
|
||||||
if (dmux == NULL) return NULL;
|
if (dmux == NULL) return NULL;
|
||||||
InitDemux(dmux, &mem);
|
InitDemux(dmux, &mem);
|
||||||
|
|
||||||
@ -761,14 +761,14 @@ void WebPDemuxDelete(WebPDemuxer* dmux) {
|
|||||||
for (f = dmux->frames_; f != NULL;) {
|
for (f = dmux->frames_; f != NULL;) {
|
||||||
Frame* const cur_frame = f;
|
Frame* const cur_frame = f;
|
||||||
f = f->next_;
|
f = f->next_;
|
||||||
free(cur_frame);
|
WebPSafeFree(cur_frame);
|
||||||
}
|
}
|
||||||
for (c = dmux->chunks_; c != NULL;) {
|
for (c = dmux->chunks_; c != NULL;) {
|
||||||
Chunk* const cur_chunk = c;
|
Chunk* const cur_chunk = c;
|
||||||
c = c->next_;
|
c = c->next_;
|
||||||
free(cur_chunk);
|
WebPSafeFree(cur_chunk);
|
||||||
}
|
}
|
||||||
free(dmux);
|
WebPSafeFree(dmux);
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "./vp8enci.h"
|
#include "./vp8enci.h"
|
||||||
#include "../utils/filters.h"
|
#include "../utils/filters.h"
|
||||||
#include "../utils/quant_levels.h"
|
#include "../utils/quant_levels.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
#include "../webp/format_constants.h"
|
#include "../webp/format_constants.h"
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
@ -34,7 +35,7 @@
|
|||||||
//
|
//
|
||||||
// 'output' corresponds to the buffer containing compressed alpha data.
|
// 'output' corresponds to the buffer containing compressed alpha data.
|
||||||
// This buffer is allocated by this method and caller should call
|
// 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.
|
// 'output_size' corresponds to size of this compressed alpha buffer.
|
||||||
//
|
//
|
||||||
// Returns 1 on successfully encoding the alpha and
|
// 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);
|
GetFilterMap(alpha, width, height, filter, effort_level);
|
||||||
InitFilterTrial(&best);
|
InitFilterTrial(&best);
|
||||||
if (try_map != FILTER_TRY_NONE) {
|
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;
|
if (filtered_alpha == NULL) return 0;
|
||||||
|
|
||||||
for (filter = WEBP_FILTER_NONE; ok && try_map; ++filter, try_map >>= 1) {
|
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 {
|
} else {
|
||||||
ok = EncodeAlphaInternal(alpha, width, height, method, WEBP_FILTER_NONE,
|
ok = EncodeAlphaInternal(alpha, width, height, method, WEBP_FILTER_NONE,
|
||||||
reduce_levels, effort_level, NULL, &best);
|
reduce_levels, effort_level, NULL, &best);
|
||||||
@ -298,7 +299,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
|||||||
filter = WEBP_FILTER_NONE;
|
filter = WEBP_FILTER_NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
quant_alpha = (uint8_t*)malloc(data_size);
|
quant_alpha = (uint8_t*)WebPSafeMalloc(1ULL, data_size);
|
||||||
if (quant_alpha == NULL) {
|
if (quant_alpha == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -325,7 +326,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
free(quant_alpha);
|
WebPSafeFree(quant_alpha);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -346,7 +347,7 @@ static int CompressAlphaJob(VP8Encoder* const enc, void* dummy) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (alpha_size != (uint32_t)alpha_size) { // Sanity check.
|
if (alpha_size != (uint32_t)alpha_size) { // Sanity check.
|
||||||
free(alpha_data);
|
WebPSafeFree(alpha_data);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
enc->alpha_data_size_ = (uint32_t)alpha_size;
|
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
|
ok = WebPWorkerSync(worker); // finish anything left in flight
|
||||||
WebPWorkerEnd(worker); // still need to end the worker, even if !ok
|
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_ = NULL;
|
||||||
enc->alpha_data_size_ = 0;
|
enc->alpha_data_size_ = 0;
|
||||||
enc->has_alpha_ = 0;
|
enc->has_alpha_ = 0;
|
||||||
|
@ -63,7 +63,7 @@ static void SmoothSegmentMap(VP8Encoder* const enc) {
|
|||||||
mb->segment_ = tmp[x + y * w];
|
mb->segment_ = tmp[x + y * w];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tmp);
|
WebPSafeFree(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
@ -89,7 +89,7 @@ void VP8LInitBackwardRefs(VP8LBackwardRefs* const refs) {
|
|||||||
|
|
||||||
void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs) {
|
void VP8LClearBackwardRefs(VP8LBackwardRefs* const refs) {
|
||||||
if (refs != NULL) {
|
if (refs != NULL) {
|
||||||
free(refs->refs);
|
WebPSafeFree(refs->refs);
|
||||||
VP8LInitBackwardRefs(refs);
|
VP8LInitBackwardRefs(refs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -116,13 +116,13 @@ static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) {
|
|||||||
|
|
||||||
static HashChain* HashChainNew(int size) {
|
static HashChain* HashChainNew(int size) {
|
||||||
int i;
|
int i;
|
||||||
HashChain* const p = (HashChain*)malloc(sizeof(*p));
|
HashChain* const p = (HashChain*)WebPSafeMalloc(1ULL, sizeof(*p));
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_));
|
p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_));
|
||||||
if (p->chain_ == NULL) {
|
if (p->chain_ == NULL) {
|
||||||
free(p);
|
WebPSafeFree(p);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
for (i = 0; i < size; ++i) {
|
for (i = 0; i < size; ++i) {
|
||||||
@ -136,8 +136,8 @@ static HashChain* HashChainNew(int size) {
|
|||||||
|
|
||||||
static void HashChainDelete(HashChain* const p) {
|
static void HashChainDelete(HashChain* const p) {
|
||||||
if (p != NULL) {
|
if (p != NULL) {
|
||||||
free(p->chain_);
|
WebPSafeFree(p->chain_);
|
||||||
free(p);
|
WebPSafeFree(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -490,7 +490,7 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
const int use_color_cache = (cache_bits > 0);
|
const int use_color_cache = (cache_bits > 0);
|
||||||
float* const cost =
|
float* const cost =
|
||||||
(float*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*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);
|
HashChain* hash_chain = HashChainNew(pix_count);
|
||||||
VP8LColorCache hashers;
|
VP8LColorCache hashers;
|
||||||
const double mul0 = (recursive_cost_model != 0) ? 1.0 : 0.68;
|
const double mul0 = (recursive_cost_model != 0) ? 1.0 : 0.68;
|
||||||
@ -597,8 +597,8 @@ static int BackwardReferencesHashChainDistanceOnly(
|
|||||||
Error:
|
Error:
|
||||||
if (cc_init) VP8LColorCacheClear(&hashers);
|
if (cc_init) VP8LColorCacheClear(&hashers);
|
||||||
HashChainDelete(hash_chain);
|
HashChainDelete(hash_chain);
|
||||||
free(cost_model);
|
WebPSafeFree(cost_model);
|
||||||
free(cost);
|
WebPSafeFree(cost);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +724,7 @@ static int BackwardReferencesTraceBackwards(int xsize, int ysize,
|
|||||||
}
|
}
|
||||||
ok = 1;
|
ok = 1;
|
||||||
Error:
|
Error:
|
||||||
free(dist_array);
|
WebPSafeFree(dist_array);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -768,7 +768,8 @@ int VP8LGetBackwardReferences(int width, int height,
|
|||||||
|
|
||||||
{
|
{
|
||||||
double bit_cost_lz77, bit_cost_rle;
|
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;
|
if (histo == NULL) goto Error1;
|
||||||
// Evaluate lz77 coding
|
// Evaluate lz77 coding
|
||||||
VP8LHistogramCreate(histo, &refs_lz77, cache_bits);
|
VP8LHistogramCreate(histo, &refs_lz77, cache_bits);
|
||||||
@ -778,7 +779,7 @@ int VP8LGetBackwardReferences(int width, int height,
|
|||||||
bit_cost_rle = VP8LHistogramEstimateBits(histo);
|
bit_cost_rle = VP8LHistogramEstimateBits(histo);
|
||||||
// Decide if LZ77 is useful.
|
// Decide if LZ77 is useful.
|
||||||
lz77_is_useful = (bit_cost_lz77 < bit_cost_rle);
|
lz77_is_useful = (bit_cost_lz77 < bit_cost_rle);
|
||||||
free(histo);
|
WebPSafeFree(histo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Choose appropriate backward reference.
|
// Choose appropriate backward reference.
|
||||||
|
@ -162,7 +162,7 @@ static int Record(int bit, proba_t* const stats) {
|
|||||||
return bit;
|
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
|
#define USE_LEVEL_CODE_TABLE
|
||||||
|
|
||||||
// Simulate block coding, but only record statistics.
|
// 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.
|
// bin_map[n][num_histo + 1] ... bin_map[n][bin_depth - 1] = un-used indices.
|
||||||
const int bin_depth = histo_image_raw_size + 1;
|
const int bin_depth = histo_image_raw_size + 1;
|
||||||
int16_t* bin_map = NULL;
|
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 =
|
VP8LHistogramSet* const init_histo =
|
||||||
VP8LAllocateHistogramSet(histo_image_raw_size, cache_bits);
|
VP8LAllocateHistogramSet(histo_image_raw_size, cache_bits);
|
||||||
|
|
||||||
@ -760,8 +761,8 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(bin_map);
|
WebPSafeFree(bin_map);
|
||||||
free(init_histo);
|
WebPSafeFree(init_histo);
|
||||||
free(histos);
|
WebPSafeFree(histos);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
@ -46,7 +46,7 @@ typedef struct {
|
|||||||
} VP8LHistogram;
|
} VP8LHistogram;
|
||||||
|
|
||||||
// Collection of histograms with fixed capacity, allocated as one
|
// 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 {
|
typedef struct {
|
||||||
int size; // number of slots currently in use
|
int size; // number of slots currently in use
|
||||||
int max_size; // maximum capacity
|
int max_size; // maximum capacity
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "./vp8enci.h"
|
#include "./vp8enci.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@ -39,6 +40,5 @@ int VP8EncFinishLayer(VP8Encoder* const enc) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VP8EncDeleteLayer(VP8Encoder* 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.
|
// the other YUV(A) buffer.
|
||||||
static int PictureAllocARGB(WebPPicture* const picture) {
|
static int PictureAllocARGB(WebPPicture* const picture) {
|
||||||
WebPPicture tmp;
|
WebPPicture tmp;
|
||||||
free(picture->memory_argb_);
|
WebPSafeFree(picture->memory_argb_);
|
||||||
PictureResetARGB(picture);
|
PictureResetARGB(picture);
|
||||||
picture->use_argb = 1;
|
picture->use_argb = 1;
|
||||||
WebPPictureGrabSpecs(picture, &tmp);
|
WebPPictureGrabSpecs(picture, &tmp);
|
||||||
@ -191,8 +191,8 @@ static int PictureAllocARGB(WebPPicture* const picture) {
|
|||||||
// Release memory owned by 'picture' (both YUV and ARGB buffers).
|
// Release memory owned by 'picture' (both YUV and ARGB buffers).
|
||||||
void WebPPictureFree(WebPPicture* picture) {
|
void WebPPictureFree(WebPPicture* picture) {
|
||||||
if (picture != NULL) {
|
if (picture != NULL) {
|
||||||
free(picture->memory_);
|
WebPSafeFree(picture->memory_);
|
||||||
free(picture->memory_argb_);
|
WebPSafeFree(picture->memory_argb_);
|
||||||
PictureResetYUVA(picture);
|
PictureResetYUVA(picture);
|
||||||
PictureResetARGB(picture);
|
PictureResetARGB(picture);
|
||||||
}
|
}
|
||||||
@ -504,7 +504,7 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
|
|||||||
AlphaMultiplyARGB(&tmp, 1);
|
AlphaMultiplyARGB(&tmp, 1);
|
||||||
}
|
}
|
||||||
WebPPictureFree(pic);
|
WebPPictureFree(pic);
|
||||||
free(work);
|
WebPSafeFree(work);
|
||||||
*pic = tmp;
|
*pic = tmp;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -538,7 +538,7 @@ int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
|||||||
if (w->size > 0) {
|
if (w->size > 0) {
|
||||||
memcpy(new_mem, w->mem, w->size);
|
memcpy(new_mem, w->mem, w->size);
|
||||||
}
|
}
|
||||||
free(w->mem);
|
WebPSafeFree(w->mem);
|
||||||
w->mem = new_mem;
|
w->mem = new_mem;
|
||||||
// down-cast is ok, thanks to WebPSafeMalloc
|
// down-cast is ok, thanks to WebPSafeMalloc
|
||||||
w->max_size = (size_t)next_max_size;
|
w->max_size = (size_t)next_max_size;
|
||||||
@ -550,6 +550,15 @@ int WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
|||||||
return 1;
|
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
|
// 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);
|
ok = import(&pic, rgba, stride) && WebPEncode(&config, &pic);
|
||||||
WebPPictureFree(&pic);
|
WebPPictureFree(&pic);
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
free(wrt.mem);
|
WebPMemoryWriterClear(&wrt);
|
||||||
*output = NULL;
|
*output = NULL;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
#include "./cost.h"
|
#include "./cost.h"
|
||||||
#include "./vp8enci.h"
|
#include "./vp8enci.h"
|
||||||
|
#include "../utils/utils.h"
|
||||||
|
|
||||||
#if !defined(DISABLE_TOKEN_BUFFER)
|
#if !defined(DISABLE_TOKEN_BUFFER)
|
||||||
|
|
||||||
@ -51,7 +52,7 @@ void VP8TBufferClear(VP8TBuffer* const b) {
|
|||||||
const VP8Tokens* p = b->pages_;
|
const VP8Tokens* p = b->pages_;
|
||||||
while (p != NULL) {
|
while (p != NULL) {
|
||||||
const VP8Tokens* const next = p->next_;
|
const VP8Tokens* const next = p->next_;
|
||||||
free((void*)p);
|
WebPSafeFree((void*)p);
|
||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
VP8TBufferInit(b);
|
VP8TBufferInit(b);
|
||||||
@ -59,7 +60,8 @@ void VP8TBufferClear(VP8TBuffer* const b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int TBufferNewPage(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) {
|
if (page == NULL) {
|
||||||
b->error_ = 1;
|
b->error_ = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -228,7 +230,7 @@ int VP8EmitTokens(VP8TBuffer* const b, VP8BitWriter* const bw,
|
|||||||
VP8PutBit(bw, bit, probas[token & 0x3fffu]);
|
VP8PutBit(bw, bit, probas[token & 0x3fffu]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (final_pass) free((void*)p);
|
if (final_pass) WebPSafeFree((void*)p);
|
||||||
p = next;
|
p = next;
|
||||||
}
|
}
|
||||||
if (final_pass) b->pages_ = NULL;
|
if (final_pass) b->pages_ = NULL;
|
||||||
|
@ -108,7 +108,7 @@ static int AnalyzeEntropy(const uint32_t* argb,
|
|||||||
|
|
||||||
VP8LHistogram* nonpredicted = NULL;
|
VP8LHistogram* nonpredicted = NULL;
|
||||||
VP8LHistogram* predicted =
|
VP8LHistogram* predicted =
|
||||||
(VP8LHistogram*)malloc(2 * sizeof(*predicted));
|
(VP8LHistogram*)WebPSafeMalloc(2ULL, sizeof(*predicted));
|
||||||
if (predicted == NULL) return 0;
|
if (predicted == NULL) return 0;
|
||||||
nonpredicted = predicted + 1;
|
nonpredicted = predicted + 1;
|
||||||
|
|
||||||
@ -135,7 +135,7 @@ static int AnalyzeEntropy(const uint32_t* argb,
|
|||||||
}
|
}
|
||||||
*nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
|
*nonpredicted_bits = VP8LHistogramEstimateBitsBulk(nonpredicted);
|
||||||
*predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
|
*predicted_bits = VP8LHistogramEstimateBitsBulk(predicted);
|
||||||
free(predicted);
|
WebPSafeFree(predicted);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -228,7 +228,7 @@ static int GetHuffBitLengthsAndCodes(
|
|||||||
|
|
||||||
End:
|
End:
|
||||||
if (!ok) {
|
if (!ok) {
|
||||||
free(mem_buf);
|
WebPSafeFree(mem_buf);
|
||||||
// If one VP8LCreateHuffmanTree() above fails, we need to clean up behind.
|
// If one VP8LCreateHuffmanTree() above fails, we need to clean up behind.
|
||||||
memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
|
memset(huffman_codes, 0, 5 * histogram_image_size * sizeof(*huffman_codes));
|
||||||
}
|
}
|
||||||
@ -362,7 +362,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
ok = 1;
|
ok = 1;
|
||||||
End:
|
End:
|
||||||
free(tokens);
|
WebPSafeFree(tokens);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -503,9 +503,9 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(histogram_image);
|
WebPSafeFree(histogram_image);
|
||||||
VP8LClearBackwardRefs(&refs);
|
VP8LClearBackwardRefs(&refs);
|
||||||
free(huffman_codes[0].codes);
|
WebPSafeFree(huffman_codes[0].codes);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -532,8 +532,8 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
assert(histogram_bits <= MAX_HUFFMAN_BITS);
|
||||||
|
|
||||||
if (histogram_image == NULL || histogram_symbols == NULL) {
|
if (histogram_image == NULL || histogram_symbols == NULL) {
|
||||||
free(histogram_image);
|
WebPSafeFree(histogram_image);
|
||||||
free(histogram_symbols);
|
WebPSafeFree(histogram_symbols);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -559,7 +559,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
goto Error;
|
goto Error;
|
||||||
}
|
}
|
||||||
// Free combined histograms.
|
// Free combined histograms.
|
||||||
free(histogram_image);
|
WebPSafeFree(histogram_image);
|
||||||
histogram_image = NULL;
|
histogram_image = NULL;
|
||||||
|
|
||||||
// Color Cache parameters.
|
// Color Cache parameters.
|
||||||
@ -593,7 +593,7 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
VP8LSubSampleSize(width, histogram_bits),
|
VP8LSubSampleSize(width, histogram_bits),
|
||||||
VP8LSubSampleSize(height, histogram_bits),
|
VP8LSubSampleSize(height, histogram_bits),
|
||||||
quality);
|
quality);
|
||||||
free(histogram_argb);
|
WebPSafeFree(histogram_argb);
|
||||||
if (!ok) goto Error;
|
if (!ok) goto Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -614,14 +614,14 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(histogram_image);
|
WebPSafeFree(histogram_image);
|
||||||
|
|
||||||
VP8LClearBackwardRefs(&refs);
|
VP8LClearBackwardRefs(&refs);
|
||||||
if (huffman_codes != NULL) {
|
if (huffman_codes != NULL) {
|
||||||
free(huffman_codes->codes);
|
WebPSafeFree(huffman_codes->codes);
|
||||||
free(huffman_codes);
|
WebPSafeFree(huffman_codes);
|
||||||
}
|
}
|
||||||
free(histogram_symbols);
|
WebPSafeFree(histogram_symbols);
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -637,7 +637,8 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
|||||||
int i;
|
int i;
|
||||||
const uint32_t* const argb = enc->argb_;
|
const uint32_t* const argb = enc->argb_;
|
||||||
double bit_cost_before, bit_cost_after;
|
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;
|
if (histo == NULL) return 0;
|
||||||
|
|
||||||
VP8LHistogramInit(histo, 1);
|
VP8LHistogramInit(histo, 1);
|
||||||
@ -656,7 +657,7 @@ static int EvalAndApplySubtractGreen(VP8LEncoder* const enc,
|
|||||||
++histo->blue_[((c >> 0) - green) & 0xff];
|
++histo->blue_[((c >> 0) - green) & 0xff];
|
||||||
}
|
}
|
||||||
bit_cost_after = VP8LHistogramEstimateBits(histo);
|
bit_cost_after = VP8LHistogramEstimateBits(histo);
|
||||||
free(histo);
|
WebPSafeFree(histo);
|
||||||
|
|
||||||
// Check if subtracting green yields low entropy.
|
// Check if subtracting green yields low entropy.
|
||||||
enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
|
enc->use_subtract_green_ = (bit_cost_after < bit_cost_before);
|
||||||
@ -907,7 +908,7 @@ static WebPEncodingError EncodePalette(VP8LBitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Error:
|
Error:
|
||||||
free(row);
|
WebPSafeFree(row);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -944,7 +945,7 @@ static void FinishEncParams(VP8LEncoder* const enc) {
|
|||||||
|
|
||||||
static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
|
static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
|
||||||
const WebPPicture* const picture) {
|
const WebPPicture* const picture) {
|
||||||
VP8LEncoder* const enc = (VP8LEncoder*)calloc(1, sizeof(*enc));
|
VP8LEncoder* const enc = (VP8LEncoder*)WebPSafeCalloc(1ULL, sizeof(*enc));
|
||||||
if (enc == NULL) {
|
if (enc == NULL) {
|
||||||
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -959,9 +960,9 @@ static VP8LEncoder* VP8LEncoderNew(const WebPConfig* const config,
|
|||||||
|
|
||||||
static void VP8LEncoderDelete(VP8LEncoder* enc) {
|
static void VP8LEncoderDelete(VP8LEncoder* enc) {
|
||||||
if (enc != NULL) {
|
if (enc != NULL) {
|
||||||
free(enc->argb_);
|
WebPSafeFree(enc->argb_);
|
||||||
|
WebPSafeFree(enc);
|
||||||
}
|
}
|
||||||
free(enc);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -269,7 +269,7 @@ static int DeleteVP8Encoder(VP8Encoder* enc) {
|
|||||||
VP8EncDeleteLayer(enc);
|
VP8EncDeleteLayer(enc);
|
||||||
#endif
|
#endif
|
||||||
VP8TBufferClear(&enc->tokens_);
|
VP8TBufferClear(&enc->tokens_);
|
||||||
free(enc);
|
WebPSafeFree(enc);
|
||||||
}
|
}
|
||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ WebPMux* WebPNewInternal(int version) {
|
|||||||
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
|
if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_MUX_ABI_VERSION)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
} else {
|
} else {
|
||||||
WebPMux* const mux = (WebPMux*)malloc(sizeof(WebPMux));
|
WebPMux* const mux = (WebPMux*)WebPSafeMalloc(1ULL, sizeof(WebPMux));
|
||||||
// If mux is NULL MuxInit is a noop.
|
// If mux is NULL MuxInit is a noop.
|
||||||
MuxInit(mux);
|
MuxInit(mux);
|
||||||
return mux;
|
return mux;
|
||||||
@ -56,7 +56,7 @@ static void MuxRelease(WebPMux* const mux) {
|
|||||||
void WebPMuxDelete(WebPMux* mux) {
|
void WebPMuxDelete(WebPMux* mux) {
|
||||||
// If mux is NULL MuxRelease is a noop.
|
// If mux is NULL MuxRelease is a noop.
|
||||||
MuxRelease(mux);
|
MuxRelease(mux);
|
||||||
free(mux);
|
WebPSafeFree(mux);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
@ -102,7 +102,7 @@ static WebPMuxError CreateFrameFragmentData(
|
|||||||
assert(info->dispose_method == (info->dispose_method & 1));
|
assert(info->dispose_method == (info->dispose_method & 1));
|
||||||
// Note: assertion on upper bounds is done in PutLE24().
|
// Note: assertion on upper bounds is done in PutLE24().
|
||||||
|
|
||||||
frame_frgm_bytes = (uint8_t*)malloc(frame_frgm_size);
|
frame_frgm_bytes = (uint8_t*)WebPSafeMalloc(1ULL, frame_frgm_size);
|
||||||
if (frame_frgm_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (frame_frgm_bytes == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
|
|
||||||
PutLE24(frame_frgm_bytes + 0, info->x_offset / 2);
|
PutLE24(frame_frgm_bytes + 0, info->x_offset / 2);
|
||||||
@ -619,7 +619,7 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
|||||||
+ ChunkListDiskSize(mux->exif_) + ChunkListDiskSize(mux->xmp_)
|
+ ChunkListDiskSize(mux->exif_) + ChunkListDiskSize(mux->xmp_)
|
||||||
+ ChunkListDiskSize(mux->unknown_) + RIFF_HEADER_SIZE;
|
+ ChunkListDiskSize(mux->unknown_) + RIFF_HEADER_SIZE;
|
||||||
|
|
||||||
data = (uint8_t*)malloc(size);
|
data = (uint8_t*)WebPSafeMalloc(1ULL, size);
|
||||||
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
|
|
||||||
// Emit header & chunks.
|
// Emit header & chunks.
|
||||||
@ -636,7 +636,7 @@ WebPMuxError WebPMuxAssemble(WebPMux* mux, WebPData* assembled_data) {
|
|||||||
// Validate mux.
|
// Validate mux.
|
||||||
err = MuxValidate(mux);
|
err = MuxValidate(mux);
|
||||||
if (err != WEBP_MUX_OK) {
|
if (err != WEBP_MUX_OK) {
|
||||||
free(data);
|
WebPSafeFree(data);
|
||||||
data = NULL;
|
data = NULL;
|
||||||
size = 0;
|
size = 0;
|
||||||
}
|
}
|
||||||
|
@ -165,7 +165,7 @@ WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
|
|||||||
return WEBP_MUX_NOT_FOUND;
|
return WEBP_MUX_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_chunk = (WebPChunk*)malloc(sizeof(*new_chunk));
|
new_chunk = (WebPChunk*)WebPSafeMalloc(1ULL, sizeof(*new_chunk));
|
||||||
if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (new_chunk == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
*new_chunk = *chunk;
|
*new_chunk = *chunk;
|
||||||
chunk->owner_ = 0;
|
chunk->owner_ = 0;
|
||||||
@ -179,7 +179,7 @@ WebPMuxError ChunkSetNth(WebPChunk* chunk, WebPChunk** chunk_list,
|
|||||||
|
|
||||||
WebPChunk* ChunkDelete(WebPChunk* const chunk) {
|
WebPChunk* ChunkDelete(WebPChunk* const chunk) {
|
||||||
WebPChunk* const next = ChunkRelease(chunk);
|
WebPChunk* const next = ChunkRelease(chunk);
|
||||||
free(chunk);
|
WebPSafeFree(chunk);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list) {
|
|||||||
wpi_list = &cur_wpi->next_;
|
wpi_list = &cur_wpi->next_;
|
||||||
}
|
}
|
||||||
|
|
||||||
new_wpi = (WebPMuxImage*)malloc(sizeof(*new_wpi));
|
new_wpi = (WebPMuxImage*)WebPSafeMalloc(1ULL, sizeof(*new_wpi));
|
||||||
if (new_wpi == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (new_wpi == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
*new_wpi = *wpi;
|
*new_wpi = *wpi;
|
||||||
new_wpi->next_ = NULL;
|
new_wpi->next_ = NULL;
|
||||||
@ -331,7 +331,7 @@ WebPMuxError MuxImagePush(const WebPMuxImage* wpi, WebPMuxImage** wpi_list) {
|
|||||||
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi) {
|
WebPMuxImage* MuxImageDelete(WebPMuxImage* const wpi) {
|
||||||
// Delete the components of wpi. If wpi is NULL this is a noop.
|
// Delete the components of wpi. If wpi is NULL this is a noop.
|
||||||
WebPMuxImage* const next = MuxImageRelease(wpi);
|
WebPMuxImage* const next = MuxImageRelease(wpi);
|
||||||
free(wpi);
|
WebPSafeFree(wpi);
|
||||||
return next;
|
return next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -220,7 +220,7 @@ WebPMux* WebPMuxCreateInternal(const WebPData* bitstream, int copy_data,
|
|||||||
data += RIFF_HEADER_SIZE;
|
data += RIFF_HEADER_SIZE;
|
||||||
size -= RIFF_HEADER_SIZE;
|
size -= RIFF_HEADER_SIZE;
|
||||||
|
|
||||||
wpi = (WebPMuxImage*)malloc(sizeof(*wpi));
|
wpi = (WebPMuxImage*)WebPSafeMalloc(1ULL, sizeof(*wpi));
|
||||||
if (wpi == NULL) goto Err;
|
if (wpi == NULL) goto Err;
|
||||||
MuxImageInit(wpi);
|
MuxImageInit(wpi);
|
||||||
|
|
||||||
@ -375,7 +375,7 @@ static WebPMuxError SynthesizeBitstream(const WebPMuxImage* const wpi,
|
|||||||
// Note: No need to output ANMF/FRGM chunk for a single image.
|
// Note: No need to output ANMF/FRGM chunk for a single image.
|
||||||
const size_t size = RIFF_HEADER_SIZE + vp8x_size + alpha_size +
|
const size_t size = RIFF_HEADER_SIZE + vp8x_size + alpha_size +
|
||||||
ChunkDiskSize(wpi->img_);
|
ChunkDiskSize(wpi->img_);
|
||||||
uint8_t* const data = (uint8_t*)malloc(size);
|
uint8_t* const data = (uint8_t*)WebPSafeMalloc(1ULL, size);
|
||||||
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
if (data == NULL) return WEBP_MUX_MEMORY_ERROR;
|
||||||
|
|
||||||
// Main RIFF header.
|
// Main RIFF header.
|
||||||
|
@ -15,7 +15,9 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <string.h> // for memcpy()
|
#include <string.h> // for memcpy()
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "./bit_writer.h"
|
#include "./bit_writer.h"
|
||||||
|
#include "./utils.h"
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// VP8BitWriter
|
// VP8BitWriter
|
||||||
@ -34,7 +36,7 @@ static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
|
|||||||
new_size = 2 * bw->max_pos_;
|
new_size = 2 * bw->max_pos_;
|
||||||
if (new_size < needed_size) new_size = needed_size;
|
if (new_size < needed_size) new_size = needed_size;
|
||||||
if (new_size < 1024) new_size = 1024;
|
if (new_size < 1024) new_size = 1024;
|
||||||
new_buf = (uint8_t*)malloc(new_size);
|
new_buf = (uint8_t*)WebPSafeMalloc(1ULL, new_size);
|
||||||
if (new_buf == NULL) {
|
if (new_buf == NULL) {
|
||||||
bw->error_ = 1;
|
bw->error_ = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -43,7 +45,7 @@ static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) {
|
|||||||
assert(bw->buf_ != NULL);
|
assert(bw->buf_ != NULL);
|
||||||
memcpy(new_buf, bw->buf_, bw->pos_);
|
memcpy(new_buf, bw->buf_, bw->pos_);
|
||||||
}
|
}
|
||||||
free(bw->buf_);
|
WebPSafeFree(bw->buf_);
|
||||||
bw->buf_ = new_buf;
|
bw->buf_ = new_buf;
|
||||||
bw->max_pos_ = new_size;
|
bw->max_pos_ = new_size;
|
||||||
return 1;
|
return 1;
|
||||||
@ -176,7 +178,7 @@ uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) {
|
|||||||
|
|
||||||
int VP8BitWriterAppend(VP8BitWriter* const bw,
|
int VP8BitWriterAppend(VP8BitWriter* const bw,
|
||||||
const uint8_t* data, size_t size) {
|
const uint8_t* data, size_t size) {
|
||||||
assert(data);
|
assert(data != NULL);
|
||||||
if (bw->nb_bits_ != -8) return 0; // kFlush() must have been called
|
if (bw->nb_bits_ != -8) return 0; // kFlush() must have been called
|
||||||
if (!BitWriterResize(bw, size)) return 0;
|
if (!BitWriterResize(bw, size)) return 0;
|
||||||
memcpy(bw->buf_ + bw->pos_, data, size);
|
memcpy(bw->buf_ + bw->pos_, data, size);
|
||||||
@ -185,8 +187,8 @@ int VP8BitWriterAppend(VP8BitWriter* const bw,
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
|
void VP8BitWriterWipeOut(VP8BitWriter* const bw) {
|
||||||
if (bw) {
|
if (bw != NULL) {
|
||||||
free(bw->buf_);
|
WebPSafeFree(bw->buf_);
|
||||||
memset(bw, 0, sizeof(*bw));
|
memset(bw, 0, sizeof(*bw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -245,7 +247,7 @@ static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
|
|||||||
if (allocated_size < size_required) allocated_size = size_required;
|
if (allocated_size < size_required) allocated_size = size_required;
|
||||||
// make allocated size multiple of 1k
|
// make allocated size multiple of 1k
|
||||||
allocated_size = (((allocated_size >> 10) + 1) << 10);
|
allocated_size = (((allocated_size >> 10) + 1) << 10);
|
||||||
allocated_buf = (uint8_t*)malloc(allocated_size);
|
allocated_buf = (uint8_t*)WebPSafeMalloc(1ULL, allocated_size);
|
||||||
if (allocated_buf == NULL) {
|
if (allocated_buf == NULL) {
|
||||||
bw->error_ = 1;
|
bw->error_ = 1;
|
||||||
return 0;
|
return 0;
|
||||||
@ -253,7 +255,7 @@ static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) {
|
|||||||
if (current_size > 0) {
|
if (current_size > 0) {
|
||||||
memcpy(allocated_buf, bw->buf_, current_size);
|
memcpy(allocated_buf, bw->buf_, current_size);
|
||||||
}
|
}
|
||||||
free(bw->buf_);
|
WebPSafeFree(bw->buf_);
|
||||||
bw->buf_ = allocated_buf;
|
bw->buf_ = allocated_buf;
|
||||||
bw->cur_ = bw->buf_ + current_size;
|
bw->cur_ = bw->buf_ + current_size;
|
||||||
bw->end_ = bw->buf_ + allocated_size;
|
bw->end_ = bw->buf_ + allocated_size;
|
||||||
@ -267,7 +269,7 @@ int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) {
|
|||||||
|
|
||||||
void VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
|
void VP8LBitWriterDestroy(VP8LBitWriter* const bw) {
|
||||||
if (bw != NULL) {
|
if (bw != NULL) {
|
||||||
free(bw->buf_);
|
WebPSafeFree(bw->buf_);
|
||||||
memset(bw, 0, sizeof(*bw));
|
memset(bw, 0, sizeof(*bw));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -307,4 +309,3 @@ uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ int VP8LColorCacheInit(VP8LColorCache* const cc, int hash_bits) {
|
|||||||
|
|
||||||
void VP8LColorCacheClear(VP8LColorCache* const cc) {
|
void VP8LColorCacheClear(VP8LColorCache* const cc) {
|
||||||
if (cc != NULL) {
|
if (cc != NULL) {
|
||||||
free(cc->colors_);
|
WebPSafeFree(cc->colors_);
|
||||||
cc->colors_ = NULL;
|
cc->colors_ = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -66,7 +66,7 @@ static int TreeInit(HuffmanTree* const tree, int num_leaves) {
|
|||||||
|
|
||||||
void HuffmanTreeRelease(HuffmanTree* const tree) {
|
void HuffmanTreeRelease(HuffmanTree* const tree) {
|
||||||
if (tree != NULL) {
|
if (tree != NULL) {
|
||||||
free(tree->root_);
|
WebPSafeFree(tree->root_);
|
||||||
tree->root_ = NULL;
|
tree->root_ = NULL;
|
||||||
tree->max_nodes_ = 0;
|
tree->max_nodes_ = 0;
|
||||||
tree->num_nodes_ = 0;
|
tree->num_nodes_ = 0;
|
||||||
@ -245,7 +245,7 @@ int HuffmanTreeBuildImplicit(HuffmanTree* const tree,
|
|||||||
}
|
}
|
||||||
ok = 1;
|
ok = 1;
|
||||||
End:
|
End:
|
||||||
free(codes);
|
WebPSafeFree(codes);
|
||||||
ok = ok && IsFull(tree);
|
ok = ok && IsFull(tree);
|
||||||
if (!ok) HuffmanTreeRelease(tree);
|
if (!ok) HuffmanTreeRelease(tree);
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -43,7 +43,7 @@ static int OptimizeHuffmanForRle(int length, int* const counts) {
|
|||||||
}
|
}
|
||||||
// 2) Let's mark all population counts that already can be encoded
|
// 2) Let's mark all population counts that already can be encoded
|
||||||
// with an rle code.
|
// with an rle code.
|
||||||
good_for_rle = (uint8_t*)calloc(length, 1);
|
good_for_rle = (uint8_t*)WebPSafeCalloc(1ULL, length);
|
||||||
if (good_for_rle == NULL) {
|
if (good_for_rle == NULL) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -119,7 +119,7 @@ static int OptimizeHuffmanForRle(int length, int* const counts) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(good_for_rle);
|
WebPSafeFree(good_for_rle);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,7 +272,7 @@ static int GenerateOptimalTree(const int* const histogram, int histogram_size,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
free(tree);
|
WebPSafeFree(tree);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,5 +38,8 @@ void* WebPSafeCalloc(uint64_t nmemb, size_t size) {
|
|||||||
return calloc((size_t)nmemb, size);
|
return calloc((size_t)nmemb, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
void WebPSafeFree(void* const ptr) {
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
@ -40,6 +40,9 @@ void* WebPSafeMalloc(uint64_t nmemb, size_t size);
|
|||||||
// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
|
// in order to favor the "calloc(num_foo, sizeof(foo))" pattern.
|
||||||
void* WebPSafeCalloc(uint64_t nmemb, size_t size);
|
void* WebPSafeCalloc(uint64_t nmemb, size_t size);
|
||||||
|
|
||||||
|
// Companion deallocation function to the above allocations.
|
||||||
|
void WebPSafeFree(void* const ptr);
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
// Reading/writing data.
|
// Reading/writing data.
|
||||||
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define WEBP_ENCODER_ABI_VERSION 0x0203 // MAJOR(8b) + MINOR(8b)
|
#define WEBP_ENCODER_ABI_VERSION 0x0204 // 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.
|
||||||
@ -229,9 +229,12 @@ struct WebPMemoryWriter {
|
|||||||
// The following must be called first before any use.
|
// The following must be called first before any use.
|
||||||
WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
|
WEBP_EXTERN(void) WebPMemoryWriterInit(WebPMemoryWriter* writer);
|
||||||
|
|
||||||
|
// The following must be called to deallocate writer->mem memory. The 'writer'
|
||||||
|
// object itself is not deallocated.
|
||||||
|
WEBP_EXTERN(void) WebPMemoryWriterClear(WebPMemoryWriter* writer);
|
||||||
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
|
// The custom writer to be used with WebPMemoryWriter as custom_ptr. Upon
|
||||||
// completion, writer.mem and writer.size will hold the coded data.
|
// completion, writer.mem and writer.size will hold the coded data.
|
||||||
// writer.mem must be freed using the call 'free(writer.mem)'.
|
// writer.mem must be freed by calling WebPMemoryWriterClear.
|
||||||
WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
WEBP_EXTERN(int) WebPMemoryWrite(const uint8_t* data, size_t data_size,
|
||||||
const WebPPicture* picture);
|
const WebPPicture* picture);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user