mirror of
https://github.com/webmproject/libwebp.git
synced 2024-11-19 20:08:28 +01:00
Remove a useless malloc for entropy image
histogram_symbols is converted to uint32_t and <<8 into histogram_argb. Using a uint32_t buffer from the start prevents copying and converting the data. Change-Id: I245003a6a0f048c31519afa25a600d4479e762e3
This commit is contained in:
parent
bc49176355
commit
a78c5356ba
@ -601,11 +601,11 @@ static void HistogramBuild(
|
||||
}
|
||||
|
||||
// Copies the histograms and computes its bit_cost.
|
||||
static const uint16_t kInvalidHistogramSymbol = (uint16_t)(-1);
|
||||
static const uint32_t kInvalidHistogramSymbol = (uint32_t)(-1);
|
||||
static void HistogramCopyAndAnalyze(VP8LHistogramSet* const orig_histo,
|
||||
VP8LHistogramSet* const image_histo,
|
||||
int* const num_used,
|
||||
uint16_t* const histogram_symbols) {
|
||||
uint32_t* const histogram_symbols) {
|
||||
int i, cluster_id;
|
||||
int num_used_orig = *num_used;
|
||||
VP8LHistogram** const orig_histograms = orig_histo->histograms;
|
||||
@ -667,7 +667,7 @@ static void HistogramAnalyzeEntropyBin(VP8LHistogramSet* const image_histo,
|
||||
// 'combine_cost_factor' has to be divided by 100.
|
||||
static void HistogramCombineEntropyBin(
|
||||
VP8LHistogramSet* const image_histo, int* num_used,
|
||||
const uint16_t* const clusters, uint16_t* const cluster_mappings,
|
||||
const uint32_t* const clusters, uint16_t* const cluster_mappings,
|
||||
VP8LHistogram* cur_combo, const uint16_t* const bin_map, int num_bins,
|
||||
int32_t combine_cost_factor, int low_effort) {
|
||||
VP8LHistogram** const histograms = image_histo->histograms;
|
||||
@ -1070,7 +1070,7 @@ static int HistogramCombineStochastic(VP8LHistogramSet* const image_histo,
|
||||
// Note: we assume that out[]->bit_cost_ is already up-to-date.
|
||||
static void HistogramRemap(const VP8LHistogramSet* const in,
|
||||
VP8LHistogramSet* const out,
|
||||
uint16_t* const symbols) {
|
||||
uint32_t* const symbols) {
|
||||
int i;
|
||||
VP8LHistogram** const in_histo = in->histograms;
|
||||
VP8LHistogram** const out_histo = out->histograms;
|
||||
@ -1131,10 +1131,10 @@ static int32_t GetCombineCostFactor(int histo_size, int quality) {
|
||||
// assign the smallest possible clusters values.
|
||||
static void OptimizeHistogramSymbols(const VP8LHistogramSet* const set,
|
||||
uint16_t* const cluster_mappings,
|
||||
int num_clusters,
|
||||
uint32_t num_clusters,
|
||||
uint16_t* const cluster_mappings_tmp,
|
||||
uint16_t* const symbols) {
|
||||
int i, cluster_max;
|
||||
uint32_t* const symbols) {
|
||||
uint32_t i, cluster_max;
|
||||
int do_continue = 1;
|
||||
// First, assign the lowest cluster to each pixel.
|
||||
while (do_continue) {
|
||||
@ -1158,7 +1158,7 @@ static void OptimizeHistogramSymbols(const VP8LHistogramSet* const set,
|
||||
set->max_size * sizeof(*cluster_mappings_tmp));
|
||||
assert(cluster_mappings[0] == 0);
|
||||
// Re-map the ids.
|
||||
for (i = 0; i < set->max_size; ++i) {
|
||||
for (i = 0; i < (uint32_t)set->max_size; ++i) {
|
||||
int cluster;
|
||||
if (symbols[i] == kInvalidHistogramSymbol) continue;
|
||||
cluster = cluster_mappings[symbols[i]];
|
||||
@ -1172,7 +1172,7 @@ static void OptimizeHistogramSymbols(const VP8LHistogramSet* const set,
|
||||
|
||||
// Make sure all cluster values are used.
|
||||
cluster_max = 0;
|
||||
for (i = 0; i < set->max_size; ++i) {
|
||||
for (i = 0; i < (uint32_t)set->max_size; ++i) {
|
||||
if (symbols[i] == kInvalidHistogramSymbol) continue;
|
||||
if (symbols[i] <= cluster_max) continue;
|
||||
++cluster_max;
|
||||
@ -1195,7 +1195,7 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
int low_effort, int histogram_bits, int cache_bits,
|
||||
VP8LHistogramSet* const image_histo,
|
||||
VP8LHistogram* const tmp_histo,
|
||||
uint16_t* const histogram_symbols,
|
||||
uint32_t* const histogram_symbols,
|
||||
const WebPPicture* const pic, int percent_range,
|
||||
int* const percent) {
|
||||
const int histo_xsize =
|
||||
|
@ -109,7 +109,7 @@ int VP8LGetHistoImageSymbols(int xsize, int ysize,
|
||||
int low_effort, int histogram_bits, int cache_bits,
|
||||
VP8LHistogramSet* const image_histo,
|
||||
VP8LHistogram* const tmp_histo,
|
||||
uint16_t* const histogram_symbols,
|
||||
uint32_t* const histogram_symbols,
|
||||
const WebPPicture* const pic, int percent_range,
|
||||
int* const percent);
|
||||
|
||||
|
@ -664,11 +664,12 @@ static WEBP_INLINE void WriteHuffmanCodeWithExtraBits(
|
||||
VP8LPutBits(bw, (bits << depth) | symbol, depth + n_bits);
|
||||
}
|
||||
|
||||
static int StoreImageToBitMask(
|
||||
VP8LBitWriter* const bw, int width, int histo_bits,
|
||||
const VP8LBackwardRefs* const refs,
|
||||
const uint16_t* histogram_symbols,
|
||||
const HuffmanTreeCode* const huffman_codes, const WebPPicture* const pic) {
|
||||
static int StoreImageToBitMask(VP8LBitWriter* const bw, int width,
|
||||
int histo_bits,
|
||||
const VP8LBackwardRefs* const refs,
|
||||
const uint32_t* histogram_symbols,
|
||||
const HuffmanTreeCode* const huffman_codes,
|
||||
const WebPPicture* const pic) {
|
||||
const int histo_xsize = histo_bits ? VP8LSubSampleSize(width, histo_bits) : 1;
|
||||
const int tile_mask = (histo_bits == 0) ? 0 : -(1 << histo_bits);
|
||||
// x and y trace the position in the image.
|
||||
@ -676,7 +677,7 @@ static int StoreImageToBitMask(
|
||||
int y = 0;
|
||||
int tile_x = x & tile_mask;
|
||||
int tile_y = y & tile_mask;
|
||||
int histogram_ix = histogram_symbols[0];
|
||||
int histogram_ix = (histogram_symbols[0] >> 8) & 0xffff;
|
||||
const HuffmanTreeCode* codes = huffman_codes + 5 * histogram_ix;
|
||||
VP8LRefsCursor c = VP8LRefsCursorInit(refs);
|
||||
while (VP8LRefsCursorOk(&c)) {
|
||||
@ -684,8 +685,10 @@ static int StoreImageToBitMask(
|
||||
if ((tile_x != (x & tile_mask)) || (tile_y != (y & tile_mask))) {
|
||||
tile_x = x & tile_mask;
|
||||
tile_y = y & tile_mask;
|
||||
histogram_ix = histogram_symbols[(y >> histo_bits) * histo_xsize +
|
||||
(x >> histo_bits)];
|
||||
histogram_ix = (histogram_symbols[(y >> histo_bits) * histo_xsize +
|
||||
(x >> histo_bits)] >>
|
||||
8) &
|
||||
0xffff;
|
||||
codes = huffman_codes + 5 * histogram_ix;
|
||||
}
|
||||
if (PixOrCopyIsLiteral(v)) {
|
||||
@ -741,7 +744,7 @@ static int EncodeImageNoHuffman(VP8LBitWriter* const bw,
|
||||
VP8LBackwardRefs* refs;
|
||||
HuffmanTreeToken* tokens = NULL;
|
||||
HuffmanTreeCode huffman_codes[5] = {{0, NULL, NULL}};
|
||||
const uint16_t histogram_symbols[1] = {0}; // only one tree, one symbol
|
||||
const uint32_t histogram_symbols[1] = {0}; // only one tree, one symbol
|
||||
int cache_bits = 0;
|
||||
VP8LHistogramSet* histogram_image = NULL;
|
||||
HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
|
||||
@ -834,14 +837,14 @@ static int EncodeImageInternal(
|
||||
int percent_start = *percent;
|
||||
VP8LHistogramSet* histogram_image = NULL;
|
||||
VP8LHistogram* tmp_histo = NULL;
|
||||
int histogram_image_size = 0;
|
||||
uint32_t i, histogram_image_size = 0;
|
||||
size_t bit_array_size = 0;
|
||||
HuffmanTree* const huff_tree = (HuffmanTree*)WebPSafeMalloc(
|
||||
3ULL * CODE_LENGTH_CODES, sizeof(*huff_tree));
|
||||
HuffmanTreeToken* tokens = NULL;
|
||||
HuffmanTreeCode* huffman_codes = NULL;
|
||||
uint16_t* const histogram_symbols = (uint16_t*)WebPSafeMalloc(
|
||||
histogram_image_xysize, sizeof(*histogram_symbols));
|
||||
uint32_t* const histogram_argb = (uint32_t*)WebPSafeMalloc(
|
||||
histogram_image_xysize, sizeof(*histogram_argb));
|
||||
int sub_configs_idx;
|
||||
int cache_bits_init, write_histogram_image;
|
||||
VP8LBitWriter bw_init = *bw, bw_best;
|
||||
@ -860,7 +863,7 @@ static int EncodeImageInternal(
|
||||
}
|
||||
|
||||
// Make sure we can allocate the different objects.
|
||||
if (huff_tree == NULL || histogram_symbols == NULL ||
|
||||
if (huff_tree == NULL || histogram_argb == NULL ||
|
||||
!VP8LHashChainInit(&hash_chain_histogram, histogram_image_xysize)) {
|
||||
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||
goto Error;
|
||||
@ -923,7 +926,7 @@ static int EncodeImageInternal(
|
||||
if (!VP8LGetHistoImageSymbols(
|
||||
width, height, &refs_array[i_cache], quality, low_effort,
|
||||
histogram_bits, cache_bits_tmp, histogram_image, tmp_histo,
|
||||
histogram_symbols, pic, i_percent_range, percent)) {
|
||||
histogram_argb, pic, i_percent_range, percent)) {
|
||||
goto Error;
|
||||
}
|
||||
// Create Huffman bit lengths and codes for each histogram image.
|
||||
@ -956,26 +959,17 @@ static int EncodeImageInternal(
|
||||
}
|
||||
|
||||
// Huffman image + meta huffman.
|
||||
histogram_image_size = 0;
|
||||
for (i = 0; i < histogram_image_xysize; ++i) {
|
||||
if (histogram_argb[i] >= histogram_image_size) {
|
||||
histogram_image_size = histogram_argb[i] + 1;
|
||||
}
|
||||
histogram_argb[i] <<= 8;
|
||||
}
|
||||
|
||||
write_histogram_image = (histogram_image_size > 1);
|
||||
VP8LPutBits(bw, write_histogram_image, 1);
|
||||
if (write_histogram_image) {
|
||||
uint32_t* const histogram_argb = (uint32_t*)WebPSafeMalloc(
|
||||
histogram_image_xysize, sizeof(*histogram_argb));
|
||||
int max_index = 0;
|
||||
uint32_t i;
|
||||
if (histogram_argb == NULL) {
|
||||
WebPEncodingSetError(pic, VP8_ENC_ERROR_OUT_OF_MEMORY);
|
||||
goto Error;
|
||||
}
|
||||
for (i = 0; i < histogram_image_xysize; ++i) {
|
||||
const int symbol_index = histogram_symbols[i] & 0xffff;
|
||||
histogram_argb[i] = (symbol_index << 8);
|
||||
if (symbol_index >= max_index) {
|
||||
max_index = symbol_index + 1;
|
||||
}
|
||||
}
|
||||
histogram_image_size = max_index;
|
||||
|
||||
VP8LPutBits(bw, histogram_bits - 2, 3);
|
||||
i_percent_range = i_remaining_percent / 2;
|
||||
i_remaining_percent -= i_percent_range;
|
||||
@ -984,15 +978,12 @@ static int EncodeImageInternal(
|
||||
VP8LSubSampleSize(width, histogram_bits),
|
||||
VP8LSubSampleSize(height, histogram_bits), quality, low_effort,
|
||||
pic, i_percent_range, percent)) {
|
||||
WebPSafeFree(histogram_argb);
|
||||
goto Error;
|
||||
}
|
||||
WebPSafeFree(histogram_argb);
|
||||
}
|
||||
|
||||
// Store Huffman codes.
|
||||
{
|
||||
int i;
|
||||
int max_tokens = 0;
|
||||
// Find maximum number of symbols for the huffman tree-set.
|
||||
for (i = 0; i < 5 * histogram_image_size; ++i) {
|
||||
@ -1015,7 +1006,7 @@ static int EncodeImageInternal(
|
||||
// Store actual literals.
|
||||
hdr_size_tmp = (int)(VP8LBitWriterNumBytes(bw) - init_byte_position);
|
||||
if (!StoreImageToBitMask(bw, width, histogram_bits, &refs_array[i_cache],
|
||||
histogram_symbols, huffman_codes, pic)) {
|
||||
histogram_argb, huffman_codes, pic)) {
|
||||
goto Error;
|
||||
}
|
||||
// Keep track of the smallest image so far.
|
||||
@ -1052,7 +1043,7 @@ static int EncodeImageInternal(
|
||||
WebPSafeFree(huffman_codes->codes);
|
||||
WebPSafeFree(huffman_codes);
|
||||
}
|
||||
WebPSafeFree(histogram_symbols);
|
||||
WebPSafeFree(histogram_argb);
|
||||
VP8LBitWriterWipeOut(&bw_best);
|
||||
return (pic->error_code == VP8_ENC_OK);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user