mirror of
https://github.com/google/brotli.git
synced 2024-11-22 11:40:06 +00:00
commit
722f8996b0
@ -1,8 +1,10 @@
|
|||||||
Want to contribute? Great! First, read this page (including the small print at the end).
|
Want to contribute? Great! First, read this page (including the small print at
|
||||||
|
the end).
|
||||||
|
|
||||||
### Before you contribute
|
### Before you contribute
|
||||||
Before we can use your code, you must sign the
|
Before we can use your code, you must sign the
|
||||||
[Google Individual Contributor License Agreement](https://cla.developers.google.com/about/google-individual)
|
[Google Individual Contributor License Agreement]
|
||||||
|
(https://cla.developers.google.com/about/google-individual)
|
||||||
(CLA), which you can do online. The CLA is necessary mainly because you own the
|
(CLA), which you can do online. The CLA is necessary mainly because you own the
|
||||||
copyright to your changes, even after your contribution becomes part of our
|
copyright to your changes, even after your contribution becomes part of our
|
||||||
codebase, so we need your permission to use and distribute your code. We also
|
codebase, so we need your permission to use and distribute your code. We also
|
||||||
@ -21,5 +23,5 @@ use Github pull requests for this purpose.
|
|||||||
|
|
||||||
### The small print
|
### The small print
|
||||||
Contributions made by corporations are covered by a different agreement than
|
Contributions made by corporations are covered by a different agreement than
|
||||||
the one above, the
|
the one above, the [Software Grant and Corporate Contributor License Agreement]
|
||||||
[Software Grant and Corporate Contributor License Agreement](https://cla.developers.google.com/about/google-corporate).
|
(https://cla.developers.google.com/about/google-corporate).
|
||||||
|
@ -44,5 +44,5 @@ int BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -14,6 +14,10 @@
|
|||||||
#include "./port.h"
|
#include "./port.h"
|
||||||
#include "./types.h"
|
#include "./types.h"
|
||||||
|
|
||||||
|
#ifdef BROTLI_DECODE_DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
@ -48,17 +52,17 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
reg_t val_; /* pre-fetched bits */
|
reg_t val_; /* pre-fetched bits */
|
||||||
uint32_t bit_pos_; /* current bit-reading position in val_ */
|
uint32_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;
|
size_t avail_in;
|
||||||
} BrotliBitReader;
|
} BrotliBitReader;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
reg_t val_;
|
reg_t val_;
|
||||||
uint32_t bit_pos_;
|
uint32_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 bitreader fields. */
|
/* Initializes the bitreader fields. */
|
||||||
@ -66,7 +70,7 @@ void BrotliInitBitReader(BrotliBitReader* const br);
|
|||||||
|
|
||||||
/* Ensures that accumulator is not empty. May consume one byte of input.
|
/* Ensures that accumulator is not empty. May consume one byte of input.
|
||||||
Returns 0 if data is required but there is no input available.
|
Returns 0 if data is required but there is no input available.
|
||||||
For BROTLI_BUILD_PORTABLE this function also prepares bit reader for aligned
|
For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
|
||||||
reading. */
|
reading. */
|
||||||
int BrotliWarmupBitReader(BrotliBitReader* const br);
|
int BrotliWarmupBitReader(BrotliBitReader* const br);
|
||||||
|
|
||||||
@ -109,9 +113,7 @@ static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) {
|
|||||||
return *((const uint16_t*)in);
|
return *((const uint16_t*)in);
|
||||||
} else if (BROTLI_BIG_ENDIAN) {
|
} else if (BROTLI_BIG_ENDIAN) {
|
||||||
uint16_t value = *((const uint16_t*)in);
|
uint16_t value = *((const uint16_t*)in);
|
||||||
return (uint16_t)(
|
return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8));
|
||||||
((value & 0xFFU) << 8) |
|
|
||||||
((value & 0xFF00U) >> 8));
|
|
||||||
} else {
|
} else {
|
||||||
return (uint16_t)(in[0] | (in[1] << 8));
|
return (uint16_t)(in[0] | (in[1] << 8));
|
||||||
}
|
}
|
||||||
@ -228,9 +230,9 @@ static BROTLI_INLINE int BrotliPullByte(BrotliBitReader* const br) {
|
|||||||
}
|
}
|
||||||
br->val_ >>= 8;
|
br->val_ >>= 8;
|
||||||
#if (BROTLI_64_BITS)
|
#if (BROTLI_64_BITS)
|
||||||
br->val_ |= ((uint64_t)*br->next_in) << 56;
|
br->val_ |= ((uint64_t)*br->next_in) << 56;
|
||||||
#else
|
#else
|
||||||
br->val_ |= ((uint32_t)*br->next_in) << 24;
|
br->val_ |= ((uint32_t)*br->next_in) << 24;
|
||||||
#endif
|
#endif
|
||||||
br->bit_pos_ -= 8;
|
br->bit_pos_ -= 8;
|
||||||
--br->avail_in;
|
--br->avail_in;
|
||||||
@ -262,7 +264,7 @@ static BROTLI_INLINE uint32_t BrotliGetBits(
|
|||||||
/* Tries to peek the specified amount of bits. Returns 0, if there is not
|
/* Tries to peek the specified amount of bits. Returns 0, if there is not
|
||||||
enough input. */
|
enough input. */
|
||||||
static BROTLI_INLINE int BrotliSafeGetBits(
|
static BROTLI_INLINE int BrotliSafeGetBits(
|
||||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||||
if (!BrotliPullByte(br)) {
|
if (!BrotliPullByte(br)) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -326,7 +328,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits(
|
|||||||
/* Tries to read the specified amount of bits. Returns 0, if there is not
|
/* Tries to read the specified amount of bits. Returns 0, if there is not
|
||||||
enough input. n_bits MUST be positive. */
|
enough input. n_bits MUST be positive. */
|
||||||
static BROTLI_INLINE int BrotliSafeReadBits(
|
static BROTLI_INLINE int BrotliSafeReadBits(
|
||||||
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
|
||||||
while (BrotliGetAvailableBits(br) < n_bits) {
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
||||||
if (!BrotliPullByte(br)) {
|
if (!BrotliPullByte(br)) {
|
||||||
return 0;
|
return 0;
|
||||||
@ -381,7 +383,7 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_BIT_READER_H_ */
|
#endif /* BROTLI_DEC_BIT_READER_H_ */
|
||||||
|
@ -102,10 +102,10 @@
|
|||||||
#include "./types.h"
|
#include "./types.h"
|
||||||
|
|
||||||
enum ContextType {
|
enum ContextType {
|
||||||
CONTEXT_LSB6 = 0,
|
CONTEXT_LSB6 = 0,
|
||||||
CONTEXT_MSB6 = 1,
|
CONTEXT_MSB6 = 1,
|
||||||
CONTEXT_UTF8 = 2,
|
CONTEXT_UTF8 = 2,
|
||||||
CONTEXT_SIGNED = 3
|
CONTEXT_SIGNED = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Common context lookup table for all context modes. */
|
/* Common context lookup table for all context modes. */
|
||||||
|
193
dec/decode.c
193
dec/decode.c
@ -28,12 +28,12 @@ extern "C" {
|
|||||||
|
|
||||||
/* BROTLI_FAILURE macro unwraps to BROTLI_RESULT_ERROR in non-debug build. */
|
/* BROTLI_FAILURE macro unwraps to BROTLI_RESULT_ERROR in non-debug build. */
|
||||||
/* In debug build it dumps file name, line and pretty function name. */
|
/* In debug build it dumps file name, line and pretty function name. */
|
||||||
#if defined(_MSC_VER) || !defined(BROTLI_DEBUG)
|
#if defined(_MSC_VER) || \
|
||||||
|
(!defined(BROTLI_DEBUG) && !defined(BROTLI_DECODE_DEBUG))
|
||||||
#define BROTLI_FAILURE() BROTLI_RESULT_ERROR
|
#define BROTLI_FAILURE() BROTLI_RESULT_ERROR
|
||||||
#else
|
#else
|
||||||
#define BROTLI_FAILURE() \
|
#define BROTLI_FAILURE() BrotliFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
|
||||||
BrotliFailure(__FILE__, __LINE__, __PRETTY_FUNCTION__)
|
static inline BrotliResult BrotliFailure(const char* f, int l, const char* fn) {
|
||||||
static inline BrotliResult BrotliFailure(const char *f, int l, const char *fn) {
|
|
||||||
fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn);
|
fprintf(stderr, "ERROR at %s:%d (%s)\n", f, l, fn);
|
||||||
fflush(stderr);
|
fflush(stderr);
|
||||||
return BROTLI_RESULT_ERROR;
|
return BROTLI_RESULT_ERROR;
|
||||||
@ -41,10 +41,10 @@ static inline BrotliResult BrotliFailure(const char *f, int l, const char *fn) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BROTLI_DECODE_DEBUG
|
#ifdef BROTLI_DECODE_DEBUG
|
||||||
#define BROTLI_LOG_UINT(name) \
|
#define BROTLI_LOG_UINT(name) \
|
||||||
printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))
|
printf("[%s] %s = %lu\n", __func__, #name, (unsigned long)(name))
|
||||||
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
|
#define BROTLI_LOG_ARRAY_INDEX(array_name, idx) \
|
||||||
printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
|
printf("[%s] %s[%lu] = %lu\n", __func__, #array_name, \
|
||||||
(unsigned long)(idx), (unsigned long)array_name[idx])
|
(unsigned long)(idx), (unsigned long)array_name[idx])
|
||||||
#define BROTLI_LOG(x) printf x
|
#define BROTLI_LOG(x) printf x
|
||||||
#else
|
#else
|
||||||
@ -61,8 +61,8 @@ static const uint32_t kNumBlockLengthCodes = 26;
|
|||||||
static const int kLiteralContextBits = 6;
|
static const int kLiteralContextBits = 6;
|
||||||
static const int kDistanceContextBits = 2;
|
static const int kDistanceContextBits = 2;
|
||||||
|
|
||||||
#define HUFFMAN_TABLE_BITS 8U
|
#define HUFFMAN_TABLE_BITS 8U
|
||||||
#define HUFFMAN_TABLE_MASK 0xff
|
#define HUFFMAN_TABLE_MASK 0xff
|
||||||
|
|
||||||
#define CODE_LENGTH_CODES 18
|
#define CODE_LENGTH_CODES 18
|
||||||
static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
|
static const uint8_t kCodeLengthCodeOrder[CODE_LENGTH_CODES] = {
|
||||||
@ -127,8 +127,7 @@ static uint32_t DecodeWindowBits(BrotliBitReader* br) {
|
|||||||
return 17;
|
return 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BROTLI_INLINE void memmove16(
|
static BROTLI_INLINE void memmove16(uint8_t* dst, uint8_t* src) {
|
||||||
uint8_t* dst, uint8_t* src) {
|
|
||||||
#if defined(__ARM_NEON__)
|
#if defined(__ARM_NEON__)
|
||||||
vst1q_u8(dst, vld1q_u8(src));
|
vst1q_u8(dst, vld1q_u8(src));
|
||||||
#else
|
#else
|
||||||
@ -479,8 +478,7 @@ static BROTLI_INLINE void ProcessSingleCodeLength(uint32_t code_len,
|
|||||||
*prev_code_len = code_len;
|
*prev_code_len = code_len;
|
||||||
*space -= 32768U >> code_len;
|
*space -= 32768U >> code_len;
|
||||||
code_length_histo[code_len]++;
|
code_length_histo[code_len]++;
|
||||||
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n",
|
BROTLI_LOG(("[ReadHuffmanCode] code_length[%d] = %d\n", *symbol, code_len));
|
||||||
*symbol, code_len));
|
|
||||||
}
|
}
|
||||||
(*symbol)++;
|
(*symbol)++;
|
||||||
}
|
}
|
||||||
@ -532,8 +530,8 @@ static BROTLI_INLINE void ProcessRepeatedCodeLength(uint32_t code_len,
|
|||||||
} while (++(*symbol) != last);
|
} while (++(*symbol) != last);
|
||||||
next_symbol[*repeat_code_len] = next;
|
next_symbol[*repeat_code_len] = next;
|
||||||
*space -= repeat_delta << (15 - *repeat_code_len);
|
*space -= repeat_delta << (15 - *repeat_code_len);
|
||||||
code_length_histo[*repeat_code_len] = (uint16_t)
|
code_length_histo[*repeat_code_len] =
|
||||||
(code_length_histo[*repeat_code_len] + repeat_delta);
|
(uint16_t)(code_length_histo[*repeat_code_len] + repeat_delta);
|
||||||
} else {
|
} else {
|
||||||
*symbol += repeat_delta;
|
*symbol += repeat_delta;
|
||||||
}
|
}
|
||||||
@ -568,8 +566,8 @@ static BrotliResult ReadSymbolCodeLengths(
|
|||||||
BrotliFillBitWindow16(br);
|
BrotliFillBitWindow16(br);
|
||||||
p += BrotliGetBitsUnmasked(br) &
|
p += BrotliGetBitsUnmasked(br) &
|
||||||
BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
|
BitMask(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH);
|
||||||
BrotliDropBits(br, p->bits); /* Use 1..5 bits */
|
BrotliDropBits(br, p->bits); /* Use 1..5 bits */
|
||||||
code_len = p->value; /* code_len == 0..17 */
|
code_len = p->value; /* code_len == 0..17 */
|
||||||
if (code_len < kCodeLengthRepeatCode) {
|
if (code_len < kCodeLengthRepeatCode) {
|
||||||
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);
|
||||||
@ -785,8 +783,8 @@ Complex: /* Decode Huffman-coded code lengths. */
|
|||||||
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
|
BROTLI_LOG(("[ReadHuffmanCode] space = %d\n", s->space));
|
||||||
return BROTLI_FAILURE();
|
return BROTLI_FAILURE();
|
||||||
}
|
}
|
||||||
table_size = BrotliBuildHuffmanTable(table, HUFFMAN_TABLE_BITS,
|
table_size = BrotliBuildHuffmanTable(
|
||||||
s->symbol_lists, s->code_length_histo);
|
table, HUFFMAN_TABLE_BITS, s->symbol_lists, s->code_length_histo);
|
||||||
if (opt_table_size) {
|
if (opt_table_size) {
|
||||||
*opt_table_size = table_size;
|
*opt_table_size = table_size;
|
||||||
}
|
}
|
||||||
@ -926,7 +924,7 @@ static BrotliResult DecodeContextMap(uint32_t context_map_size,
|
|||||||
BrotliBitReader* br = &s->br;
|
BrotliBitReader* br = &s->br;
|
||||||
BrotliResult result = BROTLI_RESULT_SUCCESS;
|
BrotliResult result = BROTLI_RESULT_SUCCESS;
|
||||||
|
|
||||||
switch((int)s->substate_context_map) {
|
switch ((int)s->substate_context_map) {
|
||||||
case BROTLI_STATE_CONTEXT_MAP_NONE:
|
case BROTLI_STATE_CONTEXT_MAP_NONE:
|
||||||
result = DecodeVarLenUint8(s, br, num_htrees);
|
result = DecodeVarLenUint8(s, br, num_htrees);
|
||||||
if (result != BROTLI_RESULT_SUCCESS) {
|
if (result != BROTLI_RESULT_SUCCESS) {
|
||||||
@ -1144,12 +1142,11 @@ static int BROTLI_NOINLINE SafeDecodeDistanceBlockSwitch(BrotliState* s) {
|
|||||||
|
|
||||||
static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
|
static BrotliResult WriteRingBuffer(size_t* available_out, uint8_t** next_out,
|
||||||
size_t* total_out, BrotliState* s) {
|
size_t* total_out, BrotliState* s) {
|
||||||
size_t pos = (s->pos > s->ringbuffer_size) ?
|
size_t pos = (s->pos > s->ringbuffer_size) ? (size_t)s->ringbuffer_size
|
||||||
(size_t)s->ringbuffer_size : (size_t)(s->pos);
|
: (size_t)(s->pos);
|
||||||
uint8_t* start = s->ringbuffer
|
uint8_t* start =
|
||||||
+ (s->partial_pos_out & (size_t)s->ringbuffer_mask);
|
s->ringbuffer + (s->partial_pos_out & (size_t)s->ringbuffer_mask);
|
||||||
size_t partial_pos_rb =
|
size_t partial_pos_rb = (s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
|
||||||
(s->rb_roundtrips * (size_t)s->ringbuffer_size) + pos;
|
|
||||||
size_t to_write = (partial_pos_rb - s->partial_pos_out);
|
size_t to_write = (partial_pos_rb - s->partial_pos_out);
|
||||||
size_t num_written = *available_out;
|
size_t num_written = *available_out;
|
||||||
if (num_written > to_write) {
|
if (num_written > to_write) {
|
||||||
@ -1199,7 +1196,7 @@ static int BROTLI_NOINLINE BrotliAllocateRingBuffer(BrotliState* s) {
|
|||||||
|
|
||||||
if (s->custom_dict) {
|
if (s->custom_dict) {
|
||||||
memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
|
memcpy(&s->ringbuffer[(-s->custom_dict_size) & s->ringbuffer_mask],
|
||||||
s->custom_dict, (size_t)s->custom_dict_size);
|
s->custom_dict, (size_t)s->custom_dict_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -1238,8 +1235,8 @@ static BrotliResult BROTLI_NOINLINE CopyUncompressedBlockToOutput(
|
|||||||
/* No break, continue to next state */
|
/* No break, continue to next state */
|
||||||
}
|
}
|
||||||
case BROTLI_STATE_UNCOMPRESSED_WRITE: {
|
case BROTLI_STATE_UNCOMPRESSED_WRITE: {
|
||||||
BrotliResult result = WriteRingBuffer(
|
BrotliResult result =
|
||||||
available_out, next_out, total_out, s);
|
WriteRingBuffer(available_out, next_out, total_out, s);
|
||||||
if (result != BROTLI_RESULT_SUCCESS) {
|
if (result != BROTLI_RESULT_SUCCESS) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -1293,10 +1290,10 @@ static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s,
|
|||||||
s->ringbuffer_size = 1 << s->window_bits;
|
s->ringbuffer_size = 1 << s->window_bits;
|
||||||
|
|
||||||
if (s->is_uncompressed) {
|
if (s->is_uncompressed) {
|
||||||
int next_block_header = BrotliPeekByte(br,
|
int next_block_header =
|
||||||
(size_t)s->meta_block_remaining_len);
|
BrotliPeekByte(br, (size_t)s->meta_block_remaining_len);
|
||||||
if (next_block_header != -1) { /* Peek succeeded */
|
if (next_block_header != -1) { /* Peek succeeded */
|
||||||
if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
|
if ((next_block_header & 3) == 3) { /* ISLAST and ISEMPTY */
|
||||||
is_last = 1;
|
is_last = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1305,8 +1302,8 @@ static void BROTLI_NOINLINE BrotliCalculateRingBufferSize(BrotliState* s,
|
|||||||
/* We need at least 2 bytes of ring buffer size to get the last two
|
/* We need at least 2 bytes of ring buffer size to get the last two
|
||||||
bytes for context from there */
|
bytes for context from there */
|
||||||
if (is_last) {
|
if (is_last) {
|
||||||
while (s->ringbuffer_size >= s->meta_block_remaining_len * 2
|
while (s->ringbuffer_size >= s->meta_block_remaining_len * 2 &&
|
||||||
&& s->ringbuffer_size > 32) {
|
s->ringbuffer_size > 32) {
|
||||||
s->ringbuffer_size >>= 1;
|
s->ringbuffer_size >>= 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1407,8 +1404,8 @@ static BROTLI_INLINE int ReadDistanceInternal(int safe,
|
|||||||
if (!safe && (s->distance_postfix_bits == 0)) {
|
if (!safe && (s->distance_postfix_bits == 0)) {
|
||||||
nbits = ((uint32_t)distval >> 1) + 1;
|
nbits = ((uint32_t)distval >> 1) + 1;
|
||||||
offset = ((2 + (distval & 1)) << nbits) - 4;
|
offset = ((2 + (distval & 1)) << nbits) - 4;
|
||||||
s->distance_code = (int)s->num_direct_distance_codes +
|
s->distance_code = (int)s->num_direct_distance_codes + offset +
|
||||||
offset + (int)BrotliReadBits(br, nbits);
|
(int)BrotliReadBits(br, nbits);
|
||||||
} else {
|
} else {
|
||||||
/* This branch also works well when s->distance_postfix_bits == 0 */
|
/* This branch also works well when s->distance_postfix_bits == 0 */
|
||||||
uint32_t bits;
|
uint32_t bits;
|
||||||
@ -1498,16 +1495,17 @@ static BROTLI_INLINE int CheckInputAmount(int safe,
|
|||||||
return BrotliCheckInputAmount(br, num);
|
return BrotliCheckInputAmount(br, num);
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BROTLI_SAFE(METHOD) { \
|
#define BROTLI_SAFE(METHOD) \
|
||||||
if (safe) { \
|
{ \
|
||||||
if (! Safe ## METHOD ) { \
|
if (safe) { \
|
||||||
result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
|
if (!Safe##METHOD) { \
|
||||||
goto saveStateAndReturn; \
|
result = BROTLI_RESULT_NEEDS_MORE_INPUT; \
|
||||||
} \
|
goto saveStateAndReturn; \
|
||||||
} else { \
|
} \
|
||||||
METHOD ; \
|
} else { \
|
||||||
} \
|
METHOD; \
|
||||||
}
|
} \
|
||||||
|
}
|
||||||
|
|
||||||
static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
|
static BROTLI_INLINE BrotliResult ProcessCommandsInternal(int safe,
|
||||||
BrotliState* s) {
|
BrotliState* s) {
|
||||||
@ -1579,8 +1577,8 @@ CommandInner:
|
|||||||
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
PreloadSymbol(safe, s->literal_htree, br, &bits, &value);
|
||||||
}
|
}
|
||||||
if (!safe) {
|
if (!safe) {
|
||||||
s->ringbuffer[pos] = (uint8_t)ReadPreloadedSymbol(
|
s->ringbuffer[pos] =
|
||||||
s->literal_htree, br, &bits, &value);
|
(uint8_t)ReadPreloadedSymbol(s->literal_htree, br, &bits, &value);
|
||||||
} else {
|
} else {
|
||||||
uint32_t literal;
|
uint32_t literal;
|
||||||
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
|
if (!SafeReadSymbol(s->literal_htree, br, &literal)) {
|
||||||
@ -1700,58 +1698,44 @@ postReadDistance:
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
||||||
"len: %d bytes left: %d\n",
|
"len: %d bytes left: %d\n",
|
||||||
pos, s->distance_code, i,
|
pos, s->distance_code, i, s->meta_block_remaining_len));
|
||||||
s->meta_block_remaining_len));
|
|
||||||
return BROTLI_FAILURE();
|
return BROTLI_FAILURE();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
||||||
"len: %d bytes left: %d\n", pos, s->distance_code, i,
|
"len: %d bytes left: %d\n",
|
||||||
s->meta_block_remaining_len));
|
pos, s->distance_code, i, s->meta_block_remaining_len));
|
||||||
return BROTLI_FAILURE();
|
return BROTLI_FAILURE();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const uint8_t *ringbuffer_end_minus_copy_length =
|
int src_start = (pos - s->distance_code) & s->ringbuffer_mask;
|
||||||
s->ringbuffer_end - i;
|
|
||||||
uint8_t* copy_src = &s->ringbuffer[
|
|
||||||
(pos - s->distance_code) & s->ringbuffer_mask];
|
|
||||||
uint8_t* copy_dst = &s->ringbuffer[pos];
|
uint8_t* copy_dst = &s->ringbuffer[pos];
|
||||||
/* Check for possible underflow and clamp the pointer to 0. */
|
uint8_t* copy_src = &s->ringbuffer[src_start];
|
||||||
if (PREDICT_FALSE(s->ringbuffer_end < (const uint8_t*)0 + i)) {
|
int dst_end = pos + i;
|
||||||
ringbuffer_end_minus_copy_length = 0;
|
int src_end = src_start + i;
|
||||||
}
|
|
||||||
/* update the recent distances cache */
|
/* update the recent distances cache */
|
||||||
s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
|
s->dist_rb[s->dist_rb_idx & 3] = s->distance_code;
|
||||||
++s->dist_rb_idx;
|
++s->dist_rb_idx;
|
||||||
s->meta_block_remaining_len -= i;
|
s->meta_block_remaining_len -= i;
|
||||||
if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
|
if (PREDICT_FALSE(s->meta_block_remaining_len < 0)) {
|
||||||
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
BROTLI_LOG(("Invalid backward reference. pos: %d distance: %d "
|
||||||
"len: %d bytes left: %d\n", pos, s->distance_code, i,
|
"len: %d bytes left: %d\n",
|
||||||
s->meta_block_remaining_len));
|
pos, s->distance_code, i, s->meta_block_remaining_len));
|
||||||
return BROTLI_FAILURE();
|
return BROTLI_FAILURE();
|
||||||
}
|
}
|
||||||
/* There is 128+ bytes of slack in the ringbuffer allocation.
|
/* There are 32+ bytes of slack in the ringbuffer allocation.
|
||||||
Also, we have 16 short codes, that make these 16 bytes irrelevant
|
Also, we have 16 short codes, that make these 16 bytes irrelevant
|
||||||
in the ringbuffer. Let's copy over them as a first guess.
|
in the ringbuffer. Let's copy over them as a first guess.
|
||||||
*/
|
*/
|
||||||
memmove16(copy_dst, copy_src);
|
memmove16(copy_dst, copy_src);
|
||||||
/* Now check if the copy extends over the ringbuffer end,
|
if (src_end > pos && dst_end > src_start) {
|
||||||
or if the copy overlaps with itself, if yes, do wrap-copy. */
|
/* Regions intersect. */
|
||||||
if (copy_src < copy_dst) {
|
goto CommandPostWrapCopy;
|
||||||
if (copy_dst >= ringbuffer_end_minus_copy_length) {
|
}
|
||||||
goto CommandPostWrapCopy;
|
if (dst_end >= s->ringbuffer_size || src_end >= s->ringbuffer_size) {
|
||||||
}
|
/* At least one region wraps. */
|
||||||
if (copy_src + i > copy_dst) {
|
goto CommandPostWrapCopy;
|
||||||
goto postSelfintersecting;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (copy_src >= ringbuffer_end_minus_copy_length) {
|
|
||||||
goto CommandPostWrapCopy;
|
|
||||||
}
|
|
||||||
if (copy_dst + i > copy_src) {
|
|
||||||
goto postSelfintersecting;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
pos += i;
|
pos += i;
|
||||||
if (i > 16) {
|
if (i > 16) {
|
||||||
@ -1772,30 +1756,17 @@ postReadDistance:
|
|||||||
} else {
|
} else {
|
||||||
goto CommandBegin;
|
goto CommandBegin;
|
||||||
}
|
}
|
||||||
postSelfintersecting:
|
|
||||||
while (--i >= 0) {
|
|
||||||
s->ringbuffer[pos] =
|
|
||||||
s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
|
|
||||||
++pos;
|
|
||||||
}
|
|
||||||
if (s->meta_block_remaining_len <= 0) {
|
|
||||||
/* Next metablock, if any */
|
|
||||||
s->state = BROTLI_STATE_METABLOCK_DONE;
|
|
||||||
goto saveStateAndReturn;
|
|
||||||
} else {
|
|
||||||
goto CommandBegin;
|
|
||||||
}
|
|
||||||
|
|
||||||
CommandPostWrapCopy:
|
CommandPostWrapCopy:
|
||||||
s->state = BROTLI_STATE_COMMAND_POST_WRAP_COPY;
|
{
|
||||||
while (--i >= 0) {
|
int wrap_guard = s->ringbuffer_size - pos;
|
||||||
s->ringbuffer[pos] =
|
while (--i >= 0) {
|
||||||
s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
|
s->ringbuffer[pos] =
|
||||||
++pos;
|
s->ringbuffer[(pos - s->distance_code) & s->ringbuffer_mask];
|
||||||
if (pos == s->ringbuffer_size) {
|
++pos;
|
||||||
/*s->partial_pos_rb += (size_t)s->ringbuffer_size;*/
|
if (PREDICT_FALSE(--wrap_guard == 0)) {
|
||||||
s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
|
s->state = BROTLI_STATE_COMMAND_POST_WRITE_2;
|
||||||
goto saveStateAndReturn;
|
goto saveStateAndReturn;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (s->meta_block_remaining_len <= 0) {
|
if (s->meta_block_remaining_len <= 0) {
|
||||||
@ -1960,8 +1931,8 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
|
|||||||
result = BROTLI_FAILURE();
|
result = BROTLI_FAILURE();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->block_len_trees = s->block_type_trees +
|
s->block_len_trees =
|
||||||
3 * BROTLI_HUFFMAN_MAX_SIZE_258;
|
s->block_type_trees + 3 * BROTLI_HUFFMAN_MAX_SIZE_258;
|
||||||
|
|
||||||
s->state = BROTLI_STATE_METABLOCK_BEGIN;
|
s->state = BROTLI_STATE_METABLOCK_BEGIN;
|
||||||
/* No break, continue to next state */
|
/* No break, continue to next state */
|
||||||
@ -2081,8 +2052,8 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
|
|||||||
}
|
}
|
||||||
s->distance_postfix_bits = bits & BitMask(2);
|
s->distance_postfix_bits = bits & BitMask(2);
|
||||||
bits >>= 2;
|
bits >>= 2;
|
||||||
s->num_direct_distance_codes = NUM_DISTANCE_SHORT_CODES +
|
s->num_direct_distance_codes =
|
||||||
(bits << s->distance_postfix_bits);
|
NUM_DISTANCE_SHORT_CODES + (bits << s->distance_postfix_bits);
|
||||||
BROTLI_LOG_UINT(s->num_direct_distance_codes);
|
BROTLI_LOG_UINT(s->num_direct_distance_codes);
|
||||||
BROTLI_LOG_UINT(s->distance_postfix_bits);
|
BROTLI_LOG_UINT(s->distance_postfix_bits);
|
||||||
s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
|
s->distance_postfix_mask = (int)BitMask(s->distance_postfix_bits);
|
||||||
@ -2159,6 +2130,8 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
|
|||||||
case 2:
|
case 2:
|
||||||
hgroup = &s->distance_hgroup;
|
hgroup = &s->distance_hgroup;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return BROTLI_FAILURE();
|
||||||
}
|
}
|
||||||
result = HuffmanTreeGroupDecode(hgroup, s);
|
result = HuffmanTreeGroupDecode(hgroup, s);
|
||||||
}
|
}
|
||||||
@ -2255,10 +2228,10 @@ BrotliResult BrotliDecompressStream(size_t* available_in,
|
|||||||
void BrotliSetCustomDictionary(
|
void BrotliSetCustomDictionary(
|
||||||
size_t size, const uint8_t* dict, BrotliState* s) {
|
size_t size, const uint8_t* dict, BrotliState* s) {
|
||||||
s->custom_dict = dict;
|
s->custom_dict = dict;
|
||||||
s->custom_dict_size = (int) size;
|
s->custom_dict_size = (int)size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -9462,5 +9462,5 @@ const uint8_t kBrotliDictionary[122784] = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -18,22 +18,21 @@ extern "C" {
|
|||||||
extern const uint8_t kBrotliDictionary[122784];
|
extern const uint8_t kBrotliDictionary[122784];
|
||||||
|
|
||||||
static const uint32_t kBrotliDictionaryOffsetsByLength[] = {
|
static const uint32_t kBrotliDictionaryOffsetsByLength[] = {
|
||||||
0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032,
|
0, 0, 0, 0, 0, 4096, 9216, 21504, 35840, 44032, 53248, 63488, 74752, 87040,
|
||||||
53248, 63488, 74752, 87040, 93696, 100864, 104704, 106752, 108928, 113536,
|
93696, 100864, 104704, 106752, 108928, 113536, 115968, 118528, 119872, 121280,
|
||||||
115968, 118528, 119872, 121280, 122016,
|
122016
|
||||||
};
|
};
|
||||||
|
|
||||||
static const uint8_t kBrotliDictionarySizeBitsByLength[] = {
|
static const uint8_t kBrotliDictionarySizeBitsByLength[] = {
|
||||||
0, 0, 0, 0, 10, 10, 11, 11, 10, 10,
|
0, 0, 0, 0, 10, 10, 11, 11, 10, 10, 10, 10, 10,
|
||||||
10, 10, 10, 9, 9, 8, 7, 7, 8, 7,
|
9, 9, 8, 7, 7, 8, 7, 7, 6, 6, 5, 5,
|
||||||
7, 6, 6, 5, 5,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const int kBrotliMinDictionaryWordLength = 4;
|
static const int kBrotliMinDictionaryWordLength = 4;
|
||||||
static const int kBrotliMaxDictionaryWordLength = 24;
|
static const int kBrotliMaxDictionaryWordLength = 24;
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_DICTIONARY_H_ */
|
#endif /* BROTLI_DEC_DICTIONARY_H_ */
|
||||||
|
200
dec/huffman.c
200
dec/huffman.c
@ -24,43 +24,43 @@ extern "C" {
|
|||||||
#else
|
#else
|
||||||
#define BROTLI_REVERSE_BITS_BASE 0
|
#define BROTLI_REVERSE_BITS_BASE 0
|
||||||
static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
|
static uint8_t kReverseBits[1 << BROTLI_REVERSE_BITS_MAX] = {
|
||||||
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
0x00, 0x80, 0x40, 0xC0, 0x20, 0xA0, 0x60, 0xE0,
|
||||||
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
0x10, 0x90, 0x50, 0xD0, 0x30, 0xB0, 0x70, 0xF0,
|
||||||
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
0x08, 0x88, 0x48, 0xC8, 0x28, 0xA8, 0x68, 0xE8,
|
||||||
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
0x18, 0x98, 0x58, 0xD8, 0x38, 0xB8, 0x78, 0xF8,
|
||||||
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
0x04, 0x84, 0x44, 0xC4, 0x24, 0xA4, 0x64, 0xE4,
|
||||||
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
0x14, 0x94, 0x54, 0xD4, 0x34, 0xB4, 0x74, 0xF4,
|
||||||
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
0x0C, 0x8C, 0x4C, 0xCC, 0x2C, 0xAC, 0x6C, 0xEC,
|
||||||
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
0x1C, 0x9C, 0x5C, 0xDC, 0x3C, 0xBC, 0x7C, 0xFC,
|
||||||
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
0x02, 0x82, 0x42, 0xC2, 0x22, 0xA2, 0x62, 0xE2,
|
||||||
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
0x12, 0x92, 0x52, 0xD2, 0x32, 0xB2, 0x72, 0xF2,
|
||||||
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
0x0A, 0x8A, 0x4A, 0xCA, 0x2A, 0xAA, 0x6A, 0xEA,
|
||||||
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
0x1A, 0x9A, 0x5A, 0xDA, 0x3A, 0xBA, 0x7A, 0xFA,
|
||||||
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
0x06, 0x86, 0x46, 0xC6, 0x26, 0xA6, 0x66, 0xE6,
|
||||||
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
0x16, 0x96, 0x56, 0xD6, 0x36, 0xB6, 0x76, 0xF6,
|
||||||
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
0x0E, 0x8E, 0x4E, 0xCE, 0x2E, 0xAE, 0x6E, 0xEE,
|
||||||
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
0x1E, 0x9E, 0x5E, 0xDE, 0x3E, 0xBE, 0x7E, 0xFE,
|
||||||
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
0x01, 0x81, 0x41, 0xC1, 0x21, 0xA1, 0x61, 0xE1,
|
||||||
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
0x11, 0x91, 0x51, 0xD1, 0x31, 0xB1, 0x71, 0xF1,
|
||||||
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
0x09, 0x89, 0x49, 0xC9, 0x29, 0xA9, 0x69, 0xE9,
|
||||||
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
0x19, 0x99, 0x59, 0xD9, 0x39, 0xB9, 0x79, 0xF9,
|
||||||
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
0x05, 0x85, 0x45, 0xC5, 0x25, 0xA5, 0x65, 0xE5,
|
||||||
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
0x15, 0x95, 0x55, 0xD5, 0x35, 0xB5, 0x75, 0xF5,
|
||||||
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
0x0D, 0x8D, 0x4D, 0xCD, 0x2D, 0xAD, 0x6D, 0xED,
|
||||||
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
0x1D, 0x9D, 0x5D, 0xDD, 0x3D, 0xBD, 0x7D, 0xFD,
|
||||||
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
0x03, 0x83, 0x43, 0xC3, 0x23, 0xA3, 0x63, 0xE3,
|
||||||
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
0x13, 0x93, 0x53, 0xD3, 0x33, 0xB3, 0x73, 0xF3,
|
||||||
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
0x0B, 0x8B, 0x4B, 0xCB, 0x2B, 0xAB, 0x6B, 0xEB,
|
||||||
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
0x1B, 0x9B, 0x5B, 0xDB, 0x3B, 0xBB, 0x7B, 0xFB,
|
||||||
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
0x07, 0x87, 0x47, 0xC7, 0x27, 0xA7, 0x67, 0xE7,
|
||||||
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
0x17, 0x97, 0x57, 0xD7, 0x37, 0xB7, 0x77, 0xF7,
|
||||||
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
0x0F, 0x8F, 0x4F, 0xCF, 0x2F, 0xAF, 0x6F, 0xEF,
|
||||||
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
0x1F, 0x9F, 0x5F, 0xDF, 0x3F, 0xBF, 0x7F, 0xFF
|
||||||
};
|
};
|
||||||
#endif /* BROTLI_RBIT */
|
#endif /* BROTLI_RBIT */
|
||||||
|
|
||||||
#define BROTLI_REVERSE_BITS_LOWEST \
|
#define BROTLI_REVERSE_BITS_LOWEST \
|
||||||
(1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
|
(1U << (BROTLI_REVERSE_BITS_MAX - 1 + BROTLI_REVERSE_BITS_BASE))
|
||||||
|
|
||||||
/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
|
/* Returns reverse(num >> BROTLI_REVERSE_BITS_BASE, BROTLI_REVERSE_BITS_MAX),
|
||||||
where reverse(value, len) is the bit-wise reversal of the len least
|
where reverse(value, len) is the bit-wise reversal of the len least
|
||||||
@ -102,20 +102,20 @@ static BROTLI_INLINE int NextTableBitSize(const uint16_t* const count,
|
|||||||
|
|
||||||
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
||||||
const uint8_t* const code_lengths,
|
const uint8_t* const code_lengths,
|
||||||
uint16_t *count) {
|
uint16_t* count) {
|
||||||
HuffmanCode code; /* current table entry */
|
HuffmanCode code; /* current table entry */
|
||||||
int symbol; /* symbol index in original or sorted table */
|
int symbol; /* symbol index in original or sorted table */
|
||||||
uint32_t key; /* prefix code */
|
uint32_t key; /* prefix code */
|
||||||
uint32_t key_step; /* prefix code addend */
|
uint32_t key_step; /* prefix code addend */
|
||||||
int step; /* step size to replicate values in current table */
|
int step; /* step size to replicate values in current table */
|
||||||
int table_size; /* size of current table */
|
int table_size; /* size of current table */
|
||||||
int sorted[18]; /* symbols sorted by code length */
|
int sorted[18]; /* symbols sorted by code length */
|
||||||
/* offsets in sorted table for each length */
|
/* offsets in sorted table for each length */
|
||||||
int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1];
|
int offset[BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH + 1];
|
||||||
int bits;
|
int bits;
|
||||||
int bits_count;
|
int bits_count;
|
||||||
BROTLI_DCHECK(
|
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <=
|
||||||
BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH <= BROTLI_REVERSE_BITS_MAX);
|
BROTLI_REVERSE_BITS_MAX);
|
||||||
|
|
||||||
/* generate offsets into sorted symbol table by code length */
|
/* generate offsets into sorted symbol table by code length */
|
||||||
symbol = -1;
|
symbol = -1;
|
||||||
@ -170,26 +170,26 @@ void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* table,
|
|||||||
uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||||
int root_bits,
|
int root_bits,
|
||||||
const uint16_t* const symbol_lists,
|
const uint16_t* const symbol_lists,
|
||||||
uint16_t *count) {
|
uint16_t* count) {
|
||||||
HuffmanCode code; /* current table entry */
|
HuffmanCode code; /* current table entry */
|
||||||
HuffmanCode* table; /* next available space in table */
|
HuffmanCode* table; /* next available space in table */
|
||||||
int len; /* current code length */
|
int len; /* current code length */
|
||||||
int symbol; /* symbol index in original or sorted table */
|
int symbol; /* symbol index in original or sorted table */
|
||||||
uint32_t key; /* prefix code */
|
uint32_t key; /* prefix code */
|
||||||
uint32_t key_step; /* prefix code addend */
|
uint32_t key_step; /* prefix code addend */
|
||||||
uint32_t sub_key; /* 2nd level table prefix code */
|
uint32_t sub_key; /* 2nd level table prefix code */
|
||||||
uint32_t sub_key_step;/* 2nd level table prefix code addend */
|
uint32_t sub_key_step; /* 2nd level table prefix code addend */
|
||||||
int step; /* step size to replicate values in current table */
|
int step; /* step size to replicate values in current table */
|
||||||
int table_bits; /* key length of current table */
|
int table_bits; /* key length of current table */
|
||||||
int table_size; /* size of current table */
|
int table_size; /* size of current table */
|
||||||
int total_size; /* sum of root table size and 2nd level table sizes */
|
int total_size; /* sum of root table size and 2nd level table sizes */
|
||||||
int max_length = -1;
|
int max_length = -1;
|
||||||
int bits;
|
int bits;
|
||||||
int bits_count;
|
int bits_count;
|
||||||
|
|
||||||
BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX);
|
BROTLI_DCHECK(root_bits <= BROTLI_REVERSE_BITS_MAX);
|
||||||
BROTLI_DCHECK(
|
BROTLI_DCHECK(BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <=
|
||||||
BROTLI_HUFFMAN_MAX_CODE_LENGTH - root_bits <= BROTLI_REVERSE_BITS_MAX);
|
BROTLI_REVERSE_BITS_MAX);
|
||||||
|
|
||||||
while (symbol_lists[max_length] == 0xFFFF) max_length--;
|
while (symbol_lists[max_length] == 0xFFFF) max_length--;
|
||||||
max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1;
|
max_length += BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1;
|
||||||
@ -246,8 +246,8 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
|||||||
sub_key = BrotliReverseBits(key);
|
sub_key = BrotliReverseBits(key);
|
||||||
key += key_step;
|
key += key_step;
|
||||||
root_table[sub_key].bits = (uint8_t)(table_bits + root_bits);
|
root_table[sub_key].bits = (uint8_t)(table_bits + root_bits);
|
||||||
root_table[sub_key].value = (uint16_t)(
|
root_table[sub_key].value =
|
||||||
((size_t)(table - root_table)) - sub_key);
|
(uint16_t)(((size_t)(table - root_table)) - sub_key);
|
||||||
sub_key = 0;
|
sub_key = 0;
|
||||||
}
|
}
|
||||||
code.bits = (uint8_t)(len - root_bits);
|
code.bits = (uint8_t)(len - root_bits);
|
||||||
@ -265,7 +265,7 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
|||||||
|
|
||||||
uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
||||||
int root_bits,
|
int root_bits,
|
||||||
uint16_t *val,
|
uint16_t* val,
|
||||||
uint32_t num_symbols) {
|
uint32_t num_symbols) {
|
||||||
uint32_t table_size = 1;
|
uint32_t table_size = 1;
|
||||||
const uint32_t goal_size = 1U << root_bits;
|
const uint32_t goal_size = 1U << root_bits;
|
||||||
@ -302,49 +302,47 @@ uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|||||||
table[3].bits = 2;
|
table[3].bits = 2;
|
||||||
table_size = 4;
|
table_size = 4;
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3: {
|
||||||
{
|
int i, k;
|
||||||
int i, k;
|
for (i = 0; i < 3; ++i) {
|
||||||
for (i = 0; i < 3; ++i) {
|
for (k = i + 1; k < 4; ++k) {
|
||||||
for (k = i + 1; k < 4; ++k) {
|
if (val[k] < val[i]) {
|
||||||
if (val[k] < val[i]) {
|
uint16_t t = val[k];
|
||||||
uint16_t t = val[k];
|
val[k] = val[i];
|
||||||
val[k] = val[i];
|
val[i] = t;
|
||||||
val[i] = t;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (i = 0; i < 4; ++i) {
|
|
||||||
table[i].bits = 2;
|
|
||||||
}
|
|
||||||
table[0].value = val[0];
|
|
||||||
table[2].value = val[1];
|
|
||||||
table[1].value = val[2];
|
|
||||||
table[3].value = val[3];
|
|
||||||
table_size = 4;
|
|
||||||
}
|
}
|
||||||
break;
|
for (i = 0; i < 4; ++i) {
|
||||||
case 4:
|
table[i].bits = 2;
|
||||||
{
|
|
||||||
int i;
|
|
||||||
if (val[3] < val[2]) {
|
|
||||||
uint16_t t = val[3];
|
|
||||||
val[3] = val[2];
|
|
||||||
val[2] = t;
|
|
||||||
}
|
|
||||||
for (i = 0; i < 7; ++i) {
|
|
||||||
table[i].value = val[0];
|
|
||||||
table[i].bits = (uint8_t)(1 + (i & 1));
|
|
||||||
}
|
|
||||||
table[1].value = val[1];
|
|
||||||
table[3].value = val[2];
|
|
||||||
table[5].value = val[1];
|
|
||||||
table[7].value = val[3];
|
|
||||||
table[3].bits = 3;
|
|
||||||
table[7].bits = 3;
|
|
||||||
table_size = 8;
|
|
||||||
}
|
}
|
||||||
|
table[0].value = val[0];
|
||||||
|
table[2].value = val[1];
|
||||||
|
table[1].value = val[2];
|
||||||
|
table[3].value = val[3];
|
||||||
|
table_size = 4;
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
case 4: {
|
||||||
|
int i;
|
||||||
|
if (val[3] < val[2]) {
|
||||||
|
uint16_t t = val[3];
|
||||||
|
val[3] = val[2];
|
||||||
|
val[2] = t;
|
||||||
|
}
|
||||||
|
for (i = 0; i < 7; ++i) {
|
||||||
|
table[i].value = val[0];
|
||||||
|
table[i].bits = (uint8_t)(1 + (i & 1));
|
||||||
|
}
|
||||||
|
table[1].value = val[1];
|
||||||
|
table[3].value = val[2];
|
||||||
|
table[5].value = val[1];
|
||||||
|
table[7].value = val[3];
|
||||||
|
table[3].bits = 3;
|
||||||
|
table[7].bits = 3;
|
||||||
|
table_size = 8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
while (table_size != goal_size) {
|
while (table_size != goal_size) {
|
||||||
memcpy(&table[table_size], &table[0],
|
memcpy(&table[table_size], &table[0],
|
||||||
@ -355,5 +353,5 @@ uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -32,22 +32,22 @@ static const uint16_t kMaxHuffmanTableSize[] = {
|
|||||||
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
|
#define BROTLI_HUFFMAN_MAX_CODE_LENGTH_CODE_LENGTH 5
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t bits; /* number of bits used for this symbol */
|
uint8_t bits; /* number of bits used for this symbol */
|
||||||
uint16_t value; /* symbol value or table offset */
|
uint16_t value; /* symbol value or table offset */
|
||||||
} HuffmanCode;
|
} HuffmanCode;
|
||||||
|
|
||||||
|
|
||||||
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
||||||
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
void BrotliBuildCodeLengthsHuffmanTable(HuffmanCode* root_table,
|
||||||
const uint8_t* const code_lengths,
|
const uint8_t* const code_lengths,
|
||||||
uint16_t *count);
|
uint16_t* count);
|
||||||
|
|
||||||
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
/* Builds Huffman lookup table assuming code lengths are in symbol order. */
|
||||||
/* Returns size of resulting table. */
|
/* Returns size of resulting table. */
|
||||||
uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
||||||
int root_bits,
|
int root_bits,
|
||||||
const uint16_t* const symbol_lists,
|
const uint16_t* const symbol_lists,
|
||||||
uint16_t *count_arg);
|
uint16_t* count_arg);
|
||||||
|
|
||||||
/* Builds a simple Huffman table. The num_symbols parameter is to be */
|
/* 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 */
|
/* interpreted as follows: 0 means 1 symbol, 1 means 2 symbols, 2 means 3 */
|
||||||
@ -55,7 +55,7 @@ uint32_t BrotliBuildHuffmanTable(HuffmanCode* root_table,
|
|||||||
/* lengths 1,2,3,3. */
|
/* lengths 1,2,3,3. */
|
||||||
uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
uint32_t BrotliBuildSimpleHuffmanTable(HuffmanCode* table,
|
||||||
int root_bits,
|
int root_bits,
|
||||||
uint16_t *symbols,
|
uint16_t* symbols,
|
||||||
uint32_t num_symbols);
|
uint32_t num_symbols);
|
||||||
|
|
||||||
/* Contains a collection of Huffman trees with the same alphabet size. */
|
/* Contains a collection of Huffman trees with the same alphabet size. */
|
||||||
@ -67,7 +67,7 @@ typedef struct {
|
|||||||
} HuffmanTreeGroup;
|
} HuffmanTreeGroup;
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_HUFFMAN_H_ */
|
#endif /* BROTLI_DEC_HUFFMAN_H_ */
|
||||||
|
40
dec/port.h
40
dec/port.h
@ -24,7 +24,7 @@
|
|||||||
#ifndef BROTLI_DEC_PORT_H_
|
#ifndef BROTLI_DEC_PORT_H_
|
||||||
#define BROTLI_DEC_PORT_H_
|
#define BROTLI_DEC_PORT_H_
|
||||||
|
|
||||||
#include<assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
/* Compatibility with non-clang compilers. */
|
/* Compatibility with non-clang compilers. */
|
||||||
#ifndef __has_builtin
|
#ifndef __has_builtin
|
||||||
@ -39,10 +39,6 @@
|
|||||||
#define __has_feature(x) 0
|
#define __has_feature(x) 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__sparc)
|
|
||||||
#define BROTLI_TARGET_SPARC
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__arm__) || defined(__thumb__) || \
|
#if defined(__arm__) || defined(__thumb__) || \
|
||||||
defined(_M_ARM) || defined(_M_ARMT)
|
defined(_M_ARM) || defined(_M_ARMT)
|
||||||
#define BROTLI_TARGET_ARM
|
#define BROTLI_TARGET_ARM
|
||||||
@ -55,6 +51,10 @@
|
|||||||
#endif /* ARMv8 */
|
#endif /* ARMv8 */
|
||||||
#endif /* ARM */
|
#endif /* ARM */
|
||||||
|
|
||||||
|
#if defined(__i386) || defined(_M_IX86)
|
||||||
|
#define BROTLI_TARGET_X86
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__x86_64__) || defined(_M_X64)
|
#if defined(__x86_64__) || defined(_M_X64)
|
||||||
#define BROTLI_TARGET_X64
|
#define BROTLI_TARGET_X64
|
||||||
#endif
|
#endif
|
||||||
@ -83,19 +83,13 @@
|
|||||||
#define BROTLI_MODERN_COMPILER 0
|
#define BROTLI_MODERN_COMPILER 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* SPARC and ARMv6 don't support unaligned read.
|
|
||||||
Choose portable build for them. */
|
|
||||||
#if !defined(BROTLI_BUILD_PORTABLE)
|
|
||||||
#if defined(BROTLI_TARGET_SPARC) || \
|
|
||||||
(defined(BROTLI_TARGET_ARM) && !defined(BROTLI_TARGET_ARMV7))
|
|
||||||
#define BROTLI_BUILD_PORTABLE
|
|
||||||
#endif /* SPARK or ARMv6 */
|
|
||||||
#endif /* portable build */
|
|
||||||
|
|
||||||
#ifdef BROTLI_BUILD_PORTABLE
|
#ifdef BROTLI_BUILD_PORTABLE
|
||||||
#define BROTLI_ALIGNED_READ 1
|
#define BROTLI_ALIGNED_READ 1
|
||||||
|
#elif defined(BROTLI_TARGET_X86) || defined(BROTLI_TARGET_X64) || \
|
||||||
|
defined(BROTLI_TARGET_ARMV7) || defined(BROTLI_TARGET_ARMV8)
|
||||||
|
#define BROTLI_ALIGNED_READ 0 /* Allow unaligned access on whitelisted CPUs. */
|
||||||
#else
|
#else
|
||||||
#define BROTLI_ALIGNED_READ 0
|
#define BROTLI_ALIGNED_READ 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers.
|
/* Define "PREDICT_TRUE" and "PREDICT_FALSE" macros for capable compilers.
|
||||||
@ -137,8 +131,8 @@ OR:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) \
|
#if defined(__cplusplus) || !defined(__STRICT_ANSI__) || \
|
||||||
|| __STDC_VERSION__ >= 199901L
|
__STDC_VERSION__ >= 199901L
|
||||||
#define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE
|
#define BROTLI_INLINE inline ATTRIBUTE_ALWAYS_INLINE
|
||||||
#else
|
#else
|
||||||
#define BROTLI_INLINE
|
#define BROTLI_INLINE
|
||||||
@ -190,14 +184,14 @@ OR:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if BROTLI_MODERN_COMPILER || __has_attribute(noinline)
|
#if BROTLI_MODERN_COMPILER || __has_attribute(noinline)
|
||||||
#define BROTLI_NOINLINE __attribute__ ((noinline))
|
#define BROTLI_NOINLINE __attribute__((noinline))
|
||||||
#else
|
#else
|
||||||
#define BROTLI_NOINLINE
|
#define BROTLI_NOINLINE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define BROTLI_REPEAT(N, X) { \
|
#define BROTLI_REPEAT(N, X) { \
|
||||||
if ((N & 1) != 0) {X;} \
|
if ((N & 1) != 0) {X;} \
|
||||||
if ((N & 2) != 0) {X; X;} \
|
if ((N & 2) != 0) {X; X;} \
|
||||||
if ((N & 4) != 0) {X; X; X; X;} \
|
if ((N & 4) != 0) {X; X; X; X;} \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,9 +214,9 @@ static BROTLI_INLINE unsigned BrotliRBit(unsigned input) {
|
|||||||
|
|
||||||
#define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
#define BROTLI_ALLOC(S, L) S->alloc_func(S->memory_manager_opaque, L)
|
||||||
|
|
||||||
#define BROTLI_FREE(S, X) { \
|
#define BROTLI_FREE(S, X) { \
|
||||||
S->free_func(S->memory_manager_opaque, X); \
|
S->free_func(S->memory_manager_opaque, X); \
|
||||||
X = NULL; \
|
X = NULL; \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BROTLI_UNUSED(X) (void)(X)
|
#define BROTLI_UNUSED(X) (void)(X)
|
||||||
|
@ -161,7 +161,7 @@ void BrotliHuffmanTreeGroupInit(BrotliState* s, HuffmanTreeGroup* group,
|
|||||||
const size_t max_table_size = kMaxHuffmanTableSize[(alphabet_size + 31) >> 5];
|
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 code_size = sizeof(HuffmanCode) * ntrees * max_table_size;
|
||||||
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
|
const size_t htree_size = sizeof(HuffmanCode*) * ntrees;
|
||||||
char *p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
|
char* p = (char*)BROTLI_ALLOC(s, code_size + htree_size);
|
||||||
group->alphabet_size = (uint16_t)alphabet_size;
|
group->alphabet_size = (uint16_t)alphabet_size;
|
||||||
group->num_htrees = (uint16_t)ntrees;
|
group->num_htrees = (uint16_t)ntrees;
|
||||||
group->codes = (HuffmanCode*)p;
|
group->codes = (HuffmanCode*)p;
|
||||||
@ -174,5 +174,5 @@ void BrotliHuffmanTreeGroupRelease(BrotliState* s, HuffmanTreeGroup* group) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
@ -150,7 +150,7 @@ struct BrotliStateStruct {
|
|||||||
int distance_postfix_mask;
|
int distance_postfix_mask;
|
||||||
uint32_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 literal_htree_index;
|
uint8_t literal_htree_index;
|
||||||
uint8_t dist_htree_index;
|
uint8_t dist_htree_index;
|
||||||
uint32_t repeat_code_len;
|
uint32_t repeat_code_len;
|
||||||
@ -174,7 +174,7 @@ struct BrotliStateStruct {
|
|||||||
uint16_t* symbol_lists;
|
uint16_t* symbol_lists;
|
||||||
/* Storage from symbol_lists. */
|
/* Storage from symbol_lists. */
|
||||||
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
uint16_t symbols_lists_array[BROTLI_HUFFMAN_MAX_CODE_LENGTH + 1 +
|
||||||
BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE];
|
BROTLI_HUFFMAN_MAX_CODE_LENGTHS_SIZE];
|
||||||
/* Tails of symbol chains. */
|
/* Tails of symbol chains. */
|
||||||
int next_symbol[32];
|
int next_symbol[32];
|
||||||
uint8_t code_length_code_lengths[18];
|
uint8_t code_length_code_lengths[18];
|
||||||
@ -242,9 +242,8 @@ int BrotliStateIsStreamStart(const BrotliState* s);
|
|||||||
produced all of the output, and 0 otherwise. */
|
produced all of the output, and 0 otherwise. */
|
||||||
int BrotliStateIsStreamEnd(const BrotliState* s);
|
int BrotliStateIsStreamEnd(const BrotliState* s);
|
||||||
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_STATE_H_ */
|
#endif /* BROTLI_DEC_STATE_H_ */
|
||||||
|
102
dec/streams.c
102
dec/streams.c
@ -1,102 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Functions for streaming input and output. */
|
|
||||||
|
|
||||||
#include <string.h>
|
|
||||||
#ifndef _WIN32
|
|
||||||
#include <unistd.h>
|
|
||||||
#endif
|
|
||||||
#include "./streams.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int BrotliMemInputFunction(void* data, uint8_t* buf, size_t count) {
|
|
||||||
BrotliMemInput* input = (BrotliMemInput*)data;
|
|
||||||
if (input->pos > input->length) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (input->pos + count > input->length) {
|
|
||||||
count = input->length - input->pos;
|
|
||||||
}
|
|
||||||
memcpy(buf, input->buffer + input->pos, count);
|
|
||||||
input->pos += count;
|
|
||||||
return (int)count;
|
|
||||||
}
|
|
||||||
|
|
||||||
BrotliInput BrotliInitMemInput(const uint8_t* buffer, size_t length,
|
|
||||||
BrotliMemInput* mem_input) {
|
|
||||||
BrotliInput input;
|
|
||||||
mem_input->buffer = buffer;
|
|
||||||
mem_input->length = length;
|
|
||||||
mem_input->pos = 0;
|
|
||||||
input.cb_ = &BrotliMemInputFunction;
|
|
||||||
input.data_ = mem_input;
|
|
||||||
return input;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrotliMemOutputFunction(void* data, const uint8_t* buf, size_t count) {
|
|
||||||
BrotliMemOutput* output = (BrotliMemOutput*)data;
|
|
||||||
size_t limit = output->length - output->pos;
|
|
||||||
if (count > limit) {
|
|
||||||
count = limit;
|
|
||||||
}
|
|
||||||
memcpy(output->buffer + output->pos, buf, count);
|
|
||||||
output->pos += count;
|
|
||||||
return (int)count;
|
|
||||||
}
|
|
||||||
|
|
||||||
BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
|
|
||||||
BrotliMemOutput* mem_output) {
|
|
||||||
BrotliOutput output;
|
|
||||||
mem_output->buffer = buffer;
|
|
||||||
mem_output->length = length;
|
|
||||||
mem_output->pos = 0;
|
|
||||||
output.cb_ = &BrotliMemOutputFunction;
|
|
||||||
output.data_ = mem_output;
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count) {
|
|
||||||
return (int)fread(buf, 1, count, (FILE*)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
BrotliInput BrotliFileInput(FILE* f) {
|
|
||||||
BrotliInput in;
|
|
||||||
in.cb_ = BrotliFileInputFunction;
|
|
||||||
in.data_ = f;
|
|
||||||
return in;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count) {
|
|
||||||
return (int)fwrite(buf, 1, count, (FILE*)data);
|
|
||||||
}
|
|
||||||
|
|
||||||
BrotliOutput BrotliFileOutput(FILE* f) {
|
|
||||||
BrotliOutput out;
|
|
||||||
out.cb_ = BrotliFileOutputFunction;
|
|
||||||
out.data_ = f;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
int BrotliNullOutputFunction(void* data , const uint8_t* buf, size_t count) {
|
|
||||||
BROTLI_UNUSED(data);
|
|
||||||
BROTLI_UNUSED(buf);
|
|
||||||
return (int)count;
|
|
||||||
}
|
|
||||||
|
|
||||||
BrotliOutput BrotliNullOutput(void) {
|
|
||||||
BrotliOutput out;
|
|
||||||
out.cb_ = BrotliNullOutputFunction;
|
|
||||||
out.data_ = NULL;
|
|
||||||
return out;
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
@ -1,95 +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
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Functions for streaming input and output. */
|
|
||||||
|
|
||||||
#ifndef BROTLI_DEC_STREAMS_H_
|
|
||||||
#define BROTLI_DEC_STREAMS_H_
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include "./port.h"
|
|
||||||
#include "./types.h"
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Function pointer type used to read len bytes into buf. Returns the */
|
|
||||||
/* number of bytes read or -1 on error. */
|
|
||||||
typedef int (*BrotliInputFunction)(void* data, uint8_t* buf, size_t len);
|
|
||||||
|
|
||||||
/* Input callback function with associated data. */
|
|
||||||
typedef struct {
|
|
||||||
BrotliInputFunction cb_;
|
|
||||||
void* data_;
|
|
||||||
} BrotliInput;
|
|
||||||
|
|
||||||
/* Reads len bytes into buf, using the in callback. */
|
|
||||||
static BROTLI_INLINE int BrotliRead(BrotliInput in, uint8_t* buf, size_t len) {
|
|
||||||
return in.cb_(in.data_, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Function pointer type used to write len bytes into buf. Returns the */
|
|
||||||
/* number of bytes written or -1 on error. */
|
|
||||||
typedef int (*BrotliOutputFunction)(void* data, const uint8_t* buf, size_t len);
|
|
||||||
|
|
||||||
/* Output callback function with associated data. */
|
|
||||||
typedef struct {
|
|
||||||
BrotliOutputFunction cb_;
|
|
||||||
void* data_;
|
|
||||||
} BrotliOutput;
|
|
||||||
|
|
||||||
/* Writes len bytes into buf, using the out callback. */
|
|
||||||
static BROTLI_INLINE int BrotliWrite(BrotliOutput out,
|
|
||||||
const uint8_t* buf, size_t len) {
|
|
||||||
return out.cb_(out.data_, buf, len);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Memory region with position. */
|
|
||||||
typedef struct {
|
|
||||||
const uint8_t* buffer;
|
|
||||||
size_t length;
|
|
||||||
size_t pos;
|
|
||||||
} BrotliMemInput;
|
|
||||||
|
|
||||||
/* Input callback where *data is a BrotliMemInput struct. */
|
|
||||||
int BrotliMemInputFunction(void* data, uint8_t* buf, size_t count);
|
|
||||||
|
|
||||||
/* Returns an input callback that wraps the given memory region. */
|
|
||||||
BrotliInput BrotliInitMemInput(const uint8_t* buffer, size_t length,
|
|
||||||
BrotliMemInput* mem_input);
|
|
||||||
|
|
||||||
/* Output buffer with position. */
|
|
||||||
typedef struct {
|
|
||||||
uint8_t* buffer;
|
|
||||||
size_t length;
|
|
||||||
size_t pos;
|
|
||||||
} BrotliMemOutput;
|
|
||||||
|
|
||||||
/* Output callback where *data is a BrotliMemOutput struct. */
|
|
||||||
int BrotliMemOutputFunction(void* data, const uint8_t* buf, size_t count);
|
|
||||||
|
|
||||||
/* Returns an output callback that wraps the given memory region. */
|
|
||||||
BrotliOutput BrotliInitMemOutput(uint8_t* buffer, size_t length,
|
|
||||||
BrotliMemOutput* mem_output);
|
|
||||||
|
|
||||||
/* Input callback that reads from a file. */
|
|
||||||
int BrotliFileInputFunction(void* data, uint8_t* buf, size_t count);
|
|
||||||
BrotliInput BrotliFileInput(FILE* f);
|
|
||||||
|
|
||||||
/* Output callback that writes to a file. */
|
|
||||||
int BrotliFileOutputFunction(void* data, const uint8_t* buf, size_t count);
|
|
||||||
BrotliOutput BrotliFileOutput(FILE* f);
|
|
||||||
|
|
||||||
/* Output callback that does nothing, always consumes the whole input. */
|
|
||||||
int BrotliNullOutputFunction(void* data, const uint8_t* buf, size_t count);
|
|
||||||
BrotliOutput BrotliNullOutput(void);
|
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
|
||||||
} /* extern "C" */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_STREAMS_H_ */
|
|
@ -17,27 +17,27 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum WordTransformType {
|
enum WordTransformType {
|
||||||
kIdentity = 0,
|
kIdentity = 0,
|
||||||
kOmitLast1 = 1,
|
kOmitLast1 = 1,
|
||||||
kOmitLast2 = 2,
|
kOmitLast2 = 2,
|
||||||
kOmitLast3 = 3,
|
kOmitLast3 = 3,
|
||||||
kOmitLast4 = 4,
|
kOmitLast4 = 4,
|
||||||
kOmitLast5 = 5,
|
kOmitLast5 = 5,
|
||||||
kOmitLast6 = 6,
|
kOmitLast6 = 6,
|
||||||
kOmitLast7 = 7,
|
kOmitLast7 = 7,
|
||||||
kOmitLast8 = 8,
|
kOmitLast8 = 8,
|
||||||
kOmitLast9 = 9,
|
kOmitLast9 = 9,
|
||||||
kUppercaseFirst = 10,
|
kUppercaseFirst = 10,
|
||||||
kUppercaseAll = 11,
|
kUppercaseAll = 11,
|
||||||
kOmitFirst1 = 12,
|
kOmitFirst1 = 12,
|
||||||
kOmitFirst2 = 13,
|
kOmitFirst2 = 13,
|
||||||
kOmitFirst3 = 14,
|
kOmitFirst3 = 14,
|
||||||
kOmitFirst4 = 15,
|
kOmitFirst4 = 15,
|
||||||
kOmitFirst5 = 16,
|
kOmitFirst5 = 16,
|
||||||
kOmitFirst6 = 17,
|
kOmitFirst6 = 17,
|
||||||
kOmitFirst7 = 18,
|
kOmitFirst7 = 18,
|
||||||
kOmitFirst8 = 19,
|
kOmitFirst8 = 19,
|
||||||
kOmitFirst9 = 20
|
kOmitFirst9 = 20
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -66,15 +66,15 @@ enum {
|
|||||||
kPFix_SP = 1,
|
kPFix_SP = 1,
|
||||||
kPFix_COMMASP = 3,
|
kPFix_COMMASP = 3,
|
||||||
kPFix_SPofSPtheSP = 6,
|
kPFix_SPofSPtheSP = 6,
|
||||||
kPFix_SPtheSP = 9,
|
kPFix_SPtheSP = 9,
|
||||||
kPFix_eSP = 12,
|
kPFix_eSP = 12,
|
||||||
kPFix_SPofSP = 15,
|
kPFix_SPofSP = 15,
|
||||||
kPFix_sSP = 20,
|
kPFix_sSP = 20,
|
||||||
kPFix_DOT = 23,
|
kPFix_DOT = 23,
|
||||||
kPFix_SPandSP = 25,
|
kPFix_SPandSP = 25,
|
||||||
kPFix_SPinSP = 31,
|
kPFix_SPinSP = 31,
|
||||||
kPFix_DQUOT = 36,
|
kPFix_DQUOT = 36,
|
||||||
kPFix_SPtoSP = 38,
|
kPFix_SPtoSP = 38,
|
||||||
kPFix_DQUOTGT = 43,
|
kPFix_DQUOTGT = 43,
|
||||||
kPFix_NEWLINE = 46,
|
kPFix_NEWLINE = 46,
|
||||||
kPFix_DOTSP = 48,
|
kPFix_DOTSP = 48,
|
||||||
@ -84,20 +84,20 @@ enum {
|
|||||||
kPFix_SPthatSP = 63,
|
kPFix_SPthatSP = 63,
|
||||||
kPFix_SQUOT = 70,
|
kPFix_SQUOT = 70,
|
||||||
kPFix_SPwithSP = 72,
|
kPFix_SPwithSP = 72,
|
||||||
kPFix_SPfromSP = 79,
|
kPFix_SPfromSP = 79,
|
||||||
kPFix_SPbySP = 86,
|
kPFix_SPbySP = 86,
|
||||||
kPFix_OPEN = 91,
|
kPFix_OPEN = 91,
|
||||||
kPFix_DOTSPTheSP = 93,
|
kPFix_DOTSPTheSP = 93,
|
||||||
kPFix_SPonSP = 100,
|
kPFix_SPonSP = 100,
|
||||||
kPFix_SPasSP = 105,
|
kPFix_SPasSP = 105,
|
||||||
kPFix_SPisSP = 110,
|
kPFix_SPisSP = 110,
|
||||||
kPFix_ingSP = 115,
|
kPFix_ingSP = 115,
|
||||||
kPFix_NEWLINETAB = 120,
|
kPFix_NEWLINETAB = 120,
|
||||||
kPFix_COLON = 123,
|
kPFix_COLON = 123,
|
||||||
kPFix_edSP = 125,
|
kPFix_edSP = 125,
|
||||||
kPFix_EQDQUOT = 129,
|
kPFix_EQDQUOT = 129,
|
||||||
kPFix_SPatSP = 132,
|
kPFix_SPatSP = 132,
|
||||||
kPFix_lySP = 137,
|
kPFix_lySP = 137,
|
||||||
kPFix_COMMA = 141,
|
kPFix_COMMA = 141,
|
||||||
kPFix_EQSQUOT = 143,
|
kPFix_EQSQUOT = 143,
|
||||||
kPFix_DOTcomSLASH = 146,
|
kPFix_DOTcomSLASH = 146,
|
||||||
@ -114,7 +114,6 @@ enum {
|
|||||||
kPFix_ousSP = 203
|
kPFix_ousSP = 203
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
static const Transform kTransforms[] = {
|
static const Transform kTransforms[] = {
|
||||||
{ kPFix_EMPTY, kIdentity, kPFix_EMPTY },
|
{ kPFix_EMPTY, kIdentity, kPFix_EMPTY },
|
||||||
{ kPFix_EMPTY, kIdentity, kPFix_SP },
|
{ kPFix_EMPTY, kIdentity, kPFix_SP },
|
||||||
@ -241,7 +240,7 @@ static const Transform kTransforms[] = {
|
|||||||
|
|
||||||
static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]);
|
static const int kNumTransforms = sizeof(kTransforms) / sizeof(kTransforms[0]);
|
||||||
|
|
||||||
static int ToUpperCase(uint8_t *p) {
|
static int ToUpperCase(uint8_t* p) {
|
||||||
if (p[0] < 0xc0) {
|
if (p[0] < 0xc0) {
|
||||||
if (p[0] >= 'a' && p[0] <= 'z') {
|
if (p[0] >= 'a' && p[0] <= 'z') {
|
||||||
p[0] ^= 32;
|
p[0] ^= 32;
|
||||||
@ -295,7 +294,7 @@ static BROTLI_NOINLINE int TransformDictionaryWord(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__cplusplus) || defined(c_plusplus)
|
#if defined(__cplusplus) || defined(c_plusplus)
|
||||||
} /* extern "C" */
|
} /* extern "C" */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_TRANSFORM_H_ */
|
#endif /* BROTLI_DEC_TRANSFORM_H_ */
|
||||||
|
@ -29,10 +29,10 @@ typedef __int64 int64_t;
|
|||||||
size length. Neither items nor size are allowed to be 0.
|
size length. Neither items nor size are allowed to be 0.
|
||||||
opaque argument is a pointer provided by client and could be used to bind
|
opaque argument is a pointer provided by client and could be used to bind
|
||||||
function to specific object (memory pool). */
|
function to specific object (memory pool). */
|
||||||
typedef void* (*brotli_alloc_func) (void* opaque, size_t size);
|
typedef void* (*brotli_alloc_func)(void* opaque, size_t size);
|
||||||
|
|
||||||
/* Deallocating function pointer. Function SHOULD be no-op in the case the
|
/* Deallocating function pointer. Function SHOULD be no-op in the case the
|
||||||
address is 0. */
|
address is 0. */
|
||||||
typedef void (*brotli_free_func) (void* opaque, void* address);
|
typedef void (*brotli_free_func)(void* opaque, void* address);
|
||||||
|
|
||||||
#endif /* BROTLI_DEC_TYPES_H_ */
|
#endif /* BROTLI_DEC_TYPES_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user