Few more HuffmanTreeToken conversions.

Change-Id: I932b5368d279f83c462c7d916978dab3e81d7709
This commit is contained in:
Vikas Arora 2012-05-16 12:14:42 +05:30
parent 89c07c9660
commit 817c9dce61
3 changed files with 26 additions and 34 deletions

View File

@ -256,16 +256,13 @@ static void ClearHuffmanTreeIfOnlyOneSymbol(
static void StoreHuffmanTreeToBitMask( static void StoreHuffmanTreeToBitMask(
VP8LBitWriter* const bw, VP8LBitWriter* const bw,
const HuffmanTreeToken* const tokens, const HuffmanTreeToken* const tokens, const int num_tokens,
const int num_tokens, const HuffmanTreeCode* const huffman_code) {
const uint8_t* code_length_bitdepth,
const uint16_t* code_length_bitdepth_symbols) {
int i; int i;
for (i = 0; i < num_tokens; ++i) { for (i = 0; i < num_tokens; ++i) {
const int ix = tokens[i].code; const int ix = tokens[i].code;
const int extra_bits = tokens[i].extra_bits; const int extra_bits = tokens[i].extra_bits;
VP8LWriteBits(bw, code_length_bitdepth[ix], VP8LWriteBits(bw, huffman_code->code_lengths[ix], huffman_code->codes[ix]);
code_length_bitdepth_symbols[ix]);
switch (ix) { switch (ix) {
case 16: case 16:
VP8LWriteBits(bw, 2, extra_bits); VP8LWriteBits(bw, 2, extra_bits);
@ -281,15 +278,15 @@ static void StoreHuffmanTreeToBitMask(
} }
static int StoreFullHuffmanCode(VP8LBitWriter* const bw, static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
const uint8_t* const bit_lengths, const HuffmanTreeCode* const tree) {
int bit_lengths_size) {
int ok = 0; int ok = 0;
uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 }; uint8_t code_length_bitdepth[CODE_LENGTH_CODES] = { 0 };
uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 }; uint16_t code_length_bitdepth_symbols[CODE_LENGTH_CODES] = { 0 };
const int max_tokens = tree->num_symbols;
int num_tokens; int num_tokens;
HuffmanTreeCode huffman_code; HuffmanTreeCode huffman_code;
HuffmanTreeToken* const tokens = HuffmanTreeToken* const tokens =
(HuffmanTreeToken*)malloc(bit_lengths_size * sizeof(*tokens)); (HuffmanTreeToken*)malloc(max_tokens * sizeof(*tokens));
if (tokens == NULL) return 0; if (tokens == NULL) return 0;
huffman_code.num_symbols = CODE_LENGTH_CODES; huffman_code.num_symbols = CODE_LENGTH_CODES;
@ -297,8 +294,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
huffman_code.codes = code_length_bitdepth_symbols; huffman_code.codes = code_length_bitdepth_symbols;
VP8LWriteBits(bw, 1, 0); VP8LWriteBits(bw, 1, 0);
num_tokens = VP8LCreateCompressedHuffmanTree(bit_lengths, bit_lengths_size, num_tokens = VP8LCreateCompressedHuffmanTree(tree, tokens, max_tokens);
tokens, bit_lengths_size);
{ {
int histogram[CODE_LENGTH_CODES] = { 0 }; int histogram[CODE_LENGTH_CODES] = { 0 };
int i; int i;
@ -342,9 +338,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
VP8LWriteBits(bw, 3, nbitpairs - 1); VP8LWriteBits(bw, 3, nbitpairs - 1);
VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2); VP8LWriteBits(bw, nbitpairs * 2, trimmed_length - 2);
} }
StoreHuffmanTreeToBitMask(bw, tokens, StoreHuffmanTreeToBitMask(bw, tokens, length, &huffman_code);
length, code_length_bitdepth,
code_length_bitdepth_symbols);
} }
ok = 1; ok = 1;
End: End:
@ -353,8 +347,7 @@ static int StoreFullHuffmanCode(VP8LBitWriter* const bw,
} }
static int StoreHuffmanCode(VP8LBitWriter* const bw, static int StoreHuffmanCode(VP8LBitWriter* const bw,
const uint8_t* const bit_lengths, const HuffmanTreeCode* const huffman_code) {
int bit_lengths_size) {
int i; int i;
int count = 0; int count = 0;
int symbols[2] = { 0, 0 }; int symbols[2] = { 0, 0 };
@ -362,8 +355,8 @@ static int StoreHuffmanCode(VP8LBitWriter* const bw,
const int kMaxSymbol = 1 << kMaxBits; const int kMaxSymbol = 1 << kMaxBits;
// Check whether it's a small tree. // Check whether it's a small tree.
for (i = 0; i < bit_lengths_size && count < 3; ++i) { for (i = 0; i < huffman_code->num_symbols && count < 3; ++i) {
if (bit_lengths[i] != 0) { if (huffman_code->code_lengths[i] != 0) {
if (count < 2) symbols[count] = i; if (count < 2) symbols[count] = i;
++count; ++count;
} }
@ -388,7 +381,7 @@ static int StoreHuffmanCode(VP8LBitWriter* const bw,
} }
return 1; return 1;
} else { } 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, VP8LBitWriter* const bw, int width, int histo_bits,
const VP8LBackwardRefs* const refs, const VP8LBackwardRefs* const refs,
const uint16_t* histogram_symbols, const uint16_t* histogram_symbols,
HuffmanTreeCode* const huffman_codes) { const HuffmanTreeCode* const huffman_codes) {
// x and y trace the position in the image. // x and y trace the position in the image.
int x = 0; int x = 0;
int y = 0; int y = 0;
@ -526,11 +519,11 @@ static int EncodeImageInternal(VP8LBitWriter* const bw,
// Store Huffman codes. // Store Huffman codes.
for (i = 0; i < 5 * histogram_image_size; ++i) { for (i = 0; i < 5 * histogram_image_size; ++i) {
const HuffmanTreeCode* const codes = &huffman_codes[i]; HuffmanTreeCode* const codes = &huffman_codes[i];
if (!StoreHuffmanCode(bw, codes->code_lengths, codes->num_symbols)) { if (!StoreHuffmanCode(bw, codes)) {
goto Error; goto Error;
} }
ClearHuffmanTreeIfOnlyOneSymbol(&huffman_codes[i]); ClearHuffmanTreeIfOnlyOneSymbol(codes);
} }
// Free combined histograms. // Free combined histograms.

View File

@ -349,20 +349,19 @@ static HuffmanTreeToken* CodeRepeatedZeros(int repetitions,
return tokens; return tokens;
} }
int VP8LCreateCompressedHuffmanTree(const uint8_t* const depth, int VP8LCreateCompressedHuffmanTree(const HuffmanTreeCode* const tree,
int depth_size, HuffmanTreeToken* tokens, int max_tokens) {
HuffmanTreeToken* tokens,
int max_tokens) {
HuffmanTreeToken* const starting_token = tokens; HuffmanTreeToken* const starting_token = tokens;
HuffmanTreeToken* const ending_token = tokens + max_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 prev_value = 8; // 8 is the initial value for rle.
int i = 0; int i = 0;
assert(tokens != NULL); assert(tokens != NULL);
while (i < depth_size) { while (i < depth_size) {
const int value = depth[i]; const int value = tree->code_lengths[i];
int k = i + 1; int k = i + 1;
int runs; int runs;
while (k < depth_size && depth[k] == value) ++k; while (k < depth_size && tree->code_lengths[k] == value) ++k;
runs = k - i; runs = k - i;
if (value == 0) { if (value == 0) {
tokens = CodeRepeatedZeros(runs, tokens); tokens = CodeRepeatedZeros(runs, tokens);

View File

@ -26,11 +26,6 @@ typedef struct {
uint8_t extra_bits; // extra bits for escape codes uint8_t extra_bits; // extra bits for escape codes
} HuffmanTreeToken; } 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). // Struct to represent the tree codes (depth and bits array).
typedef struct { typedef struct {
int num_symbols; // Number of symbols. int num_symbols; // Number of symbols.
@ -38,6 +33,11 @@ typedef struct {
uint16_t* codes; // Symbol Codes. uint16_t* codes; // Symbol Codes.
} HuffmanTreeCode; } 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. // Create an optimized tree, and tokenize it.
int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit, int VP8LCreateHuffmanTree(int* const histogram, int tree_depth_limit,
HuffmanTreeCode* const tree); HuffmanTreeCode* const tree);