mirror of
https://github.com/webmproject/libwebp.git
synced 2024-12-26 05:38:22 +01:00
Few more HuffmanTreeToken conversions.
Change-Id: I932b5368d279f83c462c7d916978dab3e81d7709
This commit is contained in:
parent
89c07c9660
commit
817c9dce61
@ -256,16 +256,13 @@ static void ClearHuffmanTreeIfOnlyOneSymbol(
|
||||
|
||||
static void StoreHuffmanTreeToBitMask(
|
||||
VP8LBitWriter* const bw,
|
||||
const HuffmanTreeToken* const tokens,
|
||||
const int num_tokens,
|
||||
const uint8_t* code_length_bitdepth,
|
||||
const uint16_t* code_length_bitdepth_symbols) {
|
||||
const HuffmanTreeToken* const tokens, const int num_tokens,
|
||||
const HuffmanTreeCode* const huffman_code) {
|
||||
int i;
|
||||
for (i = 0; i < num_tokens; ++i) {
|
||||
const int ix = tokens[i].code;
|
||||
const int extra_bits = tokens[i].extra_bits;
|
||||
VP8LWriteBits(bw, code_length_bitdepth[ix],
|
||||
code_length_bitdepth_symbols[ix]);
|
||||
VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
|
||||
switch (ix) {
|
||||
case 16:
|
||||
VP8LWriteBits(bw, 2, extra_bits);
|
||||
@ -281,15 +278,15 @@ static void StoreHuffmanTreeToBitMask(
|
||||
}
|
||||
|
||||
static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
||||
const uint8_t* const bit_lengths,
|
||||
int bit_lengths_size) {
|
||||
const HuffmanTreeCode* const tree) {
|
||||
int ok = 0;
|
||||
uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
|
||||
uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
|
||||
const int max_tokens = tree->num_symbols;
|
||||
int num_tokens;
|
||||
HuffmanTreeCode huffman_code;
|
||||
HuffmanTreeToken* const tokens =
|
||||
(HuffmanTreeToken*)malloc(bit_lengths_size * sizeof(*tokens));
|
||||
(HuffmanTreeToken*)malloc(max_tokens * sizeof(*tokens));
|
||||
if (tokens == NULL) return 0;
|
||||
|
||||
huffman_code.num_symbols = CODE_LENGTH_CODES;
|
||||
@ -297,8 +294,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
||||
huffman_code.codes = code_length_bitdepth_symbols;
|
||||
|
||||
VP8LWriteBits(bw, 1, 0);
|
||||
num_tokens = VP8LCreateCompressedHuffmanTree(bit_lengths, bit_lengths_size,
|
||||
tokens, bit_lengths_size);
|
||||
num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
|
||||
{
|
||||
int histogram[CODE_LENGTH_CODES] = { 0 };
|
||||
int i;
|
||||
@ -342,9 +338,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
||||
VP8LWriteBits(bw, 3, nbitpairs - 1);
|
||||
VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
|
||||
}
|
||||
StoreHuffmanTreeToBitMask(bw, tokens,
|
||||
length, code_length_bitdepth,
|
||||
code_length_bitdepth_symbols);
|
||||
StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
|
||||
}
|
||||
ok = 1;
|
||||
End:
|
||||
@ -353,8 +347,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
|
||||
}
|
||||
|
||||
static int StoreHuffmanCode(VP8LBitWriter* const bw,
|
||||
const uint8_t* const bit_lengths,
|
||||
int bit_lengths_size) {
|
||||
const HuffmanTreeCode* const huffman_code) {
|
||||
int i;
|
||||
int count = 0;
|
||||
int symbols[2] = { 0, 0 };
|
||||
@ -362,8 +355,8 @@ static int StoreHuffmanCode(VP8LBitWriter* const bw,
|
||||
const int kMaxSymbol = 1 << kMaxBits;
|
||||
|
||||
// Check whether it's a small tree.
|
||||
for (i = 0; i < bit_lengths_size && count < 3; ++i) {
|
||||
if (bit_lengths[i] != 0) {
|
||||
for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
|
||||
if (huffman_code->code_lengths[i] != 0) {
|
||||
if (count < 2) symbols[count] = i;
|
||||
++count;
|
||||
}
|
||||
@ -388,7 +381,7 @@ static int StoreHuffmanCode(VP8LBitWriter* const bw,
|
||||
}
|
||||
return 1;
|
||||
} else {
|
||||
return StoreFullHuffmanCode(bw, bit_lengths, bit_lengths_size);
|
||||
return StoreFullHuffmanCode(bw, huffman_code);
|
||||
}
|
||||
}
|
||||
|
||||
@ -403,7 +396,7 @@ static void StoreImageToBitMask(
|
||||
VP8LBitWriter* const bw, int width, int histo_bits,
|
||||
const VP8LBackwardRefs* const refs,
|
||||
const uint16_t* histogram_symbols,
|
||||
HuffmanTreeCode* const huffman_codes) {
|
||||
const HuffmanTreeCode* const huffman_codes) {
|
||||
// x and y trace the position in the image.
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
@ -526,11 +519,11 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
|
||||
|
||||
// Store Huffman codes.
|
||||
for (i = 0; i < 5 * histogram_image_size; ++i) {
|
||||
const HuffmanTreeCode* const codes = &huffman_codes[i];
|
||||
if (!StoreHuffmanCode(bw, codes->code_lengths, codes->num_symbols)) {
|
||||
HuffmanTreeCode* const codes = &huffman_codes[i];
|
||||
if (!StoreHuffmanCode(bw, codes)) {
|
||||
goto Error;
|
||||
}
|
||||
ClearHuffmanTreeIfOnlyOneSymbol(&huffman_codes[i]);
|
||||
ClearHuffmanTreeIfOnlyOneSymbol(codes);
|
||||
}
|
||||
|
||||
// Free combined histograms.
|
||||
|
@ -349,20 +349,19 @@ static HuffmanTreeToken* CodeRepeatedZeros(int repetitions,
|
||||
return tokens;
|
||||
}
|
||||
|
||||
int VP8LCreateCompressedHuffmanTree(const uint8_t* const depth,
|
||||
int depth_size,
|
||||
HuffmanTreeToken* tokens,
|
||||
int max_tokens) {
|
||||
int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
|
||||
HuffmanTreeToken* tokens, int max_tokens) {
|
||||
HuffmanTreeToken* const starting_token = tokens;
|
||||
HuffmanTreeToken* const ending_token = tokens + max_tokens;
|
||||
const int depth_size = tree->num_symbols;
|
||||
int prev_value = 8; // 8 is the initial value for rle.
|
||||
int i = 0;
|
||||
assert(tokens != NULL);
|
||||
while (i < depth_size) {
|
||||
const int value = depth[i];
|
||||
const int value = tree->code_lengths[i];
|
||||
int k = i + 1;
|
||||
int runs;
|
||||
while (k < depth_size && depth[k] == value) ++k;
|
||||
while (k < depth_size && tree->code_lengths[k] == value) ++k;
|
||||
runs = k - i;
|
||||
if (value == 0) {
|
||||
tokens = CodeRepeatedZeros(runs, tokens);
|
||||
|
@ -26,11 +26,6 @@ typedef struct {
|
||||
uint8_t extra_bits; // extra bits for escape codes
|
||||
} HuffmanTreeToken;
|
||||
|
||||
// Turn the Huffman tree into a token sequence.
|
||||
// Returns the number of tokens used.
|
||||
int VP8LCreateCompressedHuffmanTree(const uint8_t* const depth, int depth_size,
|
||||
HuffmanTreeToken* tokens, int max_tokens);
|
||||
|
||||
// Struct to represent the tree codes (depth and bits array).
|
||||
typedef struct {
|
||||
int num_symbols; // Number of symbols.
|
||||
@ -38,6 +33,11 @@ typedef struct {
|
||||
uint16_t* codes; // Symbol Codes.
|
||||
} HuffmanTreeCode;
|
||||
|
||||
// Turn the Huffman tree into a token sequence.
|
||||
// Returns the number of tokens used.
|
||||
int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
|
||||
HuffmanTreeToken* tokens, int max_tokens);
|
||||
|
||||
// Create an optimized tree, and tokenize it.
|
||||
int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit,
|
||||
HuffmanTreeCode* const tree);
|
||||
|
Loading…
Reference in New Issue
Block a user