roytam followup webp patch
This commit is contained in:
parent
d43821e1f8
commit
b1c0b3e0c7
|
@ -364,11 +364,7 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||||
VP8LMetadata* const hdr = &dec->hdr_;
|
VP8LMetadata* const hdr = &dec->hdr_;
|
||||||
uint32_t* huffman_image = NULL;
|
uint32_t* huffman_image = NULL;
|
||||||
HTreeGroup* htree_groups = NULL;
|
HTreeGroup* htree_groups = NULL;
|
||||||
// When reading htrees, some might be unused, as the format allows it.
|
|
||||||
// We will still read them but put them in this htree_group_bogus.
|
|
||||||
HTreeGroup htree_group_bogus;
|
|
||||||
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
|
HuffmanTables* huffman_tables = &hdr->huffman_tables_;
|
||||||
HuffmanCode* next = NULL;
|
|
||||||
int num_htree_groups = 1;
|
int num_htree_groups = 1;
|
||||||
int num_htree_groups_max = 1;
|
int num_htree_groups_max = 1;
|
||||||
int max_alphabet_size = 0;
|
int max_alphabet_size = 0;
|
||||||
|
@ -453,59 +449,70 @@ static int ReadHuffmanCodes(VP8LDecoder* const dec, int xsize, int ysize,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < num_htree_groups_max; ++i) {
|
for (i = 0; i < num_htree_groups_max; ++i) {
|
||||||
// If the index "i" is unused in the Huffman image, read the coefficients
|
// If the index "i" is unused in the Huffman image, just make sure the
|
||||||
// but store them to a bogus htree_group.
|
// coefficients are valid but do not store them.
|
||||||
const int is_bogus = (mapping != NULL && mapping[i] == -1);
|
if (mapping != NULL && mapping[i] == -1) {
|
||||||
HTreeGroup* const htree_group =
|
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||||
is_bogus ? &htree_group_bogus :
|
int alphabet_size = kAlphabetSize[j];
|
||||||
&htree_groups[(mapping == NULL) ? i : mapping[i]];
|
if (j == 0 && color_cache_bits > 0) {
|
||||||
HuffmanCode** const htrees = htree_group->htrees;
|
alphabet_size += (1 << color_cache_bits);
|
||||||
int size;
|
}
|
||||||
int total_size = 0;
|
// Passing in NULL so that nothing gets filled.
|
||||||
int is_trivial_literal = 1;
|
if (!ReadHuffmanCode(alphabet_size, dec, code_lengths, NULL)) {
|
||||||
int max_bits = 0;
|
goto Error;
|
||||||
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
|
||||||
int alphabet_size = kAlphabetSize[j];
|
|
||||||
if (j == 0 && color_cache_bits > 0) {
|
|
||||||
alphabet_size += 1 << color_cache_bits;
|
|
||||||
}
|
|
||||||
size =
|
|
||||||
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
|
|
||||||
htrees[j] = huffman_tables->curr_segment->curr_table;
|
|
||||||
if (size == 0) {
|
|
||||||
goto Error;
|
|
||||||
}
|
|
||||||
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
|
||||||
is_trivial_literal = (htrees[j]->bits == 0);
|
|
||||||
}
|
|
||||||
total_size += htrees[j]->bits;
|
|
||||||
huffman_tables->curr_segment->curr_table += size;
|
|
||||||
if (j <= ALPHA) {
|
|
||||||
int local_max_bits = code_lengths[0];
|
|
||||||
int k;
|
|
||||||
for (k = 1; k < alphabet_size; ++k) {
|
|
||||||
if (code_lengths[k] > local_max_bits) {
|
|
||||||
local_max_bits = code_lengths[k];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
max_bits += local_max_bits;
|
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
htree_group->is_trivial_literal = is_trivial_literal;
|
HTreeGroup* const htree_group =
|
||||||
htree_group->is_trivial_code = 0;
|
&htree_groups[(mapping == NULL) ? i : mapping[i]];
|
||||||
if (is_trivial_literal) {
|
HuffmanCode** const htrees = htree_group->htrees;
|
||||||
const int red = htrees[RED][0].value;
|
int size;
|
||||||
const int blue = htrees[BLUE][0].value;
|
int total_size = 0;
|
||||||
const int alpha = htrees[ALPHA][0].value;
|
int is_trivial_literal = 1;
|
||||||
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
|
int max_bits = 0;
|
||||||
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
|
for (j = 0; j < HUFFMAN_CODES_PER_META_CODE; ++j) {
|
||||||
htree_group->is_trivial_code = 1;
|
int alphabet_size = kAlphabetSize[j];
|
||||||
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
|
if (j == 0 && color_cache_bits > 0) {
|
||||||
|
alphabet_size += (1 << color_cache_bits);
|
||||||
|
}
|
||||||
|
size =
|
||||||
|
ReadHuffmanCode(alphabet_size, dec, code_lengths, huffman_tables);
|
||||||
|
htrees[j] = huffman_tables->curr_segment->curr_table;
|
||||||
|
if (size == 0) {
|
||||||
|
goto Error;
|
||||||
|
}
|
||||||
|
if (is_trivial_literal && kLiteralMap[j] == 1) {
|
||||||
|
is_trivial_literal = (htrees[j]->bits == 0);
|
||||||
|
}
|
||||||
|
total_size += htrees[j]->bits;
|
||||||
|
huffman_tables->curr_segment->curr_table += size;
|
||||||
|
if (j <= ALPHA) {
|
||||||
|
int local_max_bits = code_lengths[0];
|
||||||
|
int k;
|
||||||
|
for (k = 1; k < alphabet_size; ++k) {
|
||||||
|
if (code_lengths[k] > local_max_bits) {
|
||||||
|
local_max_bits = code_lengths[k];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
max_bits += local_max_bits;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
htree_group->is_trivial_literal = is_trivial_literal;
|
||||||
|
htree_group->is_trivial_code = 0;
|
||||||
|
if (is_trivial_literal) {
|
||||||
|
const int red = htrees[RED][0].value;
|
||||||
|
const int blue = htrees[BLUE][0].value;
|
||||||
|
const int alpha = htrees[ALPHA][0].value;
|
||||||
|
htree_group->literal_arb = ((uint32_t)alpha << 24) | (red << 16) | blue;
|
||||||
|
if (total_size == 0 && htrees[GREEN][0].value < NUM_LITERAL_CODES) {
|
||||||
|
htree_group->is_trivial_code = 1;
|
||||||
|
htree_group->literal_arb |= htrees[GREEN][0].value << 8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
htree_group->use_packed_table =
|
||||||
|
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
|
||||||
|
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
|
||||||
}
|
}
|
||||||
htree_group->use_packed_table =
|
|
||||||
!htree_group->is_trivial_code && (max_bits < HUFFMAN_PACKED_BITS);
|
|
||||||
if (htree_group->use_packed_table) BuildPackedTable(htree_group);
|
|
||||||
}
|
}
|
||||||
ok = 1;
|
ok = 1;
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,8 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
||||||
|
|
||||||
assert(code_lengths_size != 0);
|
assert(code_lengths_size != 0);
|
||||||
assert(code_lengths != NULL);
|
assert(code_lengths != NULL);
|
||||||
assert(root_table != NULL);
|
assert((root_table != NULL && sorted != NULL) ||
|
||||||
|
(root_table == NULL && sorted == NULL));
|
||||||
assert(root_bits > 0);
|
assert(root_bits > 0);
|
||||||
|
|
||||||
// Build histogram of code lengths.
|
// Build histogram of code lengths.
|
||||||
|
@ -120,16 +121,22 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
||||||
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
for (symbol = 0; symbol < code_lengths_size; ++symbol) {
|
||||||
const int symbol_code_length = code_lengths[symbol];
|
const int symbol_code_length = code_lengths[symbol];
|
||||||
if (code_lengths[symbol] > 0) {
|
if (code_lengths[symbol] > 0) {
|
||||||
sorted[offset[symbol_code_length]++] = symbol;
|
if (sorted != NULL) {
|
||||||
|
sorted[offset[symbol_code_length]++] = symbol;
|
||||||
|
} else {
|
||||||
|
offset[symbol_code_length]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Special case code with only one value.
|
// Special case code with only one value.
|
||||||
if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
|
if (offset[MAX_ALLOWED_CODE_LENGTH] == 1) {
|
||||||
HuffmanCode code;
|
if (sorted != NULL) {
|
||||||
code.bits = 0;
|
HuffmanCode code;
|
||||||
code.value = (uint16_t)sorted[0];
|
code.bits = 0;
|
||||||
ReplicateValue(table, 1, total_size, code);
|
code.value = (uint16_t)sorted[0];
|
||||||
|
ReplicateValue(table, 1, total_size, code);
|
||||||
|
}
|
||||||
return total_size;
|
return total_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,6 +158,7 @@ static int BuildHuffmanTable(HuffmanCode* const root_table, int root_bits,
|
||||||
if (num_open < 0) {
|
if (num_open < 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
if (root_table == NULL) continue;
|
||||||
for (; count[len] > 0; --count[len]) {
|
for (; count[len] > 0; --count[len]) {
|
||||||
HuffmanCode code;
|
HuffmanCode code;
|
||||||
code.bits = (uint8_t)len;
|
code.bits = (uint8_t)len;
|
||||||
|
|
Loading…
Reference in New Issue