Fix -Wconversion compiler warnings in the brotli decoder.

This commit is contained in:
Zoltan Szabadka
2014-01-08 12:34:35 +01:00
parent 4c8c7fd31c
commit dfc5a9f215
6 changed files with 135 additions and 111 deletions
+3 -2
View File
@@ -28,11 +28,12 @@ int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) {
size_t i; size_t i;
assert(br != NULL); assert(br != NULL);
br->buf_ptr_ = br->buf_;
br->input_ = input; br->input_ = input;
br->val_ = 0; br->val_ = 0;
br->pos_ = 0; br->pos_ = 0;
br->bit_pos_ = 0; br->bit_pos_ = 0;
br->end_pos_ = 0; br->bits_left_ = 64;
br->eos_ = 0; br->eos_ = 0;
if (!BrotliReadMoreInput(br)) { if (!BrotliReadMoreInput(br)) {
return 0; return 0;
@@ -41,7 +42,7 @@ int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input) {
br->val_ |= ((uint64_t)br->buf_[br->pos_]) << (8 * i); br->val_ |= ((uint64_t)br->buf_[br->pos_]) << (8 * i);
++br->pos_; ++br->pos_;
} }
return (br->end_pos_ > 0); return (br->bits_left_ > 64);
} }
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
+21 -14
View File
@@ -42,12 +42,13 @@ typedef struct {
/* Input byte buffer, consist of a ringbuffer and a "slack" region where */ /* Input byte buffer, consist of a ringbuffer and a "slack" region where */
/* bytes from the start of the ringbuffer are copied. */ /* bytes from the start of the ringbuffer are copied. */
uint8_t buf_[BROTLI_IBUF_SIZE]; uint8_t buf_[BROTLI_IBUF_SIZE];
BrotliInput input_; /* input callback */ uint8_t* buf_ptr_; /* next input will write here */
uint64_t val_; /* pre-fetched bits */ BrotliInput input_; /* input callback */
size_t pos_; /* byte position in stream */ uint64_t val_; /* pre-fetched bits */
int bit_pos_; /* current bit-reading position in val_ */ uint32_t pos_; /* byte position in stream */
size_t end_pos_; /* current end position in stream */ uint32_t bit_pos_; /* current bit-reading position in val_ */
int eos_; /* input stream is finished */ uint32_t bits_left_; /* how many valid bits left */
int eos_; /* input stream is finished */
} BrotliBitReader; } BrotliBitReader;
int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input); int BrotliInitBitReader(BrotliBitReader* const br, BrotliInput input);
@@ -59,9 +60,10 @@ static BROTLI_INLINE uint32_t BrotliPrefetchBits(BrotliBitReader* const br) {
/* For jumping over a number of bits in the bit stream when accessed with */ /* For jumping over a number of bits in the bit stream when accessed with */
/* BrotliPrefetchBits and BrotliFillBitWindow. */ /* BrotliPrefetchBits and BrotliFillBitWindow. */
static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br, int val) { static BROTLI_INLINE void BrotliSetBitPos(BrotliBitReader* const br,
uint32_t val) {
#ifdef BROTLI_DECODE_DEBUG #ifdef BROTLI_DECODE_DEBUG
int n_bits = val - br->bit_pos_; uint32_t n_bits = val - br->bit_pos_;
const uint32_t bval = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits]; const uint32_t bval = (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits];
printf("[BrotliReadBits] %010ld %2d val: %6x\n", printf("[BrotliReadBits] %010ld %2d val: %6x\n",
(br->pos_ << 3) + br->bit_pos_ - 64, n_bits, bval); (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, bval);
@@ -76,6 +78,7 @@ static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) {
br->val_ |= ((uint64_t)br->buf_[br->pos_ & BROTLI_IBUF_MASK]) << 56; br->val_ |= ((uint64_t)br->buf_[br->pos_ & BROTLI_IBUF_MASK]) << 56;
++br->pos_; ++br->pos_;
br->bit_pos_ -= 8; br->bit_pos_ -= 8;
br->bits_left_ -= 8;
} }
} }
@@ -92,12 +95,12 @@ static BROTLI_INLINE void ShiftBytes(BrotliBitReader* const br) {
every 32 bytes of input is read. every 32 bytes of input is read.
*/ */
static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) { static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
if (br->pos_ + 32 < br->end_pos_) { if (br->bits_left_ > 320) {
return 1; return 1;
} else if (br->eos_) { } else if (br->eos_) {
return (br->pos_ << 3) + br->bit_pos_ <= (br->end_pos_ << 3) + 64; return br->bit_pos_ <= br->bits_left_;
} else { } else {
uint8_t* dst = br->buf_ + (br->end_pos_ & BROTLI_IBUF_MASK); uint8_t* dst = br->buf_ptr_;
int bytes_read = BrotliRead(br->input_, dst, BROTLI_READ_SIZE); int bytes_read = BrotliRead(br->input_, dst, BROTLI_READ_SIZE);
if (bytes_read < 0) { if (bytes_read < 0) {
return 0; return 0;
@@ -124,8 +127,11 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) {
#else #else
memcpy(br->buf_ + (BROTLI_READ_SIZE << 1), br->buf_, 32); memcpy(br->buf_ + (BROTLI_READ_SIZE << 1), br->buf_, 32);
#endif #endif
br->buf_ptr_ = br->buf_ + BROTLI_READ_SIZE;
} else {
br->buf_ptr_ = br->buf_;
} }
br->end_pos_ += bytes_read; br->bits_left_ += ((uint32_t)bytes_read << 3);
return 1; return 1;
} }
} }
@@ -135,12 +141,13 @@ static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) {
if (br->bit_pos_ >= 40) { if (br->bit_pos_ >= 40) {
#if (defined(__x86_64__) || defined(_M_X64)) #if (defined(__x86_64__) || defined(_M_X64))
br->val_ >>= 40; br->val_ >>= 40;
br->bit_pos_ -= 40;
/* The expression below needs a little-endian arch to work correctly. */ /* The expression below needs a little-endian arch to work correctly. */
/* This gives a large speedup for decoding speed. */ /* This gives a large speedup for decoding speed. */
br->val_ |= *(const uint64_t*)( br->val_ |= *(const uint64_t*)(
br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24; br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24;
br->pos_ += 5; br->pos_ += 5;
br->bit_pos_ -= 40;
br->bits_left_ -= 40;
#else #else
ShiftBytes(br); ShiftBytes(br);
#endif #endif
@@ -158,7 +165,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
printf("[BrotliReadBits] %010ld %2d val: %6x\n", printf("[BrotliReadBits] %010ld %2d val: %6x\n",
(br->pos_ << 3) + br->bit_pos_ - 64, n_bits, val); (br->pos_ << 3) + br->bit_pos_ - 64, n_bits, val);
#endif #endif
br->bit_pos_ += n_bits; br->bit_pos_ += (uint32_t)n_bits;
return val; return val;
} }
+107 -91
View File
@@ -38,8 +38,8 @@ extern "C" {
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) #define BROTLI_LOG_ARRAY_INDEX(array_name, idx)
#endif #endif
static const int kDefaultCodeLength = 8; static const uint8_t kDefaultCodeLength = 8;
static const int kCodeLengthRepeatCode = 16; static const uint8_t kCodeLengthRepeatCode = 16;
static const int kNumLiteralCodes = 256; static const int kNumLiteralCodes = 256;
static const int kNumInsertAndCopyCodes = 704; static const int kNumInsertAndCopyCodes = 704;
static const int kNumBlockLengthCodes = 26; static const int kNumBlockLengthCodes = 26;
@@ -62,7 +62,7 @@ static const int kDistanceShortCodeValueOffset[NUM_DISTANCE_SHORT_CODES] = {
static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) { static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) {
if (BrotliReadBits(br, 1)) { if (BrotliReadBits(br, 1)) {
return 17 + BrotliReadBits(br, 3); return 17 + (int)BrotliReadBits(br, 3);
} else { } else {
return 16; return 16;
} }
@@ -71,35 +71,35 @@ static BROTLI_INLINE int DecodeWindowBits(BrotliBitReader* br) {
/* Decodes a number in the range [0..255], by reading 1 - 11 bits. */ /* Decodes a number in the range [0..255], by reading 1 - 11 bits. */
static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) { static BROTLI_INLINE int DecodeVarLenUint8(BrotliBitReader* br) {
if (BrotliReadBits(br, 1)) { if (BrotliReadBits(br, 1)) {
int nbits = BrotliReadBits(br, 3); int nbits = (int)BrotliReadBits(br, 3);
if (nbits == 0) { if (nbits == 0) {
return 1; return 1;
} else { } else {
return BrotliReadBits(br, nbits) + (1 << nbits); return (int)BrotliReadBits(br, nbits) + (1 << nbits);
} }
} }
return 0; return 0;
} }
static void DecodeMetaBlockLength(BrotliBitReader* br, static void DecodeMetaBlockLength(BrotliBitReader* br,
size_t* meta_block_length, int* meta_block_length,
int* input_end, int* input_end,
int* is_uncompressed) { int* is_uncompressed) {
int size_nibbles; int size_nibbles;
int i; int i;
*input_end = BrotliReadBits(br, 1); *input_end = (int)BrotliReadBits(br, 1);
*meta_block_length = 0; *meta_block_length = 0;
*is_uncompressed = 0; *is_uncompressed = 0;
if (*input_end && BrotliReadBits(br, 1)) { if (*input_end && BrotliReadBits(br, 1)) {
return; return;
} }
size_nibbles = BrotliReadBits(br, 2) + 4; size_nibbles = (int)BrotliReadBits(br, 2) + 4;
for (i = 0; i < size_nibbles; ++i) { for (i = 0; i < size_nibbles; ++i) {
*meta_block_length |= BrotliReadBits(br, 4) << (i * 4); *meta_block_length |= (int)BrotliReadBits(br, 4) << (i * 4);
} }
++(*meta_block_length); ++(*meta_block_length);
if (!*input_end) { if (!*input_end) {
*is_uncompressed = BrotliReadBits(br, 1); *is_uncompressed = (int)BrotliReadBits(br, 1);
} }
} }
@@ -107,9 +107,9 @@ static void DecodeMetaBlockLength(BrotliBitReader* br,
static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree, static BROTLI_INLINE int ReadSymbol(const HuffmanTree* tree,
BrotliBitReader* br) { BrotliBitReader* br) {
uint32_t bits; uint32_t bits;
int bitpos; uint32_t bitpos;
int lut_ix; int lut_ix;
int lut_bits; uint8_t lut_bits;
const HuffmanTreeNode* node = tree->root_; const HuffmanTreeNode* node = tree->root_;
BrotliFillBitWindow(br); BrotliFillBitWindow(br);
bits = BrotliPrefetchBits(br); bits = BrotliPrefetchBits(br);
@@ -147,9 +147,9 @@ static int ReadHuffmanCodeLengths(
BrotliBitReader* br) { BrotliBitReader* br) {
int ok = 0; int ok = 0;
int symbol; int symbol;
int prev_code_len = kDefaultCodeLength; uint8_t prev_code_len = kDefaultCodeLength;
int repeat = 0; int repeat = 0;
int repeat_length = 0; uint8_t repeat_length = 0;
int space = 32768; int space = 32768;
HuffmanTree tree; HuffmanTree tree;
@@ -167,12 +167,12 @@ static int ReadHuffmanCodeLengths(
symbol = 0; symbol = 0;
while (symbol + repeat < num_symbols && space > 0) { while (symbol + repeat < num_symbols && space > 0) {
int code_len; uint8_t code_len;
if (!BrotliReadMoreInput(br)) { if (!BrotliReadMoreInput(br)) {
printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n"); printf("[ReadHuffmanCodeLengths] Unexpected end of input.\n");
goto End; goto End;
} }
code_len = ReadSymbol(&tree, br); code_len = (uint8_t)ReadSymbol(&tree, br);
BROTLI_LOG_UINT(symbol); BROTLI_LOG_UINT(symbol);
BROTLI_LOG_UINT(repeat); BROTLI_LOG_UINT(repeat);
BROTLI_LOG_UINT(repeat_length); BROTLI_LOG_UINT(repeat_length);
@@ -198,7 +198,7 @@ static int ReadHuffmanCodeLengths(
repeat -= 2; repeat -= 2;
repeat <<= extra_bits; repeat <<= extra_bits;
} }
repeat += BrotliReadBits(br, extra_bits) + 3; repeat += (int)BrotliReadBits(br, extra_bits) + 3;
if (repeat + symbol > num_symbols) { if (repeat + symbol > num_symbols) {
goto End; goto End;
} }
@@ -250,21 +250,22 @@ static int ReadHuffmanCode(int alphabet_size,
/* simple_code_or_skip is used as follows: /* simple_code_or_skip is used as follows:
1 for simple code; 1 for simple code;
0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */ 0 for no skipping, 2 skips 2 code lengths, 3 skips 3 code lengths */
simple_code_or_skip = BrotliReadBits(br, 2); simple_code_or_skip = (int)BrotliReadBits(br, 2);
BROTLI_LOG_UINT(simple_code_or_skip); BROTLI_LOG_UINT(simple_code_or_skip);
if (simple_code_or_skip == 1) { /* Read symbols, codes & code lengths directly. */ if (simple_code_or_skip == 1) {
/* Read symbols, codes & code lengths directly. */
int i; int i;
int max_bits_counter = alphabet_size - 1; int max_bits_counter = alphabet_size - 1;
int max_bits = 0; int max_bits = 0;
int symbols[4] = { 0 }; int symbols[4] = { 0 };
const int num_symbols = BrotliReadBits(br, 2) + 1; const int num_symbols = (int)BrotliReadBits(br, 2) + 1;
while (max_bits_counter) { while (max_bits_counter) {
max_bits_counter >>= 1; max_bits_counter >>= 1;
++max_bits; ++max_bits;
} }
memset(code_lengths, 0, alphabet_size); memset(code_lengths, 0, (size_t)alphabet_size);
for (i = 0; i < num_symbols; ++i) { for (i = 0; i < num_symbols; ++i) {
symbols[i] = BrotliReadBits(br, max_bits) % alphabet_size; symbols[i] = (int)BrotliReadBits(br, max_bits) % alphabet_size;
code_lengths[symbols[i]] = 2; code_lengths[symbols[i]] = 2;
} }
code_lengths[symbols[0]] = 1; code_lengths[symbols[0]] = 1;
@@ -292,13 +293,13 @@ static int ReadHuffmanCode(int alphabet_size,
for (i = simple_code_or_skip; for (i = simple_code_or_skip;
i < CODE_LENGTH_CODES && space > 0; ++i) { i < CODE_LENGTH_CODES && space > 0; ++i) {
int code_len_idx = kCodeLengthCodeOrder[i]; int code_len_idx = kCodeLengthCodeOrder[i];
int v = BrotliReadBits(br, 2); uint8_t v = (uint8_t)BrotliReadBits(br, 2);
if (v == 1) { if (v == 1) {
v = BrotliReadBits(br, 1); v = (uint8_t)BrotliReadBits(br, 1);
if (v == 0) { if (v == 0) {
v = 2; v = 2;
} else { } else {
v = BrotliReadBits(br, 1); v = (uint8_t)BrotliReadBits(br, 1);
if (v == 0) { if (v == 0) {
v = 1; v = 1;
} else { } else {
@@ -331,7 +332,7 @@ static int ReadHuffmanCode(int alphabet_size,
static int ReadCopyDistance(const HuffmanTree* tree, static int ReadCopyDistance(const HuffmanTree* tree,
int num_direct_codes, int num_direct_codes,
int postfix_bits, int postfix_bits,
uint32_t postfix_mask, int postfix_mask,
BrotliBitReader* br) { BrotliBitReader* br) {
int code; int code;
int nbits; int nbits;
@@ -347,7 +348,7 @@ static int ReadCopyDistance(const HuffmanTree* tree,
nbits = (code >> 1) + 1; nbits = (code >> 1) + 1;
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 + (int)BrotliReadBits(br, nbits)) << postfix_bits) +
postfix); postfix);
} }
@@ -356,7 +357,7 @@ static int ReadBlockLength(const HuffmanTree* tree, BrotliBitReader* br) {
int nbits; int nbits;
code = ReadSymbol(tree, br); code = ReadSymbol(tree, br);
nbits = kBlockLengthPrefixCode[code].nbits; nbits = kBlockLengthPrefixCode[code].nbits;
return kBlockLengthPrefixCode[code].offset + BrotliReadBits(br, nbits); return kBlockLengthPrefixCode[code].offset + (int)BrotliReadBits(br, nbits);
} }
static void ReadInsertAndCopy(const HuffmanTree* tree, static void ReadInsertAndCopy(const HuffmanTree* tree,
@@ -383,17 +384,17 @@ static void ReadInsertAndCopy(const HuffmanTree* tree,
*insert_len = kInsertLengthPrefixCode[insert_code].offset; *insert_len = kInsertLengthPrefixCode[insert_code].offset;
insert_extra_bits = kInsertLengthPrefixCode[insert_code].nbits; insert_extra_bits = kInsertLengthPrefixCode[insert_code].nbits;
if (insert_extra_bits > 0) { if (insert_extra_bits > 0) {
*insert_len += BrotliReadBits(br, insert_extra_bits); *insert_len += (int)BrotliReadBits(br, insert_extra_bits);
} }
*copy_len = kCopyLengthPrefixCode[copy_code].offset; *copy_len = kCopyLengthPrefixCode[copy_code].offset;
copy_extra_bits = kCopyLengthPrefixCode[copy_code].nbits; copy_extra_bits = kCopyLengthPrefixCode[copy_code].nbits;
if (copy_extra_bits > 0) { if (copy_extra_bits > 0) {
*copy_len += BrotliReadBits(br, copy_extra_bits); *copy_len += (int)BrotliReadBits(br, copy_extra_bits);
} }
} }
static size_t TranslateShortCodes(int code, int* ringbuffer, size_t index) { static int TranslateShortCodes(int code, int* ringbuffer, int index) {
size_t val; int val;
if (code < NUM_DISTANCE_SHORT_CODES) { if (code < NUM_DISTANCE_SHORT_CODES) {
index += kDistanceShortCodeIndexOffset[code]; index += kDistanceShortCodeIndexOffset[code];
index &= 3; index &= 3;
@@ -415,7 +416,7 @@ static void InverseMoveToFrontTransform(uint8_t* v, int v_len) {
uint8_t mtf[256]; uint8_t mtf[256];
int i; int i;
for (i = 0; i < 256; ++i) { for (i = 0; i < 256; ++i) {
mtf[i] = i; mtf[i] = (uint8_t)i;
} }
for (i = 0; i < v_len; ++i) { for (i = 0; i < v_len; ++i) {
uint8_t index = v[i]; uint8_t index = v[i];
@@ -436,7 +437,7 @@ static void HuffmanTreeGroupInit(HuffmanTreeGroup* group, int alphabet_size,
int i; int i;
group->alphabet_size = alphabet_size; group->alphabet_size = alphabet_size;
group->num_htrees = ntrees; group->num_htrees = ntrees;
group->htrees = (HuffmanTree*)malloc(sizeof(HuffmanTree) * ntrees); group->htrees = (HuffmanTree*)malloc(sizeof(HuffmanTree) * (size_t)ntrees);
for (i = 0; i < ntrees; ++i) { for (i = 0; i < ntrees; ++i) {
group->htrees[i].root_ = NULL; group->htrees[i].root_ = NULL;
} }
@@ -477,22 +478,22 @@ static int DecodeContextMap(int context_map_size,
BROTLI_LOG_UINT(context_map_size); BROTLI_LOG_UINT(context_map_size);
BROTLI_LOG_UINT(*num_htrees); BROTLI_LOG_UINT(*num_htrees);
*context_map = (uint8_t*)malloc(context_map_size); *context_map = (uint8_t*)malloc((size_t)context_map_size);
if (*context_map == 0) { if (*context_map == 0) {
return 0; return 0;
} }
if (*num_htrees <= 1) { if (*num_htrees <= 1) {
memset(*context_map, 0, context_map_size); memset(*context_map, 0, (size_t)context_map_size);
return 1; return 1;
} }
{ {
HuffmanTree tree_index_htree; HuffmanTree tree_index_htree;
int use_rle_for_zeros = BrotliReadBits(br, 1); int use_rle_for_zeros = (int)BrotliReadBits(br, 1);
int max_run_length_prefix = 0; int max_run_length_prefix = 0;
int i; int i;
if (use_rle_for_zeros) { if (use_rle_for_zeros) {
max_run_length_prefix = BrotliReadBits(br, 4) + 1; max_run_length_prefix = (int)BrotliReadBits(br, 4) + 1;
} }
if (!ReadHuffmanCode(*num_htrees + max_run_length_prefix, if (!ReadHuffmanCode(*num_htrees + max_run_length_prefix,
&tree_index_htree, br)) { &tree_index_htree, br)) {
@@ -510,7 +511,7 @@ static int DecodeContextMap(int context_map_size,
(*context_map)[i] = 0; (*context_map)[i] = 0;
++i; ++i;
} else if (code <= max_run_length_prefix) { } else if (code <= max_run_length_prefix) {
int reps = 1 + (1 << code) + BrotliReadBits(br, code); int reps = 1 + (1 << code) + (int)BrotliReadBits(br, code);
while (--reps) { while (--reps) {
if (i >= context_map_size) { if (i >= context_map_size) {
ok = 0; ok = 0;
@@ -520,7 +521,7 @@ static int DecodeContextMap(int context_map_size,
++i; ++i;
} }
} else { } else {
(*context_map)[i] = code - max_run_length_prefix; (*context_map)[i] = (uint8_t)(code - max_run_length_prefix);
++i; ++i;
} }
} }
@@ -538,10 +539,10 @@ static BROTLI_INLINE void DecodeBlockType(const int max_block_type,
int tree_type, int tree_type,
int* block_types, int* block_types,
int* ringbuffers, int* ringbuffers,
size_t* indexes, int* indexes,
BrotliBitReader* br) { BrotliBitReader* br) {
int* ringbuffer = ringbuffers + tree_type * 2; int* ringbuffer = ringbuffers + tree_type * 2;
size_t* index = indexes + tree_type; int* index = indexes + tree_type;
int type_code = ReadSymbol(trees + tree_type, br); int type_code = ReadSymbol(trees + tree_type, br);
int block_type; int block_type;
if (type_code == 0) { if (type_code == 0) {
@@ -595,7 +596,7 @@ static BROTLI_INLINE void IncrementalCopyFastPath(
if (src < dst) { if (src < dst) {
while (dst - src < 8) { while (dst - src < 8) {
UNALIGNED_COPY64(dst, src); UNALIGNED_COPY64(dst, src);
len -= dst - src; len -= (int)(dst - src);
dst += dst - src; dst += dst - src;
} }
} }
@@ -613,7 +614,7 @@ int BrotliDecompressedSize(size_t encoded_size,
BrotliMemInput memin; BrotliMemInput memin;
BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin); BrotliInput input = BrotliInitMemInput(encoded_buffer, encoded_size, &memin);
BrotliBitReader br; BrotliBitReader br;
size_t meta_block_len; int meta_block_len;
int input_end; int input_end;
int is_uncompressed; int is_uncompressed;
if (!BrotliInitBitReader(&br, input)) { if (!BrotliInitBitReader(&br, input)) {
@@ -624,7 +625,7 @@ int BrotliDecompressedSize(size_t encoded_size,
if (!input_end) { if (!input_end) {
return 0; return 0;
} }
*decoded_size = meta_block_len; *decoded_size = (size_t)meta_block_len;
return 1; return 1;
} }
@@ -644,18 +645,19 @@ int BrotliDecompressBuffer(size_t encoded_size,
int BrotliDecompress(BrotliInput input, BrotliOutput output) { int BrotliDecompress(BrotliInput input, BrotliOutput output) {
int ok = 1; int ok = 1;
int i; int i;
size_t pos = 0; int pos = 0;
int input_end = 0; int input_end = 0;
int window_bits = 0; int window_bits = 0;
size_t max_backward_distance; int max_backward_distance;
size_t ringbuffer_size; int max_distance = 0;
size_t ringbuffer_mask; int ringbuffer_size;
int ringbuffer_mask;
uint8_t* ringbuffer; uint8_t* ringbuffer;
uint8_t* ringbuffer_end; uint8_t* ringbuffer_end;
/* 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] = { 16, 15, 11, 4 }; int dist_rb[4] = { 16, 15, 11, 4 };
size_t dist_rb_idx = 0; int dist_rb_idx = 0;
/* The previous 2 bytes used for context. */ /* The previous 2 bytes used for context. */
uint8_t prev_byte1 = 0; uint8_t prev_byte1 = 0;
uint8_t prev_byte2 = 0; uint8_t prev_byte2 = 0;
@@ -674,32 +676,31 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
/* Decode window size. */ /* Decode window size. */
window_bits = DecodeWindowBits(&br); window_bits = DecodeWindowBits(&br);
max_backward_distance = (1ULL << window_bits) - 16; max_backward_distance = (1 << window_bits) - 16;
ringbuffer_size = 1ULL << window_bits; ringbuffer_size = 1 << window_bits;
ringbuffer_mask = ringbuffer_size - 1; ringbuffer_mask = ringbuffer_size - 1;
ringbuffer = (uint8_t*)malloc(ringbuffer_size + ringbuffer = (uint8_t*)malloc((size_t)(ringbuffer_size +
kRingBufferWriteAheadSlack + kRingBufferWriteAheadSlack +
kMaxDictionaryWordLength); kMaxDictionaryWordLength));
if (!ringbuffer) { if (!ringbuffer) {
ok = 0; ok = 0;
} }
ringbuffer_end = ringbuffer + ringbuffer_size; ringbuffer_end = ringbuffer + ringbuffer_size;
while (!input_end && ok) { while (!input_end && ok) {
size_t meta_block_len = 0; int meta_block_remaining_len = 0;
size_t meta_block_end_pos;
int is_uncompressed; int is_uncompressed;
uint32_t block_length[3] = { 1 << 28, 1 << 28, 1 << 28 }; int block_length[3] = { 1 << 28, 1 << 28, 1 << 28 };
int block_type[3] = { 0 }; int block_type[3] = { 0 };
int num_block_types[3] = { 1, 1, 1 }; int num_block_types[3] = { 1, 1, 1 };
int block_type_rb[6] = { 0, 1, 0, 1, 0, 1 }; int block_type_rb[6] = { 0, 1, 0, 1, 0, 1 };
size_t block_type_rb_index[3] = { 0 }; int 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 distance_postfix_bits;
int num_direct_distance_codes; int num_direct_distance_codes;
uint32_t distance_postfix_mask; int distance_postfix_mask;
int num_distance_codes; int num_distance_codes;
uint8_t* context_map = NULL; uint8_t* context_map = NULL;
uint8_t* context_modes = NULL; uint8_t* context_modes = NULL;
@@ -729,22 +730,24 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
goto End; goto End;
} }
BROTLI_LOG_UINT(pos); BROTLI_LOG_UINT(pos);
DecodeMetaBlockLength(&br, &meta_block_len, &input_end, &is_uncompressed); DecodeMetaBlockLength(&br, &meta_block_remaining_len,
BROTLI_LOG_UINT(meta_block_len); &input_end, &is_uncompressed);
if (meta_block_len == 0) { BROTLI_LOG_UINT(meta_block_remaining_len);
if (meta_block_remaining_len == 0) {
goto End; goto End;
} }
meta_block_end_pos = pos + meta_block_len;
if (is_uncompressed) { if (is_uncompressed) {
BrotliSetBitPos(&br, (br.bit_pos_ + 7) & ~7); BrotliSetBitPos(&br, (br.bit_pos_ + 7) & (uint32_t)(~7UL));
for (; pos < meta_block_end_pos; ++pos) { while (meta_block_remaining_len) {
ringbuffer[pos & ringbuffer_mask] = BrotliReadBits(&br, 8); ringbuffer[pos & ringbuffer_mask] = (uint8_t)BrotliReadBits(&br, 8);
if ((pos & ringbuffer_mask) == ringbuffer_mask) { if ((pos & ringbuffer_mask) == ringbuffer_mask) {
if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) {
ok = 0; ok = 0;
goto End; goto End;
} }
} }
++pos;
--meta_block_remaining_len;
} }
goto End; goto End;
} }
@@ -776,19 +779,19 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
ok = 0; ok = 0;
goto End; goto End;
} }
distance_postfix_bits = BrotliReadBits(&br, 2); distance_postfix_bits = (int)BrotliReadBits(&br, 2);
num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES + num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
(BrotliReadBits(&br, 4) << distance_postfix_bits); ((int)BrotliReadBits(&br, 4) << distance_postfix_bits);
distance_postfix_mask = (1 << distance_postfix_bits) - 1; distance_postfix_mask = (1 << distance_postfix_bits) - 1;
num_distance_codes = (num_direct_distance_codes + num_distance_codes = (num_direct_distance_codes +
(48 << distance_postfix_bits)); (48 << distance_postfix_bits));
context_modes = (uint8_t*)malloc(num_block_types[0]); context_modes = (uint8_t*)malloc((size_t)num_block_types[0]);
if (context_modes == 0) { if (context_modes == 0) {
ok = 0; ok = 0;
goto End; goto End;
} }
for (i = 0; i < num_block_types[0]; ++i) { for (i = 0; i < num_block_types[0]; ++i) {
context_modes[i] = BrotliReadBits(&br, 2) << 1; context_modes[i] = (uint8_t)(BrotliReadBits(&br, 2) << 1);
BROTLI_LOG_ARRAY_INDEX(context_modes, i); BROTLI_LOG_ARRAY_INDEX(context_modes, i);
} }
BROTLI_LOG_UINT(num_direct_distance_codes); BROTLI_LOG_UINT(num_direct_distance_codes);
@@ -820,12 +823,11 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
context_lookup_offset1 = kContextLookupOffsets[context_mode]; context_lookup_offset1 = kContextLookupOffsets[context_mode];
context_lookup_offset2 = kContextLookupOffsets[context_mode + 1]; context_lookup_offset2 = kContextLookupOffsets[context_mode + 1];
while (pos < meta_block_end_pos) { while (meta_block_remaining_len > 0) {
int insert_length; int insert_length;
int copy_length; int copy_length;
int distance_code; int distance_code;
size_t distance; int distance;
size_t max_distance;
uint8_t context; uint8_t context;
int j; int j;
const uint8_t* copy_src; const uint8_t* copy_src;
@@ -870,19 +872,21 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
literal_htree_index = context_map_slice[context]; literal_htree_index = context_map_slice[context];
--block_length[0]; --block_length[0];
prev_byte2 = prev_byte1; prev_byte2 = prev_byte1;
prev_byte1 = ReadSymbol(&hgroup[0].htrees[literal_htree_index], &br); prev_byte1 = (uint8_t)ReadSymbol(&hgroup[0].htrees[literal_htree_index],
&br);
ringbuffer[pos & ringbuffer_mask] = prev_byte1; ringbuffer[pos & ringbuffer_mask] = prev_byte1;
BROTLI_LOG_UINT(literal_htree_index); BROTLI_LOG_UINT(literal_htree_index);
BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos & ringbuffer_mask); BROTLI_LOG_ARRAY_INDEX(ringbuffer, pos & ringbuffer_mask);
if ((pos & ringbuffer_mask) == ringbuffer_mask) { if ((pos & ringbuffer_mask) == ringbuffer_mask) {
if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) {
ok = 0; ok = 0;
goto End; goto End;
} }
} }
++pos; ++pos;
} }
if (pos == meta_block_end_pos) break; meta_block_remaining_len -= insert_length;
if (meta_block_remaining_len <= 0) break;
if (distance_code < 0) { if (distance_code < 0) {
uint8_t context; uint8_t context;
@@ -896,12 +900,12 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
block_type_trees, 2, block_type, block_type_rb, block_type_trees, 2, block_type, block_type_rb,
block_type_rb_index, &br); block_type_rb_index, &br);
block_length[2] = ReadBlockLength(&block_len_trees[2], &br); block_length[2] = ReadBlockLength(&block_len_trees[2], &br);
dist_htree_index = block_type[2]; dist_htree_index = (uint8_t)block_type[2];
dist_context_offset = block_type[2] << kDistanceContextBits; dist_context_offset = block_type[2] << kDistanceContextBits;
dist_context_map_slice = dist_context_map + dist_context_offset; dist_context_map_slice = dist_context_map + dist_context_offset;
} }
--block_length[2]; --block_length[2];
context = copy_length > 4 ? 3 : copy_length - 2; context = (uint8_t)(copy_length > 4 ? 3 : copy_length - 2);
dist_htree_index = dist_context_map_slice[context]; dist_htree_index = dist_context_map_slice[context];
distance_code = ReadCopyDistance(&hgroup[2].htrees[dist_htree_index], distance_code = ReadCopyDistance(&hgroup[2].htrees[dist_htree_index],
num_direct_distance_codes, num_direct_distance_codes,
@@ -913,30 +917,36 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
/* 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. */
distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx); distance = TranslateShortCodes(distance_code, dist_rb, dist_rb_idx);
if (distance < 0) {
ok = 0;
goto End;
}
if (distance_code > 0) { if (distance_code > 0) {
dist_rb[dist_rb_idx & 3] = distance; dist_rb[dist_rb_idx & 3] = distance;
++dist_rb_idx; ++dist_rb_idx;
} }
BROTLI_LOG_UINT(distance); BROTLI_LOG_UINT(distance);
max_distance = max_backward_distance; if (pos < max_backward_distance &&
if (pos < max_distance) { max_distance != max_backward_distance) {
max_distance = pos; max_distance = pos;
} else {
max_distance = max_backward_distance;
} }
copy_dst = &ringbuffer[pos & ringbuffer_mask]; copy_dst = &ringbuffer[pos & ringbuffer_mask];
if (distance > max_distance) { if (distance > max_distance) {
printf("Invalid backward reference. pos: %lu distance: %d " printf("Invalid backward reference. pos: %d distance: %d "
"len: %d end: %lu\n", (unsigned long)pos, (int)distance, "len: %d bytes left: %d\n", pos, distance, copy_length,
copy_length, (unsigned long)meta_block_end_pos); meta_block_remaining_len);
ok = 0; ok = 0;
goto End; goto End;
} else { } else {
if (pos + copy_length > meta_block_end_pos) { if (copy_length > meta_block_remaining_len) {
printf("Invalid backward reference. pos: %lu distance: %d " printf("Invalid backward reference. pos: %d distance: %d "
"len: %d end: %lu\n", (unsigned long)pos, (int)distance, "len: %d bytes left: %d\n", pos, distance, copy_length,
copy_length, (unsigned long)meta_block_end_pos); meta_block_remaining_len);
ok = 0; ok = 0;
goto End; goto End;
} }
@@ -953,6 +963,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
IncrementalCopyFastPath(copy_dst, copy_src, copy_length); IncrementalCopyFastPath(copy_dst, copy_src, copy_length);
} }
pos += copy_length; pos += copy_length;
meta_block_remaining_len -= copy_length;
copy_length = 0; copy_length = 0;
} }
#endif #endif
@@ -961,12 +972,13 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
ringbuffer[pos & ringbuffer_mask] = ringbuffer[pos & ringbuffer_mask] =
ringbuffer[(pos - distance) & ringbuffer_mask]; ringbuffer[(pos - distance) & ringbuffer_mask];
if ((pos & ringbuffer_mask) == ringbuffer_mask) { if ((pos & ringbuffer_mask) == ringbuffer_mask) {
if (BrotliWrite(output, ringbuffer, ringbuffer_size) < 0) { if (BrotliWrite(output, ringbuffer, (size_t)ringbuffer_size) < 0) {
ok = 0; ok = 0;
goto End; goto End;
} }
} }
++pos; ++pos;
--meta_block_remaining_len;
} }
} }
@@ -976,6 +988,10 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask]; prev_byte1 = ringbuffer[(pos - 1) & ringbuffer_mask];
prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask]; prev_byte2 = ringbuffer[(pos - 2) & ringbuffer_mask];
} }
/* Protect pos from overflow, wrap it around at every GB of input data */
pos &= 0x3fffffff;
End: End:
if (context_modes != 0) { if (context_modes != 0) {
free(context_modes); free(context_modes);
@@ -994,7 +1010,7 @@ int BrotliDecompress(BrotliInput input, BrotliOutput output) {
} }
if (ringbuffer != 0) { if (ringbuffer != 0) {
if (BrotliWrite(output, ringbuffer, pos & ringbuffer_mask) < 0) { if (BrotliWrite(output, ringbuffer, (size_t)(pos & ringbuffer_mask)) < 0) {
ok = 0; ok = 0;
} }
free(ringbuffer); free(ringbuffer);
+1 -1
View File
@@ -163,7 +163,7 @@ static int TreeAddSymbol(HuffmanTree* const tree,
--i; --i;
idx = base_code | (i << code_length); idx = base_code | (i << code_length);
tree->lut_symbol_[idx] = (int16_t)symbol; tree->lut_symbol_[idx] = (int16_t)symbol;
tree->lut_bits_[idx] = code_length; tree->lut_bits_[idx] = (uint8_t)code_length;
} while (i > 0); } while (i > 0);
} else { } else {
base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)), base_code = ReverseBitsShort((code >> (code_length - HUFF_LUT_BITS)),
+1 -1
View File
@@ -27,7 +27,7 @@ extern "C" {
#endif #endif
/* This is the maximum memory amount that we will ever try to allocate. */ /* This is the maximum memory amount that we will ever try to allocate. */
#define BROTLI_MAX_ALLOCABLE_MEMORY (1ULL << 40) #define BROTLI_MAX_ALLOCABLE_MEMORY (1 << 30)
/* size-checking safe malloc/calloc: verify that the requested size is not too /* size-checking safe malloc/calloc: verify that the requested size is not too
large, or return NULL. You don't need to call these for constructs like large, or return NULL. You don't need to call these for constructs like
+2 -2
View File
@@ -72,7 +72,7 @@ BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count) { int BrotliStdinInputFunction(void* data, uint8_t* buf, size_t count) {
#ifndef _WIN32 #ifndef _WIN32
return read(STDIN_FILENO, buf, count); return (int)read(STDIN_FILENO, buf, count);
#else #else
return -1; return -1;
#endif #endif
@@ -87,7 +87,7 @@ BrotliInput BrotliStdinInput() {
int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count) { int BrotliStdoutOutputFunction(void* data, const uint8_t* buf, size_t count) {
#ifndef _WIN32 #ifndef _WIN32
return write(STDOUT_FILENO, buf, count); return (int)write(STDOUT_FILENO, buf, count);
#else #else
return -1; return -1;
#endif #endif