brotli: Sync with upstream 1.1.0

https://github.com/google/brotli/releases/tag/v1.1.0
This commit is contained in:
Rémi Verschelde 2023-09-30 12:52:40 +02:00
parent 0ca8542329
commit 0402205ce6
No known key found for this signature in database
GPG key ID: C3336907360768E1
12 changed files with 450 additions and 325 deletions

View file

@ -74,7 +74,7 @@ fix build with our own copy of zstd (patch in `patches`).
## brotli ## brotli
- Upstream: https://github.com/google/brotli - Upstream: https://github.com/google/brotli
- Version: git (ed1995b6bda19244070ab5d331111f16f67c8054, 2023) - Version: 1.1.0 (ed738e842d2fbdf2d6459e39267a633c4a9b2f5d, 2023)
- License: MIT - License: MIT
Files extracted from upstream source: Files extracted from upstream source:

View file

@ -14,10 +14,11 @@
* BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations * BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
* BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs * BROTLI_BUILD_NO_RBIT disables "rbit" optimization for ARM CPUs
* BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read * BROTLI_BUILD_NO_UNALIGNED_READ_FAST forces off the fast-unaligned-read
optimizations (mainly for testing purposes). optimizations (mainly for testing purposes)
* BROTLI_DEBUG dumps file name and line number when decoder detects stream * BROTLI_DEBUG dumps file name and line number when decoder detects stream
or memory error or memory error
* BROTLI_ENABLE_LOG enables asserts and dumps various state information * BROTLI_ENABLE_LOG enables asserts and dumps various state information
* BROTLI_ENABLE_DUMP overrides default "dump" behaviour
*/ */
#ifndef BROTLI_COMMON_PLATFORM_H_ #ifndef BROTLI_COMMON_PLATFORM_H_
@ -208,8 +209,13 @@ OR:
#define BROTLI_TARGET_RISCV64 #define BROTLI_TARGET_RISCV64
#endif #endif
#if defined(__loongarch_lp64)
#define BROTLI_TARGET_LOONGARCH64
#endif
#if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \ #if defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8_64) || \
defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) defined(BROTLI_TARGET_POWERPC64) || defined(BROTLI_TARGET_RISCV64) || \
defined(BROTLI_TARGET_LOONGARCH64)
#define BROTLI_TARGET_64_BITS 1 #define BROTLI_TARGET_64_BITS 1
#else #else
#define BROTLI_TARGET_64_BITS 0 #define BROTLI_TARGET_64_BITS 0
@ -268,7 +274,7 @@ OR:
#define BROTLI_UNALIGNED_READ_FAST (!!0) #define BROTLI_UNALIGNED_READ_FAST (!!0)
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \ #elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \ defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8_ANY) || \
defined(BROTLI_TARGET_RISCV64) defined(BROTLI_TARGET_RISCV64) || defined(BROTLI_TARGET_LOONGARCH64)
/* These targets are known to generate efficient code for unaligned reads /* These targets are known to generate efficient code for unaligned reads
* (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd * (e.g. a single instruction, not multiple 1-byte loads, shifted and or'd
* together). */ * together). */
@ -402,14 +408,24 @@ static BROTLI_INLINE void BROTLI_UNALIGNED_STORE_PTR(void* p, const void* v) {
#endif #endif
#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) #if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
#define BROTLI_ENABLE_DUMP_DEFAULT 1
#define BROTLI_DCHECK(x) assert(x) #define BROTLI_DCHECK(x) assert(x)
#else
#define BROTLI_ENABLE_DUMP_DEFAULT 0
#define BROTLI_DCHECK(x)
#endif
#if !defined(BROTLI_ENABLE_DUMP)
#define BROTLI_ENABLE_DUMP BROTLI_ENABLE_DUMP_DEFAULT
#endif
#if BROTLI_ENABLE_DUMP
static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) { static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
fprintf(stderr, "%s:%d (%s)\n", f, l, fn); fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
fflush(stderr); fflush(stderr);
} }
#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__) #define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
#else #else
#define BROTLI_DCHECK(x)
#define BROTLI_DUMP() (void)(0) #define BROTLI_DUMP() (void)(0)
#endif #endif
@ -517,7 +533,7 @@ BROTLI_UNUSED_FUNCTION void BrotliSuppressUnusedFunctions(void) {
BROTLI_UNUSED(&brotli_max_uint8_t); BROTLI_UNUSED(&brotli_max_uint8_t);
BROTLI_UNUSED(&BrotliDefaultAllocFunc); BROTLI_UNUSED(&BrotliDefaultAllocFunc);
BROTLI_UNUSED(&BrotliDefaultFreeFunc); BROTLI_UNUSED(&BrotliDefaultFreeFunc);
#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG) #if BROTLI_ENABLE_DUMP
BROTLI_UNUSED(&BrotliDump); BROTLI_UNUSED(&BrotliDump);
#endif #endif
} }

View file

