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