Update brotli to version 1.0.9

This commit is contained in:
Tino Reichardt
2020-10-03 09:47:47 +02:00
parent 712b2f1b20
commit 32e6390fd7
64 changed files with 4074 additions and 2528 deletions

View File

@@ -27,34 +27,19 @@
extern "C" {
#endif
/* Pointer to hasher data.
*
* Excluding initialization and destruction, hasher can be passed as
* HasherHandle by value.
*
* Typically hasher data consists of 3 sections:
* * HasherCommon structure
* * private structured hasher data, depending on hasher type
* * private dynamic hasher data, depending on hasher type and parameters
*
* Using "define" instead of "typedef", because on MSVC __restrict does not work
* on typedef pointer types. */
#define HasherHandle uint8_t*
typedef struct {
/* Dynamically allocated area; first member for quickest access. */
void* extra;
size_t dict_num_lookups;
size_t dict_num_matches;
BrotliHasherParams params;
/* False if hasher needs to be "prepared" before use. */
BROTLI_BOOL is_prepared_;
size_t dict_num_lookups;
size_t dict_num_matches;
} HasherCommon;
static BROTLI_INLINE HasherCommon* GetHasherCommon(HasherHandle handle) {
return (HasherCommon*)handle;
}
#define score_t size_t
static const uint32_t kCutoffTransformsCount = 10;
@@ -149,17 +134,13 @@ static BROTLI_INLINE score_t BackwardReferencePenaltyUsingLastDistance(
}
static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
const BrotliEncoderDictionary* dictionary, size_t item,
const BrotliEncoderDictionary* dictionary, size_t len, size_t word_idx,
const uint8_t* data, size_t max_length, size_t max_backward,
size_t max_distance, HasherSearchResult* out) {
size_t len;
size_t word_idx;
size_t offset;
size_t matchlen;
size_t backward;
score_t score;
len = item & 0x1F;
word_idx = item >> 5;
offset = dictionary->words->offsets_by_length[len] + len * word_idx;
if (len > max_length) {
return BROTLI_FALSE;
@@ -193,25 +174,24 @@ static BROTLI_INLINE BROTLI_BOOL TestStaticDictionaryItem(
static BROTLI_INLINE void SearchInStaticDictionary(
const BrotliEncoderDictionary* dictionary,
HasherHandle handle, const uint8_t* data, size_t max_length,
HasherCommon* common, const uint8_t* data, size_t max_length,
size_t max_backward, size_t max_distance,
HasherSearchResult* out, BROTLI_BOOL shallow) {
size_t key;
size_t i;
HasherCommon* self = GetHasherCommon(handle);
if (self->dict_num_matches < (self->dict_num_lookups >> 7)) {
if (common->dict_num_matches < (common->dict_num_lookups >> 7)) {
return;
}
key = Hash14(data) << 1;
for (i = 0; i < (shallow ? 1u : 2u); ++i, ++key) {
size_t item = dictionary->hash_table[key];
self->dict_num_lookups++;
if (item != 0) {
common->dict_num_lookups++;
if (dictionary->hash_table_lengths[key] != 0) {
BROTLI_BOOL item_matches = TestStaticDictionaryItem(
dictionary, item, data,
dictionary, dictionary->hash_table_lengths[key],
dictionary->hash_table_words[key], data,
max_length, max_backward, max_distance, out);
if (item_matches) {
self->dict_num_matches++;
common->dict_num_matches++;
}
}
}
@@ -260,37 +240,37 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
/* MAX_NUM_MATCHES == 64 + MAX_TREE_SEARCH_DEPTH */
#define MAX_NUM_MATCHES_H10 128
/* For BUCKET_SWEEP == 1, enabling the dictionary lookup makes compression
/* For BUCKET_SWEEP_BITS == 0, enabling the dictionary lookup makes compression
a little faster (0.5% - 1%) and it compresses 0.15% better on small text
and HTML inputs. */
#define HASHER() H2
#define BUCKET_BITS 16
#define BUCKET_SWEEP 1
#define BUCKET_SWEEP_BITS 0
#define HASH_LEN 5
#define USE_DICTIONARY 1
#include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
#undef BUCKET_SWEEP
#undef BUCKET_SWEEP_BITS
#undef USE_DICTIONARY
#undef HASHER
#define HASHER() H3
#define BUCKET_SWEEP 2
#define BUCKET_SWEEP_BITS 1
#define USE_DICTIONARY 0
#include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
#undef USE_DICTIONARY
#undef BUCKET_SWEEP
#undef BUCKET_SWEEP_BITS
#undef BUCKET_BITS
#undef HASHER
#define HASHER() H4
#define BUCKET_BITS 17
#define BUCKET_SWEEP 4
#define BUCKET_SWEEP_BITS 2
#define USE_DICTIONARY 1
#include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
#undef USE_DICTIONARY
#undef HASH_LEN
#undef BUCKET_SWEEP
#undef BUCKET_SWEEP_BITS
#undef BUCKET_BITS
#undef HASHER
@@ -334,13 +314,13 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
#define HASHER() H54
#define BUCKET_BITS 20
#define BUCKET_SWEEP 4
#define BUCKET_SWEEP_BITS 2
#define HASH_LEN 7
#define USE_DICTIONARY 0
#include "./hash_longest_match_quickly_inc.h" /* NOLINT(build/include) */
#undef USE_DICTIONARY
#undef HASH_LEN
#undef BUCKET_SWEEP
#undef BUCKET_SWEEP_BITS
#undef BUCKET_BITS
#undef HASHER
@@ -393,97 +373,107 @@ static BROTLI_INLINE size_t BackwardMatchLengthCode(const BackwardMatch* self) {
#undef CAT
#undef EXPAND_CAT
#define FOR_GENERIC_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)\
H(35) H(55) H(65)
#define FOR_SIMPLE_HASHERS(H) H(2) H(3) H(4) H(5) H(6) H(40) H(41) H(42) H(54)
#define FOR_COMPOSITE_HASHERS(H) H(35) H(55) H(65)
#define FOR_GENERIC_HASHERS(H) FOR_SIMPLE_HASHERS(H) FOR_COMPOSITE_HASHERS(H)
#define FOR_ALL_HASHERS(H) FOR_GENERIC_HASHERS(H) H(10)
static BROTLI_INLINE void DestroyHasher(
MemoryManager* m, HasherHandle* handle) {
if (*handle == NULL) return;
BROTLI_FREE(m, *handle);
typedef struct {
HasherCommon common;
union {
#define MEMBER_(N) \
H ## N _H ## N;
FOR_ALL_HASHERS(MEMBER_)
#undef MEMBER_
} privat;
} Hasher;
/* MUST be invoked before any other method. */
static BROTLI_INLINE void HasherInit(Hasher* hasher) {
hasher->common.extra = NULL;
}
static BROTLI_INLINE void HasherReset(HasherHandle handle) {
if (handle == NULL) return;
GetHasherCommon(handle)->is_prepared_ = BROTLI_FALSE;
static BROTLI_INLINE void DestroyHasher(MemoryManager* m, Hasher* hasher) {
if (hasher->common.extra == NULL) return;
BROTLI_FREE(m, hasher->common.extra);
}
static BROTLI_INLINE void HasherReset(Hasher* hasher) {
hasher->common.is_prepared_ = BROTLI_FALSE;
}
static BROTLI_INLINE size_t HasherSize(const BrotliEncoderParams* params,
BROTLI_BOOL one_shot, const size_t input_size) {
size_t result = sizeof(HasherCommon);
switch (params->hasher.type) {
#define SIZE_(N) \
case N: \
result += HashMemAllocInBytesH ## N(params, one_shot, input_size); \
break;
#define SIZE_(N) \
case N: \
return HashMemAllocInBytesH ## N(params, one_shot, input_size);
FOR_ALL_HASHERS(SIZE_)
#undef SIZE_
default:
break;
}
return result;
return 0; /* Default case. */
}
static BROTLI_INLINE void HasherSetup(MemoryManager* m, HasherHandle* handle,
static BROTLI_INLINE void HasherSetup(MemoryManager* m, Hasher* hasher,
BrotliEncoderParams* params, const uint8_t* data, size_t position,
size_t input_size, BROTLI_BOOL is_last) {
HasherHandle self = NULL;
HasherCommon* common = NULL;
BROTLI_BOOL one_shot = (position == 0 && is_last);
if (*handle == NULL) {
if (hasher->common.extra == NULL) {
size_t alloc_size;
ChooseHasher(params, &params->hasher);
alloc_size = HasherSize(params, one_shot, input_size);
self = BROTLI_ALLOC(m, uint8_t, alloc_size);
if (BROTLI_IS_OOM(m)) return;
*handle = self;
common = GetHasherCommon(self);
common->params = params->hasher;
switch (common->params.type) {
#define INITIALIZE_(N) \
case N: \
InitializeH ## N(*handle, params); \
hasher->common.extra = BROTLI_ALLOC(m, uint8_t, alloc_size);
if (BROTLI_IS_OOM(m) || BROTLI_IS_NULL(hasher->common.extra)) return;
hasher->common.params = params->hasher;
switch (hasher->common.params.type) {
#define INITIALIZE_(N) \
case N: \
InitializeH ## N(&hasher->common, \
&hasher->privat._H ## N, params); \
break;
FOR_ALL_HASHERS(INITIALIZE_);
#undef INITIALIZE_
default:
break;
}
HasherReset(*handle);
HasherReset(hasher);
}
self = *handle;
common = GetHasherCommon(self);
if (!common->is_prepared_) {
switch (common->params.type) {
#define PREPARE_(N) \
case N: \
PrepareH ## N(self, one_shot, input_size, data); \
if (!hasher->common.is_prepared_) {
switch (hasher->common.params.type) {
#define PREPARE_(N) \
case N: \
PrepareH ## N( \
&hasher->privat._H ## N, \
one_shot, input_size, data); \
break;
FOR_ALL_HASHERS(PREPARE_)
#undef PREPARE_
default: break;
}
if (position == 0) {
common->dict_num_lookups = 0;
common->dict_num_matches = 0;
hasher->common.dict_num_lookups = 0;
hasher->common.dict_num_matches = 0;
}
common->is_prepared_ = BROTLI_TRUE;
hasher->common.is_prepared_ = BROTLI_TRUE;
}
}
static BROTLI_INLINE void InitOrStitchToPreviousBlock(
MemoryManager* m, HasherHandle* handle, const uint8_t* data, size_t mask,
MemoryManager* m, Hasher* hasher, const uint8_t* data, size_t mask,
BrotliEncoderParams* params, size_t position, size_t input_size,
BROTLI_BOOL is_last) {
HasherHandle self;
HasherSetup(m, handle, params, data, position, input_size, is_last);
HasherSetup(m, hasher, params, data, position, input_size, is_last);
if (BROTLI_IS_OOM(m)) return;
self = *handle;
switch (GetHasherCommon(self)->params.type) {
#define INIT_(N) \
case N: \
StitchToPreviousBlockH ## N(self, input_size, position, data, mask); \
switch (hasher->common.params.type) {
#define INIT_(N) \
case N: \
StitchToPreviousBlockH ## N( \
&hasher->privat._H ## N, \
input_size, position, data, mask); \
break;
FOR_ALL_HASHERS(INIT_)
#undef INIT_