Make the brotli decoder more C90-compatible.
(1) Move all variable declarations to the beginning of the block. (2) Remove 'z' printf modifiers. (3) Fix 'comma at the end of enumeration list' warning.
This commit is contained in:
@@ -90,7 +90,7 @@ enum ContextType {
|
|||||||
CONTEXT_SIGNED_2BIT = 9,
|
CONTEXT_SIGNED_2BIT = 9,
|
||||||
CONTEXT_SIGNED_3BIT = 10,
|
CONTEXT_SIGNED_3BIT = 10,
|
||||||
CONTEXT_SIGNED_4BIT = 11,
|
CONTEXT_SIGNED_4BIT = 11,
|
||||||
CONTEXT_SIGNED_MIXED_3BYTE = 12,
|
CONTEXT_SIGNED_MIXED_3BYTE = 12
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kContextSize[] = {
|
static const int kContextSize[] = {
|
||||||
|
|||||||
+176
-148
@@ -28,10 +28,10 @@ extern "C" {
|
|||||||
|
|
||||||
#ifdef BROTLI_DECODE_DEBUG
|
#ifdef BROTLI_DECODE_DEBUG
|
||||||
#define BROTLI_LOG_UINT(name) \
|
#define BROTLI_LOG_UINT(name) \
|
||||||
printf("[%s] %s = %zd\n", __func__, #name, (size_t)name)
|
printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)name)
|
||||||
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
|
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
|
||||||
printf("[%s] %s[%zd] = %zd\n", __func__, #array_name, \
|
printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
|
||||||
(size_t)idx, (size_t)array_name[idx])
|
(unsigned long)idx, (unsigned long)array_name[idx])
|
||||||
#else
|
#else
|
||||||
#define BROTLI_LOG_UINT(name)
|
#define BROTLI_LOG_UINT(name)
|
||||||
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
|
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
|
||||||
@@ -63,8 +63,8 @@ static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = {
|
|||||||
|
|
||||||
static int DecodeSize(BrotliBitReader* br, size_t* len) {
|
static int DecodeSize(BrotliBitReader* br, size_t* len) {
|
||||||
int size_bytes = BrotliReadBits(br, 3);
|
int size_bytes = BrotliReadBits(br, 3);
|
||||||
*len = 0;
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
*len = 0;
|
||||||
for (; i < size_bytes; ++i) {
|
for (; i < size_bytes; ++i) {
|
||||||
*len |= BrotliReadBits(br, 8) << (i * 8);
|
*len |= BrotliReadBits(br, 8) << (i * 8);
|
||||||
}
|
}
|
||||||
@@ -78,19 +78,20 @@ static int DecodeMetaBlockLength(int input_size_bits,
|
|||||||
if (BrotliReadBits(br, 1)) {
|
if (BrotliReadBits(br, 1)) {
|
||||||
*meta_block_length = remaining_length;
|
*meta_block_length = remaining_length;
|
||||||
return 1;
|
return 1;
|
||||||
|
} else {
|
||||||
|
int shift = 0;
|
||||||
|
*meta_block_length = 0;
|
||||||
|
while (input_size_bits > 0) {
|
||||||
|
*meta_block_length |= BrotliReadBits(br, 8) << shift;
|
||||||
|
input_size_bits -= 8;
|
||||||
|
shift += 8;
|
||||||
|
}
|
||||||
|
if (input_size_bits > 0) {
|
||||||
|
*meta_block_length |= BrotliReadBits(br, input_size_bits) << shift;
|
||||||
|
}
|
||||||
|
++(*meta_block_length);
|
||||||
|
return !br->error_;
|
||||||
}
|
}
|
||||||
*meta_block_length = 0;
|
|
||||||
int shift = 0;
|
|
||||||
while (input_size_bits > 0) {
|
|
||||||
*meta_block_length |= BrotliReadBits(br, 8) << shift;
|
|
||||||
input_size_bits -= 8;
|
|
||||||
shift += 8;
|
|
||||||
}
|
|
||||||
if (input_size_bits > 0) {
|
|
||||||
*meta_block_length |= BrotliReadBits(br, input_size_bits) << shift;
|
|
||||||
}
|
|
||||||
++(*meta_block_length);
|
|
||||||
return !br->error_;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Decodes the next Huffman code from bit-stream.
|
// Decodes the next Huffman code from bit-stream.
|
||||||
@@ -100,30 +101,31 @@ static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
|
|||||||
BrotliBitReader* br) {
|
BrotliBitReader* br) {
|
||||||
if (tree->fixed_bit_length_ > 0) {
|
if (tree->fixed_bit_length_ > 0) {
|
||||||
return BrotliReadBits(br, tree->fixed_bit_length_);
|
return BrotliReadBits(br, tree->fixed_bit_length_);
|
||||||
}
|
} else {
|
||||||
const HuffmanTreeNode* node = tree->root_;
|
const HuffmanTreeNode* node = tree->root_;
|
||||||
uint32_t bits = BrotliPrefetchBits(br);
|
uint32_t bits = BrotliPrefetchBits(br);
|
||||||
int bitpos = br->bit_pos_;
|
int bitpos = br->bit_pos_;
|
||||||
// Check if we find the bit combination from the Huffman lookup table.
|
// Check if we find the bit combination from the Huffman lookup table.
|
||||||
const int lut_ix = bits & (HUFF_LUT - 1);
|
const int lut_ix = bits & (HUFF_LUT - 1);
|
||||||
const int lut_bits = tree->lut_bits_[lut_ix];
|
const int lut_bits = tree->lut_bits_[lut_ix];
|
||||||
if (lut_bits <= HUFF_LUT_BITS) {
|
if (lut_bits <= HUFF_LUT_BITS) {
|
||||||
BrotliSetBitPos(br, bitpos + lut_bits);
|
BrotliSetBitPos(br, bitpos + lut_bits);
|
||||||
return tree->lut_symbol_[lut_ix];
|
return tree->lut_symbol_[lut_ix];
|
||||||
}
|
}
|
||||||
node += tree->lut_jump_[lut_ix];
|
node += tree->lut_jump_[lut_ix];
|
||||||
bitpos += HUFF_LUT_BITS;
|
bitpos += HUFF_LUT_BITS;
|
||||||
bits >>= HUFF_LUT_BITS;
|
bits >>= HUFF_LUT_BITS;
|
||||||
|
|
||||||
// Decode the value from a binary tree.
|
// Decode the value from a binary tree.
|
||||||
assert(node != NULL);
|
assert(node != NULL);
|
||||||
do {
|
do {
|
||||||
node = HuffmanTreeNextNode(node, bits & 1);
|
node = HuffmanTreeNextNode(node, bits & 1);
|
||||||
bits >>= 1;
|
bits >>= 1;
|
||||||
++bitpos;
|
++bitpos;
|
||||||
} while (HuffmanTreeNodeIsNotLeaf(node));
|
} while (HuffmanTreeNodeIsNotLeaf(node));
|
||||||
BrotliSetBitPos(br, bitpos);
|
BrotliSetBitPos(br, bitpos);
|
||||||
return node->symbol_;
|
return node->symbol_;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void PrintIntVector(const int* v, int len) {
|
static void PrintIntVector(const int* v, int len) {
|
||||||
@@ -138,6 +140,7 @@ static int ReadHuffmanCodeLengths(
|
|||||||
int ok = 0;
|
int ok = 0;
|
||||||
int symbol;
|
int symbol;
|
||||||
int max_symbol;
|
int max_symbol;
|
||||||
|
int decode_number_of_code_length_codes;
|
||||||
int prev_code_len = kDefaultCodeLength;
|
int prev_code_len = kDefaultCodeLength;
|
||||||
HuffmanTree tree;
|
HuffmanTree tree;
|
||||||
|
|
||||||
@@ -148,9 +151,9 @@ static int ReadHuffmanCodeLengths(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int use_length = BrotliReadBits(br, 1);
|
decode_number_of_code_length_codes = BrotliReadBits(br, 1);
|
||||||
BROTLI_LOG_UINT(use_length);
|
BROTLI_LOG_UINT(decode_number_of_code_length_codes);
|
||||||
if (use_length) {
|
if (decode_number_of_code_length_codes) {
|
||||||
const int length_nbits = 2 + 2 * BrotliReadBits(br, 3);
|
const int length_nbits = 2 + 2 * BrotliReadBits(br, 3);
|
||||||
max_symbol = 2 + BrotliReadBits(br, length_nbits);
|
max_symbol = 2 + BrotliReadBits(br, length_nbits);
|
||||||
BROTLI_LOG_UINT(length_nbits);
|
BROTLI_LOG_UINT(length_nbits);
|
||||||
@@ -220,6 +223,7 @@ static int RepairHuffmanCodeLengths(int num_symbols, int* code_lengths) {
|
|||||||
return 1;
|
return 1;
|
||||||
if (space < 0) {
|
if (space < 0) {
|
||||||
int count_longest = 0;
|
int count_longest = 0;
|
||||||
|
int new_length = max_length;
|
||||||
for(i = 0; i < num_symbols; i++) {
|
for(i = 0; i < num_symbols; i++) {
|
||||||
if (code_lengths[i] == max_length)
|
if (code_lengths[i] == max_length)
|
||||||
count_longest++;
|
count_longest++;
|
||||||
@@ -230,7 +234,6 @@ static int RepairHuffmanCodeLengths(int num_symbols, int* code_lengths) {
|
|||||||
space += count_longest * (kUnitInterval >> max_length);
|
space += count_longest * (kUnitInterval >> max_length);
|
||||||
if (space < 0)
|
if (space < 0)
|
||||||
return 0;
|
return 0;
|
||||||
int new_length = max_length;
|
|
||||||
while (space < count_longest * (kUnitInterval >> new_length))
|
while (space < count_longest * (kUnitInterval >> new_length))
|
||||||
new_length++;
|
new_length++;
|
||||||
space -= count_longest * (kUnitInterval >> new_length);
|
space -= count_longest * (kUnitInterval >> new_length);
|
||||||
@@ -332,25 +335,31 @@ static int ReadCopyDistance(const HuffmanTree* tree,
|
|||||||
int postfix_bits,
|
int postfix_bits,
|
||||||
uint32_t postfix_mask,
|
uint32_t postfix_mask,
|
||||||
BrotliBitReader* br) {
|
BrotliBitReader* br) {
|
||||||
|
int code;
|
||||||
|
int nbits;
|
||||||
|
int postfix;
|
||||||
|
int offset;
|
||||||
BrotliFillBitWindow(br);
|
BrotliFillBitWindow(br);
|
||||||
int code = ReadSymbol(tree, br);
|
code = ReadSymbol(tree, br);
|
||||||
if (code < num_direct_codes) {
|
if (code < num_direct_codes) {
|
||||||
return code;
|
return code;
|
||||||
}
|
}
|
||||||
code -= num_direct_codes;
|
code -= num_direct_codes;
|
||||||
int postfix = code & postfix_mask;
|
postfix = code & postfix_mask;
|
||||||
code >>= postfix_bits;
|
code >>= postfix_bits;
|
||||||
int nbits = (code >> 1) + 1;
|
nbits = (code >> 1) + 1;
|
||||||
int offset = ((2 + (code & 1)) << nbits) - 4;
|
offset = ((2 + (code & 1)) << nbits) - 4;
|
||||||
return (num_direct_codes +
|
return (num_direct_codes +
|
||||||
((offset + BrotliReadBits(br, nbits)) << postfix_bits) +
|
((offset + BrotliReadBits(br, nbits)) << postfix_bits) +
|
||||||
postfix);
|
postfix);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ReadBlockLength(const HuffmanTree* tree, BrotliBitReader* br) {
|
static int ReadBlockLength(const HuffmanTree* tree, BrotliBitReader* br) {
|
||||||
|
int code;
|
||||||
|
int nbits;
|
||||||
BrotliFillBitWindow(br);
|
BrotliFillBitWindow(br);
|
||||||
int code = ReadSymbol(tree, br);
|
code = ReadSymbol(tree, br);
|
||||||
int nbits = kBlockLengthPrefixCode[code].nbits;
|
nbits = kBlockLengthPrefixCode[code].nbits;
|
||||||
return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);
|
return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -359,17 +368,21 @@ static void ReadInsertAndCopy(const HuffmanTree* tree,
|
|||||||
int* copy_len,
|
int* copy_len,
|
||||||
int* copy_dist,
|
int* copy_dist,
|
||||||
BrotliBitReader* br) {
|
BrotliBitReader* br) {
|
||||||
|
int code;
|
||||||
|
int range_idx;
|
||||||
|
int insert_code;
|
||||||
|
int copy_code;
|
||||||
BrotliFillBitWindow(br);
|
BrotliFillBitWindow(br);
|
||||||
int code = ReadSymbol(tree, br);
|
code = ReadSymbol(tree, br);
|
||||||
int range_idx = code >> 6;
|
range_idx = code >> 6;
|
||||||
if (range_idx >= 2) {
|
if (range_idx >= 2) {
|
||||||
range_idx -= 2;
|
range_idx -= 2;
|
||||||
*copy_dist = -1;
|
*copy_dist = -1;
|
||||||
} else {
|
} else {
|
||||||
*copy_dist = 0;
|
*copy_dist = 0;
|
||||||
}
|
}
|
||||||
int insert_code = (kInsertRangeLut[range_idx] << 3) + ((code >> 3) & 7);
|
insert_code = (kInsertRangeLut[range_idx] << 3) + ((code >> 3) & 7);
|
||||||
int copy_code = (kCopyRangeLut[range_idx] << 3) + (code & 7);
|
copy_code = (kCopyRangeLut[range_idx] << 3) + (code & 7);
|
||||||
*insert_len =
|
*insert_len =
|
||||||
kInsertLengthPrefixCode[insert_code].offset +
|
kInsertLengthPrefixCode[insert_code].offset +
|
||||||
BrotliReadBits(br, kInsertLengthPrefixCode[insert_code].nbits);
|
BrotliReadBits(br, kInsertLengthPrefixCode[insert_code].nbits);
|
||||||
@@ -381,9 +394,8 @@ static void ReadInsertAndCopy(const HuffmanTree* tree,
|
|||||||
static int TranslateShortCodes(int code, int* ringbuffer, size_t* index) {
|
static int TranslateShortCodes(int code, int* ringbuffer, size_t* index) {
|
||||||
int val;
|
int val;
|
||||||
if (code < NUM_DISTANCE_SHORT_CODES) {
|
if (code < NUM_DISTANCE_SHORT_CODES) {
|
||||||
val = code;
|
int index_offset = kDistanceShortCodeIndexOffset[code];
|
||||||
int index_offset = kDistanceShortCodeIndexOffset[val];
|
int value_offset = kDistanceShortCodeValueOffset[code];
|
||||||
int value_offset = kDistanceShortCodeValueOffset[val];
|
|
||||||
val = ringbuffer[(*index + index_offset) & 3] + value_offset;
|
val = ringbuffer[(*index + index_offset) & 3] + value_offset;
|
||||||
} else {
|
} else {
|
||||||
val = code - NUM_DISTANCE_SHORT_CODES + 1;
|
val = code - NUM_DISTANCE_SHORT_CODES + 1;
|
||||||
@@ -453,6 +465,7 @@ static int DecodeContextMap(int num_block_types,
|
|||||||
int* num_htrees,
|
int* num_htrees,
|
||||||
uint8_t** context_map,
|
uint8_t** context_map,
|
||||||
BrotliBitReader* br) {
|
BrotliBitReader* br) {
|
||||||
|
int context_map_size;
|
||||||
int use_context = BrotliReadBits(br, 1);
|
int use_context = BrotliReadBits(br, 1);
|
||||||
if (!use_context) {
|
if (!use_context) {
|
||||||
*context_mode = 0;
|
*context_mode = 0;
|
||||||
@@ -471,7 +484,7 @@ static int DecodeContextMap(int num_block_types,
|
|||||||
*contexts_per_block = 4;
|
*contexts_per_block = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
int context_map_size = *contexts_per_block * num_block_types;
|
context_map_size = *contexts_per_block * num_block_types;
|
||||||
*num_htrees = BrotliReadBits(br, 8) + 1;
|
*num_htrees = BrotliReadBits(br, 8) + 1;
|
||||||
|
|
||||||
BROTLI_LOG_UINT(*context_mode);
|
BROTLI_LOG_UINT(*context_mode);
|
||||||
@@ -484,46 +497,51 @@ static int DecodeContextMap(int num_block_types,
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int i;
|
|
||||||
if (*num_htrees == context_map_size) {
|
if (*num_htrees == context_map_size) {
|
||||||
|
int i;
|
||||||
for (i = 0; i < context_map_size; ++i) {
|
for (i = 0; i < context_map_size; ++i) {
|
||||||
(*context_map)[i] = i;
|
(*context_map)[i] = i;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
int use_rle_for_zeros = BrotliReadBits(br, 1);
|
{
|
||||||
int max_run_length_prefix = 0;
|
HuffmanTree tree_index_htree;
|
||||||
if (use_rle_for_zeros) {
|
int use_rle_for_zeros = BrotliReadBits(br, 1);
|
||||||
max_run_length_prefix = BrotliReadBits(br, 4) + 1;
|
int max_run_length_prefix = 0;
|
||||||
}
|
if (use_rle_for_zeros) {
|
||||||
HuffmanTree tree_index_htree;
|
max_run_length_prefix = BrotliReadBits(br, 4) + 1;
|
||||||
ReadHuffmanCode(*num_htrees + max_run_length_prefix,
|
}
|
||||||
&tree_index_htree, br);
|
ReadHuffmanCode(*num_htrees + max_run_length_prefix,
|
||||||
if (use_rle_for_zeros) {
|
&tree_index_htree, br);
|
||||||
for (i = 0; i < context_map_size;) {
|
if (use_rle_for_zeros) {
|
||||||
BrotliFillBitWindow(br);
|
int i;
|
||||||
int code = ReadSymbol(&tree_index_htree, br);
|
for (i = 0; i < context_map_size;) {
|
||||||
if (code == 0) {
|
int code;
|
||||||
(*context_map)[i] = 0;
|
BrotliFillBitWindow(br);
|
||||||
++i;
|
code = ReadSymbol(&tree_index_htree, br);
|
||||||
} else if (code <= max_run_length_prefix) {
|
if (code == 0) {
|
||||||
int reps = 1 + (1 << code) + BrotliReadBits(br, code);
|
|
||||||
while (--reps) {
|
|
||||||
(*context_map)[i] = 0;
|
(*context_map)[i] = 0;
|
||||||
++i;
|
++i;
|
||||||
|
} else if (code <= max_run_length_prefix) {
|
||||||
|
int reps = 1 + (1 << code) + BrotliReadBits(br, code);
|
||||||
|
while (--reps) {
|
||||||
|
(*context_map)[i] = 0;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
(*context_map)[i] = code - max_run_length_prefix;
|
||||||
|
++i;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
(*context_map)[i] = code - max_run_length_prefix;
|
} else {
|
||||||
++i;
|
int i;
|
||||||
|
for (i = 0; i < context_map_size; ++i) {
|
||||||
|
BrotliFillBitWindow(br);
|
||||||
|
(*context_map)[i] = ReadSymbol(&tree_index_htree, br);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
BrotliHuffmanTreeRelease(&tree_index_htree);
|
||||||
for (i = 0; i < context_map_size; ++i) {
|
|
||||||
BrotliFillBitWindow(br);
|
|
||||||
(*context_map)[i] = ReadSymbol(&tree_index_htree, br);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
BrotliHuffmanTreeRelease(&tree_index_htree);
|
|
||||||
if (BrotliReadBits(br, 1)) {
|
if (BrotliReadBits(br, 1)) {
|
||||||
InverseMoveToFrontTransform(*context_map, context_map_size);
|
InverseMoveToFrontTransform(*context_map, context_map_size);
|
||||||
}
|
}
|
||||||
@@ -564,46 +582,40 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
const uint8_t* encoded_buffer,
|
const uint8_t* encoded_buffer,
|
||||||
size_t* decoded_size,
|
size_t* decoded_size,
|
||||||
uint8_t* decoded_buffer) {
|
uint8_t* decoded_buffer) {
|
||||||
BrotliBitReader br;
|
int ok = 1;
|
||||||
BrotliInitBitReader(&br, encoded_buffer, encoded_size);
|
|
||||||
|
|
||||||
int ok = DecodeSize(&br, decoded_size);
|
|
||||||
if (!ok) return 0;
|
|
||||||
|
|
||||||
if (*decoded_size == 0) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
size_t n = *decoded_size;
|
|
||||||
int input_size_bits = (n == (n &~ (n - 1))) ? -1 : 0;
|
|
||||||
while (n) {
|
|
||||||
++input_size_bits;
|
|
||||||
n >>= 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
BROTLI_LOG_UINT(*decoded_size);
|
|
||||||
BROTLI_LOG_UINT(input_size_bits);
|
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
size_t pos = 0;
|
size_t pos = 0;
|
||||||
const size_t end = *decoded_size;
|
|
||||||
uint8_t* data = decoded_buffer;
|
uint8_t* data = decoded_buffer;
|
||||||
|
int input_size_bits;
|
||||||
// This ring buffer holds a few past copy distances that will be used by
|
// This ring buffer holds a few past copy distances that will be used by
|
||||||
// some special distance codes.
|
// some special distance codes.
|
||||||
int dist_rb[4] = { 4, 11, 15, 16 };
|
int dist_rb[4] = { 4, 11, 15, 16 };
|
||||||
size_t dist_rb_idx = 0;
|
size_t dist_rb_idx = 0;
|
||||||
HuffmanTreeGroup hgroup[3];
|
HuffmanTreeGroup hgroup[3];
|
||||||
|
BrotliBitReader br;
|
||||||
|
BrotliInitBitReader(&br, encoded_buffer, encoded_size);
|
||||||
|
|
||||||
while (pos < end && ok) {
|
ok = DecodeSize(&br, decoded_size);
|
||||||
BROTLI_LOG_UINT(pos);
|
if (!ok) return 0;
|
||||||
size_t meta_block_len = 0;
|
|
||||||
if (!DecodeMetaBlockLength(input_size_bits, end - pos,
|
if (*decoded_size == 0) {
|
||||||
&br, &meta_block_len)) {
|
return 1;
|
||||||
printf("Could not decode meta-block length.\n");
|
}
|
||||||
ok = 0;
|
{
|
||||||
goto End;
|
size_t n = *decoded_size;
|
||||||
|
input_size_bits = (n == (n &~ (n - 1))) ? -1 : 0;
|
||||||
|
while (n) {
|
||||||
|
++input_size_bits;
|
||||||
|
n >>= 1;
|
||||||
}
|
}
|
||||||
BROTLI_LOG_UINT(meta_block_len);
|
}
|
||||||
size_t meta_block_end = pos + meta_block_len;
|
|
||||||
|
BROTLI_LOG_UINT(*decoded_size);
|
||||||
|
BROTLI_LOG_UINT(input_size_bits);
|
||||||
|
|
||||||
|
while (pos < *decoded_size && ok) {
|
||||||
|
size_t meta_block_len = 0;
|
||||||
|
size_t meta_block_end;
|
||||||
size_t block_length[3] = { 0 };
|
size_t block_length[3] = { 0 };
|
||||||
int block_type[3] = { 0 };
|
int block_type[3] = { 0 };
|
||||||
int num_block_types[3] = { 0 };
|
int num_block_types[3] = { 0 };
|
||||||
@@ -611,6 +623,34 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
size_t block_type_rb_index[3] = { 0 };
|
size_t block_type_rb_index[3] = { 0 };
|
||||||
HuffmanTree block_type_trees[3];
|
HuffmanTree block_type_trees[3];
|
||||||
HuffmanTree block_len_trees[3];
|
HuffmanTree block_len_trees[3];
|
||||||
|
int distance_postfix_bits;
|
||||||
|
int num_direct_distance_codes;
|
||||||
|
uint32_t distance_postfix_mask;
|
||||||
|
int num_distance_codes;
|
||||||
|
uint8_t* context_map = NULL;
|
||||||
|
int context_mode;
|
||||||
|
int contexts_per_block;
|
||||||
|
int num_literal_htrees;
|
||||||
|
uint8_t* dist_context_map = NULL;
|
||||||
|
int dist_context_mode;
|
||||||
|
int dist_contexts_per_block;
|
||||||
|
int num_dist_htrees;
|
||||||
|
int context_offset = 0;
|
||||||
|
uint8_t* context_map_slice = NULL;
|
||||||
|
uint8_t literal_htree_index = 0;
|
||||||
|
int dist_context_offset = 0;
|
||||||
|
uint8_t* dist_context_map_slice = NULL;
|
||||||
|
uint8_t dist_htree_index = 0;
|
||||||
|
|
||||||
|
BROTLI_LOG_UINT(pos);
|
||||||
|
if (!DecodeMetaBlockLength(input_size_bits, *decoded_size - pos,
|
||||||
|
&br, &meta_block_len)) {
|
||||||
|
printf("Could not decode meta-block length.\n");
|
||||||
|
ok = 0;
|
||||||
|
goto End;
|
||||||
|
}
|
||||||
|
BROTLI_LOG_UINT(meta_block_len);
|
||||||
|
meta_block_end = pos + meta_block_len;
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
block_type_trees[i].root_ = NULL;
|
block_type_trees[i].root_ = NULL;
|
||||||
block_len_trees[i].root_ = NULL;
|
block_len_trees[i].root_ = NULL;
|
||||||
@@ -633,27 +673,18 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
BROTLI_LOG_UINT(block_length[1]);
|
BROTLI_LOG_UINT(block_length[1]);
|
||||||
BROTLI_LOG_UINT(block_length[2]);
|
BROTLI_LOG_UINT(block_length[2]);
|
||||||
|
|
||||||
int distance_postfix_bits = BrotliReadBits(&br, 2);
|
distance_postfix_bits = BrotliReadBits(&br, 2);
|
||||||
int num_direct_distance_codes =
|
num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
|
||||||
NUM_DISTANCE_SHORT_CODES +
|
|
||||||
(BrotliReadBits(&br, 4) << distance_postfix_bits);
|
(BrotliReadBits(&br, 4) << distance_postfix_bits);
|
||||||
uint32_t distance_postfix_mask = (1 << distance_postfix_bits) - 1;
|
distance_postfix_mask = (1 << distance_postfix_bits) - 1;
|
||||||
int num_distance_codes = (num_direct_distance_codes +
|
num_distance_codes = (num_direct_distance_codes +
|
||||||
(48 << distance_postfix_bits));
|
(48 << distance_postfix_bits));
|
||||||
BROTLI_LOG_UINT(num_direct_distance_codes);
|
BROTLI_LOG_UINT(num_direct_distance_codes);
|
||||||
BROTLI_LOG_UINT(distance_postfix_bits);
|
BROTLI_LOG_UINT(distance_postfix_bits);
|
||||||
|
|
||||||
uint8_t* context_map;
|
|
||||||
int context_mode;
|
|
||||||
int contexts_per_block;
|
|
||||||
int num_literal_htrees;
|
|
||||||
DecodeContextMap(num_block_types[0], 0, &context_mode, &contexts_per_block,
|
DecodeContextMap(num_block_types[0], 0, &context_mode, &contexts_per_block,
|
||||||
&num_literal_htrees, &context_map, &br);
|
&num_literal_htrees, &context_map, &br);
|
||||||
|
|
||||||
uint8_t* dist_context_map;
|
|
||||||
int dist_context_mode;
|
|
||||||
int dist_contexts_per_block;
|
|
||||||
int num_dist_htrees;
|
|
||||||
DecodeContextMap(num_block_types[2], 2, &dist_context_mode,
|
DecodeContextMap(num_block_types[2], 2, &dist_context_mode,
|
||||||
&dist_contexts_per_block,
|
&dist_contexts_per_block,
|
||||||
&num_dist_htrees, &dist_context_map, &br);
|
&num_dist_htrees, &dist_context_map, &br);
|
||||||
@@ -667,30 +698,26 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
HuffmanTreeGroupDecode(&hgroup[i], &br);
|
HuffmanTreeGroupDecode(&hgroup[i], &br);
|
||||||
}
|
}
|
||||||
|
|
||||||
HuffmanTree* literal_htrees = hgroup[0].htrees;
|
context_map_slice = context_map;
|
||||||
int context_offset = 0;
|
dist_context_map_slice = dist_context_map;
|
||||||
uint8_t* context_map_slice = context_map;
|
|
||||||
uint8_t literal_htree_index = 0;
|
|
||||||
int dist_context_offset = 0;
|
|
||||||
uint8_t* dist_context_map_slice = dist_context_map;
|
|
||||||
uint8_t dist_htree_index = 0;
|
|
||||||
|
|
||||||
while (pos < meta_block_end) {
|
while (pos < meta_block_end) {
|
||||||
|
int insert_length;
|
||||||
|
int copy_length;
|
||||||
|
int distance_code;
|
||||||
|
int distance;
|
||||||
|
int j;
|
||||||
if (block_length[1] == 0) {
|
if (block_length[1] == 0) {
|
||||||
DecodeBlockType(block_type_trees, 1, block_type, block_type_rb,
|
DecodeBlockType(block_type_trees, 1, block_type, block_type_rb,
|
||||||
block_type_rb_index, &br);
|
block_type_rb_index, &br);
|
||||||
block_length[1] = ReadBlockLength(&block_len_trees[1], &br);
|
block_length[1] = ReadBlockLength(&block_len_trees[1], &br);
|
||||||
}
|
}
|
||||||
--block_length[1];
|
--block_length[1];
|
||||||
int insert_length;
|
|
||||||
int copy_length;
|
|
||||||
int distance_code;
|
|
||||||
ReadInsertAndCopy(&hgroup[1].htrees[block_type[1]],
|
ReadInsertAndCopy(&hgroup[1].htrees[block_type[1]],
|
||||||
&insert_length, ©_length, &distance_code, &br);
|
&insert_length, ©_length, &distance_code, &br);
|
||||||
BROTLI_LOG_UINT(insert_length);
|
BROTLI_LOG_UINT(insert_length);
|
||||||
BROTLI_LOG_UINT(copy_length);
|
BROTLI_LOG_UINT(copy_length);
|
||||||
BROTLI_LOG_UINT(distance_code);
|
BROTLI_LOG_UINT(distance_code);
|
||||||
int j;
|
|
||||||
for (j = 0; j < insert_length; ++j) {
|
for (j = 0; j < insert_length; ++j) {
|
||||||
if (block_length[0] == 0) {
|
if (block_length[0] == 0) {
|
||||||
DecodeBlockType(block_type_trees, 0, block_type, block_type_rb,
|
DecodeBlockType(block_type_trees, 0, block_type, block_type_rb,
|
||||||
@@ -712,7 +739,7 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
BROTLI_LOG_UINT(context);
|
BROTLI_LOG_UINT(context);
|
||||||
literal_htree_index = context_map_slice[context];
|
literal_htree_index = context_map_slice[context];
|
||||||
}
|
}
|
||||||
data[pos] = ReadSymbol(&literal_htrees[literal_htree_index], &br);
|
data[pos] = ReadSymbol(&hgroup[0].htrees[literal_htree_index], &br);
|
||||||
BROTLI_LOG_UINT(literal_htree_index);
|
BROTLI_LOG_UINT(literal_htree_index);
|
||||||
BROTLI_LOG_ARRAY_INDEX(data, pos);
|
BROTLI_LOG_ARRAY_INDEX(data, pos);
|
||||||
++pos;
|
++pos;
|
||||||
@@ -753,20 +780,21 @@ int BrotliDecompressBuffer(size_t encoded_size,
|
|||||||
|
|
||||||
// Convert the distance code to the actual distance by possibly looking
|
// Convert the distance code to the actual distance by possibly looking
|
||||||
// up past distnaces from the ringbuffer.
|
// up past distnaces from the ringbuffer.
|
||||||
int dist = TranslateShortCodes(distance_code, dist_rb, &dist_rb_idx);
|
distance = TranslateShortCodes(distance_code, dist_rb, &dist_rb_idx);
|
||||||
BROTLI_LOG_UINT(dist);
|
BROTLI_LOG_UINT(distance);
|
||||||
|
|
||||||
// Do the actual copy if it is valid.
|
// Do the actual copy if it is valid.
|
||||||
if (pos >= dist && pos + copy_length <= end) {
|
if (distance > 0 && pos >= (size_t)distance &&
|
||||||
|
pos + copy_length <= *decoded_size) {
|
||||||
int j;
|
int j;
|
||||||
for (j = 0; j < copy_length; ++j) {
|
for (j = 0; j < copy_length; ++j) {
|
||||||
data[pos + j] = data[pos + j - dist];
|
data[pos + j] = data[pos + j - distance];
|
||||||
}
|
}
|
||||||
pos += copy_length;
|
pos += copy_length;
|
||||||
} else {
|
} else {
|
||||||
printf("Invalid backward reference. pos: %zd dist: %d "
|
printf("Invalid backward reference. pos: %lu distance: %d "
|
||||||
"len: %d end:%zd\n",
|
"len: %d end: %lu\n", (unsigned long)pos, distance, copy_length,
|
||||||
pos, dist, copy_length, end);
|
(unsigned long)*decoded_size);
|
||||||
ok = 0;
|
ok = 0;
|
||||||
goto End;
|
goto End;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user