Merge "harness some malloc/calloc to use WebPSafeMalloc and WebPSafeCalloc" into 0.2.0

This commit is contained in:
Pascal Massimino
2012-08-01 18:16:46 -07:00
committed by Gerrit Code Review
15 changed files with 108 additions and 98 deletions

View File

@ -111,6 +111,7 @@ static int EncodeAlphaInternal(const uint8_t* const data, int width, int height,
size_t expected_size;
const size_t data_size = width * height;
assert((uint64_t)data_size == (uint64_t)width * height); // as per spec
assert(filter >= 0 && filter < WEBP_FILTER_LAST);
assert(method >= ALPHA_NO_COMPRESSION);
assert(method <= ALPHA_LOSSLESS_COMPRESSION);
@ -171,6 +172,7 @@ static int EncodeAlpha(VP8Encoder* const enc,
const int reduce_levels = (quality < 100);
// quick sanity checks
assert((uint64_t)data_size == (uint64_t)width * height); // as per spec
assert(enc != NULL && pic != NULL && pic->a != NULL);
assert(output != NULL && output_size != NULL);
assert(width > 0 && height > 0);

View File

@ -15,6 +15,7 @@
#include "./vp8enci.h"
#include "./cost.h"
#include "../utils/utils.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
@ -35,7 +36,8 @@ static void SmoothSegmentMap(VP8Encoder* const enc) {
const int w = enc->mb_w_;
const int h = enc->mb_h_;
const int majority_cnt_3_x_3_grid = 5;
uint8_t* const tmp = (uint8_t*)malloc(w * h * sizeof(uint8_t));
uint8_t* const tmp = (uint8_t*)WebPSafeMalloc((uint64_t)w * h, sizeof(*tmp));
assert((uint64_t)(w * h) == (uint64_t)w * h); // no overflow, as per spec
if (tmp == NULL) return;
for (y = 1; y < h - 1; ++y) {

View File

@ -15,6 +15,7 @@
#include "./backward_references.h"
#include "./histogram.h"
#include "../utils/color_cache.h"
#include "../utils/utils.h"
#define VALUES_IN_BYTE 256
@ -93,7 +94,8 @@ int VP8LBackwardRefsAlloc(VP8LBackwardRefs* const refs, int max_size) {
assert(refs != NULL);
refs->size = 0;
refs->max_size = 0;
refs->refs = (PixOrCopy*)malloc(max_size * sizeof(*refs->refs));
refs->refs = (PixOrCopy*)WebPSafeMalloc((uint64_t)max_size,
sizeof(*refs->refs));
if (refs->refs == NULL) return 0;
refs->max_size = max_size;
return 1;
@ -110,7 +112,7 @@ static WEBP_INLINE uint64_t GetPixPairHash64(const uint32_t* const argb) {
static int HashChainInit(HashChain* const p, int size) {
int i;
p->chain_ = (int*)malloc(size * sizeof(*p->chain_));
p->chain_ = (int*)WebPSafeMalloc((uint64_t)size, sizeof(*p->chain_));
if (p->chain_ == NULL) {
return 0;
}
@ -437,7 +439,8 @@ static int BackwardReferencesHashChainDistanceOnly(
const int quality = 100;
const int pix_count = xsize * ysize;
const int use_color_cache = (cache_bits > 0);
double* const cost = (double*)malloc(pix_count * sizeof(*cost));
double* const cost =
(double*)WebPSafeMalloc((uint64_t)pix_count, sizeof(*cost));
CostModel* cost_model = (CostModel*)malloc(sizeof(*cost_model));
HashChain* hash_chain = (HashChain*)malloc(sizeof(*hash_chain));
VP8LColorCache hashers;
@ -564,7 +567,8 @@ static int TraceBackwards(const uint32_t* const dist_array,
}
// Allocate.
*chosen_path_size = count;
*chosen_path = (uint32_t*)malloc(count * sizeof(*chosen_path));
*chosen_path =
(uint32_t*)WebPSafeMalloc((uint64_t)count, sizeof(**chosen_path));
if (*chosen_path == NULL) return 0;
// Write in reverse order.
@ -658,7 +662,7 @@ static int BackwardReferencesTraceBackwards(int xsize, int ysize,
uint32_t* chosen_path = NULL;
int chosen_path_size = 0;
uint32_t* dist_array =
(uint32_t*)malloc(dist_array_size * sizeof(*dist_array));
(uint32_t*)WebPSafeMalloc((uint64_t)dist_array_size, sizeof(*dist_array));
if (dist_array == NULL) goto Error;

View File

@ -17,6 +17,7 @@
#include "./backward_references.h"
#include "./histogram.h"
#include "../dsp/lossless.h"
#include "../utils/utils.h"
#if defined(_MSC_VER) && !defined(NOT_HAVE_LOG2)
# define NOT_HAVE_LOG2 1
@ -65,10 +66,10 @@ VP8LHistogramSet* VP8LAllocateHistogramSet(int size, int cache_bits) {
int i;
VP8LHistogramSet* set;
VP8LHistogram* bulk;
const size_t total_size = sizeof(*set)
+ size * sizeof(*set->histograms)
+ size * sizeof(**set->histograms);
uint8_t* memory = (uint8_t*)malloc(total_size);
const uint64_t total_size = (uint64_t)sizeof(*set)
+ size * sizeof(*set->histograms)
+ size * sizeof(**set->histograms);
uint8_t* memory = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*memory));
if (memory == NULL) return NULL;
set = (VP8LHistogramSet*)memory;

View File

@ -15,6 +15,7 @@
#include "./vp8enci.h"
#include "../utils/rescaler.h"
#include "../utils/utils.h"
#include "../dsp/dsp.h"
#if defined(__cplusplus) || defined(c_plusplus)
@ -81,14 +82,12 @@ int WebPPictureAlloc(WebPPicture* picture) {
// Security and validation checks
if (width <= 0 || height <= 0 || // luma/alpha param error
uv_width < 0 || uv_height < 0 || // u/v param error
y_size >= (1ULL << 40) || // reasonable global size
(size_t)total_size != total_size) { // overflow on 32bit
uv_width < 0 || uv_height < 0) { // u/v param error
return 0;
}
// Clear previous buffer and allocate a new one.
WebPPictureFree(picture); // erase previous buffer
mem = (uint8_t*)malloc((size_t)total_size);
mem = (uint8_t*)WebPSafeMalloc(total_size, sizeof(*mem));
if (mem == NULL) return 0;
// From now on, we're in the clear, we can no longer fail...
@ -119,15 +118,12 @@ int WebPPictureAlloc(WebPPicture* picture) {
} else {
void* memory;
const uint64_t argb_size = (uint64_t)width * height;
const uint64_t total_size = argb_size * sizeof(*picture->argb);
if (width <= 0 || height <= 0 ||
argb_size >= (1ULL << 40) ||
(size_t)total_size != total_size) {
if (width <= 0 || height <= 0) {
return 0;
}
// Clear previous buffer and allocate a new one.
WebPPictureFree(picture); // erase previous buffer
memory = malloc((size_t)total_size);
memory = WebPSafeMalloc(argb_size, sizeof(*picture->argb));
if (memory == NULL) return 0;
// TODO(skal): align plane to cache line?
@ -416,7 +412,7 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
if (!WebPPictureAlloc(&tmp)) return 0;
if (!pic->use_argb) {
work = (int32_t*)malloc(2 * width * sizeof(*work));
work = (int32_t*)WebPSafeMalloc(2ULL * width, sizeof(*work));
if (work == NULL) {
WebPPictureFree(&tmp);
return 0;
@ -449,7 +445,7 @@ int WebPPictureRescale(WebPPicture* pic, int width, int height) {
}
#endif
} else {
work = (int32_t*)malloc(2 * width * 4 * sizeof(*work));
work = (int32_t*)WebPSafeMalloc(2ULL * width * 4, sizeof(*work));
if (work == NULL) {
WebPPictureFree(&tmp);
return 0;
@ -480,17 +476,17 @@ void WebPMemoryWriterInit(WebPMemoryWriter* writer) {
int WebPMemoryWrite(const uint8_t* data, size_t data_size,
const WebPPicture* picture) {
WebPMemoryWriter* const w = (WebPMemoryWriter*)picture->custom_ptr;
size_t next_size;
uint64_t next_size;
if (w == NULL) {
return 1;
}
next_size = w->size + data_size;
next_size = (uint64_t)w->size + data_size;
if (next_size > w->max_size) {
uint8_t* new_mem;
size_t next_max_size = w->max_size * 2;
uint64_t next_max_size = 2ULL * w->max_size;
if (next_max_size < next_size) next_max_size = next_size;
if (next_max_size < 8192) next_max_size = 8192;
new_mem = (uint8_t*)malloc(next_max_size);
if (next_max_size < 8192ULL) next_max_size = 8192ULL;
new_mem = (uint8_t*)WebPSafeMalloc(next_max_size, 1);
if (new_mem == NULL) {
return 0;
}
@ -499,7 +495,8 @@ int WebPMemoryWrite(const uint8_t* data, size_t data_size,
}
free(w->mem);
w->mem = new_mem;
w->max_size = next_max_size;
// down-cast is ok, thanks to WebPSafeMalloc
w->max_size = (size_t)next_max_size;
}
if (data_size > 0) {
memcpy(w->mem + w->size, data, data_size);

View File

@ -20,6 +20,7 @@
#include "../dsp/lossless.h"
#include "../utils/bit_writer.h"
#include "../utils/huffman_encode.h"
#include "../utils/utils.h"
#include "../webp/format_constants.h"
#if defined(__cplusplus) || defined(c_plusplus)
@ -106,7 +107,8 @@ static int AnalyzeEntropy(const WebPPicture* const pic,
uint32_t last_pix = argb[0]; // so we're sure that pix_diff == 0
VP8LHistogram* nonpredicted = NULL;
VP8LHistogram* predicted = (VP8LHistogram*)malloc(2 * sizeof(*predicted));
VP8LHistogram* predicted =
(VP8LHistogram*)malloc(2 * sizeof(*predicted));
if (predicted == NULL) return 0;
nonpredicted = predicted + 1;
@ -167,7 +169,7 @@ static int GetHuffBitLengthsAndCodes(
HuffmanTreeCode* const huffman_codes) {
int i, k;
int ok = 1;
int total_length_size = 0;
uint64_t total_length_size = 0;
uint8_t* mem_buf = NULL;
const int histogram_image_size = histogram_image->size;
@ -188,9 +190,8 @@ static int GetHuffBitLengthsAndCodes(
{
uint16_t* codes;
uint8_t* lengths;
const size_t total_buf_size = total_length_size * sizeof(*lengths)
+ total_length_size * sizeof(*codes);
mem_buf = (uint8_t*)calloc(total_buf_size, 1);
mem_buf = (uint8_t*)WebPSafeCalloc(total_length_size,
sizeof(*lengths) + sizeof(*codes));
if (mem_buf == NULL) {
ok = 0;
goto End;
@ -292,7 +293,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
int num_tokens;
HuffmanTreeCode huffman_code;
HuffmanTreeToken* const tokens =
(HuffmanTreeToken*)malloc(max_tokens * sizeof(*tokens));
(HuffmanTreeToken*)WebPSafeMalloc((uint64_t)max_tokens, sizeof(*tokens));
if (tokens == NULL) return 0;
huffman_code.num_symbols = CODE_LENGTH_CODES;
@ -499,21 +500,21 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
const uint32_t* const argb,
int width, int height, int quality,
int cache_bits, int histogram_bits) {
int i;
int ok = 0;
const int use_2d_locality = 1;
const int use_color_cache = (cache_bits > 0);
const int histogram_image_xysize =
const uint32_t histogram_image_xysize =
VP8LSubSampleSize(width, histogram_bits) *
VP8LSubSampleSize(height, histogram_bits);
VP8LHistogramSet* histogram_image =
VP8LAllocateHistogramSet(histogram_image_xysize, 0);
int histogram_image_size = 0;
int bit_array_size = 0;
size_t bit_array_size = 0;
HuffmanTreeCode* huffman_codes = NULL;
VP8LBackwardRefs refs;
uint16_t* const histogram_symbols =
(uint16_t*)malloc(histogram_image_xysize * sizeof(*histogram_symbols));
(uint16_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
sizeof(*histogram_symbols));
assert(histogram_bits >= MIN_HUFFMAN_BITS);
assert(histogram_bits <= MAX_HUFFMAN_BITS);
if (histogram_image == NULL || histogram_symbols == NULL) goto Error;
@ -533,8 +534,8 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
// Create Huffman bit lengths and codes for each histogram image.
histogram_image_size = histogram_image->size;
bit_array_size = 5 * histogram_image_size;
huffman_codes = (HuffmanTreeCode*)calloc(bit_array_size,
sizeof(*huffman_codes));
huffman_codes = (HuffmanTreeCode*)WebPSafeCalloc(bit_array_size,
sizeof(*huffman_codes));
if (huffman_codes == NULL ||
!GetHuffBitLengthsAndCodes(histogram_image, huffman_codes)) {
goto Error;
@ -552,8 +553,10 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
VP8LWriteBits(bw, 1, write_histogram_image);
if (write_histogram_image) {
uint32_t* const histogram_argb =
(uint32_t*)malloc(histogram_image_xysize * sizeof(*histogram_argb));
(uint32_t*)WebPSafeMalloc((uint64_t)histogram_image_xysize,
sizeof(*histogram_argb));
int max_index = 0;
uint32_t i;
if (histogram_argb == NULL) goto Error;
for (i = 0; i < histogram_image_xysize; ++i) {
const int index = histogram_symbols[i] & 0xffff;
@ -575,14 +578,14 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
}
// Store Huffman codes.
for (i = 0; i < 5 * histogram_image_size; ++i) {
HuffmanTreeCode* const codes = &huffman_codes[i];
if (!StoreHuffmanCode(bw, codes)) {
goto Error;
{
int i;
for (i = 0; i < 5 * histogram_image_size; ++i) {
HuffmanTreeCode* const codes = &huffman_codes[i];
if (!StoreHuffmanCode(bw, codes)) goto Error;
ClearHuffmanTreeIfOnlyOneSymbol(codes);
}
ClearHuffmanTreeIfOnlyOneSymbol(codes);
}
// Free combined histograms.
free(histogram_image);
histogram_image = NULL;
@ -769,14 +772,14 @@ static WebPEncodingError AllocateTransformBuffer(VP8LEncoder* const enc,
int width, int height) {
WebPEncodingError err = VP8_ENC_OK;
const int tile_size = 1 << enc->transform_bits_;
const size_t image_size = width * height;
const size_t argb_scratch_size = tile_size * width + width;
const size_t transform_data_size =
VP8LSubSampleSize(width, enc->transform_bits_) *
VP8LSubSampleSize(height, enc->transform_bits_);
const size_t total_size =
const uint64_t image_size = width * height;
const uint64_t argb_scratch_size = tile_size * width + width;
const uint64_t transform_data_size =
(uint64_t)VP8LSubSampleSize(width, enc->transform_bits_) *
(uint64_t)VP8LSubSampleSize(height, enc->transform_bits_);
const uint64_t total_size =
image_size + argb_scratch_size + transform_data_size;
uint32_t* mem = (uint32_t*)malloc(total_size * sizeof(*mem));
uint32_t* mem = (uint32_t*)WebPSafeMalloc(total_size, sizeof(*mem));
if (mem == NULL) {
err = VP8_ENC_ERROR_OUT_OF_MEMORY;
goto Error;

View File

@ -16,6 +16,7 @@
#include "./vp8enci.h"
#include "./vp8li.h"
#include "../utils/utils.h"
// #define PRINT_MEMORY_INFO
@ -164,13 +165,14 @@ static VP8Encoder* InitVP8Encoder(const WebPConfig* const config,
config->autofilter ? sizeof(LFStats) + ALIGN_CST : 0;
VP8Encoder* enc;
uint8_t* mem;
size_t size = sizeof(VP8Encoder) + ALIGN_CST // main struct
+ cache_size // working caches
+ info_size // modes info
+ preds_size // prediction modes
+ samples_size // top/left samples
+ nz_size // coeff context bits
+ lf_stats_size; // autofilter stats
const uint64_t size = (uint64_t)sizeof(VP8Encoder) // main struct
+ ALIGN_CST // cache alignment
+ cache_size // working caches
+ info_size // modes info
+ preds_size // prediction modes
+ samples_size // top/left samples
+ nz_size // coeff context bits
+ lf_stats_size; // autofilter stats
#ifdef PRINT_MEMORY_INFO
printf("===================================\n");
@ -198,7 +200,7 @@ static VP8Encoder* InitVP8Encoder(const WebPConfig* const config,
mb_w * mb_h * 384 * sizeof(uint8_t));
printf("===================================\n");
#endif
mem = (uint8_t*)malloc(size);
mem = (uint8_t*)WebPSafeMalloc(size, sizeof(*mem));
if (mem == NULL) {
WebPEncodingSetError(picture, VP8_ENC_ERROR_OUT_OF_MEMORY);
return NULL;