BaseTools: Update Brotli Compress to the latest one 1.0.6
https://bugzilla.tianocore.org/show_bug.cgi?id=1201 Update Brotli to the latest version 1.0.6 https://github.com/google/brotli Verify VS2017, GCC5 build. Verify Decompression boot functionality. Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Liming Gao <liming.gao@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com>
This commit is contained in:
@@ -8,8 +8,8 @@
|
||||
|
||||
#include "./bit_reader.h"
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./port.h"
|
||||
#include "../common/platform.h"
|
||||
#include <brotli/types.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@@ -24,7 +24,7 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
||||
size_t aligned_read_mask = (sizeof(br->val_) >> 1) - 1;
|
||||
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
||||
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
||||
enough space in accumulator to fix aligment. */
|
||||
enough space in accumulator to fix alignment. */
|
||||
if (!BROTLI_ALIGNED_READ) {
|
||||
aligned_read_mask = 0;
|
||||
}
|
||||
|
@@ -11,22 +11,16 @@
|
||||
|
||||
#include <string.h> /* memcpy */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./port.h"
|
||||
#include "../common/platform.h"
|
||||
#include <brotli/types.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if (BROTLI_64_BITS)
|
||||
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 4
|
||||
typedef uint64_t reg_t;
|
||||
#else
|
||||
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ 2
|
||||
typedef uint32_t reg_t;
|
||||
#endif
|
||||
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
|
||||
|
||||
static const uint32_t kBitMask[33] = { 0x0000,
|
||||
static const uint32_t kBitMask[33] = { 0x00000000,
|
||||
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
||||
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
||||
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
||||
@@ -38,34 +32,35 @@ static const uint32_t kBitMask[33] = { 0x0000,
|
||||
};
|
||||
|
||||
static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
||||
if (IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
||||
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
||||
/* Masking with this expression turns to a single
|
||||
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
|
||||
return ~((0xffffffffU) << n);
|
||||
return ~((0xFFFFFFFFu) << n);
|
||||
} else {
|
||||
return kBitMask[n];
|
||||
}
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
reg_t val_; /* pre-fetched bits */
|
||||
brotli_reg_t val_; /* pre-fetched bits */
|
||||
uint32_t bit_pos_; /* current bit-reading position in val_ */
|
||||
const uint8_t* next_in; /* the byte we're reading from */
|
||||
size_t avail_in;
|
||||
} BrotliBitReader;
|
||||
|
||||
typedef struct {
|
||||
reg_t val_;
|
||||
brotli_reg_t val_;
|
||||
uint32_t bit_pos_;
|
||||
const uint8_t* next_in;
|
||||
size_t avail_in;
|
||||
} BrotliBitReaderState;
|
||||
|
||||
/* Initializes the bitreader fields. */
|
||||
/* Initializes the BrotliBitReader fields. */
|
||||
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);
|
||||
|
||||
/* Ensures that accumulator is not empty. May consume one byte of input.
|
||||
Returns 0 if data is required but there is no input available.
|
||||
/* Ensures that accumulator is not empty.
|
||||
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.
|
||||
For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
|
||||
reading. */
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
|
||||
@@ -97,89 +92,34 @@ static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
|
||||
return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
|
||||
}
|
||||
|
||||
/* Checks if there is at least num bytes left in the input ringbuffer (excluding
|
||||
the bits remaining in br->val_). */
|
||||
/* Checks if there is at least |num| bytes left in the input ring-buffer
|
||||
(excluding the bits remaining in br->val_). */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
||||
BrotliBitReader* const br, size_t num) {
|
||||
return TO_BROTLI_BOOL(br->avail_in >= num);
|
||||
}
|
||||
|
||||
static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) {
|
||||
if (BROTLI_LITTLE_ENDIAN) {
|
||||
return *((const uint16_t*)in);
|
||||
} else if (BROTLI_BIG_ENDIAN) {
|
||||
uint16_t value = *((const uint16_t*)in);
|
||||
return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8));
|
||||
} else {
|
||||
return (uint16_t)(in[0] | (in[1] << 8));
|
||||
}
|
||||
}
|
||||
|
||||
static BROTLI_INLINE uint32_t BrotliLoad32LE(const uint8_t* in) {
|
||||
if (BROTLI_LITTLE_ENDIAN) {
|
||||
return *((const uint32_t*)in);
|
||||
} else if (BROTLI_BIG_ENDIAN) {
|
||||
uint32_t value = *((const uint32_t*)in);
|
||||
return ((value & 0xFFU) << 24) | ((value & 0xFF00U) << 8) |
|
||||
((value & 0xFF0000U) >> 8) | ((value & 0xFF000000U) >> 24);
|
||||
} else {
|
||||
uint32_t value = (uint32_t)(*(in++));
|
||||
value |= (uint32_t)(*(in++)) << 8;
|
||||
value |= (uint32_t)(*(in++)) << 16;
|
||||
value |= (uint32_t)(*(in++)) << 24;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
#if (BROTLI_64_BITS)
|
||||
static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) {
|
||||
if (BROTLI_LITTLE_ENDIAN) {
|
||||
return *((const uint64_t*)in);
|
||||
} else if (BROTLI_BIG_ENDIAN) {
|
||||
uint64_t value = *((const uint64_t*)in);
|
||||
return
|
||||
((value & 0xFFU) << 56) |
|
||||
((value & 0xFF00U) << 40) |
|
||||
((value & 0xFF0000U) << 24) |
|
||||
((value & 0xFF000000U) << 8) |
|
||||
((value & 0xFF00000000U) >> 8) |
|
||||
((value & 0xFF0000000000U) >> 24) |
|
||||
((value & 0xFF000000000000U) >> 40) |
|
||||
((value & 0xFF00000000000000U) >> 56);
|
||||
} else {
|
||||
uint64_t value = (uint64_t)(*(in++));
|
||||
value |= (uint64_t)(*(in++)) << 8;
|
||||
value |= (uint64_t)(*(in++)) << 16;
|
||||
value |= (uint64_t)(*(in++)) << 24;
|
||||
value |= (uint64_t)(*(in++)) << 32;
|
||||
value |= (uint64_t)(*(in++)) << 40;
|
||||
value |= (uint64_t)(*(in++)) << 48;
|
||||
value |= (uint64_t)(*(in++)) << 56;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Guarantees that there are at least n_bits + 1 bits in accumulator.
|
||||
/* Guarantees that there are at least |n_bits| + 1 bits in accumulator.
|
||||
Precondition: accumulator contains at least 1 bit.
|
||||
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. */
|
||||
|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. */
|
||||
static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
#if (BROTLI_64_BITS)
|
||||
if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
||||
if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
||||
if (br->bit_pos_ >= 56) {
|
||||
br->val_ >>= 56;
|
||||
br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */
|
||||
br->val_ |= BrotliLoad64LE(br->next_in) << 8;
|
||||
br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8;
|
||||
br->avail_in -= 7;
|
||||
br->next_in += 7;
|
||||
}
|
||||
} else if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 16)) {
|
||||
} else if (
|
||||
!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 16)) {
|
||||
if (br->bit_pos_ >= 48) {
|
||||
br->val_ >>= 48;
|
||||
br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */
|
||||
br->val_ |= BrotliLoad64LE(br->next_in) << 16;
|
||||
br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16;
|
||||
br->avail_in -= 6;
|
||||
br->next_in += 6;
|
||||
}
|
||||
@@ -187,17 +127,17 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
if (br->bit_pos_ >= 32) {
|
||||
br->val_ >>= 32;
|
||||
br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */
|
||||
br->val_ |= ((uint64_t)BrotliLoad32LE(br->next_in)) << 32;
|
||||
br->val_ |= ((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32;
|
||||
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
||||
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
||||
}
|
||||
}
|
||||
#else
|
||||
if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
||||
if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
|
||||
if (br->bit_pos_ >= 24) {
|
||||
br->val_ >>= 24;
|
||||
br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */
|
||||
br->val_ |= BrotliLoad32LE(br->next_in) << 8;
|
||||
br->val_ |= BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8;
|
||||
br->avail_in -= 3;
|
||||
br->next_in += 3;
|
||||
}
|
||||
@@ -205,7 +145,7 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
if (br->bit_pos_ >= 16) {
|
||||
br->val_ >>= 16;
|
||||
br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */
|
||||
br->val_ |= ((uint32_t)BrotliLoad16LE(br->next_in)) << 16;
|
||||
br->val_ |= ((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16;
|
||||
br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
||||
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
||||
}
|
||||
@@ -213,13 +153,14 @@ static BROTLI_INLINE void BrotliFillBitWindow(
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Mosltly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
|
||||
/* Mostly like BrotliFillBitWindow, but guarantees only 16 bits and reads no
|
||||
more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */
|
||||
static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
|
||||
BrotliFillBitWindow(br, 17);
|
||||
}
|
||||
|
||||
/* Pulls one byte of input to accumulator. */
|
||||
/* Tries to pull one byte of input to accumulator.
|
||||
Returns BROTLI_FALSE if there is no input available. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
||||
if (br->avail_in == 0) {
|
||||
return BROTLI_FALSE;
|
||||
@@ -237,8 +178,9 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
||||
}
|
||||
|
||||
/* Returns currently available bits.
|
||||
The number of valid bits could be calclulated by BrotliGetAvailableBits. */
|
||||
static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) {
|
||||
The number of valid bits could be calculated by BrotliGetAvailableBits. */
|
||||
static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
|
||||
BrotliBitReader* const br) {
|
||||
return br->val_ >> br->bit_pos_;
|
||||
}
|
||||
|
||||
@@ -250,15 +192,16 @@ static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(
|
||||
return (uint32_t)BrotliGetBitsUnmasked(br);
|
||||
}
|
||||
|
||||
/* Returns the specified number of bits from br without advancing bit pos. */
|
||||
/* Returns the specified number of bits from |br| without advancing bit
|
||||
position. */
|
||||
static BROTLI_INLINE uint32_t BrotliGetBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
BrotliFillBitWindow(br, n_bits);
|
||||
return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
}
|
||||
|
||||
/* Tries to peek the specified amount of bits. Returns 0, if there is not
|
||||
enough input. */
|
||||
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
|
||||
is not enough input. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||
@@ -270,7 +213,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
/* Advances the bit pos by n_bits. */
|
||||
/* Advances the bit pos by |n_bits|. */
|
||||
static BROTLI_INLINE void BrotliDropBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
br->bit_pos_ += n_bits;
|
||||
@@ -289,17 +232,17 @@ static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
||||
br->bit_pos_ += unused_bits;
|
||||
}
|
||||
|
||||
/* Reads the specified number of bits from br and advances the bit pos.
|
||||
Precondition: accumulator MUST contain at least n_bits. */
|
||||
/* Reads the specified number of bits from |br| and advances the bit pos.
|
||||
Precondition: accumulator MUST contain at least |n_bits|. */
|
||||
static BROTLI_INLINE void BrotliTakeBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
*val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
||||
BROTLI_LOG(("[BrotliReadBits] %d %d %d val: %6x\n",
|
||||
(int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val));
|
||||
(int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
|
||||
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. */
|
||||
static BROTLI_INLINE uint32_t BrotliReadBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits) {
|
||||
@@ -319,8 +262,8 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
|
||||
}
|
||||
}
|
||||
|
||||
/* Tries to read the specified amount of bits. Returns 0, if there is not
|
||||
enough input. n_bits MUST be positive. */
|
||||
/* Tries to read the specified amount of bits. Returns BROTLI_FALSE, if there
|
||||
is not enough input. |n_bits| MUST be positive. */
|
||||
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||
@@ -343,25 +286,8 @@ static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
||||
return TO_BROTLI_BOOL(pad_bits == 0);
|
||||
}
|
||||
|
||||
/* Peeks a byte at specified offset.
|
||||
Precondition: bit reader is parked to a byte boundary.
|
||||
Returns -1 if operation is not feasible. */
|
||||
static BROTLI_INLINE int BrotliPeekByte(BrotliBitReader* br, size_t offset) {
|
||||
uint32_t available_bits = BrotliGetAvailableBits(br);
|
||||
size_t bytes_left = available_bits >> 3;
|
||||
BROTLI_DCHECK((available_bits & 7) == 0);
|
||||
if (offset < bytes_left) {
|
||||
return (BrotliGetBitsUnmasked(br) >> (unsigned)(offset << 3)) & 0xFF;
|
||||
}
|
||||
offset -= bytes_left;
|
||||
if (offset < br->avail_in) {
|
||||
return br->next_in[offset];
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
||||
num may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
||||
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
||||
warmed up again after this. */
|
||||
static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
||||
BrotliBitReader* br, size_t num) {
|
||||
|
@@ -1,251 +0,0 @@
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Lookup table to map the previous two bytes to a context id.
|
||||
|
||||
There are four different context modeling modes defined here:
|
||||
CONTEXT_LSB6: context id is the least significant 6 bits of the last byte,
|
||||
CONTEXT_MSB6: context id is the most significant 6 bits of the last byte,
|
||||
CONTEXT_UTF8: second-order context model tuned for UTF8-encoded text,
|
||||
CONTEXT_SIGNED: second-order context model tuned for signed integers.
|
||||
|
||||
The context id for the UTF8 context model is calculated as follows. If p1
|
||||
and p2 are the previous two bytes, we calculate the context as
|
||||
|
||||
context = kContextLookup[p1] | kContextLookup[p2 + 256].
|
||||
|
||||
If the previous two bytes are ASCII characters (i.e. < 128), this will be
|
||||
equivalent to
|
||||
|
||||
context = 4 * context1(p1) + context2(p2),
|
||||
|
||||
where context1 is based on the previous byte in the following way:
|
||||
|
||||
0 : non-ASCII control
|
||||
1 : \t, \n, \r
|
||||
2 : space
|
||||
3 : other punctuation
|
||||
4 : " '
|
||||
5 : %
|
||||
6 : ( < [ {
|
||||
7 : ) > ] }
|
||||
8 : , ; :
|
||||
9 : .
|
||||
10 : =
|
||||
11 : number
|
||||
12 : upper-case vowel
|
||||
13 : upper-case consonant
|
||||
14 : lower-case vowel
|
||||
15 : lower-case consonant
|
||||
|
||||
and context2 is based on the second last byte:
|
||||
|
||||
0 : control, space
|
||||
1 : punctuation
|
||||
2 : upper-case letter, number
|
||||
3 : lower-case letter
|
||||
|
||||
If the last byte is ASCII, and the second last byte is not (in a valid UTF8
|
||||
stream it will be a continuation byte, value between 128 and 191), the
|
||||
context is the same as if the second last byte was an ASCII control or space.
|
||||
|
||||
If the last byte is a UTF8 lead byte (value >= 192), then the next byte will
|
||||
be a continuation byte and the context id is 2 or 3 depending on the LSB of
|
||||
the last byte and to a lesser extent on the second last byte if it is ASCII.
|
||||
|
||||
If the last byte is a UTF8 continuation byte, the second last byte can be:
|
||||
- continuation byte: the next byte is probably ASCII or lead byte (assuming
|
||||
4-byte UTF8 characters are rare) and the context id is 0 or 1.
|
||||
- lead byte (192 - 207): next byte is ASCII or lead byte, context is 0 or 1
|
||||
- lead byte (208 - 255): next byte is continuation byte, context is 2 or 3
|
||||
|
||||
The possible value combinations of the previous two bytes, the range of
|
||||
context ids and the type of the next byte is summarized in the table below:
|
||||
|
||||
|--------\-----------------------------------------------------------------|
|
||||
| \ Last byte |
|
||||
| Second \---------------------------------------------------------------|
|
||||
| last byte \ ASCII | cont. byte | lead byte |
|
||||
| \ (0-127) | (128-191) | (192-) |
|
||||
|=============|===================|=====================|==================|
|
||||
| ASCII | next: ASCII/lead | not valid | next: cont. |
|
||||
| (0-127) | context: 4 - 63 | | context: 2 - 3 |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| cont. byte | next: ASCII/lead | next: ASCII/lead | next: cont. |
|
||||
| (128-191) | context: 4 - 63 | context: 0 - 1 | context: 2 - 3 |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| lead byte | not valid | next: ASCII/lead | not valid |
|
||||
| (192-207) | | context: 0 - 1 | |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
| lead byte | not valid | next: cont. | not valid |
|
||||
| (208-) | | context: 2 - 3 | |
|
||||
|-------------|-------------------|---------------------|------------------|
|
||||
|
||||
The context id for the signed context mode is calculated as:
|
||||
|
||||
context = (kContextLookup[512 + p1] << 3) | kContextLookup[512 + p2].
|
||||
|
||||
For any context modeling modes, the context ids can be calculated by |-ing
|
||||
together two lookups from one table using context model dependent offsets:
|
||||
|
||||
context = kContextLookup[offset1 + p1] | kContextLookup[offset2 + p2].
|
||||
|
||||
where offset1 and offset2 are dependent on the context mode.
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_CONTEXT_H_
|
||||
#define BROTLI_DEC_CONTEXT_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
enum ContextType {
|
||||
CONTEXT_LSB6 = 0,
|
||||
CONTEXT_MSB6 = 1,
|
||||
CONTEXT_UTF8 = 2,
|
||||
CONTEXT_SIGNED = 3
|
||||
};
|
||||
|
||||
/* Common context lookup table for all context modes. */
|
||||
static const uint8_t kContextLookup[1792] = {
|
||||
/* CONTEXT_UTF8, last byte. */
|
||||
/* ASCII range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 0, 0, 4, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
8, 12, 16, 12, 12, 20, 12, 16, 24, 28, 12, 12, 32, 12, 36, 12,
|
||||
44, 44, 44, 44, 44, 44, 44, 44, 44, 44, 32, 32, 24, 40, 28, 12,
|
||||
12, 48, 52, 52, 52, 48, 52, 52, 52, 48, 52, 52, 52, 52, 52, 48,
|
||||
52, 52, 52, 52, 52, 48, 52, 52, 52, 52, 52, 24, 12, 28, 12, 12,
|
||||
12, 56, 60, 60, 60, 56, 60, 60, 60, 56, 60, 60, 60, 60, 60, 56,
|
||||
60, 60, 60, 60, 60, 56, 60, 60, 60, 60, 60, 24, 12, 28, 12, 0,
|
||||
/* UTF8 continuation byte range. */
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1,
|
||||
/* UTF8 lead byte range. */
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
/* CONTEXT_UTF8 second last byte. */
|
||||
/* ASCII range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1,
|
||||
1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1,
|
||||
1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 0,
|
||||
/* UTF8 continuation byte range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
/* UTF8 lead byte range. */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
/* CONTEXT_SIGNED, second last byte. */
|
||||
0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
|
||||
6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7,
|
||||
/* CONTEXT_SIGNED, last byte, same as the above values shifted by 3 bits. */
|
||||
0, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32, 32,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||
40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40,
|
||||
48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 56,
|
||||
/* CONTEXT_LSB6, last byte. */
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
|
||||
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
|
||||
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
|
||||
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
|
||||
/* CONTEXT_MSB6, last byte. */
|
||||
0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3,
|
||||
4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7,
|
||||
8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11,
|
||||
12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15,
|
||||
16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 19,
|
||||
20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 23, 23, 23, 23,
|
||||
24, 24, 24, 24, 25, 25, 25, 25, 26, 26, 26, 26, 27, 27, 27, 27,
|
||||
28, 28, 28, 28, 29, 29, 29, 29, 30, 30, 30, 30, 31, 31, 31, 31,
|
||||
32, 32, 32, 32, 33, 33, 33, 33, 34, 34, 34, 34, 35, 35, 35, 35,
|
||||
36, 36, 36, 36, 37, 37, 37, 37, 38, 38, 38, 38, 39, 39, 39, 39,
|
||||
40, 40, 40, 40, 41, 41, 41, 41, 42, 42, 42, 42, 43, 43, 43, 43,
|
||||
44, 44, 44, 44, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47,
|
||||
48, 48, 48, 48, 49, 49, 49, 49, 50, 50, 50, 50, 51, 51, 51, 51,
|
||||
52, 52, 52, 52, 53, 53, 53, 53, 54, 54, 54, 54, 55, 55, 55, 55,
|
||||
56, 56, 56, 56, 57, 57, 57, 57, 58, 58, 58, 58, 59, 59, 59, 59,
|
||||
60, 60, 60, 60, 61, 61, 61, 61, 62, 62, 62, 62, 63, 63, 63, 63,
|
||||
/* CONTEXT_{M,L}SB6, second last byte, */
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
static const int kContextLookupOffsets[8] = {
|
||||
/* CONTEXT_LSB6 */
|
||||
1024, 1536,
|
||||
/* CONTEXT_MSB6 */
|
||||
1280, 1536,
|
||||
/* CONTEXT_UTF8 */
|
||||
0, 256,
|
||||
/* CONTEXT_SIGNED */
|
||||
768, 512,
|
||||
};
|
||||
|
||||
#endif /* BROTLI_DEC_CONTEXT_H_ */
|
File diff suppressed because it is too large
Load Diff
@@ -1,188 +0,0 @@
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* API for Brotli decompression */
|
||||
|
||||
#ifndef BROTLI_DEC_DECODE_H_
|
||||
#define BROTLI_DEC_DECODE_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct BrotliDecoderStateStruct BrotliDecoderState;
|
||||
|
||||
typedef enum {
|
||||
/* Decoding error, e.g. corrupt input or memory allocation problem */
|
||||
BROTLI_DECODER_RESULT_ERROR = 0,
|
||||
/* Decoding successfully completed */
|
||||
BROTLI_DECODER_RESULT_SUCCESS = 1,
|
||||
/* Partially done; should be called again with more input */
|
||||
BROTLI_DECODER_RESULT_NEEDS_MORE_INPUT = 2,
|
||||
/* Partially done; should be called again with more output */
|
||||
BROTLI_DECODER_RESULT_NEEDS_MORE_OUTPUT = 3
|
||||
} BrotliDecoderResult;
|
||||
|
||||
#define BROTLI_DECODER_ERROR_CODES_LIST(BROTLI_ERROR_CODE, SEPARATOR) \
|
||||
BROTLI_ERROR_CODE(_, NO_ERROR, 0) SEPARATOR \
|
||||
/* Same as BrotliDecoderResult values */ \
|
||||
BROTLI_ERROR_CODE(_, SUCCESS, 1) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_, NEEDS_MORE_INPUT, 2) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_, NEEDS_MORE_OUTPUT, 3) SEPARATOR \
|
||||
\
|
||||
/* Errors caused by invalid input */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_NIBBLE, -1) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, RESERVED, -2) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, EXUBERANT_META_NIBBLE, -3) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_ALPHABET, -4) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, SIMPLE_HUFFMAN_SAME, -5) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, CL_SPACE, -6) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, HUFFMAN_SPACE, -7) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, CONTEXT_MAP_REPEAT, -8) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_1, -9) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, BLOCK_LENGTH_2, -10) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, TRANSFORM, -11) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, DICTIONARY, -12) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, WINDOW_BITS, -13) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_1, -14) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_FORMAT_, PADDING_2, -15) SEPARATOR \
|
||||
\
|
||||
/* -16..-20 codes are reserved */ \
|
||||
\
|
||||
/* Memory allocation problems */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MODES, -21) SEPARATOR \
|
||||
/* Literal, insert and distance trees together */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, TREE_GROUPS, -22) SEPARATOR \
|
||||
/* -23..-24 codes are reserved for distinct tree groups */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, CONTEXT_MAP, -25) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_1, -26) SEPARATOR \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, RING_BUFFER_2, -27) SEPARATOR \
|
||||
/* -28..-29 codes are reserved for dynamic ringbuffer allocation */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_ALLOC_, BLOCK_TYPE_TREES, -30) SEPARATOR \
|
||||
\
|
||||
/* "Impossible" states */ \
|
||||
BROTLI_ERROR_CODE(_ERROR_, UNREACHABLE, -31)
|
||||
|
||||
typedef enum {
|
||||
#define _BROTLI_COMMA ,
|
||||
#define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
|
||||
BROTLI_DECODER ## PREFIX ## NAME = CODE
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
|
||||
#undef _BROTLI_ERROR_CODE_ENUM_ITEM
|
||||
#undef _BROTLI_COMMA
|
||||
} BrotliDecoderErrorCode;
|
||||
|
||||
#define BROTLI_LAST_ERROR_CODE BROTLI_DECODER_ERROR_UNREACHABLE
|
||||
|
||||
/* Creates the instance of BrotliDecoderState and initializes it. |alloc_func|
|
||||
and |free_func| MUST be both zero or both non-zero. In the case they are both
|
||||
zero, default memory allocators are used. |opaque| is passed to |alloc_func|
|
||||
and |free_func| when they are called. */
|
||||
BrotliDecoderState* BrotliDecoderCreateInstance(
|
||||
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
|
||||
|
||||
/* Deinitializes and frees BrotliDecoderState instance. */
|
||||
void BrotliDecoderDestroyInstance(BrotliDecoderState* state);
|
||||
|
||||
/* Decompresses the data in |encoded_buffer| into |decoded_buffer|, and sets
|
||||
|*decoded_size| to the decompressed length. */
|
||||
BrotliDecoderResult BrotliDecoderDecompress(
|
||||
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
|
||||
uint8_t* decoded_buffer);
|
||||
|
||||
/* Decompresses the data. Supports partial input and output.
|
||||
|
||||
Must be called with an allocated input buffer in |*next_in| and an allocated
|
||||
output buffer in |*next_out|. The values |*available_in| and |*available_out|
|
||||
must specify the allocated size in |*next_in| and |*next_out| respectively.
|
||||
|
||||
After each call, |*available_in| will be decremented by the amount of input
|
||||
bytes consumed, and the |*next_in| pointer will be incremented by that
|
||||
amount. Similarly, |*available_out| will be decremented by the amount of
|
||||
output bytes written, and the |*next_out| pointer will be incremented by that
|
||||
amount. |total_out|, if it is not a null-pointer, will be set to the number
|
||||
of bytes decompressed since the last state initialization.
|
||||
|
||||
Input is never overconsumed, so |next_in| and |available_in| could be passed
|
||||
to the next consumer after decoding is complete. */
|
||||
BrotliDecoderResult BrotliDecoderDecompressStream(
|
||||
BrotliDecoderState* s, size_t* available_in, const uint8_t** next_in,
|
||||
size_t* available_out, uint8_t** next_out, size_t* total_out);
|
||||
|
||||
/* Fills the new state with a dictionary for LZ77, warming up the ringbuffer,
|
||||
e.g. for custom static dictionaries for data formats.
|
||||
Not to be confused with the built-in transformable dictionary of Brotli.
|
||||
|size| should be less or equal to 2^24 (16MiB), otherwise the dictionary will
|
||||
be ignored. The dictionary must exist in memory until decoding is done and
|
||||
is owned by the caller. To use:
|
||||
1) Allocate and initialize state with BrotliCreateInstance
|
||||
2) Use BrotliSetCustomDictionary
|
||||
3) Use BrotliDecompressStream
|
||||
4) Clean up and free state with BrotliDestroyState
|
||||
*/
|
||||
void BrotliDecoderSetCustomDictionary(
|
||||
BrotliDecoderState* s, size_t size, const uint8_t* dict);
|
||||
|
||||
/* Returns true, if decoder has some unconsumed output.
|
||||
Otherwise returns false. */
|
||||
BROTLI_BOOL BrotliDecoderHasMoreOutput(const BrotliDecoderState* s);
|
||||
|
||||
/* Returns true, if decoder has already received some input bytes.
|
||||
Otherwise returns false. */
|
||||
BROTLI_BOOL BrotliDecoderIsUsed(const BrotliDecoderState* s);
|
||||
|
||||
/* Returns true, if decoder is in a state where we reached the end of the input
|
||||
and produced all of the output; returns false otherwise. */
|
||||
BROTLI_BOOL BrotliDecoderIsFinished(const BrotliDecoderState* s);
|
||||
|
||||
/* Returns detailed error code after BrotliDecompressStream returns
|
||||
BROTLI_DECODER_RESULT_ERROR. */
|
||||
BrotliDecoderErrorCode BrotliDecoderGetErrorCode(const BrotliDecoderState* s);
|
||||
|
||||
const char* BrotliDecoderErrorString(BrotliDecoderErrorCode c);
|
||||
|
||||
/* DEPRECATED >>> */
|
||||
typedef enum {
|
||||
BROTLI_RESULT_ERROR = 0,
|
||||
BROTLI_RESULT_SUCCESS = 1,
|
||||
BROTLI_RESULT_NEEDS_MORE_INPUT = 2,
|
||||
BROTLI_RESULT_NEEDS_MORE_OUTPUT = 3
|
||||
} BrotliResult;
|
||||
typedef enum {
|
||||
#define _BROTLI_COMMA ,
|
||||
#define _BROTLI_ERROR_CODE_ENUM_ITEM(PREFIX, NAME, CODE) \
|
||||
BROTLI ## PREFIX ## NAME = CODE
|
||||
BROTLI_DECODER_ERROR_CODES_LIST(_BROTLI_ERROR_CODE_ENUM_ITEM, _BROTLI_COMMA)
|
||||
#undef _BROTLI_ERROR_CODE_ENUM_ITEM
|
||||
#undef _BROTLI_COMMA
|
||||
} BrotliErrorCode;
|
||||
typedef struct BrotliStateStruct BrotliState;
|
||||
BrotliState* BrotliCreateState(
|
||||
brotli_alloc_func alloc, brotli_free_func free, void* opaque);
|
||||
void BrotliDestroyState(BrotliState* state);
|
||||
BROTLI_BOOL BrotliDecompressedSize(
|
||||
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size);
|
||||
BrotliResult BrotliDecompressBuffer(
|
||||
size_t encoded_size, const uint8_t* encoded_buffer, size_t* decoded_size,
|
||||
uint8_t* decoded_buffer);
|
||||
BrotliResult BrotliDecompressStream(
|
||||
size_t* available_in, const uint8_t** next_in, size_t* available_out,
|
||||
uint8_t** next_out, size_t* total_out, BrotliState* s);
|
||||
void BrotliSetCustomDictionary(
|
||||
size_t size, const uint8_t* dict, BrotliState* s);
|
||||
BROTLI_BOOL BrotliStateIsStreamStart(const BrotliState* s);
|
||||
BROTLI_BOOL BrotliStateIsStreamEnd(const BrotliState* s);
|
||||
BrotliErrorCode BrotliGetErrorCode(const BrotliState* s);
|
||||
const char* BrotliErrorString(BrotliErrorCode c);
|
||||
/* <<< DEPRECATED */
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* BROTLI_DEC_DECODE_H_ */
|
@@ -11,8 +11,8 @@
|
||||
#include <string.h> /* memcpy, memset */
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "./port.h"
|
||||
#include "../common/platform.h"
|
||||
#include <brotli/types.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@@ -20,8 +20,9 @@ extern "C" {
|
||||
|
||||
#define BROTLI_REVERSE_BITS_MAX 8
|
||||
|
||||
#ifdef BROTLI_RBIT
|
||||
#define BROTLI_REVERSE_BITS_BASE (32 - BROTLI_REVERSE_BITS_MAX)
|
||||
#if defined(BROTLI_RBIT)
|
||||
#define BROTLI_REVERSE_BITS_BASE \
|
||||
((sizeof(brotli_reg_t) << 3) - BROTLI_REVERSE_BITS_MAX)
|
||||
#else
|
||||
#define BROTLI_REVERSE_BITS_BASE 0
|
||||
static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
|
||||
@@ -61,13 +62,13 @@ static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
|
||||
#endif /* BROTLI_RBIT */
|
||||
|
||||
#define BROTLI_REVERSE_BITS_LOWEST \
|
||||
(1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
|
||||
((brotli_reg_t)1 << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
|
||||
|
||||
/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
|
||||
where reverse(value, len) is the bit-wise reversal of the len least
|
||||
significant bits of value. */
|
||||
static BROTLI_INLINE uint32_t BrotliReverseBits(uint32_t num) {
|
||||
#ifdef BROTLI_RBIT
|
||||
static BROTLI_INLINE brotli_reg_t BrotliReverseBits(brotli_reg_t num) {
|
||||
#if defined(BROTLI_RBIT)
|
||||
return BROTLI_RBIT(num);
|
||||
#else
|
||||
return kReverseBits[num];
|
||||
@@ -85,9 +86,9 @@ static BROTLI_INLINE void ReplicateValue(HuffmanCode* table,
|
||||
} while (end > 0);
|
||||
}
|
||||
|
||||
/* Returns the table width of the next 2nd level table. count is the histogram
|
||||
of bit lengths for the remaining symbols, len is the code length of the next
|
||||
processed symbol */
|
||||
/* Returns the table width of the next 2nd level table. |count| is the histogram
|
||||
of bit lengths for the remaining symbols, |len| is the code length of the
|
||||
next processed symbol. */
|
||||
static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count,
|
||||
int len, int root_bits) {
|
||||
int left = 1 << (len - root_bits);
|
||||
@@ -103,12 +104,12 @@ static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count,
|
||||
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||
const uint8_t* const code_lengths,
|
||||
uint16_t* count) {
|
||||
HuffmanCode code; /* current table entry */
|
||||
int symbol; /* symbol index in original or sorted table */
|
||||
uint32_t key; /* prefix code */
|
||||
uint32_t key_step; /* prefix code addend */
|
||||
int step; /* step size to replicate values in current table */
|
||||
int table_size; /* size of current table */
|
||||
HuffmanCode code; /* current table entry */
|
||||
int symbol; /* symbol index in original or sorted table */
|
||||
brotli_reg_t key; /* prefix code */
|
||||
brotli_reg_t key_step; /* prefix code addend */
|
||||
int step; /* step size to replicate values in current table */
|
||||
int table_size; /* size of current table */
|
||||
int sorted[BROTLI_CODE_LENGTH_CODES]; /* symbols sorted by code length */
|
||||
/* offsets in sorted table for each length */
|
||||
int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1];
|
||||
@@ -117,7 +118,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
|
||||
BROTLI_REVERSE_BITS_MAX);
|
||||
|
||||
/* generate offsets into sorted symbol table by code length */
|
||||
/* Generate offsets into sorted symbol table by code length. */
|
||||
symbol = -1;
|
||||
bits = 1;
|
||||
BROTLI_REPEAT(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH, {
|
||||
@@ -128,7 +129,7 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||
/* Symbols with code length 0 are placed after all other symbols. */
|
||||
offset[0] = BROTLI_CODE_LENGTH_CODES - 1;
|
||||
|
||||
/* sort symbols by length, by symbol order within each length */
|
||||
/* Sort symbols by length, by symbol order within each length. */
|
||||
symbol = BROTLI_CODE_LENGTH_CODES;
|
||||
do {
|
||||
BROTLI_REPEAT(6, {
|
||||
@@ -143,13 +144,13 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||
if (offset[0] == 0) {
|
||||
code.bits = 0;
|
||||
code.value = (uint16_t)sorted[0];
|
||||
for (key = 0; key < (uint32_t)table_size; ++key) {
|
||||
for (key = 0; key < (brotli_reg_t)table_size; ++key) {
|
||||
table[key] = code;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* fill in table */
|
||||
/* Fill in table. */
|
||||
key = 0;
|
||||
key_step = BROTLI_REVERSE_BITS_LOWEST;
|
||||
symbol = 0;
|
||||
@@ -175,10 +176,10 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||
HuffmanCode* table; /* next available space in table */
|
||||
int len; /* current code length */
|
||||
int symbol; /* symbol index in original or sorted table */
|
||||
uint32_t key; /* prefix code */
|
||||
uint32_t key_step; /* prefix code addend */
|
||||
uint32_t sub_key; /* 2nd level table prefix code */
|
||||
uint32_t sub_key_step; /* 2nd level table prefix code addend */
|
||||
brotli_reg_t key; /* prefix code */
|
||||
brotli_reg_t key_step; /* prefix code addend */
|
||||
brotli_reg_t sub_key; /* 2nd level table prefix code */
|
||||
brotli_reg_t sub_key_step; /* 2nd level table prefix code addend */
|
||||
int step; /* step size to replicate values in current table */
|
||||
int table_bits; /* key length of current table */
|
||||
int table_size; /* size of current table */
|
||||
@@ -199,9 +200,8 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||
table_size = 1 << table_bits;
|
||||
total_size = table_size;
|
||||
|
||||
/* fill in root table */
|
||||
/* let's reduce the table size to a smaller size if possible, and */
|
||||
/* create the repetitions by memcpy if possible in the coming loop */
|
||||
/* Fill in the root table. Reduce the table size to if possible,
|
||||
and create the repetitions by memcpy. */
|
||||
if (table_bits > max_length) {
|
||||
table_bits = max_length;
|
||||
table_size = 1 << table_bits;
|
||||
@@ -223,15 +223,14 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||
key_step >>= 1;
|
||||
} while (++bits <= table_bits);
|
||||
|
||||
/* if root_bits != table_bits we only created one fraction of the */
|
||||
/* table, and we need to replicate it now. */
|
||||
/* If root_bits != table_bits then replicate to fill the remaining slots. */
|
||||
while (total_size != table_size) {
|
||||
memcpy(&table[table_size], &table[0],
|
||||
(size_t)table_size * sizeof(table[0]));
|
||||
table_size <<= 1;
|
||||
}
|
||||
|
||||
/* fill in 2nd level tables and add pointers to root table */
|
||||
/* Fill in 2nd level tables and add pointers to root table. */
|
||||
key_step = BROTLI_REVERSE_BITS_LOWEST >> (root_bits - 1);
|
||||
sub_key = (BROTLI_REVERSE_BITS_LOWEST << 1);
|
||||
sub_key_step = BROTLI_REVERSE_BITS_LOWEST;
|
||||
|
@@ -9,8 +9,8 @@
|
||||
#ifndef BROTLI_DEC_HUFFMAN_H_
|
||||
#define BROTLI_DEC_HUFFMAN_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./port.h"
|
||||
#include "../common/platform.h"
|
||||
#include <brotli/types.h>
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@@ -19,10 +19,11 @@ extern "C" {
|
||||
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH 15
|
||||
|
||||
/* Maximum possible Huffman table size for an alphabet size of (index * 32),
|
||||
* max code length 15 and root table bits 8. */
|
||||
max code length 15 and root table bits 8. */
|
||||
static const uint16_t kMaxHuffmanTableSize[] = {
|
||||
256, 402, 436, 468, 500, 534, 566, 598, 630, 662, 694, 726, 758, 790, 822,
|
||||
854, 886, 920, 952, 984, 1016, 1048, 1080};
|
||||
854, 886, 920, 952, 984, 1016, 1048, 1080, 1112, 1144, 1176, 1208, 1240, 1272,
|
||||
1304, 1336, 1368, 1400, 1432, 1464, 1496, 1528};
|
||||
/* BROTLI_NUM_BLOCK_LEN_SYMBOLS == 26 */
|
||||
#define BROTLI_HUFFMAN_MAX_SIZE_26 396
|
||||
/* BROTLI_MAX_BLOCK_TYPE_SYMBOLS == 258 */
|
||||
@@ -41,23 +42,26 @@ typedef struct {
|
||||
BROTLI_INTERNAL void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
||||
const uint8_t* const code_lengths, uint16_t* count);
|
||||
|
||||
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
||||
/* Returns size of resulting table. */
|
||||
/* Builds Huffman lookup table assuming code lengths are in symbol order.
|
||||
Returns size of resulting table. */
|
||||
BROTLI_INTERNAL uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||
int root_bits, const uint16_t* const symbol_lists, uint16_t* count_arg);
|
||||
|
||||
/* Builds a simple Huffman table. The num_symbols parameter is to be */
|
||||
/* interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, 2 means 3 */
|
||||
/* symbols, 3 means 4 symbols with lengths 2,2,2,2, 4 means 4 symbols with */
|
||||
/* lengths 1,2,3,3. */
|
||||
/* Builds a simple Huffman table. The |num_symbols| parameter is to be
|
||||
interpreted as follows: 0 means 1 symbol, 1 means 2 symbols,
|
||||
2 means 3 symbols, 3 means 4 symbols with lengths [2, 2, 2, 2],
|
||||
4 means 4 symbols with lengths [1, 2, 3, 3]. */
|
||||
BROTLI_INTERNAL uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
||||
int root_bits, uint16_t* symbols, uint32_t num_symbols);
|
||||
|
||||
/* Contains a collection of Huffman trees with the same alphabet size. */
|
||||
/* max_symbol is needed due to simple codes since log2(alphabet_size) could be
|
||||
greater than log2(max_symbol). */
|
||||
typedef struct {
|
||||
HuffmanCode** htrees;
|
||||
HuffmanCode* codes;
|
||||
uint16_t alphabet_size;
|
||||
uint16_t max_symbol;
|
||||
uint16_t num_htrees;
|
||||
} HuffmanTreeGroup;
|
||||
|
||||
|
@@ -1,159 +0,0 @@
|
||||
/* Copyright 2015 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Macros for compiler / platform specific features and build options.
|
||||
|
||||
Build options are:
|
||||
* BROTLI_BUILD_32_BIT disables 64-bit optimizations
|
||||
* BROTLI_BUILD_64_BIT forces to use 64-bit optimizations
|
||||
* BROTLI_BUILD_BIG_ENDIAN forces to use big-endian optimizations
|
||||
* BROTLI_BUILD_ENDIAN_NEUTRAL disables endian-aware optimizations
|
||||
* BROTLI_BUILD_LITTLE_ENDIAN forces to use little-endian optimizations
|
||||
* BROTLI_BUILD_MODERN_COMPILER forces to use modern compilers built-ins,
|
||||
features and attributes
|
||||
* BROTLI_BUILD_PORTABLE disables dangerous optimizations, like unaligned
|
||||
read and overlapping memcpy; this reduces decompression speed by 5%
|
||||
* BROTLI_DEBUG dumps file name and line number when decoder detects stream
|
||||
or memory error
|
||||
* BROTLI_ENABLE_LOG enables asserts and dumps various state information
|
||||
*/
|
||||
|
||||
#ifndef BROTLI_DEC_PORT_H_
|
||||
#define BROTLI_DEC_PORT_H_
|
||||
|
||||
#if defined(BROTLI_ENABLE_LOG) || defined(BROTLI_DEBUG)
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#endif
|
||||
|
||||
#include "../common/port.h"
|
||||
|
||||
#if defined(__arm__) || defined(__thumb__) || \
|
||||
defined(_M_ARM) || defined(_M_ARMT)
|
||||
#define BROTLI_TARGET_ARM
|
||||
#if (defined(__ARM_ARCH) && (__ARM_ARCH >= 7)) || \
|
||||
(defined(M_ARM) && (M_ARM >= 7))
|
||||
#define BROTLI_TARGET_ARMV7
|
||||
#endif /* ARMv7 */
|
||||
#if defined(__aarch64__)
|
||||
#define BROTLI_TARGET_ARMV8
|
||||
#endif /* ARMv8 */
|
||||
#endif /* ARM */
|
||||
|
||||
#if defined(__i386) || defined(_M_IX86)
|
||||
#define BROTLI_TARGET_X86
|
||||
#endif
|
||||
|
||||
#if defined(__x86_64__) || defined(_M_X64)
|
||||
#define BROTLI_TARGET_X64
|
||||
#endif
|
||||
|
||||
#if defined(__PPC64__)
|
||||
#define BROTLI_TARGET_POWERPC64
|
||||
#endif
|
||||
|
||||
#ifdef BROTLI_BUILD_PORTABLE
|
||||
#define BROTLI_ALIGNED_READ (!!1)
|
||||
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
||||
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
|
||||
/* Allow unaligned read only for whitelisted CPUs. */
|
||||
#define BROTLI_ALIGNED_READ (!!0)
|
||||
#else
|
||||
#define BROTLI_ALIGNED_READ (!!1)
|
||||
#endif
|
||||
|
||||
/* IS_CONSTANT macros returns true for compile-time constant expressions. */
|
||||
#if BROTLI_MODERN_COMPILER || __has_builtin(__builtin_constant_p)
|
||||
#define IS_CONSTANT(x) (!!__builtin_constant_p(x))
|
||||
#else
|
||||
#define IS_CONSTANT(x) (!!0)
|
||||
#endif
|
||||
|
||||
#ifdef BROTLI_ENABLE_LOG
|
||||
#define BROTLI_DCHECK(x) assert(x)
|
||||
#define BROTLI_LOG(x) printf x
|
||||
#else
|
||||
#define BROTLI_DCHECK(x)
|
||||
#define BROTLI_LOG(x)
|
||||
#endif
|
||||
|
||||
#if defined(BROTLI_DEBUG) || defined(BROTLI_ENABLE_LOG)
|
||||
static BROTLI_INLINE void BrotliDump(const char* f, int l, const char* fn) {
|
||||
fprintf(stderr, "%s:%d (%s)\n", f, l, fn);
|
||||
fflush(stderr);
|
||||
}
|
||||
#define BROTLI_DUMP() BrotliDump(__FILE__, __LINE__, __FUNCTION__)
|
||||
#else
|
||||
#define BROTLI_DUMP() (void)(0)
|
||||
#endif
|
||||
|
||||
#if defined(BROTLI_BUILD_64_BIT)
|
||||
#define BROTLI_64_BITS 1
|
||||
#elif defined(BROTLI_BUILD_32_BIT)
|
||||
#define BROTLI_64_BITS 0
|
||||
#elif defined(BROTLI_TARGET_X64) || defined(BROTLI_TARGET_ARMV8) || \
|
||||
defined(BROTLI_TARGET_POWERPC64)
|
||||
#define BROTLI_64_BITS 1
|
||||
#else
|
||||
#define BROTLI_64_BITS 0
|
||||
#endif
|
||||
|
||||
#if defined(BROTLI_BUILD_BIG_ENDIAN)
|
||||
#define BROTLI_LITTLE_ENDIAN 0
|
||||
#define BROTLI_BIG_ENDIAN 1
|
||||
#elif defined(BROTLI_BUILD_LITTLE_ENDIAN)
|
||||
#define BROTLI_LITTLE_ENDIAN 1
|
||||
#define BROTLI_BIG_ENDIAN 0
|
||||
#elif defined(BROTLI_BUILD_ENDIAN_NEUTRAL)
|
||||
#define BROTLI_LITTLE_ENDIAN 0
|
||||
#define BROTLI_BIG_ENDIAN 0
|
||||
#elif defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
|
||||
#define BROTLI_LITTLE_ENDIAN 1
|
||||
#define BROTLI_BIG_ENDIAN 0
|
||||
#elif defined(_WIN32)
|
||||
/* Win32 can currently always be assumed to be little endian */
|
||||
#define BROTLI_LITTLE_ENDIAN 1
|
||||
#define BROTLI_BIG_ENDIAN 0
|
||||
#else
|
||||
#if (defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__))
|
||||
#define BROTLI_BIG_ENDIAN 1
|
||||
#else
|
||||
#define BROTLI_BIG_ENDIAN 0
|
||||
#endif
|
||||
#define BROTLI_LITTLE_ENDIAN 0
|
||||
#endif
|
||||
|
||||
#define BROTLI_REPEAT(N, X) { \
|
||||
if ((N & 1) != 0) {X;} \
|
||||
if ((N & 2) != 0) {X; X;} \
|
||||
if ((N & 4) != 0) {X; X; X; X;} \
|
||||
}
|
||||
|
||||
#if BROTLI_MODERN_COMPILER || defined(__llvm__)
|
||||
#if defined(BROTLI_TARGET_ARMV7)
|
||||
static BROTLI_INLINE unsigned BrotliRBit(unsigned input) {
|
||||
unsigned output;
|
||||
__asm__("rbit %0, %1\n" : "=r"(output) : "r"(input));
|
||||
return output;
|
||||
}
|
||||
#define BROTLI_RBIT(x) BrotliRBit(x)
|
||||
#endif /* armv7 */
|
||||
#endif /* gcc || clang */
|
||||
|
||||
#if defined(BROTLI_TARGET_ARM)
|
||||
#define BROTLI_HAS_UBFX (!!1)
|
||||
#else
|
||||
#define BROTLI_HAS_UBFX (!!0)
|
||||
#endif
|
||||
|
||||
#define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
||||
|
||||
#define BROTLI_FREE(S, X) { \
|
||||
S->free_func(S->memory_manager_opaque, X); \
|
||||
X = NULL; \
|
||||
}
|
||||
|
||||
#endif /* BROTLI_DEC_PORT_H_ */
|
@@ -5,17 +5,16 @@
|
||||
*/
|
||||
|
||||
/* Lookup tables to map prefix codes to value ranges. This is used during
|
||||
decoding of the block lengths, literal insertion lengths and copy lengths.
|
||||
*/
|
||||
decoding of the block lengths, literal insertion lengths and copy lengths. */
|
||||
|
||||
#ifndef BROTLI_DEC_PREFIX_H_
|
||||
#define BROTLI_DEC_PREFIX_H_
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include <brotli/types.h>
|
||||
|
||||
/* Represents the range of values belonging to a prefix code: */
|
||||
/* [offset, offset + 2^nbits) */
|
||||
/* Represents the range of values belonging to a prefix code:
|
||||
[offset, offset + 2^nbits) */
|
||||
struct PrefixCodeRange {
|
||||
uint16_t offset;
|
||||
uint8_t nbits;
|
||||
|
@@ -8,32 +8,18 @@
|
||||
|
||||
#include <stdlib.h> /* free, malloc */
|
||||
|
||||
#include "../common/types.h"
|
||||
#include <brotli/types.h>
|
||||
#include "./huffman.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
static void* DefaultAllocFunc(void* opaque, size_t size) {
|
||||
BROTLI_UNUSED(opaque);
|
||||
return malloc(size);
|
||||
}
|
||||
|
||||
static void DefaultFreeFunc(void* opaque, void* address) {
|
||||
BROTLI_UNUSED(opaque);
|
||||
free(address);
|
||||
}
|
||||
|
||||
void BrotliDecoderStateInit(BrotliDecoderState* s) {
|
||||
BrotliDecoderStateInitWithCustomAllocators(s, 0, 0, 0);
|
||||
}
|
||||
|
||||
void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
||||
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque) {
|
||||
if (!alloc_func) {
|
||||
s->alloc_func = DefaultAllocFunc;
|
||||
s->free_func = DefaultFreeFunc;
|
||||
s->alloc_func = BrotliDefaultAllocFunc;
|
||||
s->free_func = BrotliDefaultFreeFunc;
|
||||
s->memory_manager_opaque = 0;
|
||||
} else {
|
||||
s->alloc_func = alloc_func;
|
||||
@@ -41,8 +27,11 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
s->memory_manager_opaque = opaque;
|
||||
}
|
||||
|
||||
s->error_code = 0; /* BROTLI_DECODER_NO_ERROR */
|
||||
|
||||
BrotliInitBitReader(&s->br);
|
||||
s->state = BROTLI_STATE_UNINITED;
|
||||
s->large_window = 0;
|
||||
s->substate_metablock_header = BROTLI_STATE_METABLOCK_HEADER_NONE;
|
||||
s->substate_tree_group = BROTLI_STATE_TREE_GROUP_NONE;
|
||||
s->substate_context_map = BROTLI_STATE_CONTEXT_MAP_NONE;
|
||||
@@ -60,6 +49,9 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
s->block_type_trees = NULL;
|
||||
s->block_len_trees = NULL;
|
||||
s->ringbuffer = NULL;
|
||||
s->ringbuffer_size = 0;
|
||||
s->new_ringbuffer_size = 0;
|
||||
s->ringbuffer_mask = 0;
|
||||
|
||||
s->context_map = NULL;
|
||||
s->context_modes = NULL;
|
||||
@@ -76,10 +68,12 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
s->distance_hgroup.codes = NULL;
|
||||
s->distance_hgroup.htrees = NULL;
|
||||
|
||||
s->custom_dict = NULL;
|
||||
s->custom_dict_size = 0;
|
||||
|
||||
s->is_last_metablock = 0;
|
||||
s->is_uncompressed = 0;
|
||||
s->is_metadata = 0;
|
||||
s->should_wrap_ringbuffer = 0;
|
||||
s->canny_ringbuffer_allocation = 1;
|
||||
|
||||
s->window_bits = 0;
|
||||
s->max_distance = 0;
|
||||
s->dist_rb[0] = 16;
|
||||
@@ -93,14 +87,19 @@ void BrotliDecoderStateInitWithCustomAllocators(BrotliDecoderState* s,
|
||||
/* Make small negative indexes addressable. */
|
||||
s->symbol_lists = &s->symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1];
|
||||
|
||||
s->mtf_upper_bound = 255;
|
||||
s->mtf_upper_bound = 63;
|
||||
|
||||
s->dictionary = BrotliGetDictionary();
|
||||
s->transforms = BrotliGetTransforms();
|
||||
|
||||
return BROTLI_TRUE;
|
||||
}
|
||||
|
||||
void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
|
||||
s->meta_block_remaining_len = 0;
|
||||
s->block_length[0] = 1U << 28;
|
||||
s->block_length[1] = 1U << 28;
|
||||
s->block_length[2] = 1U << 28;
|
||||
s->block_length[0] = 1U << 24;
|
||||
s->block_length[1] = 1U << 24;
|
||||
s->block_length[2] = 1U << 24;
|
||||
s->num_block_types[0] = 1;
|
||||
s->num_block_types[1] = 1;
|
||||
s->num_block_types[2] = 1;
|
||||
@@ -117,8 +116,7 @@ void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
|
||||
s->literal_htree = NULL;
|
||||
s->dist_context_map_slice = NULL;
|
||||
s->dist_htree_index = 0;
|
||||
s->context_lookup1 = NULL;
|
||||
s->context_lookup2 = NULL;
|
||||
s->context_lookup = NULL;
|
||||
s->literal_hgroup.codes = NULL;
|
||||
s->literal_hgroup.htrees = NULL;
|
||||
s->insert_copy_hgroup.codes = NULL;
|
||||
@@ -128,39 +126,37 @@ void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s) {
|
||||
}
|
||||
|
||||
void BrotliDecoderStateCleanupAfterMetablock(BrotliDecoderState* s) {
|
||||
BROTLI_FREE(s, s->context_modes);
|
||||
BROTLI_FREE(s, s->context_map);
|
||||
BROTLI_FREE(s, s->dist_context_map);
|
||||
|
||||
BrotliDecoderHuffmanTreeGroupRelease(s, &s->literal_hgroup);
|
||||
BrotliDecoderHuffmanTreeGroupRelease(s, &s->insert_copy_hgroup);
|
||||
BrotliDecoderHuffmanTreeGroupRelease(s, &s->distance_hgroup);
|
||||
BROTLI_DECODER_FREE(s, s->context_modes);
|
||||
BROTLI_DECODER_FREE(s, s->context_map);
|
||||
BROTLI_DECODER_FREE(s, s->dist_context_map);
|
||||
BROTLI_DECODER_FREE(s, s->literal_hgroup.htrees);
|
||||
BROTLI_DECODER_FREE(s, s->insert_copy_hgroup.htrees);
|
||||
BROTLI_DECODER_FREE(s, s->distance_hgroup.htrees);
|
||||
}
|
||||
|
||||
void BrotliDecoderStateCleanup(BrotliDecoderState* s) {
|
||||
BrotliDecoderStateCleanupAfterMetablock(s);
|
||||
|
||||
BROTLI_FREE(s, s->ringbuffer);
|
||||
BROTLI_FREE(s, s->block_type_trees);
|
||||
BROTLI_DECODER_FREE(s, s->ringbuffer);
|
||||
BROTLI_DECODER_FREE(s, s->block_type_trees);
|
||||
}
|
||||
|
||||
void BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
|
||||
HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t ntrees) {
|
||||
BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(BrotliDecoderState* s,
|
||||
HuffmanTreeGroup* group, uint32_t alphabet_size, uint32_t max_symbol,
|
||||
uint32_t ntrees) {
|
||||
/* Pack two allocations into one */
|
||||
const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
|
||||
const size_t code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
|
||||
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
|
||||
char* p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
|
||||
/* Pointer alignment is, hopefully, wider than sizeof(HuffmanCode). */
|
||||
HuffmanCode** p = (HuffmanCode**)BROTLI_DECODER_ALLOC(s,
|
||||
code_size + htree_size);
|
||||
group->alphabet_size = (uint16_t)alphabet_size;
|
||||
group->max_symbol = (uint16_t)max_symbol;
|
||||
group->num_htrees = (uint16_t)ntrees;
|
||||
group->codes = (HuffmanCode*)p;
|
||||
group->htrees = (HuffmanCode**)(p + code_size);
|
||||
}
|
||||
|
||||
void BrotliDecoderHuffmanTreeGroupRelease(
|
||||
BrotliDecoderState* s, HuffmanTreeGroup* group) {
|
||||
BROTLI_FREE(s, group->codes);
|
||||
group->htrees = NULL;
|
||||
group->htrees = p;
|
||||
group->codes = (HuffmanCode*)(&p[ntrees]);
|
||||
return !!p;
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
|
@@ -10,10 +10,12 @@
|
||||
#define BROTLI_DEC_STATE_H_
|
||||
|
||||
#include "../common/constants.h"
|
||||
#include "../common/types.h"
|
||||
#include "../common/dictionary.h"
|
||||
#include "../common/platform.h"
|
||||
#include "../common/transform.h"
|
||||
#include <brotli/types.h>
|
||||
#include "./bit_reader.h"
|
||||
#include "./huffman.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
@@ -21,6 +23,8 @@ extern "C" {
|
||||
|
||||
typedef enum {
|
||||
BROTLI_STATE_UNINITED,
|
||||
BROTLI_STATE_LARGE_WINDOW_BITS,
|
||||
BROTLI_STATE_INITIALIZE,
|
||||
BROTLI_STATE_METABLOCK_BEGIN,
|
||||
BROTLI_STATE_METABLOCK_HEADER,
|
||||
BROTLI_STATE_METABLOCK_HEADER_2,
|
||||
@@ -115,7 +119,6 @@ struct BrotliDecoderStateStruct {
|
||||
|
||||
int pos;
|
||||
int max_backward_distance;
|
||||
int max_backward_distance_minus_custom_dict_size;
|
||||
int max_distance;
|
||||
int ringbuffer_size;
|
||||
int ringbuffer_mask;
|
||||
@@ -126,21 +129,22 @@ struct BrotliDecoderStateStruct {
|
||||
uint8_t* ringbuffer;
|
||||
uint8_t* ringbuffer_end;
|
||||
HuffmanCode* htree_command;
|
||||
const uint8_t* context_lookup1;
|
||||
const uint8_t* context_lookup2;
|
||||
const uint8_t* context_lookup;
|
||||
uint8_t* context_map_slice;
|
||||
uint8_t* dist_context_map_slice;
|
||||
|
||||
/* This ring buffer holds a few past copy distances that will be used by */
|
||||
/* some special distance codes. */
|
||||
/* This ring buffer holds a few past copy distances that will be used by
|
||||
some special distance codes. */
|
||||
HuffmanTreeGroup literal_hgroup;
|
||||
HuffmanTreeGroup insert_copy_hgroup;
|
||||
HuffmanTreeGroup distance_hgroup;
|
||||
HuffmanCode* block_type_trees;
|
||||
HuffmanCode* block_len_trees;
|
||||
/* This is true if the literal context map histogram type always matches the
|
||||
block type. It is then not needed to keep the context (faster decoding). */
|
||||
block type. It is then not needed to keep the context (faster decoding). */
|
||||
int trivial_literal_context;
|
||||
/* Distance context is actual after command is decoded and before distance is
|
||||
computed. After distance computation it is used as a temporary variable. */
|
||||
int distance_context;
|
||||
int meta_block_remaining_len;
|
||||
uint32_t block_length_index;
|
||||
@@ -160,17 +164,17 @@ struct BrotliDecoderStateStruct {
|
||||
int copy_length;
|
||||
int distance_code;
|
||||
|
||||
/* For partial write operations */
|
||||
size_t rb_roundtrips; /* How many times we went around the ringbuffer */
|
||||
size_t partial_pos_out; /* How much output to the user in total (<= rb) */
|
||||
/* For partial write operations. */
|
||||
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 */
|
||||
|
||||
/* For ReadHuffmanCode */
|
||||
/* For ReadHuffmanCode. */
|
||||
uint32_t symbol;
|
||||
uint32_t repeat;
|
||||
uint32_t space;
|
||||
|
||||
HuffmanCode table[32];
|
||||
/* List of of symbol chains. */
|
||||
/* List of heads of symbol chains. */
|
||||
uint16_t* symbol_lists;
|
||||
/* Storage from symbol_lists. */
|
||||
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
||||
@@ -178,29 +182,26 @@ struct BrotliDecoderStateStruct {
|
||||
/* Tails of symbol chains. */
|
||||
int next_symbol[32];
|
||||
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];
|
||||
|
||||
/* For HuffmanTreeGroupDecode */
|
||||
/* For HuffmanTreeGroupDecode. */
|
||||
int htree_index;
|
||||
HuffmanCode* next;
|
||||
|
||||
/* For DecodeContextMap */
|
||||
/* For DecodeContextMap. */
|
||||
uint32_t context_index;
|
||||
uint32_t max_run_length_prefix;
|
||||
uint32_t code;
|
||||
HuffmanCode context_map_table[BROTLI_HUFFMAN_MAX_SIZE_272];
|
||||
|
||||
/* For InverseMoveToFrontTransform */
|
||||
/* For InverseMoveToFrontTransform. */
|
||||
uint32_t mtf_upper_bound;
|
||||
uint8_t mtf[256 + 4];
|
||||
uint32_t mtf[64 + 1];
|
||||
|
||||
/* For custom dictionaries */
|
||||
const uint8_t* custom_dict;
|
||||
int custom_dict_size;
|
||||
/* Less used attributes are at the end of this struct. */
|
||||
|
||||
/* less used attributes are in the end of this struct */
|
||||
/* States inside function calls */
|
||||
/* States inside function calls. */
|
||||
BrotliRunningMetablockHeaderState substate_metablock_header;
|
||||
BrotliRunningTreeGroupState substate_tree_group;
|
||||
BrotliRunningContextMapState substate_context_map;
|
||||
@@ -209,35 +210,46 @@ struct BrotliDecoderStateStruct {
|
||||
BrotliRunningDecodeUint8State substate_decode_uint8;
|
||||
BrotliRunningReadBlockLengthState substate_read_block_length;
|
||||
|
||||
uint8_t is_last_metablock;
|
||||
uint8_t is_uncompressed;
|
||||
uint8_t is_metadata;
|
||||
uint8_t size_nibbles;
|
||||
unsigned int is_last_metablock : 1;
|
||||
unsigned int is_uncompressed : 1;
|
||||
unsigned int is_metadata : 1;
|
||||
unsigned int should_wrap_ringbuffer : 1;
|
||||
unsigned int canny_ringbuffer_allocation : 1;
|
||||
unsigned int large_window : 1;
|
||||
unsigned int size_nibbles : 8;
|
||||
uint32_t window_bits;
|
||||
|
||||
int new_ringbuffer_size;
|
||||
|
||||
uint32_t num_literal_htrees;
|
||||
uint8_t* context_map;
|
||||
uint8_t* context_modes;
|
||||
|
||||
const BrotliDictionary* dictionary;
|
||||
const BrotliTransforms* transforms;
|
||||
|
||||
uint32_t trivial_literal_contexts[8]; /* 256 bits */
|
||||
};
|
||||
|
||||
typedef struct BrotliDecoderStateStruct BrotliDecoderStateInternal;
|
||||
#define BrotliDecoderState BrotliDecoderStateInternal
|
||||
|
||||
BROTLI_INTERNAL void BrotliDecoderStateInit(BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL void BrotliDecoderStateInitWithCustomAllocators(
|
||||
BrotliDecoderState* s, brotli_alloc_func alloc_func,
|
||||
brotli_free_func free_func, void* opaque);
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderStateInit(BrotliDecoderState* s,
|
||||
brotli_alloc_func alloc_func, brotli_free_func free_func, void* opaque);
|
||||
BROTLI_INTERNAL void BrotliDecoderStateCleanup(BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL void BrotliDecoderStateMetablockBegin(BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL void BrotliDecoderStateCleanupAfterMetablock(
|
||||
BrotliDecoderState* s);
|
||||
BROTLI_INTERNAL void BrotliDecoderHuffmanTreeGroupInit(
|
||||
BROTLI_INTERNAL BROTLI_BOOL BrotliDecoderHuffmanTreeGroupInit(
|
||||
BrotliDecoderState* s, HuffmanTreeGroup* group, uint32_t alphabet_size,
|
||||
uint32_t ntrees);
|
||||
BROTLI_INTERNAL void BrotliDecoderHuffmanTreeGroupRelease(
|
||||
BrotliDecoderState* s, HuffmanTreeGroup* group);
|
||||
uint32_t max_symbol, uint32_t ntrees);
|
||||
|
||||
#define BROTLI_DECODER_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
||||
|
||||
#define BROTLI_DECODER_FREE(S, X) { \
|
||||
S->free_func(S->memory_manager_opaque, X); \
|
||||
X = NULL; \
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
||||
|
@@ -1,300 +0,0 @@
|
||||
/* Copyright 2013 Google Inc. All Rights Reserved.
|
||||
|
||||
Distributed under MIT license.
|
||||
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
/* Transformations on dictionary words. */
|
||||
|
||||
#ifndef BROTLI_DEC_TRANSFORM_H_
|
||||
#define BROTLI_DEC_TRANSFORM_H_
|
||||
|
||||
#include "../common/types.h"
|
||||
#include "./port.h"
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
enum WordTransformType {
|
||||
kIdentity = 0,
|
||||
kOmitLast1 = 1,
|
||||
kOmitLast2 = 2,
|
||||
kOmitLast3 = 3,
|
||||
kOmitLast4 = 4,
|
||||
kOmitLast5 = 5,
|
||||
kOmitLast6 = 6,
|
||||
kOmitLast7 = 7,
|
||||
kOmitLast8 = 8,
|
||||
kOmitLast9 = 9,
|
||||
kUppercaseFirst = 10,
|
||||
kUppercaseAll = 11,
|
||||
kOmitFirst1 = 12,
|
||||
kOmitFirst2 = 13,
|
||||
kOmitFirst3 = 14,
|
||||
kOmitFirst4 = 15,
|
||||
kOmitFirst5 = 16,
|
||||
kOmitFirst6 = 17,
|
||||
kOmitFirst7 = 18,
|
||||
kOmitFirst8 = 19,
|
||||
kOmitFirst9 = 20
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
const uint8_t prefix_id;
|
||||
const uint8_t transform;
|
||||
const uint8_t suffix_id;
|
||||
} Transform;
|
||||
|
||||
static const char kPrefixSuffix[208] =
|
||||
"\0 \0, \0 of the \0 of \0s \0.\0 and \0 in \0\"\0 to \0\">\0\n\0. \0]\0"
|
||||
" for \0 a \0 that \0\'\0 with \0 from \0 by \0(\0. The \0 on \0 as \0"
|
||||
" is \0ing \0\n\t\0:\0ed \0=\"\0 at \0ly \0,\0=\'\0.com/\0. This \0"
|
||||
" not \0er \0al \0ful \0ive \0less \0est \0ize \0\xc2\xa0\0ous ";
|
||||
|
||||
enum {
|
||||
/* EMPTY = ""
|
||||
SP = " "
|
||||
DQUOT = "\""
|
||||
SQUOT = "'"
|
||||
CLOSEBR = "]"
|
||||
OPEN = "("
|
||||
SLASH = "/"
|
||||
NBSP = non-breaking space "\0xc2\xa0"
|
||||
*/
|
||||
kPFix_EMPTY = 0,
|
||||
kPFix_SP = 1,
|
||||
kPFix_COMMASP = 3,
|
||||
kPFix_SPofSPtheSP = 6,
|
||||
kPFix_SPtheSP = 9,
|
||||
kPFix_eSP = 12,
|
||||
kPFix_SPofSP = 15,
|
||||
kPFix_sSP = 20,
|
||||
kPFix_DOT = 23,
|
||||
kPFix_SPandSP = 25,
|
||||
kPFix_SPinSP = 31,
|
||||
kPFix_DQUOT = 36,
|
||||
kPFix_SPtoSP = 38,
|
||||
kPFix_DQUOTGT = 43,
|
||||
kPFix_NEWLINE = 46,
|
||||
kPFix_DOTSP = 48,
|
||||
kPFix_CLOSEBR = 51,
|
||||
kPFix_SPforSP = 53,
|
||||
kPFix_SPaSP = 59,
|
||||
kPFix_SPthatSP = 63,
|
||||
kPFix_SQUOT = 70,
|
||||
kPFix_SPwithSP = 72,
|
||||
kPFix_SPfromSP = 79,
|
||||
kPFix_SPbySP = 86,
|
||||
kPFix_OPEN = 91,
|
||||
kPFix_DOTSPTheSP = 93,
|
||||
kPFix_SPonSP = 100,
|
||||
kPFix_SPasSP = 105,
|
||||
kPFix_SPisSP = 110,
|
||||
kPFix_ingSP = 115,
|
||||
kPFix_NEWLINETAB = 120,
|
||||
kPFix_COLON = 123,
|
||||
kPFix_edSP = 125,
|
||||
kPFix_EQDQUOT = 129,
|
||||
kPFix_SPatSP = 132,
|
||||
kPFix_lySP = 137,
|
||||
kPFix_COMMA = 141,
|
||||
kPFix_EQSQUOT = 143,
|
||||
kPFix_DOTcomSLASH = 146,
|
||||
kPFix_DOTSPThisSP = 152,
|
||||
kPFix_SPnotSP = 160,
|
||||
kPFix_erSP = 166,
|
||||
kPFix_alSP = 170,
|
||||
kPFix_fulSP = 174,
|
||||
kPFix_iveSP = 179,
|
||||
kPFix_lessSP = 184,
|
||||
kPFix_estSP = 190,
|
||||
kPFix_izeSP = 195,
|
||||
kPFix_NBSP = 200,
|
||||
kPFix_ousSP = 203
|
||||
};
|
||||
|
||||
static const Transform kTransforms[] = {
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SP },
|
||||
{ kPFix_SP, kIdentity, kPFix_SP },
|
||||
{ kPFix_EMPTY, kOmitFirst1, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPtheSP },
|
||||
{ kPFix_SP, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_sSP, kIdentity, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPofSP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPandSP },
|
||||
{ kPFix_EMPTY, kOmitFirst2, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast1, kPFix_EMPTY },
|
||||
{ kPFix_COMMASP, kIdentity, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_COMMASP },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPinSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPtoSP },
|
||||
{ kPFix_eSP, kIdentity, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DQUOTGT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_NEWLINE },
|
||||
{ kPFix_EMPTY, kOmitLast3, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_CLOSEBR },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPforSP },
|
||||
{ kPFix_EMPTY, kOmitFirst3, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast2, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPaSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPthatSP },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DOTSP },
|
||||
{ kPFix_DOT, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_SP, kIdentity, kPFix_COMMASP },
|
||||
{ kPFix_EMPTY, kOmitFirst4, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPwithSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPfromSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPbySP },
|
||||
{ kPFix_EMPTY, kOmitFirst5, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitFirst6, kPFix_EMPTY },
|
||||
{ kPFix_SPtheSP, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast4, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DOTSPTheSP },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPonSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPasSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPisSP },
|
||||
{ kPFix_EMPTY, kOmitLast7, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast1, kPFix_ingSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_NEWLINETAB },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_COLON },
|
||||
{ kPFix_SP, kIdentity, kPFix_DOTSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_edSP },
|
||||
{ kPFix_EMPTY, kOmitFirst9, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitFirst7, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast6, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_OPEN },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_COMMASP },
|
||||
{ kPFix_EMPTY, kOmitLast8, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPatSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_lySP },
|
||||
{ kPFix_SPtheSP, kIdentity, kPFix_SPofSP },
|
||||
{ kPFix_EMPTY, kOmitLast5, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kOmitLast9, kPFix_EMPTY },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_COMMASP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_DQUOT },
|
||||
{ kPFix_DOT, kIdentity, kPFix_OPEN },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_SP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_DQUOTGT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_EQDQUOT },
|
||||
{ kPFix_SP, kIdentity, kPFix_DOT },
|
||||
{ kPFix_DOTcomSLASH, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_SPtheSP, kIdentity, kPFix_SPofSPtheSP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_SQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_DOTSPThisSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_COMMA },
|
||||
{ kPFix_DOT, kIdentity, kPFix_SP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_OPEN },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_DOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_SPnotSP },
|
||||
{ kPFix_SP, kIdentity, kPFix_EQDQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_erSP },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_SP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_alSP },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_EMPTY },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_EQSQUOT },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_DQUOT },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_DOTSP },
|
||||
{ kPFix_SP, kIdentity, kPFix_OPEN },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_fulSP },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_DOTSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_iveSP },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_lessSP },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_SQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_estSP },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_DOT },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_DQUOTGT },
|
||||
{ kPFix_SP, kIdentity, kPFix_EQSQUOT },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_COMMA },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_izeSP },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_DOT },
|
||||
{ kPFix_NBSP, kIdentity, kPFix_EMPTY },
|
||||
{ kPFix_SP, kIdentity, kPFix_COMMA },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_EQDQUOT },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_EQDQUOT },
|
||||
{ kPFix_EMPTY, kIdentity, kPFix_ousSP },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_COMMASP },
|
||||
{ kPFix_EMPTY, kUppercaseFirst, kPFix_EQSQUOT },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_COMMA },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_EQDQUOT },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_COMMASP },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_COMMA },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_OPEN },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_DOTSP },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_DOT },
|
||||
{ kPFix_EMPTY, kUppercaseAll, kPFix_EQSQUOT },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_DOTSP },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_EQDQUOT },
|
||||
{ kPFix_SP, kUppercaseAll, kPFix_EQSQUOT },
|
||||
{ kPFix_SP, kUppercaseFirst, kPFix_EQSQUOT },
|
||||
};
|
||||
|
||||
static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]);
|
||||
|
||||
static int ToUpperCase(uint8_t* p) {
|
||||
if (p[0] < 0xc0) {
|
||||
if (p[0] >= 'a' && p[0] <= 'z') {
|
||||
p[0] ^= 32;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/* An overly simplified uppercasing model for utf-8. */
|
||||
if (p[0] < 0xe0) {
|
||||
p[1] ^= 32;
|
||||
return 2;
|
||||
}
|
||||
/* An arbitrary transform for three byte characters. */
|
||||
p[2] ^= 5;
|
||||
return 3;
|
||||
}
|
||||
|
||||
static BROTLI_NOINLINE int TransformDictionaryWord(
|
||||
uint8_t* dst, const uint8_t* word, int len, int transform) {
|
||||
int idx = 0;
|
||||
{
|
||||
const char* prefix = &kPrefixSuffix[kTransforms[transform].prefix_id];
|
||||
while (*prefix) { dst[idx++] = (uint8_t)*prefix++; }
|
||||
}
|
||||
{
|
||||
const int t = kTransforms[transform].transform;
|
||||
int i = 0;
|
||||
int skip = t - (kOmitFirst1 - 1);
|
||||
if (skip > 0) {
|
||||
word += skip;
|
||||
len -= skip;
|
||||
} else if (t <= kOmitLast9) {
|
||||
len -= t;
|
||||
}
|
||||
while (i < len) { dst[idx++] = word[i++]; }
|
||||
if (t == kUppercaseFirst) {
|
||||
ToUpperCase(&dst[idx - len]);
|
||||
} else if (t == kUppercaseAll) {
|
||||
uint8_t* uppercase = &dst[idx - len];
|
||||
while (len > 0) {
|
||||
int step = ToUpperCase(uppercase);
|
||||
uppercase += step;
|
||||
len -= step;
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
const char* suffix = &kPrefixSuffix[kTransforms[transform].suffix_id];
|
||||
while (*suffix) { dst[idx++] = (uint8_t)*suffix++; }
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(__cplusplus) || defined(c_plusplus)
|
||||
} /* extern "C" */
|
||||
#endif
|
||||
|
||||
#endif /* BROTLI_DEC_TRANSFORM_H_ */
|
Reference in New Issue
Block a user