diff --git a/dec/bit_reader.h b/dec/bit_reader.h index 10a2cc8..4e3b7fb 100644 --- a/dec/bit_reader.h +++ b/dec/bit_reader.h @@ -191,19 +191,19 @@ static BROTLI_INLINE int BrotliReadMoreInput(BrotliBitReader* const br) { /* Guarantees that there are at least 24 bits in the buffer. */ static BROTLI_INLINE void BrotliFillBitWindow(BrotliBitReader* const br) { #if (BROTLI_USE_64_BITS) - if (br->bit_pos_ >= 40) { + if (br->bit_pos_ >= 32) { /* - * Advances the Read buffer by 5 bytes to make room for reading next + * Advances the Read buffer by 4 bytes to make room for reading next * 24 bits. * The expression below needs a little-endian arch to work correctly. * This gives a large speedup for decoding speed. */ - br->val_ >>= 40; - br->val_ |= *(const uint64_t*)( - br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)) << 24; - br->pos_ += 5; - br->bit_pos_ -= 40; - br->bit_end_pos_ -= 40; + br->val_ >>= 32; + br->val_ |= ((uint64_t)(*(const uint32_t*)( + br->buf_ + (br->pos_ & BROTLI_IBUF_MASK)))) << 32; + br->pos_ += 4; + br->bit_pos_ -= 32; + br->bit_end_pos_ -= 32; } #else ShiftBytes32(br); diff --git a/dec/decode.c b/dec/decode.c index b033cf5..dbeaf0f 100644 --- a/dec/decode.c +++ b/dec/decode.c @@ -222,13 +222,16 @@ static BrotliResult ReadHuffmanCodeLengths( p += (br->val_ >> br->bit_pos_) & 31; br->bit_pos_ += p->bits; code_len = (uint8_t)p->value; + /* We predict that branch will be taken and write value now. + Even if branch is mispredicted - it works as prefetch. */ + code_lengths[s->symbol] = code_len; if (code_len < kCodeLengthRepeatCode) { s->repeat = 0; - code_lengths[s->symbol++] = code_len; if (code_len != 0) { s->prev_code_len = code_len; s->space -= 32768 >> code_len; } + s->symbol++; } else { const int extra_bits = code_len - 14; int old_repeat; diff --git a/dec/huffman.c b/dec/huffman.c index 3925087..f4802e0 100644 --- a/dec/huffman.c +++ b/dec/huffman.c @@ -19,6 +19,7 @@ #include #include #include "./huffman.h" +#include "./port.h" #include "./safe_malloc.h" #if defined(__cplusplus) || defined(c_plusplus) @@ -27,6 +28,9 @@ extern "C" { #define MAX_LENGTH 15 +/* For current format this constant equals to kNumInsertAndCopyCodes */ +#define MAX_CODE_LENGTHS_SIZE 704 + /* Returns reverse(reverse(key, len) + 1, len), where reverse(key, len) is the bit-wise reversal of the len least significant bits of key. */ static BROTLI_INLINE int GetNextKey(int key, int len) { @@ -78,12 +82,11 @@ int BrotliBuildHuffmanTable(HuffmanCode* root_table, int table_bits; /* key length of current table */ int table_size; /* size of current table */ int total_size; /* sum of root table size and 2nd level table sizes */ - int* sorted; /* symbols sorted by code length */ + int sorted[MAX_CODE_LENGTHS_SIZE]; /* symbols sorted by code length */ int count[MAX_LENGTH + 1] = { 0 }; /* number of codes of each length */ int offset[MAX_LENGTH + 1]; /* offsets in sorted table for each length */ - sorted = (int*)malloc((size_t)code_lengths_size * sizeof(*sorted)); - if (sorted == NULL) { + if (PREDICT_FALSE(code_lengths_size > MAX_CODE_LENGTHS_SIZE)) { return 0; } @@ -117,7 +120,6 @@ int BrotliBuildHuffmanTable(HuffmanCode* root_table, for (key = 0; key < total_size; ++key) { table[key] = code; } - free(sorted); return total_size; } @@ -154,7 +156,6 @@ int BrotliBuildHuffmanTable(HuffmanCode* root_table, } } - free(sorted); return total_size; }