mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-28 14:38:21 +01:00
Allocate single memory in GetHuffBitLengthsAndCodes.
Allocate big chunk of memory in GetHuffBitLengthsAndCodes, instead of allocating in a loop. Also fixed the potential memleak. Change-Id: Idc23ffa306f76100217304444191a8d2fef9c44a
This commit is contained in:
parent
2924a5aee6
commit
41d8049451
116
src/enc/vp8l.c
116
src/enc/vp8l.c
@ -271,21 +271,51 @@ static int GetHuffBitLengthsAndCodes(
|
|||||||
uint16_t** const bit_codes, uint8_t** const bit_lengths) {
|
uint16_t** const bit_codes, uint8_t** const bit_lengths) {
|
||||||
int i, k;
|
int i, k;
|
||||||
int ok = 1;
|
int ok = 1;
|
||||||
|
int total_length_size = 0;
|
||||||
|
uint8_t* mem_buf = NULL;
|
||||||
const int histogram_image_size = histogram_image->size;
|
const int histogram_image_size = histogram_image->size;
|
||||||
|
|
||||||
|
// Iterate over all histograms and get the aggregate number of codes used.
|
||||||
for (i = 0; i < histogram_image_size; ++i) {
|
for (i = 0; i < histogram_image_size; ++i) {
|
||||||
VP8LHistogram* const histo = histogram_image->histograms[i];
|
VP8LHistogram* const histo = histogram_image->histograms[i];
|
||||||
const int num_literals = VP8LHistogramNumCodes(histo);
|
const int num_literals = VP8LHistogramNumCodes(histo);
|
||||||
k = 0;
|
k = 0;
|
||||||
// TODO(vikasa): Alloc one big buffer instead of allocating in the loop.
|
|
||||||
bit_length_sizes[5 * i] = num_literals;
|
bit_length_sizes[5 * i] = num_literals;
|
||||||
bit_lengths[5 * i] = (uint8_t*)calloc(num_literals, 1);
|
total_length_size += num_literals;
|
||||||
bit_codes[5 * i] = (uint16_t*)
|
for (k = 1; k < 5; ++k) {
|
||||||
malloc(num_literals * sizeof(*bit_codes[5 * i]));
|
const int val = (k == 4) ? DISTANCE_CODES_MAX : 256;
|
||||||
if (bit_lengths[5 * i] == NULL || bit_codes[5 * i] == NULL) {
|
bit_length_sizes[5 * i + k] = val;
|
||||||
ok = 0;
|
total_length_size += val;
|
||||||
goto Error;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Allocate and Set bit_lengths and bit_codes.
|
||||||
|
{
|
||||||
|
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);
|
||||||
|
if (mem_buf == NULL) {
|
||||||
|
ok = 0;
|
||||||
|
goto End;
|
||||||
|
}
|
||||||
|
codes = (uint16_t*)mem_buf;
|
||||||
|
lengths = (uint8_t*)&codes[total_length_size];
|
||||||
|
for (i = 0; i < 5 * histogram_image_size; ++i) {
|
||||||
|
const int bit_length = bit_length_sizes[i];
|
||||||
|
bit_codes[i] = codes;
|
||||||
|
bit_lengths[i] = lengths;
|
||||||
|
codes += bit_length;
|
||||||
|
lengths += bit_length;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create Huffman trees.
|
||||||
|
for (i = 0; i < histogram_image_size; ++i) {
|
||||||
|
const int ix = 5 * i;
|
||||||
|
VP8LHistogram* const histo = histogram_image->histograms[i];
|
||||||
|
const int num_literals = bit_length_sizes[ix];
|
||||||
// For each component, optimize histogram for Huffman with RLE compression.
|
// For each component, optimize histogram for Huffman with RLE compression.
|
||||||
ok = ok && OptimizeHuffmanForRle(num_literals, histo->literal_);
|
ok = ok && OptimizeHuffmanForRle(num_literals, histo->literal_);
|
||||||
if (!use_color_cache) {
|
if (!use_color_cache) {
|
||||||
@ -295,54 +325,37 @@ static int GetHuffBitLengthsAndCodes(
|
|||||||
// palette entry, so zero it out.
|
// palette entry, so zero it out.
|
||||||
histo->literal_[256 + kLengthCodes] = 0;
|
histo->literal_[256 + kLengthCodes] = 0;
|
||||||
}
|
}
|
||||||
ok = ok && OptimizeHuffmanForRle(256, histo->red_);
|
|
||||||
ok = ok && OptimizeHuffmanForRle(256, histo->blue_);
|
|
||||||
ok = ok && OptimizeHuffmanForRle(256, histo->alpha_);
|
|
||||||
ok = ok && OptimizeHuffmanForRle(DISTANCE_CODES_MAX, histo->distance_);
|
|
||||||
|
|
||||||
// Create a Huffman tree (in the form of bit lengths) for each component.
|
// Create a Huffman tree (in the form of bit lengths) for each component.
|
||||||
ok = ok && VP8LCreateHuffmanTree(histo->literal_, num_literals,
|
ok = ok && VP8LCreateHuffmanTree(histo->literal_, num_literals, 15,
|
||||||
15, bit_lengths[5 * i]);
|
bit_lengths[ix]);
|
||||||
for (k = 1; k < 5; ++k) {
|
|
||||||
const int val = (k == 4) ? DISTANCE_CODES_MAX : 256;
|
ok = ok && OptimizeHuffmanForRle(256, histo->red_);
|
||||||
bit_length_sizes[5 * i + k] = val;
|
ok = ok && VP8LCreateHuffmanTree(histo->red_, 256, 15,
|
||||||
bit_lengths[5 * i + k] = (uint8_t*)calloc(val, 1);
|
bit_lengths[ix + 1]);
|
||||||
bit_codes[5 * i + k] = (uint16_t*)calloc(val, sizeof(*bit_codes[0]));
|
|
||||||
if (bit_lengths[5 * i + k] == NULL ||
|
ok = ok && OptimizeHuffmanForRle(256, histo->blue_);
|
||||||
bit_codes[5 * i + k] == NULL) {
|
ok = ok && VP8LCreateHuffmanTree(histo->blue_, 256, 15,
|
||||||
ok = 0;
|
bit_lengths[ix + 2]);
|
||||||
goto Error;
|
|
||||||
}
|
ok = ok && OptimizeHuffmanForRle(256, histo->alpha_);
|
||||||
}
|
ok = ok && VP8LCreateHuffmanTree(histo->alpha_, 256, 15,
|
||||||
ok = ok &&
|
bit_lengths[ix + 3]);
|
||||||
VP8LCreateHuffmanTree(histo->red_, 256, 15,
|
|
||||||
bit_lengths[5 * i + 1]) &&
|
ok = ok && OptimizeHuffmanForRle(DISTANCE_CODES_MAX, histo->distance_);
|
||||||
VP8LCreateHuffmanTree(histo->blue_, 256, 15,
|
ok = ok && VP8LCreateHuffmanTree(histo->distance_, DISTANCE_CODES_MAX, 15,
|
||||||
bit_lengths[5 * i + 2]) &&
|
bit_lengths[ix + 4]);
|
||||||
VP8LCreateHuffmanTree(histo->alpha_, 256, 15,
|
|
||||||
bit_lengths[5 * i + 3]) &&
|
|
||||||
VP8LCreateHuffmanTree(histo->distance_, DISTANCE_CODES_MAX, 15,
|
|
||||||
bit_lengths[5 * i + 4]);
|
|
||||||
// Create the actual bit codes for the bit lengths.
|
// Create the actual bit codes for the bit lengths.
|
||||||
for (k = 0; k < 5; ++k) {
|
for (k = 0; k < 5; ++k) {
|
||||||
int ix = 5 * i + k;
|
VP8LConvertBitDepthsToSymbols(bit_lengths[ix + k],
|
||||||
VP8LConvertBitDepthsToSymbols(bit_lengths[ix], bit_length_sizes[ix],
|
bit_length_sizes[ix + k],
|
||||||
bit_codes[ix]);
|
bit_codes[ix + k]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ok;
|
|
||||||
|
|
||||||
Error:
|
End:
|
||||||
{
|
if (!ok) free(mem_buf);
|
||||||
int idx;
|
return ok;
|
||||||
for (idx = 0; idx <= 5 * i + k; ++idx) {
|
|
||||||
free(bit_lengths[idx]);
|
|
||||||
free(bit_codes[idx]);
|
|
||||||
bit_lengths[idx] = NULL;
|
|
||||||
bit_codes[idx] = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ClearHuffmanTreeIfOnlyOneSymbol(const int num_symbols,
|
static void ClearHuffmanTreeIfOnlyOneSymbol(const int num_symbols,
|
||||||
@ -688,12 +701,9 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
|||||||
if (!ok) free(histogram_image);
|
if (!ok) free(histogram_image);
|
||||||
|
|
||||||
VP8LClearBackwardRefs(&refs);
|
VP8LClearBackwardRefs(&refs);
|
||||||
for (i = 0; i < bit_array_size; ++i) {
|
|
||||||
free(bit_lengths[i]);
|
|
||||||
free(bit_codes[i]);
|
|
||||||
}
|
|
||||||
free(bit_lengths_sizes);
|
free(bit_lengths_sizes);
|
||||||
free(bit_lengths);
|
free(bit_lengths);
|
||||||
|
free(*bit_codes);
|
||||||
free(bit_codes);
|
free(bit_codes);
|
||||||
free(histogram_symbols);
|
free(histogram_symbols);
|
||||||
return ok;
|
return ok;
|
||||||
|
Loading…
Reference in New Issue
Block a user