@ -20,6 +20,8 @@
extern "C" { extern "C" {
#endif #endif
#if defined(BROTLI_EXPERIMENTAL)
#define BROTLI_NUM_ENCODED_LENGTHS (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH \ #define BROTLI_NUM_ENCODED_LENGTHS (SHARED_BROTLI_MAX_DICTIONARY_WORD_LENGTH \
- SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH + 1) - SHARED_BROTLI_MIN_DICTIONARY_WORD_LENGTH + 1)
@ -442,6 +444,8 @@ static BROTLI_BOOL DecodeSharedDictionary(
return ParseDictionary(encoded, size, dict); return ParseDictionary(encoded, size, dict);
} }
#endif /* BROTLI_EXPERIMENTAL */
void BrotliSharedDictionaryDestroyInstance( void BrotliSharedDictionaryDestroyInstance(
BrotliSharedDictionary* dict) { BrotliSharedDictionary* dict) {
if (!dict) { if (!dict) {
@ -464,9 +468,12 @@ BROTLI_BOOL BrotliSharedDictionaryAttach(
if (!dict) { if (!dict) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
#if defined(BROTLI_EXPERIMENTAL)
if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) { if (type == BROTLI_SHARED_DICTIONARY_SERIALIZED) {
return DecodeSharedDictionary(data, data_size, dict); return DecodeSharedDictionary(data, data_size, dict);
} else if (type == BROTLI_SHARED_DICTIONARY_RAW) { }
#endif /* BROTLI_EXPERIMENTAL */
if (type == BROTLI_SHARED_DICTIONARY_RAW) {
if (dict->num_prefix >= SHARED_BROTLI_MAX_COMPOUND_DICTS) { if (dict->num_prefix >= SHARED_BROTLI_MAX_COMPOUND_DICTS) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
@ -474,9 +481,8 @@ BROTLI_BOOL BrotliSharedDictionaryAttach(
dict->prefix[dict->num_prefix] = data; dict->prefix[dict->num_prefix] = data;
dict->num_prefix++; dict->num_prefix++;
return BROTLI_TRUE; return BROTLI_TRUE;
} else {
return BROTLI_FALSE;
} }
return BROTLI_FALSE;
} }
BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance( BrotliSharedDictionary* BrotliSharedDictionaryCreateInstance(

View file

@ -9,18 +9,43 @@
#ifndef BROTLI_COMMON_VERSION_H_ #ifndef BROTLI_COMMON_VERSION_H_
#define BROTLI_COMMON_VERSION_H_ #define BROTLI_COMMON_VERSION_H_
/* This macro should only be used when library is compiled together with client. /* Compose 3 components into a single number. In a hexadecimal representation
If library is dynamically linked, use BrotliDecoderVersion and B and C components occupy exactly 3 digits. */
#define BROTLI_MAKE_HEX_VERSION(A, B, C) ((A << 24) | (B << 12) | C)
/* Those macros should only be used when library is compiled together with
the client. If library is dynamically linked, use BrotliDecoderVersion and
BrotliEncoderVersion methods. */ BrotliEncoderVersion methods. */
/* Semantic version, calculated as (MAJOR << 24) | (MINOR << 12) | PATCH */ #define BROTLI_VERSION_MAJOR 1
#define BROTLI_VERSION 0x1000009 #define BROTLI_VERSION_MINOR 1
#define BROTLI_VERSION_PATCH 0
#define BROTLI_VERSION BROTLI_MAKE_HEX_VERSION( \
BROTLI_VERSION_MAJOR, BROTLI_VERSION_MINOR, BROTLI_VERSION_PATCH)
/* This macro is used by build system to produce Libtool-friendly soname. See /* This macro is used by build system to produce Libtool-friendly soname. See
https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html https://www.gnu.org/software/libtool/manual/html_node/Libtool-versioning.html
Version evolution rules:
- interfaces added (or change is compatible) -> current+1:0:age+1
- interfaces removed (or changed is incompatible) -> current+1:0:0
- interfaces not changed -> current:revision+1:age
*/ */
/* ABI version, calculated as (CURRENT << 24) | (REVISION << 12) | AGE */ #define BROTLI_ABI_CURRENT 2
#define BROTLI_ABI_VERSION 0x1009000 #define BROTLI_ABI_REVISION 0
#define BROTLI_ABI_AGE 1
#if BROTLI_VERSION_MAJOR != (BROTLI_ABI_CURRENT - BROTLI_ABI_AGE)
#error ABI/API version inconsistency
#endif
#if BROTLI_VERSION_MINOR != BROTLI_ABI_AGE
#error ABI/API version inconsistency
#endif
#if BROTLI_VERSION_PATCH != BROTLI_ABI_REVISION
#error ABI/API version inconsistency
#endif
#endif /* BROTLI_COMMON_VERSION_H_ */ #endif /* BROTLI_COMMON_VERSION_H_ */

View file

@ -16,7 +16,7 @@
extern "C" { extern "C" {
#endif #endif
const uint32_t kBrotliBitMask[33] = { 0x00000000, const brotli_reg_t kBrotliBitMask[33] = { 0x00000000,
0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x00000001, 0x00000003, 0x00000007, 0x0000000F,
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF, 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF, 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
@ -29,7 +29,7 @@ const uint32_t kBrotliBitMask[33] = { 0x00000000,
void BrotliInitBitReader(BrotliBitReader* const br) { void BrotliInitBitReader(BrotliBitReader* const br) {
br->val_ = 0; br->val_ = 0;
br->bit_pos_ = sizeof(br->val_) << 3; br->bit_pos_ = 0;
} }
BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) { BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
@ -41,6 +41,7 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
aligned_read_mask = 0; aligned_read_mask = 0;
} }
if (BrotliGetAvailableBits(br) == 0) { if (BrotliGetAvailableBits(br) == 0) {
br->val_ = 0;
if (!BrotliPullByte(br)) { if (!BrotliPullByte(br)) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
@ -56,9 +57,9 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
} }
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br, BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
uint32_t n_bits, uint32_t* val) { brotli_reg_t n_bits, brotli_reg_t* val) {
uint32_t low_val; brotli_reg_t low_val;
uint32_t high_val; brotli_reg_t high_val;
BrotliBitReaderState memento; BrotliBitReaderState memento;
BROTLI_DCHECK(n_bits <= 32); BROTLI_DCHECK(n_bits <= 32);
BROTLI_DCHECK(n_bits > 24); BROTLI_DCHECK(n_bits > 24);

View file

@ -22,13 +22,16 @@ extern "C" {
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1) #define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33]; /* 162 bits + 7 bytes */
#define BROTLI_FAST_INPUT_SLACK 28
static BROTLI_INLINE uint32_t BitMask(uint32_t n) { BROTLI_INTERNAL extern const brotli_reg_t kBrotliBitMask[33];
static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) {
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) { if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
/* Masking with this expression turns to a single /* Masking with this expression turns to a single
"Unsigned Bit Field Extract" UBFX instruction on ARM. */ "Unsigned Bit Field Extract" UBFX instruction on ARM. */
return ~((0xFFFFFFFFu) << n); return ~(~((brotli_reg_t)0) << n);
} else { } else {
return kBrotliBitMask[n]; return kBrotliBitMask[n];
} }
@ -36,40 +39,57 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
typedef struct { typedef struct {
brotli_reg_t val_; /* pre-fetched bits */ brotli_reg_t val_; /* pre-fetched bits */
uint32_t bit_pos_; /* current bit-reading position in val_ */ brotli_reg_t bit_pos_; /* current bit-reading position in val_ */
const uint8_t* next_in; /* the byte we're reading from */ const uint8_t* next_in; /* the byte we're reading from */
size_t avail_in; const uint8_t* guard_in; /* position from which "fast-path" is prohibited */
const uint8_t* last_in; /* == next_in + avail_in */
} BrotliBitReader; } BrotliBitReader;
typedef struct { typedef struct {
brotli_reg_t val_; brotli_reg_t val_;
uint32_t bit_pos_; brotli_reg_t bit_pos_;
const uint8_t* next_in; const uint8_t* next_in;
size_t avail_in; size_t avail_in;
} BrotliBitReaderState; } BrotliBitReaderState;
/* Initializes the BrotliBitReader fields. */ /* Initializes the BrotliBitReader fields. */
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br); BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* br);
/* Ensures that accumulator is not empty. /* Ensures that accumulator is not empty.
May consume up to sizeof(brotli_reg_t) - 1 bytes of input. May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
Returns BROTLI_FALSE if data is required but there is no input available. Returns BROTLI_FALSE if data is required but there is no input available.
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
aligned reading. */ aligned reading. */
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br); BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br);
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden /* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
the main code-path. Never called for RFC brotli streams, required only for the main code-path. Never called for RFC brotli streams, required only for
"large-window" mode and other extensions. */ "large-window" mode and other extensions. */
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow( BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val); BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val);
static BROTLI_INLINE size_t
BrotliBitReaderGetAvailIn(BrotliBitReader* const br) {
return (size_t)(br->last_in - br->next_in);
}
static BROTLI_INLINE void BrotliBitReaderSaveState( static BROTLI_INLINE void BrotliBitReaderSaveState(
BrotliBitReader* const from, BrotliBitReaderState* to) { BrotliBitReader* const from, BrotliBitReaderState* to) {
to->val_ = from->val_; to->val_ = from->val_;
to->bit_pos_ = from->bit_pos_; to->bit_pos_ = from->bit_pos_;
to->next_in = from->next_in; to->next_in = from->next_in;
to->avail_in = from->avail_in; to->avail_in = BrotliBitReaderGetAvailIn(from);
}
static BROTLI_INLINE void BrotliBitReaderSetInput(
BrotliBitReader* const br, const uint8_t* next_in, size_t avail_in) {
br->next_in = next_in;
br->last_in = (avail_in == 0) ? next_in : (next_in + avail_in);
if (avail_in + 1 > BROTLI_FAST_INPUT_SLACK) {
br->guard_in = next_in + (avail_in + 1 - BROTLI_FAST_INPUT_SLACK);
} else {
br->guard_in = next_in;
}
} }
static BROTLI_INLINE void BrotliBitReaderRestoreState( static BROTLI_INLINE void BrotliBitReaderRestoreState(
@ -77,12 +97,12 @@ static BROTLI_INLINE void BrotliBitReaderRestoreState(
to->val_ = from->val_; to->val_ = from->val_;
to->bit_pos_ = from->bit_pos_; to->bit_pos_ = from->bit_pos_;
to->next_in = from->next_in; to->next_in = from->next_in;
to->avail_in = from->avail_in; BrotliBitReaderSetInput(to, from->next_in, from->avail_in);
} }
static BROTLI_INLINE uint32_t BrotliGetAvailableBits( static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
const BrotliBitReader* br) { const BrotliBitReader* br) {
return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_; return br->bit_pos_;
} }
/* Returns amount of unread bytes the bit reader still has buffered from the /* Returns amount of unread bytes the bit reader still has buffered from the
@ -90,15 +110,27 @@ static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
maximal ring-buffer size (larger number won't be utilized anyway). */ maximal ring-buffer size (larger number won't be utilized anyway). */
static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) { static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS; static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
if (br->avail_in > kCap) return kCap; size_t avail_in = BrotliBitReaderGetAvailIn(br);
return br->avail_in + (BrotliGetAvailableBits(br) >> 3); if (avail_in > kCap) return kCap;
return avail_in + (BrotliGetAvailableBits(br) >> 3);
} }
/* Checks if there is at least |num| bytes left in the input ring-buffer /* Checks if there is at least |num| bytes left in the input ring-buffer
(excluding the bits remaining in br->val_). */ (excluding the bits remaining in br->val_). */
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount( static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
BrotliBitReader* const br, size_t num) { BrotliBitReader* const br) {
return TO_BROTLI_BOOL(br->avail_in >= num); return TO_BROTLI_BOOL(br->next_in < br->guard_in);
}
/* Load more bits into accumulator. */
static BROTLI_INLINE brotli_reg_t BrotliBitReaderLoadBits(brotli_reg_t val,
brotli_reg_t new_bits,
brotli_reg_t count,
brotli_reg_t offset) {
BROTLI_DCHECK(
!((val >> offset) & ~new_bits & ~(~((brotli_reg_t)0) << count)));
(void)count;
return val | (new_bits << offset);
} }
/* Guarantees that there are at least |n_bits| + 1 bits in accumulator. /* Guarantees that there are at least |n_bits| + 1 bits in accumulator.
@ -106,61 +138,51 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|n_bits| should be in the range [1..24] for regular build. For portable |n_bits| should be in the range [1..24] for regular build. For portable
non-64-bit little-endian build only 16 bits are safe to request. */ non-64-bit little-endian build only 16 bits are safe to request. */
static BROTLI_INLINE void BrotliFillBitWindow( static BROTLI_INLINE void BrotliFillBitWindow(
BrotliBitReader* const br, uint32_t n_bits) { BrotliBitReader* const br, brotli_reg_t n_bits) {
#if (BROTLI_64_BITS) #if (BROTLI_64_BITS)
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 8)) { (n_bits <= 8)) {
uint32_t bit_pos = br->bit_pos_; brotli_reg_t bit_pos = br->bit_pos_;
if (bit_pos >= 56) { if (bit_pos <= 8) {
br->val_ = br->val_ = BrotliBitReaderLoadBits(br->val_,
(br->val_ >> 56) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8); BROTLI_UNALIGNED_LOAD64LE(br->next_in), 56, bit_pos);
br->bit_pos_ = br->bit_pos_ = bit_pos + 56;
bit_pos ^ 56; /* here same as -= 56 because of the if condition */
br->avail_in -= 7;
br->next_in += 7; br->next_in += 7;
} }
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && } else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 16)) { (n_bits <= 16)) {
uint32_t bit_pos = br->bit_pos_; brotli_reg_t bit_pos = br->bit_pos_;
if (bit_pos >= 48) { if (bit_pos <= 16) {
br->val_ = br->val_ = BrotliBitReaderLoadBits(br->val_,
(br->val_ >> 48) | (BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16); BROTLI_UNALIGNED_LOAD64LE(br->next_in), 48, bit_pos);
br->bit_pos_ = br->bit_pos_ = bit_pos + 48;
bit_pos ^ 48; /* here same as -= 48 because of the if condition */
br->avail_in -= 6;
br->next_in += 6; br->next_in += 6;
} }
} else { } else {
uint32_t bit_pos = br->bit_pos_; brotli_reg_t bit_pos = br->bit_pos_;
if (bit_pos >= 32) { if (bit_pos <= 32) {
br->val_ = (br->val_ >> 32) | br->val_ = BrotliBitReaderLoadBits(br->val_,
(((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32); (uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in), 32, bit_pos);
br->bit_pos_ = br->bit_pos_ = bit_pos + 32;
bit_pos ^ 32; /* here same as -= 32 because of the if condition */
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
} }
} }
#else #else
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) && if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
(n_bits <= 8)) { (n_bits <= 8)) {
uint32_t bit_pos = br->bit_pos_; brotli_reg_t bit_pos = br->bit_pos_;
if (bit_pos >= 24) { if (bit_pos <= 8) {
br->val_ = br->val_ = BrotliBitReaderLoadBits(br->val_,
(br->val_ >> 24) | (BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8); BROTLI_UNALIGNED_LOAD32LE(br->next_in), 24, bit_pos);
br->bit_pos_ = br->bit_pos_ = bit_pos + 24;
bit_pos ^ 24; /* here same as -= 24 because of the if condition */
br->avail_in -= 3;
br->next_in += 3; br->next_in += 3;
} }
} else { } else {
uint32_t bit_pos = br->bit_pos_; brotli_reg_t bit_pos = br->bit_pos_;
if (bit_pos >= 16) { if (bit_pos <= 16) {
br->val_ = (br->val_ >> 16) | br->val_ = BrotliBitReaderLoadBits(br->val_,
(((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16); (uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in), 16, bit_pos);
br->bit_pos_ = br->bit_pos_ = bit_pos + 16;
bit_pos ^ 16; /* here same as -= 16 because of the if condition */
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ; br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
} }
} }
@ -176,17 +198,12 @@ static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
/* Tries to pull one byte of input to accumulator. /* Tries to pull one byte of input to accumulator.
Returns BROTLI_FALSE if there is no input available. */ Returns BROTLI_FALSE if there is no input available. */
static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) { static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
if (br->avail_in == 0) { if (br->next_in == br->last_in) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
br->val_ >>= 8; br->val_ = BrotliBitReaderLoadBits(br->val_,
#if (BROTLI_64_BITS) (brotli_reg_t)*br->next_in, 8, br->bit_pos_);
br->val_ |= ((uint64_t)*br->next_in) << 56; br->bit_pos_ += 8;
#else
br->val_ |= ((uint32_t)*br->next_in) << 24;
#endif
br->bit_pos_ -= 8;
--br->avail_in;
++br->next_in; ++br->next_in;
return BROTLI_TRUE; return BROTLI_TRUE;
} }
@ -195,81 +212,90 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
The number of valid bits could be calculated by BrotliGetAvailableBits. */ The number of valid bits could be calculated by BrotliGetAvailableBits. */
static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked( static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
BrotliBitReader* const br) { BrotliBitReader* const br) {
return br->val_ >> br->bit_pos_; return br->val_;
} }
/* Like BrotliGetBits, but does not mask the result. /* Like BrotliGetBits, but does not mask the result.
The result contains at least 16 valid bits. */ The result contains at least 16 valid bits. */
static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked( static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
BrotliBitReader* const br) { BrotliBitReader* const br) {
BrotliFillBitWindow(br, 16); BrotliFillBitWindow(br, 16);
return (uint32_t)BrotliGetBitsUnmasked(br); return (brotli_reg_t)BrotliGetBitsUnmasked(br);
} }
/* Returns the specified number of bits from |br| without advancing bit /* Returns the specified number of bits from |br| without advancing bit
position. */ position. */
static BROTLI_INLINE uint32_t BrotliGetBits( static BROTLI_INLINE brotli_reg_t BrotliGetBits(
BrotliBitReader* const br, uint32_t n_bits) { BrotliBitReader* const br, brotli_reg_t n_bits) {
BrotliFillBitWindow(br, n_bits); BrotliFillBitWindow(br, n_bits);
return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); return BrotliGetBitsUnmasked(br) & BitMask(n_bits);
} }
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there /* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
is not enough input. */ is not enough input. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits( static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
while (BrotliGetAvailableBits(br) < n_bits) { while (BrotliGetAvailableBits(br) < n_bits) {
if (!BrotliPullByte(br)) { if (!BrotliPullByte(br)) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
} }
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); *val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
return BROTLI_TRUE; return BROTLI_TRUE;
} }
/* Advances the bit pos by |n_bits|. */ /* Advances the bit pos by |n_bits|. */
static BROTLI_INLINE void BrotliDropBits( static BROTLI_INLINE void BrotliDropBits(
BrotliBitReader* const br, uint32_t n_bits) { BrotliBitReader* const br, brotli_reg_t n_bits) {
br->bit_pos_ += n_bits; br->bit_pos_ -= n_bits;
br->val_ >>= n_bits;
}
/* Make sure that there are no spectre bits in accumulator.
This is important for the cases when some bytes are skipped
(i.e. never placed into accumulator). */
static BROTLI_INLINE void BrotliBitReaderNormalize(BrotliBitReader* br) {
/* Actually, it is enough to normalize when br->bit_pos_ == 0 */
if (br->bit_pos_ < (sizeof(brotli_reg_t) << 3u)) {
br->val_ &= (((brotli_reg_t)1) << br->bit_pos_) - 1;
}
} }
static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) { static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3; brotli_reg_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
uint32_t unused_bits = unused_bytes << 3; brotli_reg_t unused_bits = unused_bytes << 3;
br->avail_in += unused_bytes; br->next_in =
br->next_in -= unused_bytes; (unused_bytes == 0) ? br->next_in : (br->next_in - unused_bytes);
if (unused_bits == sizeof(br->val_) << 3) { br->bit_pos_ -= unused_bits;
br->val_ = 0; BrotliBitReaderNormalize(br);
} else {
br->val_ <<= unused_bits;
}
br->bit_pos_ += unused_bits;
} }
/* Reads the specified number of bits from |br| and advances the bit pos. /* Reads the specified number of bits from |br| and advances the bit pos.
Precondition: accumulator MUST contain at least |n_bits|. */ Precondition: accumulator MUST contain at least |n_bits|. */
static BROTLI_INLINE void BrotliTakeBits( static BROTLI_INLINE void BrotliTakeBits(BrotliBitReader* const br,
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { brotli_reg_t n_bits,
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits); brotli_reg_t* val) {
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n", BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
(int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val)); (int)BrotliBitReaderGetAvailIn(br), (int)br->bit_pos_,
(int)n_bits, (int)*val));
BrotliDropBits(br, n_bits); BrotliDropBits(br, n_bits);
} }
/* Reads the specified number of bits from |br| and advances the bit pos. /* Reads the specified number of bits from |br| and advances the bit pos.
Assumes that there is enough input to perform BrotliFillBitWindow. Assumes that there is enough input to perform BrotliFillBitWindow.
Up to 24 bits are allowed to be requested from this method. */ Up to 24 bits are allowed to be requested from this method. */
static BROTLI_INLINE uint32_t BrotliReadBits24( static BROTLI_INLINE brotli_reg_t BrotliReadBits24(
BrotliBitReader* const br, uint32_t n_bits) { BrotliBitReader* const br, brotli_reg_t n_bits) {
BROTLI_DCHECK(n_bits <= 24); BROTLI_DCHECK(n_bits <= 24);
if (BROTLI_64_BITS || (n_bits <= 16)) { if (BROTLI_64_BITS || (n_bits <= 16)) {
uint32_t val; brotli_reg_t val;
BrotliFillBitWindow(br, n_bits); BrotliFillBitWindow(br, n_bits);
BrotliTakeBits(br, n_bits, &val); BrotliTakeBits(br, n_bits, &val);
return val; return val;
} else { } else {
uint32_t low_val; brotli_reg_t low_val;
uint32_t high_val; brotli_reg_t high_val;
BrotliFillBitWindow(br, 16); BrotliFillBitWindow(br, 16);
BrotliTakeBits(br, 16, &low_val); BrotliTakeBits(br, 16, &low_val);
BrotliFillBitWindow(br, 8); BrotliFillBitWindow(br, 8);
@ -279,17 +305,17 @@ static BROTLI_INLINE uint32_t BrotliReadBits24(
} }
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */ /* Same as BrotliReadBits24, but allows reading up to 32 bits. */
static BROTLI_INLINE uint32_t BrotliReadBits32( static BROTLI_INLINE brotli_reg_t BrotliReadBits32(
BrotliBitReader* const br, uint32_t n_bits) { BrotliBitReader* const br, brotli_reg_t n_bits) {
BROTLI_DCHECK(n_bits <= 32); BROTLI_DCHECK(n_bits <= 32);
if (BROTLI_64_BITS || (n_bits <= 16)) { if (BROTLI_64_BITS || (n_bits <= 16)) {
uint32_t val; brotli_reg_t val;
BrotliFillBitWindow(br, n_bits); BrotliFillBitWindow(br, n_bits);
BrotliTakeBits(br, n_bits, &val); BrotliTakeBits(br, n_bits, &val);
return val; return val;
} else { } else {
uint32_t low_val; brotli_reg_t low_val;
uint32_t high_val; brotli_reg_t high_val;
BrotliFillBitWindow(br, 16); BrotliFillBitWindow(br, 16);
BrotliTakeBits(br, 16, &low_val); BrotliTakeBits(br, 16, &low_val);
BrotliFillBitWindow(br, 16); BrotliFillBitWindow(br, 16);
@ -302,7 +328,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits32(
is not enough input. |n_bits| MUST be positive. is not enough input. |n_bits| MUST be positive.
Up to 24 bits are allowed to be requested from this method. */ Up to 24 bits are allowed to be requested from this method. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits( static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
BROTLI_DCHECK(n_bits <= 24); BROTLI_DCHECK(n_bits <= 24);
while (BrotliGetAvailableBits(br) < n_bits) { while (BrotliGetAvailableBits(br) < n_bits) {
if (!BrotliPullByte(br)) { if (!BrotliPullByte(br)) {
@ -315,7 +341,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */ /* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32( static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
BROTLI_DCHECK(n_bits <= 32); BROTLI_DCHECK(n_bits <= 32);
if (BROTLI_64_BITS || (n_bits <= 24)) { if (BROTLI_64_BITS || (n_bits <= 24)) {
while (BrotliGetAvailableBits(br) < n_bits) { while (BrotliGetAvailableBits(br) < n_bits) {
@ -333,16 +359,19 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
/* Advances the bit reader position to the next byte boundary and verifies /* Advances the bit reader position to the next byte boundary and verifies
that any skipped bits are set to zero. */ that any skipped bits are set to zero. */
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) { static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7; brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
uint32_t pad_bits = 0; brotli_reg_t pad_bits = 0;
if (pad_bits_count != 0) { if (pad_bits_count != 0) {
BrotliTakeBits(br, pad_bits_count, &pad_bits); BrotliTakeBits(br, pad_bits_count, &pad_bits);
} }
BrotliBitReaderNormalize(br);
return TO_BROTLI_BOOL(pad_bits == 0); return TO_BROTLI_BOOL(pad_bits == 0);
} }
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) { static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
br->avail_in -= num; /* Check detour is legal: accumulator must to be empty. */
BROTLI_DCHECK(br->bit_pos_ == 0);
BROTLI_DCHECK(br->val_ == 0);
br->next_in += num; br->next_in += num;
} }
@ -357,12 +386,36 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
++dest; ++dest;
--num; --num;
} }
BrotliBitReaderNormalize(br);
if (num > 0) { if (num > 0) {
memcpy(dest, br->next_in, num); memcpy(dest, br->next_in, num);
BrotliDropBytes(br, num); BrotliDropBytes(br, num);
} }
} }
BROTLI_UNUSED_FUNCTION void BrotliBitReaderSuppressUnusedFunctions(void) {
BROTLI_UNUSED(&BrotliBitReaderSuppressUnusedFunctions);
BROTLI_UNUSED(&BrotliBitReaderGetAvailIn);
BROTLI_UNUSED(&BrotliBitReaderLoadBits);
BROTLI_UNUSED(&BrotliBitReaderRestoreState);
BROTLI_UNUSED(&BrotliBitReaderSaveState);
BROTLI_UNUSED(&BrotliBitReaderSetInput);
BROTLI_UNUSED(&BrotliBitReaderUnload);
BROTLI_UNUSED(&BrotliCheckInputAmount);
BROTLI_UNUSED(&BrotliCopyBytes);
BROTLI_UNUSED(&BrotliFillBitWindow16);
BROTLI_UNUSED(&BrotliGet16BitsUnmasked);
BROTLI_UNUSED(&BrotliGetBits);
BROTLI_UNUSED(&BrotliGetRemainingBytes);
BROTLI_UNUSED(&BrotliJumpToByteBoundary);
BROTLI_UNUSED(&BrotliReadBits24);
BROTLI_UNUSED(&BrotliReadBits32);
BROTLI_UNUSED(&BrotliSafeGetBits);
BROTLI_UNUSED(&BrotliSafeReadBits);
BROTLI_UNUSED(&BrotliSafeReadBits32);
}
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -44,7 +44,7 @@ extern "C" {
- doing up to two 16-byte copies for fast backward copying - doing up to two 16-byte copies for fast backward copying
- inserting transformed dictionary word: - inserting transformed dictionary word:
255 prefix + 32 base + 255 suffix */ 255 prefix + 32 base + 255 suffix */
static const uint32_t kRingBufferWriteAheadSlack = 542; static const brotli_reg_t kRingBufferWriteAheadSlack = 542;
static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = { static const uint8_t kCodeLengthCodeOrder[BROTLI_CODE_LENGTH_CODES] = {
1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15,
@ -116,6 +116,10 @@ static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) { BrotliDecoderState* s, BrotliDecoderErrorCode e, size_t consumed_input) {
s->error_code = (int)e; s->error_code = (int)e;
s->used_input += consumed_input; s->used_input += consumed_input;
if ((s->buffer_length != 0) && (s->br.next_in == s->br.last_in)) {
/* If internal buffer is depleted at last, reset it. */
s->buffer_length = 0;
}
switch (e) { switch (e) {
case BROTLI_DECODER_SUCCESS: case BROTLI_DECODER_SUCCESS:
return BROTLI_DECODER_RESULT_SUCCESS; return BROTLI_DECODER_RESULT_SUCCESS;
@ -135,7 +139,7 @@ static BROTLI_NOINLINE BrotliDecoderResult SaveErrorCode(
Precondition: bit-reader accumulator has at least 8 bits. */ Precondition: bit-reader accumulator has at least 8 bits. */
static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s, static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
BrotliBitReader* br) { BrotliBitReader* br) {
uint32_t n; brotli_reg_t n;
BROTLI_BOOL large_window = s->large_window; BROTLI_BOOL large_window = s->large_window;
s->large_window = BROTLI_FALSE; s->large_window = BROTLI_FALSE;
BrotliTakeBits(br, 1, &n); BrotliTakeBits(br, 1, &n);
@ -145,7 +149,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
} }
BrotliTakeBits(br, 3, &n); BrotliTakeBits(br, 3, &n);
if (n != 0) { if (n != 0) {
s->window_bits = 17 + n; s->window_bits = (17u + n) & 63u;
return BROTLI_DECODER_SUCCESS; return BROTLI_DECODER_SUCCESS;
} }
BrotliTakeBits(br, 3, &n); BrotliTakeBits(br, 3, &n);
@ -162,7 +166,7 @@ static BrotliDecoderErrorCode DecodeWindowBits(BrotliDecoderState* s,
} }
} }
if (n != 0) { if (n != 0) {
s->window_bits = 8 + n; s->window_bits = (8u + n) & 63u;
return BROTLI_DECODER_SUCCESS; return BROTLI_DECODER_SUCCESS;
} }
s->window_bits = 17; s->window_bits = 17;
@ -181,8 +185,8 @@ static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
/* 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_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8( static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
BrotliDecoderState* s, BrotliBitReader* br, uint32_t* value) { BrotliDecoderState* s, BrotliBitReader* br, brotli_reg_t* value) {
uint32_t bits; brotli_reg_t bits;
switch (s->substate_decode_uint8) { switch (s->substate_decode_uint8) {
case BROTLI_STATE_DECODE_UINT8_NONE: case BROTLI_STATE_DECODE_UINT8_NONE:
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) { if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, 1, &bits))) {
@ -226,7 +230,7 @@ static BROTLI_NOINLINE BrotliDecoderErrorCode DecodeVarLenUint8(
/* Decodes a metablock length and flags by reading 2 - 31 bits. */ /* Decodes a metablock length and flags by reading 2 - 31 bits. */
static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength( static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
BrotliDecoderState* s, BrotliBitReader* br) { BrotliDecoderState* s, BrotliBitReader* br) {
uint32_t bits; brotli_reg_t bits;
int i; int i;
for (;;) { for (;;) {
switch (s->substate_metablock_header) { switch (s->substate_metablock_header) {
@ -349,13 +353,13 @@ static BrotliDecoderErrorCode BROTLI_NOINLINE DecodeMetaBlockLength(
This method doesn't read data from the bit reader, BUT drops the amount of This method doesn't read data from the bit reader, BUT drops the amount of
bits that correspond to the decoded symbol. bits that correspond to the decoded symbol.
bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */ bits MUST contain at least 15 (BROTLI_HUFFMAN_MAX_CODE_LENGTH) valid bits. */
static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits, static BROTLI_INLINE brotli_reg_t DecodeSymbol(brotli_reg_t bits,
const HuffmanCode* table, const HuffmanCode* table,
BrotliBitReader* br) { BrotliBitReader* br) {
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK); BROTLI_HC_ADJUST_TABLE_INDEX(table, bits & HUFFMAN_TABLE_MASK);
if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) { if (BROTLI_HC_FAST_LOAD_BITS(table) > HUFFMAN_TABLE_BITS) {
uint32_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS; brotli_reg_t nbits = BROTLI_HC_FAST_LOAD_BITS(table) - HUFFMAN_TABLE_BITS;
BrotliDropBits(br, HUFFMAN_TABLE_BITS); BrotliDropBits(br, HUFFMAN_TABLE_BITS);
BROTLI_HC_ADJUST_TABLE_INDEX(table, BROTLI_HC_ADJUST_TABLE_INDEX(table,
BROTLI_HC_FAST_LOAD_VALUE(table) + BROTLI_HC_FAST_LOAD_VALUE(table) +
@ -367,17 +371,17 @@ static BROTLI_INLINE uint32_t DecodeSymbol(uint32_t bits,
/* Reads and decodes the next Huffman code from bit-stream. /* Reads and decodes the next Huffman code from bit-stream.
This method peeks 16 bits of input and drops 0 - 15 of them. */ This method peeks 16 bits of input and drops 0 - 15 of them. */
static BROTLI_INLINE uint32_t ReadSymbol(const HuffmanCode* table, static BROTLI_INLINE brotli_reg_t ReadSymbol(const HuffmanCode* table,
BrotliBitReader* br) { BrotliBitReader* br) {
return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br); return DecodeSymbol(BrotliGet16BitsUnmasked(br), table, br);
} }
/* Same as DecodeSymbol, but it is known that there is less than 15 bits of /* Same as DecodeSymbol, but it is known that there is less than 15 bits of
input are currently available. */ input are currently available. */
static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol( static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) { const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
uint32_t val; brotli_reg_t val;
uint32_t available_bits = BrotliGetAvailableBits(br); brotli_reg_t available_bits = BrotliGetAvailableBits(br);
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table); BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(table);
if (available_bits == 0) { if (available_bits == 0) {
if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) { if (BROTLI_HC_FAST_LOAD_BITS(table) == 0) {
@ -386,7 +390,7 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
} }
return BROTLI_FALSE; /* No valid bits at all. */ return BROTLI_FALSE; /* No valid bits at all. */
} }
val = (uint32_t)BrotliGetBitsUnmasked(br); val = BrotliGetBitsUnmasked(br);
BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK); BROTLI_HC_ADJUST_TABLE_INDEX(table, val & HUFFMAN_TABLE_MASK);
if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) { if (BROTLI_HC_FAST_LOAD_BITS(table) <= HUFFMAN_TABLE_BITS) {
if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) { if (BROTLI_HC_FAST_LOAD_BITS(table) <= available_bits) {
@ -415,8 +419,8 @@ static BROTLI_NOINLINE BROTLI_BOOL SafeDecodeSymbol(
} }
static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol( static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) { const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
uint32_t val; brotli_reg_t val;
if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) { if (BROTLI_PREDICT_TRUE(BrotliSafeGetBits(br, 15, &val))) {
*result = DecodeSymbol(val, table, br); *result = DecodeSymbol(val, table, br);
return BROTLI_TRUE; return BROTLI_TRUE;
@ -428,8 +432,8 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadSymbol(
static BROTLI_INLINE void PreloadSymbol(int safe, static BROTLI_INLINE void PreloadSymbol(int safe,
const HuffmanCode* table, const HuffmanCode* table,
BrotliBitReader* br, BrotliBitReader* br,
uint32_t* bits, brotli_reg_t* bits,
uint32_t* value) { brotli_reg_t* value) {
if (safe) { if (safe) {
return; return;
} }
@ -441,15 +445,15 @@ static BROTLI_INLINE void PreloadSymbol(int safe,
/* Decodes the next Huffman code using data prepared by PreloadSymbol. /* Decodes the next Huffman code using data prepared by PreloadSymbol.
Reads 0 - 15 bits. Also peeks 8 following bits. */ Reads 0 - 15 bits. Also peeks 8 following bits. */
static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table, static BROTLI_INLINE brotli_reg_t ReadPreloadedSymbol(const HuffmanCode* table,
BrotliBitReader* br, BrotliBitReader* br,
uint32_t* bits, brotli_reg_t* bits,
uint32_t* value) { brotli_reg_t* value) {
uint32_t result = *value; brotli_reg_t result = *value;
if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) { if (BROTLI_PREDICT_FALSE(*bits > HUFFMAN_TABLE_BITS)) {
uint32_t val = BrotliGet16BitsUnmasked(br); brotli_reg_t val = BrotliGet16BitsUnmasked(br);
const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value; const HuffmanCode* ext = table + (val & HUFFMAN_TABLE_MASK) + *value;
uint32_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS)); brotli_reg_t mask = BitMask((*bits - HUFFMAN_TABLE_BITS));
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext); BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(ext);
BrotliDropBits(br, HUFFMAN_TABLE_BITS); BrotliDropBits(br, HUFFMAN_TABLE_BITS);
BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask); BROTLI_HC_ADJUST_TABLE_INDEX(ext, (val >> HUFFMAN_TABLE_BITS) & mask);
@ -462,8 +466,8 @@ static BROTLI_INLINE uint32_t ReadPreloadedSymbol(const HuffmanCode* table,
return result; return result;
} }
static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) { static BROTLI_INLINE brotli_reg_t Log2Floor(brotli_reg_t x) {
uint32_t result = 0; brotli_reg_t result = 0;
while (x) { while (x) {
x >>= 1; x >>= 1;
++result; ++result;
@ -475,16 +479,16 @@ static BROTLI_INLINE uint32_t Log2Floor(uint32_t x) {
Totally 1..4 symbols are read, 1..11 bits each. Totally 1..4 symbols are read, 1..11 bits each.
The list of symbols MUST NOT contain duplicates. */ The list of symbols MUST NOT contain duplicates. */
static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols( static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
uint32_t alphabet_size_max, uint32_t alphabet_size_limit, brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
BrotliDecoderState* s) { BrotliDecoderState* s) {
/* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */ /* max_bits == 1..11; symbol == 0..3; 1..44 bits will be read. */
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
BrotliMetablockHeaderArena* h = &s->arena.header; BrotliMetablockHeaderArena* h = &s->arena.header;
uint32_t max_bits = Log2Floor(alphabet_size_max - 1); brotli_reg_t max_bits = Log2Floor(alphabet_size_max - 1);
uint32_t i = h->sub_loop_counter; brotli_reg_t i = h->sub_loop_counter;
uint32_t num_symbols = h->symbol; brotli_reg_t num_symbols = h->symbol;
while (i <= num_symbols) { while (i <= num_symbols) {
uint32_t v; brotli_reg_t v;
if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) { if (BROTLI_PREDICT_FALSE(!BrotliSafeReadBits(br, max_bits, &v))) {
h->sub_loop_counter = i; h->sub_loop_counter = i;
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ; h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_READ;
@ -500,7 +504,7 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
} }
for (i = 0; i < num_symbols; ++i) { for (i = 0; i < num_symbols; ++i) {
uint32_t k = i + 1; brotli_reg_t k = i + 1;
for (; k <= num_symbols; ++k) { for (; k <= num_symbols; ++k) {
if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) { if (h->symbols_lists_array[i] == h->symbols_lists_array[k]) {
return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME); return BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_SIMPLE_HUFFMAN_SAME);
@ -517,9 +521,9 @@ static BrotliDecoderErrorCode ReadSimpleHuffmanSymbols(
C) extend corresponding index-chain C) extend corresponding index-chain
D) reduce the Huffman space D) reduce the Huffman space
E) update the histogram */ E) update the histogram */
static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len, static BROTLI_INLINE void ProcessSingleCodeLength(brotli_reg_t code_len,
uint32_t* symbol, uint32_t* repeat, uint32_t* space, brotli_reg_t* symbol, brotli_reg_t* repeat, brotli_reg_t* space,
uint32_t* prev_code_len, uint16_t* symbol_lists, brotli_reg_t* prev_code_len, uint16_t* symbol_lists,
uint16_t* code_length_histo, int* next_symbol) { uint16_t* code_length_histo, int* next_symbol) {
*repeat = 0; *repeat = 0;
if (code_len != 0) { /* code_len == 1..15 */ if (code_len != 0) { /* code_len == 1..15 */
@ -544,14 +548,14 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or PRECONDITION: code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH or
code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */ code_len == BROTLI_REPEAT_ZERO_CODE_LENGTH */
static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len, static BROTLI_INLINE void ProcessRepeatedCodeLength(brotli_reg_t code_len,
uint32_t repeat_delta, uint32_t alphabet_size, uint32_t* symbol, brotli_reg_t repeat_delta, brotli_reg_t alphabet_size, brotli_reg_t* symbol,
uint32_t* repeat, uint32_t* space, uint32_t* prev_code_len, brotli_reg_t* repeat, brotli_reg_t* space, brotli_reg_t* prev_code_len,
uint32_t* repeat_code_len, uint16_t* symbol_lists, brotli_reg_t* repeat_code_len, uint16_t* symbol_lists,
uint16_t* code_length_histo, int* next_symbol) { uint16_t* code_length_histo, int* next_symbol) {
uint32_t old_repeat; brotli_reg_t old_repeat;
uint32_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ brotli_reg_t extra_bits = 3; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
uint32_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */ brotli_reg_t new_len = 0; /* for BROTLI_REPEAT_ZERO_CODE_LENGTH */
if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) { if (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) {
new_len = *prev_code_len; new_len = *prev_code_len;
extra_bits = 2; extra_bits = 2;
@ -576,7 +580,7 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n", BROTLI_LOG(("[ReadHuffmanCode] code_length[%d..%d] = %d\n",
(int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len)); (int)*symbol, (int)(*symbol + repeat_delta - 1), (int)*repeat_code_len));
if (*repeat_code_len != 0) { if (*repeat_code_len != 0) {
unsigned last = *symbol + repeat_delta; brotli_reg_t last = *symbol + repeat_delta;
int next = next_symbol[*repeat_code_len]; int next = next_symbol[*repeat_code_len];
do { do {
symbol_lists[next] = (uint16_t)*symbol; symbol_lists[next] = (uint16_t)*symbol;
@ -593,14 +597,14 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
/* Reads and decodes symbol codelengths. */ /* Reads and decodes symbol codelengths. */
static BrotliDecoderErrorCode ReadSymbolCodeLengths( static BrotliDecoderErrorCode ReadSymbolCodeLengths(
uint32_t alphabet_size, BrotliDecoderState* s) { brotli_reg_t alphabet_size, BrotliDecoderState* s) {
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
BrotliMetablockHeaderArena* h = &s->arena.header; BrotliMetablockHeaderArena* h = &s->arena.header;
uint32_t symbol = h->symbol; brotli_reg_t symbol = h->symbol;
uint32_t repeat = h->repeat; brotli_reg_t repeat = h->repeat;
uint32_t space = h->space; brotli_reg_t space = h->space;
uint32_t prev_code_len = h->prev_code_len; brotli_reg_t prev_code_len = h->prev_code_len;
uint32_t repeat_code_len = h->repeat_code_len; brotli_reg_t repeat_code_len = h->repeat_code_len;
uint16_t* symbol_lists = h->symbol_lists; uint16_t* symbol_lists = h->symbol_lists;
uint16_t* code_length_histo = h->code_length_histo; uint16_t* code_length_histo = h->code_length_histo;
int* next_symbol = h->next_symbol; int* next_symbol = h->next_symbol;
@ -609,9 +613,9 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
} }
while (symbol < alphabet_size && space > 0) { while (symbol < alphabet_size && space > 0) {
const HuffmanCode* p = h->table; const HuffmanCode* p = h->table;
uint32_t code_len; brotli_reg_t code_len;
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p); BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
if (!BrotliCheckInputAmount(br, BROTLI_SHORT_FILL_BIT_WINDOW_READ)) { if (!BrotliCheckInputAmount(br)) {
h->symbol = symbol; h->symbol = symbol;
h->repeat = repeat; h->repeat = repeat;
h->prev_code_len = prev_code_len; h->prev_code_len = prev_code_len;
@ -628,10 +632,10 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
ProcessSingleCodeLength(code_len, &symbol, &repeat, &space, ProcessSingleCodeLength(code_len, &symbol, &repeat, &space,
&prev_code_len, symbol_lists, code_length_histo, next_symbol); &prev_code_len, symbol_lists, code_length_histo, next_symbol);
} else { /* code_len == 16..17, extra_bits == 2..3 */ } else { /* code_len == 16..17, extra_bits == 2..3 */
uint32_t extra_bits = brotli_reg_t extra_bits =
(code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3; (code_len == BROTLI_REPEAT_PREVIOUS_CODE_LENGTH) ? 2 : 3;
uint32_t repeat_delta = brotli_reg_t repeat_delta =
(uint32_t)BrotliGetBitsUnmasked(br) & BitMask(extra_bits); BrotliGetBitsUnmasked(br) & BitMask(extra_bits);
BrotliDropBits(br, extra_bits); BrotliDropBits(br, extra_bits);
ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size, ProcessRepeatedCodeLength(code_len, repeat_delta, alphabet_size,
&symbol, &repeat, &space, &prev_code_len, &repeat_code_len, &symbol, &repeat, &space, &prev_code_len, &repeat_code_len,
@ -643,15 +647,15 @@ static BrotliDecoderErrorCode ReadSymbolCodeLengths(
} }
static BrotliDecoderErrorCode SafeReadSymbolCodeLengths( static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
uint32_t alphabet_size, BrotliDecoderState* s) { brotli_reg_t alphabet_size, BrotliDecoderState* s) {
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
BrotliMetablockHeaderArena* h = &s->arena.header; BrotliMetablockHeaderArena* h = &s->arena.header;
BROTLI_BOOL get_byte = BROTLI_FALSE; BROTLI_BOOL get_byte = BROTLI_FALSE;
while (h->symbol < alphabet_size && h->space > 0) { while (h->symbol < alphabet_size && h->space > 0) {
const HuffmanCode* p = h->table; const HuffmanCode* p = h->table;
uint32_t code_len; brotli_reg_t code_len;
uint32_t available_bits; brotli_reg_t available_bits;
uint32_t bits = 0; brotli_reg_t bits = 0;
BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p); BROTLI_HC_MARK_TABLE_FOR_FAST_LOAD(p);
if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT; if (get_byte && !BrotliPullByte(br)) return BROTLI_DECODER_NEEDS_MORE_INPUT;
get_byte = BROTLI_FALSE; get_byte = BROTLI_FALSE;
@ -672,8 +676,8 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
&h->prev_code_len, h->symbol_lists, h->code_length_histo, &h->prev_code_len, h->symbol_lists, h->code_length_histo,
h->next_symbol); h->next_symbol);
} else { /* code_len == 16..17, extra_bits == 2..3 */ } else { /* code_len == 16..17, extra_bits == 2..3 */
uint32_t extra_bits = code_len - 14U; brotli_reg_t extra_bits = code_len - 14U;
uint32_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) & brotli_reg_t repeat_delta = (bits >> BROTLI_HC_FAST_LOAD_BITS(p)) &
BitMask(extra_bits); BitMask(extra_bits);
if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) { if (available_bits < BROTLI_HC_FAST_LOAD_BITS(p) + extra_bits) {
get_byte = BROTLI_TRUE; get_byte = BROTLI_TRUE;
@ -694,15 +698,15 @@ static BrotliDecoderErrorCode SafeReadSymbolCodeLengths(
static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) { static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
BrotliMetablockHeaderArena* h = &s->arena.header; BrotliMetablockHeaderArena* h = &s->arena.header;
uint32_t num_codes = h->repeat; brotli_reg_t num_codes = h->repeat;
unsigned space = h->space; brotli_reg_t space = h->space;
uint32_t i = h->sub_loop_counter; brotli_reg_t i = h->sub_loop_counter;
for (; i < BROTLI_CODE_LENGTH_CODES; ++i) { for (; i < BROTLI_CODE_LENGTH_CODES; ++i) {
const uint8_t code_len_idx = kCodeLengthCodeOrder[i]; const uint8_t code_len_idx = kCodeLengthCodeOrder[i];
uint32_t ix; brotli_reg_t ix;
uint32_t v; brotli_reg_t v;
if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) { if (BROTLI_PREDICT_FALSE(!BrotliSafeGetBits(br, 4, &ix))) {
uint32_t available_bits = BrotliGetAvailableBits(br); brotli_reg_t available_bits = BrotliGetAvailableBits(br);
if (available_bits != 0) { if (available_bits != 0) {
ix = BrotliGetBitsUnmasked(br) & 0xF; ix = BrotliGetBitsUnmasked(br) & 0xF;
} else { } else {
@ -747,10 +751,10 @@ static BrotliDecoderErrorCode ReadCodeLengthCodeLengths(BrotliDecoderState* s) {
encoded with predefined entropy code. 32 - 74 bits are used. encoded with predefined entropy code. 32 - 74 bits are used.
B.2) Decoded table is used to decode code lengths of symbols in resulting B.2) Decoded table is used to decode code lengths of symbols in resulting
Huffman table. In worst case 3520 bits are read. */ Huffman table. In worst case 3520 bits are read. */
static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max, static BrotliDecoderErrorCode ReadHuffmanCode(brotli_reg_t alphabet_size_max,
uint32_t alphabet_size_limit, brotli_reg_t alphabet_size_limit,
HuffmanCode* table, HuffmanCode* table,
uint32_t* opt_table_size, brotli_reg_t* opt_table_size,
BrotliDecoderState* s) { BrotliDecoderState* s) {
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
BrotliMetablockHeaderArena* h = &s->arena.header; BrotliMetablockHeaderArena* h = &s->arena.header;
@ -796,9 +800,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: { case BROTLI_STATE_HUFFMAN_SIMPLE_BUILD: {
uint32_t table_size; brotli_reg_t table_size;
if (h->symbol == 3) { if (h->symbol == 3) {
uint32_t bits; brotli_reg_t bits;
if (!BrotliSafeReadBits(br, 1, &bits)) { if (!BrotliSafeReadBits(br, 1, &bits)) {
h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD; h->substate_huffman = BROTLI_STATE_HUFFMAN_SIMPLE_BUILD;
return BROTLI_DECODER_NEEDS_MORE_INPUT; return BROTLI_DECODER_NEEDS_MORE_INPUT;
@ -806,8 +810,9 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
h->symbol += bits; h->symbol += bits;
} }
BROTLI_LOG_UINT(h->symbol); BROTLI_LOG_UINT(h->symbol);
table_size = BrotliBuildSimpleHuffmanTable( table_size = BrotliBuildSimpleHuffmanTable(table, HUFFMAN_TABLE_BITS,
table, HUFFMAN_TABLE_BITS, h->symbols_lists_array, h->symbol); h->symbols_lists_array,
(uint32_t)h->symbol);
if (opt_table_size) { if (opt_table_size) {
*opt_table_size = table_size; *opt_table_size = table_size;
} }
@ -817,7 +822,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
/* Decode Huffman-coded code lengths. */ /* Decode Huffman-coded code lengths. */
case BROTLI_STATE_HUFFMAN_COMPLEX: { case BROTLI_STATE_HUFFMAN_COMPLEX: {
uint32_t i; brotli_reg_t i;
BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s); BrotliDecoderErrorCode result = ReadCodeLengthCodeLengths(s);
if (result != BROTLI_DECODER_SUCCESS) { if (result != BROTLI_DECODER_SUCCESS) {
return result; return result;
@ -841,7 +846,7 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: { case BROTLI_STATE_HUFFMAN_LENGTH_SYMBOLS: {
uint32_t table_size; brotli_reg_t table_size;
BrotliDecoderErrorCode result = ReadSymbolCodeLengths( BrotliDecoderErrorCode result = ReadSymbolCodeLengths(
alphabet_size_limit, s); alphabet_size_limit, s);
if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) { if (result == BROTLI_DECODER_NEEDS_MORE_INPUT) {
@ -872,10 +877,10 @@ static BrotliDecoderErrorCode ReadHuffmanCode(uint32_t alphabet_size_max,
} }
/* Decodes a block length by reading 3..39 bits. */ /* Decodes a block length by reading 3..39 bits. */
static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table, static BROTLI_INLINE brotli_reg_t ReadBlockLength(const HuffmanCode* table,
BrotliBitReader* br) { BrotliBitReader* br) {
uint32_t code; brotli_reg_t code;
uint32_t nbits; brotli_reg_t nbits;
code = ReadSymbol(table, br); code = ReadSymbol(table, br);
nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */ nbits = _kBrotliPrefixCodeRanges[code].nbits; /* nbits == 2..24 */
return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits); return _kBrotliPrefixCodeRanges[code].offset + BrotliReadBits24(br, nbits);
@ -884,9 +889,9 @@ static BROTLI_INLINE uint32_t ReadBlockLength(const HuffmanCode* table,
/* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then /* WARNING: if state is not BROTLI_STATE_READ_BLOCK_LENGTH_NONE, then
reading can't be continued with ReadBlockLength. */ reading can't be continued with ReadBlockLength. */
static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength( static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
BrotliDecoderState* s, uint32_t* result, const HuffmanCode* table, BrotliDecoderState* s, brotli_reg_t* result, const HuffmanCode* table,
BrotliBitReader* br) { BrotliBitReader* br) {
uint32_t index; brotli_reg_t index;
if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) { if (s->substate_read_block_length == BROTLI_STATE_READ_BLOCK_LENGTH_NONE) {
if (!SafeReadSymbol(table, br, &index)) { if (!SafeReadSymbol(table, br, &index)) {
return BROTLI_FALSE; return BROTLI_FALSE;
@ -895,9 +900,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
index = s->block_length_index; index = s->block_length_index;
} }
{ {
uint32_t bits; brotli_reg_t bits;
uint32_t nbits = _kBrotliPrefixCodeRanges[index].nbits; brotli_reg_t nbits = _kBrotliPrefixCodeRanges[index].nbits;
uint32_t offset = _kBrotliPrefixCodeRanges[index].offset; brotli_reg_t offset = _kBrotliPrefixCodeRanges[index].offset;
if (!BrotliSafeReadBits(br, nbits, &bits)) { if (!BrotliSafeReadBits(br, nbits, &bits)) {
s->block_length_index = index; s->block_length_index = index;
s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX; s->substate_read_block_length = BROTLI_STATE_READ_BLOCK_LENGTH_SUFFIX;
@ -924,10 +929,10 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBlockLength(
Most of input values are 0 and 1. To reduce number of branches, we replace Most of input values are 0 and 1. To reduce number of branches, we replace
inner for loop with do-while. */ inner for loop with do-while. */
static BROTLI_NOINLINE void InverseMoveToFrontTransform( static BROTLI_NOINLINE void InverseMoveToFrontTransform(
uint8_t* v, uint32_t v_len, BrotliDecoderState* state) { uint8_t* v, brotli_reg_t v_len, BrotliDecoderState* state) {
/* Reinitialize elements that could have been changed. */ /* Reinitialize elements that could have been changed. */
uint32_t i = 1; brotli_reg_t i = 1;
uint32_t upper_bound = state->mtf_upper_bound; brotli_reg_t upper_bound = state->mtf_upper_bound;
uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */ uint32_t* mtf = &state->mtf[1]; /* Make mtf[-1] addressable. */
uint8_t* mtf_u8 = (uint8_t*)mtf; uint8_t* mtf_u8 = (uint8_t*)mtf;
/* Load endian-aware constant. */ /* Load endian-aware constant. */
@ -970,7 +975,7 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP; h->substate_tree_group = BROTLI_STATE_TREE_GROUP_LOOP;
} }
while (h->htree_index < group->num_htrees) { while (h->htree_index < group->num_htrees) {
uint32_t table_size; brotli_reg_t table_size;
BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max, BrotliDecoderErrorCode result = ReadHuffmanCode(group->alphabet_size_max,
group->alphabet_size_limit, h->next, &table_size, s); group->alphabet_size_limit, h->next, &table_size, s);
if (result != BROTLI_DECODER_SUCCESS) return result; if (result != BROTLI_DECODER_SUCCESS) return result;
@ -990,8 +995,8 @@ static BrotliDecoderErrorCode HuffmanTreeGroupDecode(
This table will be used for reading context map items. This table will be used for reading context map items.
3) Read context map items; "0" values could be run-length encoded. 3) Read context map items; "0" values could be run-length encoded.
4) Optionally, apply InverseMoveToFront transform to the resulting map. */ 4) Optionally, apply InverseMoveToFront transform to the resulting map. */
static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size, static BrotliDecoderErrorCode DecodeContextMap(brotli_reg_t context_map_size,
uint32_t* num_htrees, brotli_reg_t* num_htrees,
uint8_t** context_map_arg, uint8_t** context_map_arg,
BrotliDecoderState* s) { BrotliDecoderState* s) {
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
@ -1021,7 +1026,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: { case BROTLI_STATE_CONTEXT_MAP_READ_PREFIX: {
uint32_t bits; brotli_reg_t bits;
/* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe /* In next stage ReadHuffmanCode uses at least 4 bits, so it is safe
to peek 4 bits ahead. */ to peek 4 bits ahead. */
if (!BrotliSafeGetBits(br, 5, &bits)) { if (!BrotliSafeGetBits(br, 5, &bits)) {
@ -1040,7 +1045,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: { case BROTLI_STATE_CONTEXT_MAP_HUFFMAN: {
uint32_t alphabet_size = *num_htrees + h->max_run_length_prefix; brotli_reg_t alphabet_size = *num_htrees + h->max_run_length_prefix;
result = ReadHuffmanCode(alphabet_size, alphabet_size, result = ReadHuffmanCode(alphabet_size, alphabet_size,
h->context_map_table, NULL, s); h->context_map_table, NULL, s);
if (result != BROTLI_DECODER_SUCCESS) return result; if (result != BROTLI_DECODER_SUCCESS) return result;
@ -1050,10 +1055,10 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_CONTEXT_MAP_DECODE: { case BROTLI_STATE_CONTEXT_MAP_DECODE: {
uint32_t context_index = h->context_index; brotli_reg_t context_index = h->context_index;
uint32_t max_run_length_prefix = h->max_run_length_prefix; brotli_reg_t max_run_length_prefix = h->max_run_length_prefix;
uint8_t* context_map = *context_map_arg; uint8_t* context_map = *context_map_arg;
uint32_t code = h->code; brotli_reg_t code = h->code;
BROTLI_BOOL skip_preamble = (code != 0xFFFF); BROTLI_BOOL skip_preamble = (code != 0xFFFF);
while (context_index < context_map_size || skip_preamble) { while (context_index < context_map_size || skip_preamble) {
if (!skip_preamble) { if (!skip_preamble) {
@ -1078,7 +1083,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
} }
/* RLE sub-stage. */ /* RLE sub-stage. */
{ {
uint32_t reps; brotli_reg_t reps;
if (!BrotliSafeReadBits(br, code, &reps)) { if (!BrotliSafeReadBits(br, code, &reps)) {
h->code = code; h->code = code;
h->context_index = context_index; h->context_index = context_index;
@ -1099,7 +1104,7 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: { case BROTLI_STATE_CONTEXT_MAP_TRANSFORM: {
uint32_t bits; brotli_reg_t bits;
if (!BrotliSafeReadBits(br, 1, &bits)) { if (!BrotliSafeReadBits(br, 1, &bits)) {
h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM; h->substate_context_map = BROTLI_STATE_CONTEXT_MAP_TRANSFORM;
return BROTLI_DECODER_NEEDS_MORE_INPUT; return BROTLI_DECODER_NEEDS_MORE_INPUT;
@ -1121,14 +1126,14 @@ static BrotliDecoderErrorCode DecodeContextMap(uint32_t context_map_size,
Reads 3..54 bits. */ Reads 3..54 bits. */
static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength( static BROTLI_INLINE BROTLI_BOOL DecodeBlockTypeAndLength(
int safe, BrotliDecoderState* s, int tree_type) { int safe, BrotliDecoderState* s, int tree_type) {
uint32_t max_block_type = s->num_block_types[tree_type]; brotli_reg_t max_block_type = s->num_block_types[tree_type];
const HuffmanCode* type_tree = &s->block_type_trees[ const HuffmanCode* type_tree = &s->block_type_trees[
tree_type * BROTLI_HUFFMAN_MAX_SIZE_258]; tree_type * BROTLI_HUFFMAN_MAX_SIZE_258];
const HuffmanCode* len_tree = &s->block_len_trees[ const HuffmanCode* len_tree = &s->block_len_trees[
tree_type * BROTLI_HUFFMAN_MAX_SIZE_26]; tree_type * BROTLI_HUFFMAN_MAX_SIZE_26];
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
uint32_t* ringbuffer = &s->block_type_rb[tree_type * 2]; brotli_reg_t* ringbuffer = &s->block_type_rb[tree_type * 2];
uint32_t block_type; brotli_reg_t block_type;
if (max_block_type <= 1) { if (max_block_type <= 1) {
return BROTLI_FALSE; return BROTLI_FALSE;
} }
@ -1173,6 +1178,7 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
size_t sample = s->context_map[offset]; size_t sample = s->context_map[offset];
size_t j; size_t j;
for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) { for (j = 0; j < (1u << BROTLI_LITERAL_CONTEXT_BITS);) {
/* NOLINTNEXTLINE(bugprone-macro-repeated-side-effects) */
BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; }) BROTLI_REPEAT_4({ error |= s->context_map[offset + j++] ^ sample; })
} }
if (error == 0) { if (error == 0) {
@ -1184,8 +1190,8 @@ static BROTLI_INLINE void DetectTrivialLiteralBlockTypes(
static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) { static BROTLI_INLINE void PrepareLiteralDecoding(BrotliDecoderState* s) {
uint8_t context_mode; uint8_t context_mode;
size_t trivial; size_t trivial;
uint32_t block_type = s->block_type_rb[1]; brotli_reg_t block_type = s->block_type_rb[1];
uint32_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS; brotli_reg_t context_offset = block_type << BROTLI_LITERAL_CONTEXT_BITS;
s->context_map_slice = s->context_map + context_offset; s->context_map_slice = s->context_map + context_offset;
trivial = s->trivial_literal_contexts[block_type >> 5]; trivial = s->trivial_literal_contexts[block_type >> 5];
s->trivial_literal_context = (trivial >> (block_type & 31)) & 1; s->trivial_literal_context = (trivial >> (block_type & 31)) & 1;
@ -1549,8 +1555,8 @@ static int CopyFromCompoundDictionary(BrotliDecoderState* s, int pos) {
BROTLI_BOOL BrotliDecoderAttachDictionary( BROTLI_BOOL BrotliDecoderAttachDictionary(
BrotliDecoderState* state, BrotliSharedDictionaryType type, BrotliDecoderState* state, BrotliSharedDictionaryType type,
size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) { size_t data_size, const uint8_t data[BROTLI_ARRAY_PARAM(data_size)]) {
uint32_t i; brotli_reg_t i;
uint32_t num_prefix_before = state->dictionary->num_prefix; brotli_reg_t num_prefix_before = state->dictionary->num_prefix;
if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE; if (state->state != BROTLI_STATE_UNINITED) return BROTLI_FALSE;
if (!BrotliSharedDictionaryAttach(state->dictionary, type, data_size, data)) { if (!BrotliSharedDictionaryAttach(state->dictionary, type, data_size, data)) {
return BROTLI_FALSE; return BROTLI_FALSE;
@ -1616,7 +1622,7 @@ static BrotliDecoderErrorCode ReadContextModes(BrotliDecoderState* s) {
int i = s->loop_counter; int i = s->loop_counter;
while (i < (int)s->num_block_types[0]) { while (i < (int)s->num_block_types[0]) {
uint32_t bits; brotli_reg_t bits;
if (!BrotliSafeReadBits(br, 2, &bits)) { if (!BrotliSafeReadBits(br, 2, &bits)) {
s->loop_counter = i; s->loop_counter = i;
return BROTLI_DECODER_NEEDS_MORE_INPUT; return BROTLI_DECODER_NEEDS_MORE_INPUT;
@ -1656,7 +1662,7 @@ static BROTLI_INLINE void TakeDistanceFromRingBuffer(BrotliDecoderState* s) {
} }
static BROTLI_INLINE BROTLI_BOOL SafeReadBits( static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
if (n_bits != 0) { if (n_bits != 0) {
return BrotliSafeReadBits(br, n_bits, val); return BrotliSafeReadBits(br, n_bits, val);
} else { } else {
@ -1666,7 +1672,7 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits(
} }
static BROTLI_INLINE BROTLI_BOOL SafeReadBits32( static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) { BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
if (n_bits != 0) { if (n_bits != 0) {
return BrotliSafeReadBits32(br, n_bits, val); return BrotliSafeReadBits32(br, n_bits, val);
} else { } else {
@ -1744,16 +1750,16 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadBits32(
NB: it is possible to have all 64 tables precalculated. */ NB: it is possible to have all 64 tables precalculated. */
static void CalculateDistanceLut(BrotliDecoderState* s) { static void CalculateDistanceLut(BrotliDecoderState* s) {
BrotliMetablockBodyArena* b = &s->arena.body; BrotliMetablockBodyArena* b = &s->arena.body;
uint32_t npostfix = s->distance_postfix_bits; brotli_reg_t npostfix = s->distance_postfix_bits;
uint32_t ndirect = s->num_direct_distance_codes; brotli_reg_t ndirect = s->num_direct_distance_codes;
uint32_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit; brotli_reg_t alphabet_size_limit = s->distance_hgroup.alphabet_size_limit;
uint32_t postfix = 1u << npostfix; brotli_reg_t postfix = 1u << npostfix;
uint32_t j; brotli_reg_t j;
uint32_t bits = 1; brotli_reg_t bits = 1;
uint32_t half = 0; brotli_reg_t half = 0;
/* Skip short codes. */ /* Skip short codes. */
uint32_t i = BROTLI_NUM_DISTANCE_SHORT_CODES; brotli_reg_t i = BROTLI_NUM_DISTANCE_SHORT_CODES;
/* Fill direct codes. */ /* Fill direct codes. */
for (j = 0; j < ndirect; ++j) { for (j = 0; j < ndirect; ++j) {
@ -1764,7 +1770,7 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
/* Fill regular distance codes. */ /* Fill regular distance codes. */
while (i < alphabet_size_limit) { while (i < alphabet_size_limit) {
uint32_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1; brotli_reg_t base = ndirect + ((((2 + half) << bits) - 4) << npostfix) + 1;
/* Always fill the complete group. */ /* Always fill the complete group. */
for (j = 0; j < postfix; ++j) { for (j = 0; j < postfix; ++j) {
b->dist_extra_bits[i] = (uint8_t)bits; b->dist_extra_bits[i] = (uint8_t)bits;
@ -1780,8 +1786,8 @@ static void CalculateDistanceLut(BrotliDecoderState* s) {
static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal( static BROTLI_INLINE BROTLI_BOOL ReadDistanceInternal(
int safe, BrotliDecoderState* s, BrotliBitReader* br) { int safe, BrotliDecoderState* s, BrotliBitReader* br) {
BrotliMetablockBodyArena* b = &s->arena.body; BrotliMetablockBodyArena* b = &s->arena.body;
uint32_t code; brotli_reg_t code;
uint32_t bits; brotli_reg_t bits;
BrotliBitReaderState memento; BrotliBitReaderState memento;
HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index]; HuffmanCode* distance_tree = s->distance_hgroup.htrees[s->dist_htree_index];
if (!safe) { if (!safe) {
@ -1827,9 +1833,9 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadDistance(
static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal( static BROTLI_INLINE BROTLI_BOOL ReadCommandInternal(
int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) { int safe, BrotliDecoderState* s, BrotliBitReader* br, int* insert_length) {
uint32_t cmd_code; brotli_reg_t cmd_code;
uint32_t insert_len_extra = 0; brotli_reg_t insert_len_extra = 0;
uint32_t copy_length; brotli_reg_t copy_length;
CmdLutElement v; CmdLutElement v;
BrotliBitReaderState memento; BrotliBitReaderState memento;
if (!safe) { if (!safe) {
@ -1874,11 +1880,11 @@ static BROTLI_INLINE BROTLI_BOOL SafeReadCommand(
} }
static BROTLI_INLINE BROTLI_BOOL CheckInputAmount( static BROTLI_INLINE BROTLI_BOOL CheckInputAmount(
int safe, BrotliBitReader* const br, size_t num) { int safe, BrotliBitReader* const br) {
if (safe) { if (safe) {
return BROTLI_TRUE; return BROTLI_TRUE;
} }
return BrotliCheckInputAmount(br, num); return BrotliCheckInputAmount(br);
} }
#define BROTLI_SAFE(METHOD) \ #define BROTLI_SAFE(METHOD) \
@ -1901,7 +1907,7 @@ static BROTLI_INLINE BrotliDecoderErrorCode ProcessCommandsInternal(
BrotliBitReader* br = &s->br; BrotliBitReader* br = &s->br;
int compound_dictionary_size = GetCompoundDictionarySize(s); int compound_dictionary_size = GetCompoundDictionarySize(s);
if (!CheckInputAmount(safe, br, 28)) { if (!CheckInputAmount(safe, br)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
} }
@ -1926,7 +1932,7 @@ CommandBegin:
if (safe) { if (safe) {
s->state = BROTLI_STATE_COMMAND_BEGIN; s->state = BROTLI_STATE_COMMAND_BEGIN;
} }
if (!CheckInputAmount(safe, br, 28)) { /* 156 bits + 7 bytes */ if (!CheckInputAmount(safe, br)) {
s->state = BROTLI_STATE_COMMAND_BEGIN; s->state = BROTLI_STATE_COMMAND_BEGIN;
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
@ -1950,25 +1956,23 @@ CommandInner:
} }
/* Read the literals in the command. */ /* Read the literals in the command. */
if (s->trivial_literal_context) { if (s->trivial_literal_context) {
uint32_t bits; brotli_reg_t bits;
uint32_t value; brotli_reg_t value;
PreloadSymbol(safe, s->literal_htree, br, &bits, &value); PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
do { do {
if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */ if (!CheckInputAmount(safe, br)) {
s->state = BROTLI_STATE_COMMAND_INNER; s->state = BROTLI_STATE_COMMAND_INNER;
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
} }
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) { if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); goto NextLiteralBlock;
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
if (!s->trivial_literal_context) goto CommandInner;
} }
if (!safe) { if (!safe) {
s->ringbuffer[pos] = s->ringbuffer[pos] =
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value); (uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
} else { } else {
uint32_t literal; brotli_reg_t literal;
if (!SafeReadSymbol(s->literal_htree, br, &literal)) { if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
@ -1990,14 +1994,13 @@ CommandInner:
do { do {
const HuffmanCode* hc; const HuffmanCode* hc;
uint8_t context; uint8_t context;
if (!CheckInputAmount(safe, br, 28)) { /* 162 bits + 7 bytes */ if (!CheckInputAmount(safe, br)) {
s->state = BROTLI_STATE_COMMAND_INNER; s->state = BROTLI_STATE_COMMAND_INNER;
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
} }
if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) { if (BROTLI_PREDICT_FALSE(s->block_length[0] == 0)) {
BROTLI_SAFE(DecodeLiteralBlockSwitch(s)); goto NextLiteralBlock;
if (s->trivial_literal_context) goto CommandInner;
} }
context = BROTLI_CONTEXT(p1, p2, s->context_lookup); context = BROTLI_CONTEXT(p1, p2, s->context_lookup);
BROTLI_LOG_UINT(context); BROTLI_LOG_UINT(context);
@ -2006,7 +2009,7 @@ CommandInner:
if (!safe) { if (!safe) {
p1 = (uint8_t)ReadSymbol(hc, br); p1 = (uint8_t)ReadSymbol(hc, br);
} else { } else {
uint32_t literal; brotli_reg_t literal;
if (!SafeReadSymbol(hc, br, &literal)) { if (!SafeReadSymbol(hc, br, &literal)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
goto saveStateAndReturn; goto saveStateAndReturn;
@ -2087,7 +2090,7 @@ CommandPostDecodeLiterals:
const BrotliDictionary* words = s->dictionary->words[dict_id]; const BrotliDictionary* words = s->dictionary->words[dict_id];
const BrotliTransforms* transforms = s->dictionary->transforms[dict_id]; const BrotliTransforms* transforms = s->dictionary->transforms[dict_id];
int offset = (int)words->offsets_by_length[i]; int offset = (int)words->offsets_by_length[i];
uint32_t shift = words->size_bits_by_length[i]; brotli_reg_t shift = words->size_bits_by_length[i];
int address = int address =
s->distance_code - s->max_distance - 1 - compound_dictionary_size; s->distance_code - s->max_distance - 1 - compound_dictionary_size;
int mask = (int)BitMask(shift); int mask = (int)BitMask(shift);
@ -2110,7 +2113,7 @@ CommandPostDecodeLiterals:
if (dict_id2 != dict_id && words2->size_bits_by_length[i] != 0) { if (dict_id2 != dict_id && words2->size_bits_by_length[i] != 0) {
const BrotliTransforms* transforms2 = const BrotliTransforms* transforms2 =
s->dictionary->transforms[dict_id2]; s->dictionary->transforms[dict_id2];
uint32_t shift2 = words2->size_bits_by_length[i]; brotli_reg_t shift2 = words2->size_bits_by_length[i];
int num = (int)((1u << shift2) & ~1u) * int num = (int)((1u << shift2) & ~1u) *
(int)transforms2->num_transforms; (int)transforms2->num_transforms;
if (dist_remaining < num) { if (dist_remaining < num) {
@ -2236,6 +2239,10 @@ CommandPostWrapCopy:
goto CommandBegin; goto CommandBegin;
} }
NextLiteralBlock:
BROTLI_SAFE(DecodeLiteralBlockSwitch(s));
goto CommandInner;
saveStateAndReturn: saveStateAndReturn:
s->pos = pos; s->pos = pos;
s->loop_counter = i; s->loop_counter = i;
@ -2312,14 +2319,13 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
} }
if (!*available_out) next_out = 0; if (!*available_out) next_out = 0;
if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */ if (s->buffer_length == 0) { /* Just connect bit reader to input stream. */
br->avail_in = *available_in; BrotliBitReaderSetInput(br, *next_in, *available_in);
br->next_in = *next_in;
} else { } else {
/* At least one byte of input is required. More than one byte of input may /* At least one byte of input is required. More than one byte of input may
be required to complete the transaction -> reading more data must be be required to complete the transaction -> reading more data must be
done in a loop -> do it in a main loop. */ done in a loop -> do it in a main loop. */
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
br->next_in = &s->buffer.u8[0]; BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
} }
/* State machine */ /* State machine */
for (;;) { for (;;) {
@ -2336,23 +2342,23 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
} }
} }
if (s->buffer_length != 0) { /* Used with internal buffer. */ if (s->buffer_length != 0) { /* Used with internal buffer. */
if (br->avail_in == 0) { if (br->next_in == br->last_in) {
/* Successfully finished read transaction. /* Successfully finished read transaction.
Accumulator contains less than 8 bits, because internal buffer Accumulator contains less than 8 bits, because internal buffer
is expanded byte-by-byte until it is enough to complete read. */ is expanded byte-by-byte until it is enough to complete read. */
s->buffer_length = 0; s->buffer_length = 0;
/* Switch to input stream and restart. */ /* Switch to input stream and restart. */
result = BROTLI_DECODER_SUCCESS; result = BROTLI_DECODER_SUCCESS;
br->avail_in = *available_in; BrotliBitReaderSetInput(br, *next_in, *available_in);
br->next_in = *next_in;
continue; continue;
} else if (*available_in != 0) { } else if (*available_in != 0) {
/* Not enough data in buffer, but can take one more byte from /* Not enough data in buffer, but can take one more byte from
input stream. */ input stream. */
result = BROTLI_DECODER_SUCCESS; result = BROTLI_DECODER_SUCCESS;
BROTLI_DCHECK(s->buffer_length < 8);
s->buffer.u8[s->buffer_length] = **next_in; s->buffer.u8[s->buffer_length] = **next_in;
s->buffer_length++; s->buffer_length++;
br->avail_in = s->buffer_length; BrotliBitReaderSetInput(br, &s->buffer.u8[0], s->buffer_length);
(*next_in)++; (*next_in)++;
(*available_in)--; (*available_in)--;
/* Retry with more data in buffer. */ /* Retry with more data in buffer. */
@ -2363,7 +2369,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
} else { /* Input stream doesn't contain enough input. */ } else { /* Input stream doesn't contain enough input. */
/* Copy tail to internal buffer and return. */ /* Copy tail to internal buffer and return. */
*next_in = br->next_in; *next_in = br->next_in;
*available_in = br->avail_in; *available_in = BrotliBitReaderGetAvailIn(br);
while (*available_in) { while (*available_in) {
s->buffer.u8[s->buffer_length] = **next_in; s->buffer.u8[s->buffer_length] = **next_in;
s->buffer_length++; s->buffer_length++;
@ -2386,7 +2392,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
stream it has less than 8 bits in accumulator, so it is safe to stream it has less than 8 bits in accumulator, so it is safe to
return unused accumulator bits there. */ return unused accumulator bits there. */
BrotliBitReaderUnload(br); BrotliBitReaderUnload(br);
*available_in = br->avail_in; *available_in = BrotliBitReaderGetAvailIn(br);
*next_in = br->next_in; *next_in = br->next_in;
} }
break; break;
@ -2410,17 +2416,20 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
s->state = BROTLI_STATE_INITIALIZE; s->state = BROTLI_STATE_INITIALIZE;
break; break;
case BROTLI_STATE_LARGE_WINDOW_BITS: case BROTLI_STATE_LARGE_WINDOW_BITS: {
if (!BrotliSafeReadBits(br, 6, &s->window_bits)) { brotli_reg_t bits;
if (!BrotliSafeReadBits(br, 6, &bits)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
break; break;
} }
s->window_bits = bits & 63u;
if (s->window_bits < BROTLI_LARGE_MIN_WBITS || if (s->window_bits < BROTLI_LARGE_MIN_WBITS ||
s->window_bits > BROTLI_LARGE_MAX_WBITS) { s->window_bits > BROTLI_LARGE_MAX_WBITS) {
result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS); result = BROTLI_FAILURE(BROTLI_DECODER_ERROR_FORMAT_WINDOW_BITS);
break; break;
} }
s->state = BROTLI_STATE_INITIALIZE; s->state = BROTLI_STATE_INITIALIZE;
}
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_INITIALIZE: case BROTLI_STATE_INITIALIZE:
@ -2518,7 +2527,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_HUFFMAN_CODE_1: { case BROTLI_STATE_HUFFMAN_CODE_1: {
uint32_t alphabet_size = s->num_block_types[s->loop_counter] + 2; brotli_reg_t alphabet_size = s->num_block_types[s->loop_counter] + 2;
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258; int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_258;
result = ReadHuffmanCode(alphabet_size, alphabet_size, result = ReadHuffmanCode(alphabet_size, alphabet_size,
&s->block_type_trees[tree_offset], NULL, s); &s->block_type_trees[tree_offset], NULL, s);
@ -2528,7 +2537,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_HUFFMAN_CODE_2: { case BROTLI_STATE_HUFFMAN_CODE_2: {
uint32_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS; brotli_reg_t alphabet_size = BROTLI_NUM_BLOCK_LEN_SYMBOLS;
int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26; int tree_offset = s->loop_counter * BROTLI_HUFFMAN_MAX_SIZE_26;
result = ReadHuffmanCode(alphabet_size, alphabet_size, result = ReadHuffmanCode(alphabet_size, alphabet_size,
&s->block_len_trees[tree_offset], NULL, s); &s->block_len_trees[tree_offset], NULL, s);
@ -2569,7 +2578,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
break; break;
case BROTLI_STATE_METABLOCK_HEADER_2: { case BROTLI_STATE_METABLOCK_HEADER_2: {
uint32_t bits; brotli_reg_t bits;
if (!BrotliSafeReadBits(br, 6, &bits)) { if (!BrotliSafeReadBits(br, 6, &bits)) {
result = BROTLI_DECODER_NEEDS_MORE_INPUT; result = BROTLI_DECODER_NEEDS_MORE_INPUT;
break; break;
@ -2610,15 +2619,16 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
/* Fall through. */ /* Fall through. */
case BROTLI_STATE_CONTEXT_MAP_2: { case BROTLI_STATE_CONTEXT_MAP_2: {
uint32_t npostfix = s->distance_postfix_bits; brotli_reg_t npostfix = s->distance_postfix_bits;
uint32_t ndirect = s->num_direct_distance_codes; brotli_reg_t ndirect = s->num_direct_distance_codes;
uint32_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( brotli_reg_t distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS); npostfix, ndirect, BROTLI_MAX_DISTANCE_BITS);
uint32_t distance_alphabet_size_limit = distance_alphabet_size_max; brotli_reg_t distance_alphabet_size_limit = distance_alphabet_size_max;
BROTLI_BOOL allocation_success = BROTLI_TRUE; BROTLI_BOOL allocation_success = BROTLI_TRUE;
if (s->large_window) { if (s->large_window) {
BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit( BrotliDistanceCodeLimit limit = BrotliCalculateDistanceCodeLimit(
BROTLI_MAX_ALLOWED_DISTANCE, npostfix, ndirect); BROTLI_MAX_ALLOWED_DISTANCE, (uint32_t)npostfix,
(uint32_t)ndirect);
distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE( distance_alphabet_size_max = BROTLI_DISTANCE_ALPHABET_SIZE(
npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS); npostfix, ndirect, BROTLI_LARGE_MAX_DISTANCE_BITS);
distance_alphabet_size_limit = limit.max_alphabet_size; distance_alphabet_size_limit = limit.max_alphabet_size;
@ -2749,7 +2759,7 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
} }
if (s->buffer_length == 0) { if (s->buffer_length == 0) {
BrotliBitReaderUnload(br); BrotliBitReaderUnload(br);
*available_in = br->avail_in; *available_in = BrotliBitReaderGetAvailIn(br);
*next_in = br->next_in; *next_in = br->next_in;
} }
s->state = BROTLI_STATE_DONE; s->state = BROTLI_STATE_DONE;
@ -2821,7 +2831,7 @@ BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s) {
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) { const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c) {
switch (c) { switch (c) {
#define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \ #define BROTLI_ERROR_CODE_CASE_(PREFIX, NAME, CODE) \
case BROTLI_DECODER ## PREFIX ## NAME: return #NAME; case BROTLI_DECODER ## PREFIX ## NAME: return #PREFIX #NAME;
#define BROTLI_NOTHING_ #define BROTLI_NOTHING_
BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_) BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE_CASE_, BROTLI_NOTHING_)
#undef BROTLI_ERROR_CODE_CASE_ #undef BROTLI_ERROR_CODE_CASE_
@ -2846,16 +2856,16 @@ void BrotliDecoderSetMetadataCallbacks(
/* Escalate internal functions visibility; for testing purposes only. */ /* Escalate internal functions visibility; for testing purposes only. */
#if defined(BROTLI_TEST) #if defined(BROTLI_TEST)
BROTLI_BOOL SafeReadSymbolForTest( BROTLI_BOOL SafeReadSymbolForTest(
const HuffmanCode*, BrotliBitReader*, uint32_t*); const HuffmanCode*, BrotliBitReader*, brotli_reg_t*);
BROTLI_BOOL SafeReadSymbolForTest( BROTLI_BOOL SafeReadSymbolForTest(
const HuffmanCode* table, BrotliBitReader* br, uint32_t* result) { const HuffmanCode* table, BrotliBitReader* br, brotli_reg_t* result) {
return SafeReadSymbol(table, br, result); return SafeReadSymbol(table, br, result);
} }
void InverseMoveToFrontTransformForTest( void InverseMoveToFrontTransformForTest(
uint8_t*, uint32_t, BrotliDecoderState*); uint8_t*, brotli_reg_t, BrotliDecoderState*);
void InverseMoveToFrontTransformForTest( void InverseMoveToFrontTransformForTest(
uint8_t* v, uint32_t l, BrotliDecoderState* s) { uint8_t* v, brotli_reg_t l, BrotliDecoderState* s) {
InverseMoveToFrontTransform(v, l, s); InverseMoveToFrontTransform(v, l, s);
} }
#endif #endif

View file

@ -98,9 +98,9 @@ BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) { void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
s->meta_block_remaining_len = 0; s->meta_block_remaining_len = 0;
s->block_length[0] = 1U << 24; s->block_length[0] = BROTLI_BLOCK_SIZE_CAP;
s->block_length[1] = 1U << 24; s->block_length[1] = BROTLI_BLOCK_SIZE_CAP;
s->block_length[2] = 1U << 24; s->block_length[2] = BROTLI_BLOCK_SIZE_CAP;
s->num_block_types[0] = 1; s->num_block_types[0] = 1;
s->num_block_types[1] = 1; s->num_block_types[1] = 1;
s->num_block_types[2] = 1; s->num_block_types[2] = 1;
@ -158,8 +158,8 @@ void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
} }
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s, BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
HuffmanTreeGroup* group, uint32_t alphabet_size_max, HuffmanTreeGroup* group, brotli_reg_t alphabet_size_max,
uint32_t alphabet_size_limit, uint32_t ntrees) { brotli_reg_t alphabet_size_limit, brotli_reg_t ntrees) {
/* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables) /* 376 = 256 (1-st level table) + 4 + 7 + 15 + 31 + 63 (2-nd level mix-tables)
This number is discovered "unlimited" "enough" calculator; it is actually This number is discovered "unlimited" "enough" calculator; it is actually
a wee bigger than required in several cases (especially for alphabets with a wee bigger than required in several cases (especially for alphabets with

View file

@ -211,15 +211,15 @@ typedef struct BrotliMetablockHeaderArena {
BrotliRunningContextMapState substate_context_map; BrotliRunningContextMapState substate_context_map;
BrotliRunningHuffmanState substate_huffman; BrotliRunningHuffmanState substate_huffman;
uint32_t sub_loop_counter; brotli_reg_t sub_loop_counter;
uint32_t repeat_code_len; brotli_reg_t repeat_code_len;
uint32_t prev_code_len; brotli_reg_t prev_code_len;
/* For ReadHuffmanCode. */ /* For ReadHuffmanCode. */
uint32_t symbol; brotli_reg_t symbol;
uint32_t repeat; brotli_reg_t repeat;
uint32_t space; brotli_reg_t space;
/* Huffman table for "histograms". */ /* Huffman table for "histograms". */
HuffmanCode table[32]; HuffmanCode table[32];
@ -233,21 +233,22 @@ typedef struct BrotliMetablockHeaderArena {
uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES]; uint8_t code_length_code_lengths[BROTLI_CODE_LENGTH_CODES];
/* Population counts for the code lengths. */ /* Population counts for the code lengths. */
uint16_t code_length_histo[16]; uint16_t code_length_histo[16];
/* TODO(eustas): +2 bytes padding */
/* For HuffmanTreeGroupDecode. */ /* For HuffmanTreeGroupDecode. */
int htree_index; int htree_index;
HuffmanCode* next; HuffmanCode* next;
/* For DecodeContextMap. */ /* For DecodeContextMap. */
uint32_t context_index; brotli_reg_t context_index;
uint32_t max_run_length_prefix; brotli_reg_t max_run_length_prefix;
uint32_t code; brotli_reg_t code;
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272]; HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
} BrotliMetablockHeaderArena; } BrotliMetablockHeaderArena;
typedef struct BrotliMetablockBodyArena { typedef struct BrotliMetablockBodyArena {
uint8_t dist_extra_bits[544]; uint8_t dist_extra_bits[544];
uint32_t dist_offset[544]; brotli_reg_t dist_offset[544];
} BrotliMetablockBodyArena; } BrotliMetablockBodyArena;
struct BrotliDecoderStateStruct { struct BrotliDecoderStateStruct {
@ -268,7 +269,7 @@ struct BrotliDecoderStateStruct {
uint64_t u64; uint64_t u64;
uint8_t u8[8]; uint8_t u8[8];
} buffer; } buffer;
uint32_t buffer_length; brotli_reg_t buffer_length;
int pos; int pos;
int max_backward_distance; int max_backward_distance;
@ -278,6 +279,8 @@ struct BrotliDecoderStateStruct {
int dist_rb_idx; int dist_rb_idx;
int dist_rb[4]; int dist_rb[4];
int error_code; int error_code;
int meta_block_remaining_len;
uint8_t* ringbuffer; uint8_t* ringbuffer;
uint8_t* ringbuffer_end; uint8_t* ringbuffer_end;
HuffmanCode* htree_command; HuffmanCode* htree_command;
@ -298,29 +301,30 @@ struct BrotliDecoderStateStruct {
/* Distance context is actual after command is decoded and before distance is /* Distance context is actual after command is decoded and before distance is
computed. After distance computation it is used as a temporary variable. */ computed. After distance computation it is used as a temporary variable. */
int distance_context; int distance_context;
int meta_block_remaining_len; brotli_reg_t block_length[3];
uint32_t block_length_index; brotli_reg_t block_length_index;
uint32_t block_length[3]; brotli_reg_t num_block_types[3];
uint32_t num_block_types[3]; brotli_reg_t block_type_rb[6];
uint32_t block_type_rb[6]; brotli_reg_t distance_postfix_bits;
uint32_t distance_postfix_bits; brotli_reg_t num_direct_distance_codes;
uint32_t num_direct_distance_codes; brotli_reg_t num_dist_htrees;
uint32_t num_dist_htrees;
uint8_t* dist_context_map; uint8_t* dist_context_map;
HuffmanCode* literal_htree; HuffmanCode* literal_htree;
uint8_t dist_htree_index;
int copy_length;
int distance_code;
/* For partial write operations. */ /* For partial write operations. */
size_t rb_roundtrips; /* how many times we went around the ring-buffer */ size_t rb_roundtrips; /* how many times we went around the ring-buffer */
size_t partial_pos_out; /* how much output to the user in total */ size_t partial_pos_out; /* how much output to the user in total */
/* For InverseMoveToFrontTransform. */ /* For InverseMoveToFrontTransform. */
uint32_t mtf_upper_bound; brotli_reg_t mtf_upper_bound;
uint32_t mtf[64 + 1]; uint32_t mtf[64 + 1];
int copy_length;
int distance_code;
uint8_t dist_htree_index;
/* TODO(eustas): +3 bytes padding */
/* Less used attributes are at the end of this struct. */ /* Less used attributes are at the end of this struct. */
brotli_decoder_metadata_start_func metadata_start_func; brotli_decoder_metadata_start_func metadata_start_func;
@ -336,18 +340,20 @@ struct BrotliDecoderStateStruct {
BrotliRunningDecodeUint8State substate_decode_uint8; BrotliRunningDecodeUint8State substate_decode_uint8;
BrotliRunningReadBlockLengthState substate_read_block_length; BrotliRunningReadBlockLengthState substate_read_block_length;
int new_ringbuffer_size;
/* TODO(eustas): +4 bytes padding */
unsigned int is_last_metablock : 1; unsigned int is_last_metablock : 1;
unsigned int is_uncompressed : 1; unsigned int is_uncompressed : 1;
unsigned int is_metadata : 1; unsigned int is_metadata : 1;
unsigned int should_wrap_ringbuffer : 1; unsigned int should_wrap_ringbuffer : 1;
unsigned int canny_ringbuffer_allocation : 1; unsigned int canny_ringbuffer_allocation : 1;
unsigned int large_window : 1; unsigned int large_window : 1;
unsigned int window_bits : 6;
unsigned int size_nibbles : 8; unsigned int size_nibbles : 8;
uint32_t window_bits; /* TODO(eustas): +12 bits padding */
int new_ringbuffer_size; brotli_reg_t num_literal_htrees;
uint32_t num_literal_htrees;
uint8_t* context_map; uint8_t* context_map;
uint8_t* context_modes; uint8_t* context_modes;
@ -372,8 +378,9 @@ BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock( BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
BrotliDecoderState* s); BrotliDecoderState* s);
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit( BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size_max, BrotliDecoderState* s, HuffmanTreeGroup* group,
uint32_t alphabet_size_limit, uint32_t ntrees); brotli_reg_t alphabet_size_max, brotli_reg_t alphabet_size_limit,
brotli_reg_t ntrees);
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L) #define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
@ -382,6 +389,10 @@ BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
X = NULL; \ X = NULL; \
} }
/* Literal/Command/Distance block size maximum; same as maximum metablock size;
used as block size when there is no block switching. */
#define BROTLI_BLOCK_SIZE_CAP (1U << 24)
#if defined(__cplusplus) || defined(c_plusplus) #if defined(__cplusplus) || defined(c_plusplus)
} /* extern "C" */ } /* extern "C" */
#endif #endif

View file

@ -357,7 +357,7 @@ BROTLI_DEC_API const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
/** /**
* Gets a decoder library version. * Gets a decoder library version.
* *
* Look at BROTLI_VERSION for more information. * Look at BROTLI_MAKE_HEX_VERSION for more information.
*/ */
BROTLI_DEC_API uint32_t BrotliDecoderVersion(void); BROTLI_DEC_API uint32_t BrotliDecoderVersion(void);

View file

@ -490,7 +490,7 @@ BROTLI_ENC_EXTRA_API size_t BrotliEncoderGetPreparedDictionarySize(
/** /**
* Gets an encoder library version. * Gets an encoder library version.
* *
* Look at BROTLI_VERSION for more information. * Look at BROTLI_MAKE_HEX_VERSION for more information.
*/ */
BROTLI_ENC_API uint32_t BrotliEncoderVersion(void); BROTLI_ENC_API uint32_t BrotliEncoderVersion(void);

View file

@ -35,7 +35,10 @@ typedef struct BrotliSharedDictionaryStruct BrotliSharedDictionary;
typedef enum BrotliSharedDictionaryType { typedef enum BrotliSharedDictionaryType {
/** Raw LZ77 prefix dictionary. */ /** Raw LZ77 prefix dictionary. */
BROTLI_SHARED_DICTIONARY_RAW = 0, BROTLI_SHARED_DICTIONARY_RAW = 0,
/** Serialized shared dictionary. */ /** Serialized shared dictionary.
*
* DO NOT USE: methods accepting this value will fail.
*/
BROTLI_SHARED_DICTIONARY_SERIALIZED = 1 BROTLI_SHARED_DICTIONARY_SERIALIZED = 1
} BrotliSharedDictionaryType; } BrotliSharedDictionaryType;