multi_compress 0.3.2 → 0.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -3
- data/GET_STARTED.md +3 -3
- data/README.md +75 -66
- data/THIRD_PARTY_NOTICES.md +24 -0
- data/ext/multi_compress/brotli_dec_static_init.c +3 -0
- data/ext/multi_compress/brotli_enc_static_init.c +3 -0
- data/ext/multi_compress/extconf.rb +79 -3
- data/ext/multi_compress/multi_compress.c +199 -120
- data/ext/multi_compress/vendor/.vendored +2 -2
- data/ext/multi_compress/vendor/brotli/LICENSE +19 -0
- data/ext/multi_compress/vendor/brotli/c/common/constants.c +7 -7
- data/ext/multi_compress/vendor/brotli/c/common/constants.h +2 -5
- data/ext/multi_compress/vendor/brotli/c/common/context.c +2 -2
- data/ext/multi_compress/vendor/brotli/c/common/context.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.c +4 -5856
- data/ext/multi_compress/vendor/brotli/c/common/dictionary.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/dictionary_inc.h +5847 -0
- data/ext/multi_compress/vendor/brotli/c/common/platform.c +0 -4
- data/ext/multi_compress/vendor/brotli/c/common/platform.h +182 -43
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary.c +3 -7
- data/ext/multi_compress/vendor/brotli/c/common/shared_dictionary_internal.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/common/static_init.h +56 -0
- data/ext/multi_compress/vendor/brotli/c/common/transform.c +6 -4
- data/ext/multi_compress/vendor/brotli/c/common/transform.h +1 -2
- data/ext/multi_compress/vendor/brotli/c/common/version.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.c +2 -3
- data/ext/multi_compress/vendor/brotli/c/dec/bit_reader.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/dec/decode.c +128 -39
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.c +2 -5
- data/ext/multi_compress/vendor/brotli/c/dec/huffman.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.c +67 -0
- data/ext/multi_compress/vendor/brotli/c/dec/prefix.h +18 -708
- data/ext/multi_compress/vendor/brotli/c/dec/prefix_inc.h +707 -0
- data/ext/multi_compress/vendor/brotli/c/dec/state.c +18 -15
- data/ext/multi_compress/vendor/brotli/c/dec/state.h +2 -6
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.c +53 -0
- data/ext/multi_compress/vendor/brotli/c/dec/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.c +32 -8
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.c +15 -15
- data/ext/multi_compress/vendor/brotli/c/enc/backward_references_hq.h +1 -5
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.c +28 -4
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost.h +8 -40
- data/ext/multi_compress/vendor/brotli/c/enc/bit_cost_inc.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.c +9 -12
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter.h +0 -3
- data/ext/multi_compress/vendor/brotli/c/enc/block_splitter_inc.h +14 -8
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.c +10 -9
- data/ext/multi_compress/vendor/brotli/c/enc/brotli_bit_stream.h +0 -6
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.c +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/cluster.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/command.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/command.h +8 -10
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.c +3 -5
- data/ext/multi_compress/vendor/brotli/c/enc/compound_dictionary.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.c +3 -13
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.c +5 -15
- data/ext/multi_compress/vendor/brotli/c/enc/compress_fragment_two_pass.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.c +127 -1830
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash.h +23 -3
- data/ext/multi_compress/vendor/brotli/c/enc/dictionary_hash_inc.h +1829 -0
- data/ext/multi_compress/vendor/brotli/c/enc/encode.c +77 -52
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.c +9 -7
- data/ext/multi_compress/vendor/brotli/c/enc/encoder_dict.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.c +3 -6
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode.h +2 -4
- data/ext/multi_compress/vendor/brotli/c/enc/entropy_encode_static.h +18 -12
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/fast_log.h +2 -3
- data/ext/multi_compress/vendor/brotli/c/enc/find_match_length.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/hash.h +38 -31
- data/ext/multi_compress/vendor/brotli/c/enc/hash_base.h +38 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +11 -1
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_inc.h +24 -7
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match64_simd_inc.h +304 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_inc.h +30 -11
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -0
- data/ext/multi_compress/vendor/brotli/c/enc/hash_longest_match_simd_inc.h +278 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.c +1 -0
- data/ext/multi_compress/vendor/brotli/c/enc/histogram.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.c +4 -6
- data/ext/multi_compress/vendor/brotli/c/enc/literal_cost.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/matching_tag_mask.h +69 -0
- data/ext/multi_compress/vendor/brotli/c/enc/memory.c +0 -5
- data/ext/multi_compress/vendor/brotli/c/enc/memory.h +0 -4
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.c +7 -9
- data/ext/multi_compress/vendor/brotli/c/enc/metablock.h +3 -3
- data/ext/multi_compress/vendor/brotli/c/enc/metablock_inc.h +4 -4
- data/ext/multi_compress/vendor/brotli/c/enc/params.h +0 -1
- data/ext/multi_compress/vendor/brotli/c/enc/prefix.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/quality.h +17 -10
- data/ext/multi_compress/vendor/brotli/c/enc/ringbuffer.h +1 -4
- data/ext/multi_compress/vendor/brotli/c/enc/state.h +2 -2
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.c +5 -11
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict.h +1 -3
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.c +224 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut.h +20 -5837
- data/ext/multi_compress/vendor/brotli/c/enc/static_dict_lut_inc.h +5830 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.c +59 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init.h +30 -0
- data/ext/multi_compress/vendor/brotli/c/enc/static_init_lazy.cc +26 -0
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/ext/multi_compress/vendor/brotli/c/enc/utf8_util.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/enc/write_bits.h +0 -2
- data/ext/multi_compress/vendor/brotli/c/include/brotli/decode.h +1 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/encode.h +5 -1
- data/ext/multi_compress/vendor/brotli/c/include/brotli/port.h +4 -7
- data/ext/multi_compress/vendor/brotli/c/include/brotli/types.h +2 -2
- data/ext/multi_compress/vendor/lz4/LICENSE +12 -0
- data/ext/multi_compress/vendor/zstd/COPYING +339 -0
- data/ext/multi_compress/vendor/zstd/LICENSE +30 -0
- data/ext/multi_compress/vendor/zstd/lib/Makefile +67 -35
- data/ext/multi_compress/vendor/zstd/lib/README.md +33 -2
- data/ext/multi_compress/vendor/zstd/lib/common/allocations.h +55 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bits.h +205 -0
- data/ext/multi_compress/vendor/zstd/lib/common/bitstream.h +84 -108
- data/ext/multi_compress/vendor/zstd/lib/common/compiler.h +170 -41
- data/ext/multi_compress/vendor/zstd/lib/common/cpu.h +37 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.c +7 -1
- data/ext/multi_compress/vendor/zstd/lib/common/debug.h +21 -21
- data/ext/multi_compress/vendor/zstd/lib/common/entropy_common.c +12 -40
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.c +10 -2
- data/ext/multi_compress/vendor/zstd/lib/common/error_private.h +46 -47
- data/ext/multi_compress/vendor/zstd/lib/common/fse.h +8 -100
- data/ext/multi_compress/vendor/zstd/lib/common/fse_decompress.c +28 -116
- data/ext/multi_compress/vendor/zstd/lib/common/huf.h +79 -166
- data/ext/multi_compress/vendor/zstd/lib/common/mem.h +46 -66
- data/ext/multi_compress/vendor/zstd/lib/common/pool.c +27 -11
- data/ext/multi_compress/vendor/zstd/lib/common/pool.h +8 -11
- data/ext/multi_compress/vendor/zstd/lib/common/portability_macros.h +45 -11
- data/ext/multi_compress/vendor/zstd/lib/common/threading.c +74 -14
- data/ext/multi_compress/vendor/zstd/lib/common/threading.h +5 -18
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.c +5 -11
- data/ext/multi_compress/vendor/zstd/lib/common/xxhash.h +2411 -1003
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_common.c +1 -36
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_deps.h +13 -1
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_internal.h +13 -182
- data/ext/multi_compress/vendor/zstd/lib/common/zstd_trace.h +6 -13
- data/ext/multi_compress/vendor/zstd/lib/compress/clevels.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/fse_compress.c +15 -131
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.c +11 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/hist.h +8 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/huf_compress.c +283 -189
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress.c +2419 -903
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_internal.h +423 -245
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.c +116 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_literals.h +16 -8
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.c +10 -10
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_sequences.h +8 -7
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.c +254 -139
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_compress_superblock.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_cwksp.h +184 -95
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.c +163 -81
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_double_fast.h +18 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.c +507 -197
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_fast.h +7 -14
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.c +579 -484
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_lazy.h +133 -65
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.c +61 -40
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm.h +7 -15
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_ldm_geartab.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.c +352 -218
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_opt.h +37 -21
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.c +238 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstd_preSplit.h +33 -0
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.c +239 -175
- data/ext/multi_compress/vendor/zstd/lib/compress/zstdmt_compress.h +5 -16
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress.c +543 -488
- data/ext/multi_compress/vendor/zstd/lib/decompress/huf_decompress_amd64.S +78 -61
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_ddict.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress.c +295 -115
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.c +430 -293
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_block.h +7 -2
- data/ext/multi_compress/vendor/zstd/lib/decompress/zstd_decompress_internal.h +11 -7
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_common.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_compress.c +1 -1
- data/ext/multi_compress/vendor/zstd/lib/deprecated/zbuff_decompress.c +3 -1
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.c +95 -46
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/cover.h +3 -9
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/divsufsort.h +0 -10
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/fastcover.c +4 -4
- data/ext/multi_compress/vendor/zstd/lib/dictBuilder/zdict.c +25 -97
- data/ext/multi_compress/vendor/zstd/lib/dll/example/Makefile +1 -1
- data/ext/multi_compress/vendor/zstd/lib/dll/example/README.md +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_legacy.h +38 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.c +19 -50
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v01.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.c +27 -80
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v02.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.c +28 -83
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v03.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.c +25 -74
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v04.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.c +31 -76
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v05.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.c +44 -88
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v06.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.c +33 -84
- data/ext/multi_compress/vendor/zstd/lib/legacy/zstd_v07.h +1 -1
- data/ext/multi_compress/vendor/zstd/lib/libzstd.mk +65 -33
- data/ext/multi_compress/vendor/zstd/lib/libzstd.pc.in +5 -5
- data/ext/multi_compress/vendor/zstd/lib/module.modulemap +13 -3
- data/ext/multi_compress/vendor/zstd/lib/zdict.h +65 -36
- data/ext/multi_compress/vendor/zstd/lib/zstd.h +890 -267
- data/ext/multi_compress/vendor/zstd/lib/zstd_errors.h +28 -16
- data/lib/multi_compress/version.rb +1 -1
- data/lib/multi_compress.rb +80 -41
- metadata +29 -2
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
/* NOLINT(build/header_guard) */
|
|
2
|
+
/* Copyright 2010 Google Inc. All Rights Reserved.
|
|
3
|
+
Distributed under MIT license.
|
|
4
|
+
See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
|
|
5
|
+
*/
|
|
6
|
+
/* template parameters: FN */
|
|
7
|
+
/* A (forgetful) hash table to the data seen by the compressor, to
|
|
8
|
+
help create backward references to previous data.
|
|
9
|
+
This is a hash map of fixed size (bucket_size_) to a ring buffer of
|
|
10
|
+
fixed size (block_size_). The ring buffer contains the last block_size_
|
|
11
|
+
index positions of the given hash key in the compressed data. */
|
|
12
|
+
#define HashLongestMatch HASHER()
|
|
13
|
+
#define TAG_HASH_BITS 8
|
|
14
|
+
#define TAG_HASH_MASK ((1 << TAG_HASH_BITS) - 1)
|
|
15
|
+
static BROTLI_INLINE size_t FN(HashTypeLength)(void) { return 4; }
|
|
16
|
+
static BROTLI_INLINE size_t FN(StoreLookahead)(void) { return 4; }
|
|
17
|
+
/* HashBytes is the function that chooses the bucket to place the address in. */
|
|
18
|
+
static uint32_t FN(HashBytes)(
|
|
19
|
+
const uint8_t* BROTLI_RESTRICT data, const int shift) {
|
|
20
|
+
uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
|
|
21
|
+
/* The higher bits contain more mixture from the multiplication,
|
|
22
|
+
so we take our results from there. */
|
|
23
|
+
return (uint32_t)(h >> shift);
|
|
24
|
+
}
|
|
25
|
+
typedef struct HashLongestMatch {
|
|
26
|
+
/* Number of hash buckets. */
|
|
27
|
+
size_t bucket_size_;
|
|
28
|
+
/* Only block_size_ newest backward references are kept,
|
|
29
|
+
and the older are forgotten. */
|
|
30
|
+
size_t block_size_;
|
|
31
|
+
/* Left-shift for computing hash bucket index from hash value. */
|
|
32
|
+
int hash_shift_;
|
|
33
|
+
/* Mask for accessing entries in a block (in a ring-buffer manner). */
|
|
34
|
+
uint32_t block_mask_;
|
|
35
|
+
int block_bits_;
|
|
36
|
+
int num_last_distances_to_check_;
|
|
37
|
+
/* Shortcuts. */
|
|
38
|
+
HasherCommon* common_;
|
|
39
|
+
/* --- Dynamic size members --- */
|
|
40
|
+
/* Number of entries in a particular bucket. */
|
|
41
|
+
uint16_t* num_; /* uint16_t[bucket_size]; */
|
|
42
|
+
uint8_t* tags_;
|
|
43
|
+
/* Buckets containing block_size_ of backward references. */
|
|
44
|
+
uint32_t* buckets_; /* uint32_t[bucket_size * block_size]; */
|
|
45
|
+
} HashLongestMatch;
|
|
46
|
+
static void FN(Initialize)(
|
|
47
|
+
HasherCommon* common, HashLongestMatch* BROTLI_RESTRICT self,
|
|
48
|
+
const BrotliEncoderParams* params) {
|
|
49
|
+
self->common_ = common;
|
|
50
|
+
BROTLI_UNUSED(params);
|
|
51
|
+
self->hash_shift_ = 32 - common->params.bucket_bits - TAG_HASH_BITS;
|
|
52
|
+
self->bucket_size_ = (size_t)1 << common->params.bucket_bits;
|
|
53
|
+
self->block_size_ = (size_t)1 << common->params.block_bits;
|
|
54
|
+
self->block_mask_ = (uint32_t)(self->block_size_ - 1);
|
|
55
|
+
self->num_ = (uint16_t*)common->extra[0];
|
|
56
|
+
self->tags_ = (uint8_t*)common->extra[1];
|
|
57
|
+
self->buckets_ = (uint32_t*)common->extra[2];
|
|
58
|
+
self->block_bits_ = common->params.block_bits;
|
|
59
|
+
self->num_last_distances_to_check_ =
|
|
60
|
+
common->params.num_last_distances_to_check;
|
|
61
|
+
}
|
|
62
|
+
static void FN(Prepare)(
|
|
63
|
+
HashLongestMatch* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
|
|
64
|
+
size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
|
|
65
|
+
uint16_t* BROTLI_RESTRICT num = self->num_;
|
|
66
|
+
/* Partial preparation is 100 times slower (per socket). */
|
|
67
|
+
size_t partial_prepare_threshold = self->bucket_size_ >> 6;
|
|
68
|
+
if (one_shot && input_size <= partial_prepare_threshold) {
|
|
69
|
+
size_t i;
|
|
70
|
+
for (i = 0; i < input_size; ++i) {
|
|
71
|
+
const uint32_t hash = FN(HashBytes)(&data[i], self->hash_shift_);
|
|
72
|
+
const uint32_t key = hash >> TAG_HASH_BITS;
|
|
73
|
+
num[key] = 65535;
|
|
74
|
+
}
|
|
75
|
+
} else {
|
|
76
|
+
/* Set all the bytes of num to 255, which makes each uint16_t 65535. */
|
|
77
|
+
memset(num, 255, self->bucket_size_ * sizeof(num[0]));
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
static BROTLI_INLINE void FN(HashMemAllocInBytes)(
|
|
81
|
+
const BrotliEncoderParams* params, BROTLI_BOOL one_shot,
|
|
82
|
+
size_t input_size, size_t* alloc_size) {
|
|
83
|
+
size_t bucket_size = (size_t)1 << params->hasher.bucket_bits;
|
|
84
|
+
size_t block_size = (size_t)1 << params->hasher.block_bits;
|
|
85
|
+
BROTLI_UNUSED(one_shot);
|
|
86
|
+
BROTLI_UNUSED(input_size);
|
|
87
|
+
alloc_size[0] = sizeof(uint16_t) * bucket_size;
|
|
88
|
+
alloc_size[1] = sizeof(uint8_t) * bucket_size * block_size;
|
|
89
|
+
alloc_size[2] = sizeof(uint32_t) * bucket_size * block_size;
|
|
90
|
+
}
|
|
91
|
+
/* Look at 4 bytes at &data[ix & mask].
|
|
92
|
+
Compute a hash from these, and store the value of ix at that position. */
|
|
93
|
+
static BROTLI_INLINE void FN(Store)(
|
|
94
|
+
HashLongestMatch* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
|
|
95
|
+
const size_t mask, const size_t ix) {
|
|
96
|
+
uint16_t* BROTLI_RESTRICT num = self->num_;
|
|
97
|
+
uint8_t* BROTLI_RESTRICT tags = self->tags_;
|
|
98
|
+
uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
|
|
99
|
+
const size_t hash = FN(HashBytes)(&data[ix & mask], self->hash_shift_);
|
|
100
|
+
const size_t key = hash >> TAG_HASH_BITS;
|
|
101
|
+
const uint8_t tag = hash & TAG_HASH_MASK;
|
|
102
|
+
const size_t minor_ix = num[key] & self->block_mask_;
|
|
103
|
+
const size_t offset = minor_ix + (key << self->block_bits_);
|
|
104
|
+
--num[key];
|
|
105
|
+
buckets[offset] = (uint32_t)ix;
|
|
106
|
+
tags[offset] = tag;
|
|
107
|
+
}
|
|
108
|
+
static BROTLI_INLINE void FN(StoreRange)(HashLongestMatch* BROTLI_RESTRICT self,
|
|
109
|
+
const uint8_t* BROTLI_RESTRICT data, const size_t mask,
|
|
110
|
+
const size_t ix_start, const size_t ix_end) {
|
|
111
|
+
size_t i;
|
|
112
|
+
for (i = ix_start; i < ix_end; ++i) {
|
|
113
|
+
FN(Store)(self, data, mask, i);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
static BROTLI_INLINE void FN(StitchToPreviousBlock)(
|
|
117
|
+
HashLongestMatch* BROTLI_RESTRICT self,
|
|
118
|
+
size_t num_bytes, size_t position, const uint8_t* ringbuffer,
|
|
119
|
+
size_t ringbuffer_mask) {
|
|
120
|
+
if (num_bytes >= FN(HashTypeLength)() - 1 && position >= 3) {
|
|
121
|
+
/* Prepare the hashes for three last bytes of the last write.
|
|
122
|
+
These could not be calculated before, since they require knowledge
|
|
123
|
+
of both the previous and the current block. */
|
|
124
|
+
FN(Store)(self, ringbuffer, ringbuffer_mask, position - 3);
|
|
125
|
+
FN(Store)(self, ringbuffer, ringbuffer_mask, position - 2);
|
|
126
|
+
FN(Store)(self, ringbuffer, ringbuffer_mask, position - 1);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
static BROTLI_INLINE void FN(PrepareDistanceCache)(
|
|
130
|
+
HashLongestMatch* BROTLI_RESTRICT self,
|
|
131
|
+
int* BROTLI_RESTRICT distance_cache) {
|
|
132
|
+
PrepareDistanceCache(distance_cache, self->num_last_distances_to_check_);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/* Find a longest backward match of &data[cur_ix] up to the length of
|
|
136
|
+
max_length and stores the position cur_ix in the hash table.
|
|
137
|
+
REQUIRES: FN(PrepareDistanceCache) must be invoked for current distance cache
|
|
138
|
+
values; if this method is invoked repeatedly with the same distance
|
|
139
|
+
cache values, it is enough to invoke FN(PrepareDistanceCache) once.
|
|
140
|
+
Does not look for matches longer than max_length.
|
|
141
|
+
Does not look for matches further away than max_backward.
|
|
142
|
+
Writes the best match into |out|.
|
|
143
|
+
|out|->score is updated only if a better match is found. */
|
|
144
|
+
static BROTLI_INLINE void FN(FindLongestMatch)(
|
|
145
|
+
HashLongestMatch* BROTLI_RESTRICT self,
|
|
146
|
+
const BrotliEncoderDictionary* dictionary,
|
|
147
|
+
const uint8_t* BROTLI_RESTRICT data, const size_t ring_buffer_mask,
|
|
148
|
+
const int* BROTLI_RESTRICT distance_cache, const size_t cur_ix,
|
|
149
|
+
const size_t max_length, const size_t max_backward,
|
|
150
|
+
const size_t dictionary_distance, const size_t max_distance,
|
|
151
|
+
HasherSearchResult* BROTLI_RESTRICT out) {
|
|
152
|
+
uint16_t* BROTLI_RESTRICT num = self->num_;
|
|
153
|
+
uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
|
|
154
|
+
uint8_t* BROTLI_RESTRICT tags = self->tags_;
|
|
155
|
+
const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
|
|
156
|
+
/* Don't accept a short copy from far away. */
|
|
157
|
+
score_t min_score = out->score;
|
|
158
|
+
score_t best_score = out->score;
|
|
159
|
+
size_t best_len = out->len;
|
|
160
|
+
size_t i;
|
|
161
|
+
/* Precalculate the hash key and prefetch the bucket. */
|
|
162
|
+
const uint32_t hash =
|
|
163
|
+
FN(HashBytes)(&data[cur_ix_masked], self->hash_shift_);
|
|
164
|
+
const uint32_t key = hash >> TAG_HASH_BITS;
|
|
165
|
+
uint32_t* BROTLI_RESTRICT bucket = &buckets[key << self->block_bits_];
|
|
166
|
+
uint8_t* BROTLI_RESTRICT tag_bucket = &tags[key << self->block_bits_];
|
|
167
|
+
PREFETCH_L1(bucket);
|
|
168
|
+
PREFETCH_L1(tag_bucket);
|
|
169
|
+
if (self->block_bits_ > 4) PREFETCH_L1(bucket + 16);
|
|
170
|
+
out->len = 0;
|
|
171
|
+
out->len_code_delta = 0;
|
|
172
|
+
|
|
173
|
+
BROTLI_DCHECK(cur_ix_masked + max_length <= ring_buffer_mask);
|
|
174
|
+
|
|
175
|
+
/* Try last distance first. */
|
|
176
|
+
for (i = 0; i < (size_t)self->num_last_distances_to_check_; ++i) {
|
|
177
|
+
const size_t backward = (size_t)distance_cache[i];
|
|
178
|
+
size_t prev_ix = (size_t)(cur_ix - backward);
|
|
179
|
+
if (prev_ix >= cur_ix) {
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
if (BROTLI_PREDICT_FALSE(backward > max_backward)) {
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
prev_ix &= ring_buffer_mask;
|
|
186
|
+
|
|
187
|
+
if (cur_ix_masked + best_len > ring_buffer_mask) {
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
if (prev_ix + best_len > ring_buffer_mask ||
|
|
191
|
+
data[cur_ix_masked + best_len] != data[prev_ix + best_len]) {
|
|
192
|
+
continue;
|
|
193
|
+
}
|
|
194
|
+
{
|
|
195
|
+
const size_t len = FindMatchLengthWithLimit(&data[prev_ix],
|
|
196
|
+
&data[cur_ix_masked],
|
|
197
|
+
max_length);
|
|
198
|
+
if (len >= 3 || (len == 2 && i < 2)) {
|
|
199
|
+
/* Comparing for >= 2 does not change the semantics, but just saves for
|
|
200
|
+
a few unnecessary binary logarithms in backward reference score,
|
|
201
|
+
since we are not interested in such short matches. */
|
|
202
|
+
score_t score = BackwardReferenceScoreUsingLastDistance(len);
|
|
203
|
+
if (best_score < score) {
|
|
204
|
+
if (i != 0) score -= BackwardReferencePenaltyUsingLastDistance(i);
|
|
205
|
+
if (best_score < score) {
|
|
206
|
+
best_score = score;
|
|
207
|
+
best_len = len;
|
|
208
|
+
out->len = best_len;
|
|
209
|
+
out->distance = backward;
|
|
210
|
+
out->score = best_score;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
/* we require matches of len >4, so increase best_len to 3, so we can compare
|
|
217
|
+
* 4 bytes all the time. */
|
|
218
|
+
if (best_len < 3) {
|
|
219
|
+
best_len = 3;
|
|
220
|
+
}
|
|
221
|
+
{
|
|
222
|
+
const uint8_t tag = hash & TAG_HASH_MASK;
|
|
223
|
+
const size_t head = (num[key] + 1) & self->block_mask_;
|
|
224
|
+
uint64_t matches =
|
|
225
|
+
GetMatchingTagMask(self->block_size_ / 16, tag, tag_bucket, head);
|
|
226
|
+
/* Mask off any matches from uninitialized tags. */
|
|
227
|
+
uint16_t n = 65535 - num[key];
|
|
228
|
+
uint64_t block_has_unused_slots = self->block_size_ > n;
|
|
229
|
+
uint64_t mask = (block_has_unused_slots << (n & (64 - 1))) - 1;
|
|
230
|
+
matches &= mask;
|
|
231
|
+
for (; matches > 0; matches &= (matches - 1)) {
|
|
232
|
+
const size_t rb_index =
|
|
233
|
+
(head + (size_t)BROTLI_TZCNT64(matches)) & self->block_mask_;
|
|
234
|
+
size_t prev_ix = bucket[rb_index];
|
|
235
|
+
const size_t backward = cur_ix - prev_ix;
|
|
236
|
+
if (BROTLI_PREDICT_FALSE(backward > max_backward)) {
|
|
237
|
+
break;
|
|
238
|
+
}
|
|
239
|
+
prev_ix &= ring_buffer_mask;
|
|
240
|
+
if (cur_ix_masked + best_len > ring_buffer_mask) {
|
|
241
|
+
break;
|
|
242
|
+
}
|
|
243
|
+
if (prev_ix + best_len > ring_buffer_mask ||
|
|
244
|
+
/* compare 4 bytes ending at best_len + 1 */
|
|
245
|
+
BrotliUnalignedRead32(&data[cur_ix_masked + best_len - 3]) !=
|
|
246
|
+
BrotliUnalignedRead32(&data[prev_ix + best_len - 3])) {
|
|
247
|
+
continue;
|
|
248
|
+
}
|
|
249
|
+
{
|
|
250
|
+
const size_t len = FindMatchLengthWithLimit(&data[prev_ix],
|
|
251
|
+
&data[cur_ix_masked],
|
|
252
|
+
max_length);
|
|
253
|
+
if (len >= 4) {
|
|
254
|
+
/* Comparing for >= 3 does not change the semantics, but just saves
|
|
255
|
+
for a few unnecessary binary logarithms in backward reference
|
|
256
|
+
score, since we are not interested in such short matches. */
|
|
257
|
+
score_t score = BackwardReferenceScore(len, backward);
|
|
258
|
+
if (best_score < score) {
|
|
259
|
+
best_score = score;
|
|
260
|
+
best_len = len;
|
|
261
|
+
out->len = best_len;
|
|
262
|
+
out->distance = backward;
|
|
263
|
+
out->score = best_score;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
bucket[num[key] & self->block_mask_] = (uint32_t)cur_ix;
|
|
269
|
+
tag_bucket[num[key] & self->block_mask_] = tag;
|
|
270
|
+
--num[key];
|
|
271
|
+
}
|
|
272
|
+
if (min_score == out->score) {
|
|
273
|
+
SearchInStaticDictionary(dictionary,
|
|
274
|
+
self->common_, &data[cur_ix_masked], max_length, dictionary_distance,
|
|
275
|
+
max_distance, out, BROTLI_FALSE);
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
#undef HashLongestMatch
|
|
@@ -9,10 +9,6 @@
|
|
|
9
9
|
|
|
10
10
|
#include "literal_cost.h"
|
|
11
11
|
|
|
12
|
-
#include <string.h> /* memset */
|
|
13
|
-
|
|
14
|
-
#include <brotli/types.h>
|
|
15
|
-
|
|
16
12
|
#include "../common/platform.h"
|
|
17
13
|
#include "fast_log.h"
|
|
18
14
|
#include "utf8_util.h"
|
|
@@ -106,6 +102,8 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask,
|
|
|
106
102
|
size_t utf8_pos = UTF8Position(last_c, c, max_utf8);
|
|
107
103
|
size_t masked_pos = (pos + i) & mask;
|
|
108
104
|
size_t histo = histogram[256 * utf8_pos + data[masked_pos]];
|
|
105
|
+
static const size_t prologue_length = 2000;
|
|
106
|
+
static const double multiplier = 0.35 / 2000;
|
|
109
107
|
double lit_cost;
|
|
110
108
|
if (histo == 0) {
|
|
111
109
|
histo = 1;
|
|
@@ -120,8 +118,8 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask,
|
|
|
120
118
|
Perhaps because the entropy source is changing its properties
|
|
121
119
|
rapidly in the beginning of the file, perhaps because the beginning
|
|
122
120
|
of the data is a statistical "anomaly". */
|
|
123
|
-
if (i <
|
|
124
|
-
lit_cost += 0.
|
|
121
|
+
if (i < prologue_length) {
|
|
122
|
+
lit_cost += 0.35 + multiplier * (double)i;
|
|
125
123
|
}
|
|
126
124
|
cost[i] = (float)lit_cost;
|
|
127
125
|
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#ifndef THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_
|
|
2
|
+
#define THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_
|
|
3
|
+
|
|
4
|
+
#include "../common/platform.h"
|
|
5
|
+
|
|
6
|
+
#if defined(__SSE2__) || defined(_M_AMD64) || \
|
|
7
|
+
(defined(_M_IX86) && defined(_M_IX86_FP) && (_M_IX86_FP >= 2))
|
|
8
|
+
#define SUPPORTS_SSE_2
|
|
9
|
+
#endif
|
|
10
|
+
|
|
11
|
+
#if defined(SUPPORTS_SSE_2)
|
|
12
|
+
#include <immintrin.h>
|
|
13
|
+
#endif
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
static BROTLI_INLINE uint64_t GetMatchingTagMask(
|
|
17
|
+
size_t chunk_count, const uint8_t tag,
|
|
18
|
+
const uint8_t* BROTLI_RESTRICT tag_bucket, const size_t head) {
|
|
19
|
+
uint64_t matches = 0;
|
|
20
|
+
#if defined(SUPPORTS_SSE_2)
|
|
21
|
+
const __m128i comparison_mask = _mm_set1_epi8((char)tag);
|
|
22
|
+
size_t i;
|
|
23
|
+
for (i = 0; i < chunk_count && i < 4; i++) {
|
|
24
|
+
const __m128i chunk =
|
|
25
|
+
_mm_loadu_si128((const __m128i*)(const void*)(tag_bucket + 16 * i));
|
|
26
|
+
const __m128i equal_mask = _mm_cmpeq_epi8(chunk, comparison_mask);
|
|
27
|
+
matches |= (uint64_t)_mm_movemask_epi8(equal_mask) << 16 * i;
|
|
28
|
+
}
|
|
29
|
+
#else
|
|
30
|
+
const int chunk_size = sizeof(size_t);
|
|
31
|
+
const size_t shift_amount = ((chunk_size * 8) - chunk_size);
|
|
32
|
+
const size_t xFF = ~((size_t)0);
|
|
33
|
+
const size_t x01 = xFF / 0xFF;
|
|
34
|
+
const size_t x80 = x01 << 7;
|
|
35
|
+
const size_t splat_char = tag * x01;
|
|
36
|
+
int i = ((int)chunk_count * 16) - chunk_size;
|
|
37
|
+
BROTLI_DCHECK((sizeof(size_t) == 4) || (sizeof(size_t) == 8));
|
|
38
|
+
#if BROTLI_LITTLE_ENDIAN
|
|
39
|
+
const size_t extractMagic = (xFF / 0x7F) >> chunk_size;
|
|
40
|
+
do {
|
|
41
|
+
size_t chunk = BrotliUnalignedReadSizeT(&tag_bucket[i]);
|
|
42
|
+
chunk ^= splat_char;
|
|
43
|
+
chunk = (((chunk | x80) - x01) | chunk) & x80;
|
|
44
|
+
matches <<= chunk_size;
|
|
45
|
+
matches |= (chunk * extractMagic) >> shift_amount;
|
|
46
|
+
i -= chunk_size;
|
|
47
|
+
} while (i >= 0);
|
|
48
|
+
#else
|
|
49
|
+
const size_t msb = xFF ^ (xFF >> 1);
|
|
50
|
+
const size_t extractMagic = (msb / 0x1FF) | msb;
|
|
51
|
+
do {
|
|
52
|
+
size_t chunk = BrotliUnalignedReadSizeT(&tag_bucket[i]);
|
|
53
|
+
chunk ^= splat_char;
|
|
54
|
+
chunk = (((chunk | x80) - x01) | chunk) & x80;
|
|
55
|
+
matches <<= chunk_size;
|
|
56
|
+
matches |= ((chunk >> 7) * extractMagic) >> shift_amount;
|
|
57
|
+
i -= chunk_size;
|
|
58
|
+
} while (i >= 0);
|
|
59
|
+
#endif
|
|
60
|
+
matches = ~matches;
|
|
61
|
+
#endif
|
|
62
|
+
if (chunk_count == 1) return BrotliRotateRight16((uint16_t)matches, head);
|
|
63
|
+
if (chunk_count == 2) return BrotliRotateRight32((uint32_t)matches, head);
|
|
64
|
+
return BrotliRotateRight64(matches, head);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
#undef SUPPORTS_SSE_2
|
|
68
|
+
|
|
69
|
+
#endif // THIRD_PARTY_BROTLI_ENC_MATCHING_TAG_MASK_H_
|
|
@@ -9,18 +9,18 @@
|
|
|
9
9
|
|
|
10
10
|
#include "metablock.h"
|
|
11
11
|
|
|
12
|
-
#include <brotli/types.h>
|
|
13
|
-
|
|
14
12
|
#include "../common/constants.h"
|
|
15
13
|
#include "../common/context.h"
|
|
16
14
|
#include "../common/platform.h"
|
|
17
15
|
#include "bit_cost.h"
|
|
18
16
|
#include "block_splitter.h"
|
|
19
17
|
#include "cluster.h"
|
|
18
|
+
#include "command.h"
|
|
20
19
|
#include "entropy_encode.h"
|
|
21
20
|
#include "histogram.h"
|
|
22
21
|
#include "memory.h"
|
|
23
|
-
#include "
|
|
22
|
+
#include "params.h"
|
|
23
|
+
#include "prefix.h"
|
|
24
24
|
|
|
25
25
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
26
26
|
extern "C" {
|
|
@@ -298,8 +298,6 @@ void BrotliBuildMetaBlock(MemoryManager* m,
|
|
|
298
298
|
#include "metablock_inc.h" /* NOLINT(build/include) */
|
|
299
299
|
#undef FN
|
|
300
300
|
|
|
301
|
-
#define BROTLI_MAX_STATIC_CONTEXTS 13
|
|
302
|
-
|
|
303
301
|
/* Greedy block splitter for one block category (literal, command or distance).
|
|
304
302
|
Gathers histograms for all context buckets. */
|
|
305
303
|
typedef struct ContextBlockSplitter {
|
|
@@ -400,7 +398,7 @@ static void ContextBlockSplitterFinishBlock(
|
|
|
400
398
|
|
|
401
399
|
for (i = 0; i < num_contexts; ++i) {
|
|
402
400
|
last_entropy[i] =
|
|
403
|
-
|
|
401
|
+
BrotliBitsEntropy(histograms[i].data_, self->alphabet_size_);
|
|
404
402
|
last_entropy[num_contexts + i] = last_entropy[i];
|
|
405
403
|
}
|
|
406
404
|
++self->num_blocks_;
|
|
@@ -426,15 +424,15 @@ static void ContextBlockSplitterFinishBlock(
|
|
|
426
424
|
for (i = 0; i < num_contexts; ++i) {
|
|
427
425
|
size_t curr_histo_ix = self->curr_histogram_ix_ + i;
|
|
428
426
|
size_t j;
|
|
429
|
-
entropy[i] =
|
|
430
|
-
|
|
427
|
+
entropy[i] = BrotliBitsEntropy(histograms[curr_histo_ix].data_,
|
|
428
|
+
self->alphabet_size_);
|
|
431
429
|
for (j = 0; j < 2; ++j) {
|
|
432
430
|
size_t jx = j * num_contexts + i;
|
|
433
431
|
size_t last_histogram_ix = self->last_histogram_ix_[j] + i;
|
|
434
432
|
combined_histo[jx] = histograms[curr_histo_ix];
|
|
435
433
|
HistogramAddHistogramLiteral(&combined_histo[jx],
|
|
436
434
|
&histograms[last_histogram_ix]);
|
|
437
|
-
combined_entropy[jx] =
|
|
435
|
+
combined_entropy[jx] = BrotliBitsEntropy(
|
|
438
436
|
&combined_histo[jx].data_[0], self->alphabet_size_);
|
|
439
437
|
diff[j] += combined_entropy[jx] - entropy[i] - last_entropy[jx];
|
|
440
438
|
}
|
|
@@ -10,20 +10,20 @@
|
|
|
10
10
|
#ifndef BROTLI_ENC_METABLOCK_H_
|
|
11
11
|
#define BROTLI_ENC_METABLOCK_H_
|
|
12
12
|
|
|
13
|
-
#include <brotli/types.h>
|
|
14
|
-
|
|
15
13
|
#include "../common/context.h"
|
|
16
14
|
#include "../common/platform.h"
|
|
17
15
|
#include "block_splitter.h"
|
|
18
16
|
#include "command.h"
|
|
19
17
|
#include "histogram.h"
|
|
20
18
|
#include "memory.h"
|
|
21
|
-
#include "
|
|
19
|
+
#include "params.h"
|
|
22
20
|
|
|
23
21
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
24
22
|
extern "C" {
|
|
25
23
|
#endif
|
|
26
24
|
|
|
25
|
+
#define BROTLI_MAX_STATIC_CONTEXTS 13
|
|
26
|
+
|
|
27
27
|
typedef struct MetaBlockSplit {
|
|
28
28
|
BlockSplit literal_split;
|
|
29
29
|
BlockSplit command_split;
|
|
@@ -96,7 +96,7 @@ static void FN(BlockSplitterFinishBlock)(
|
|
|
96
96
|
split->lengths[0] = (uint32_t)self->block_size_;
|
|
97
97
|
split->types[0] = 0;
|
|
98
98
|
last_entropy[0] =
|
|
99
|
-
|
|
99
|
+
BrotliBitsEntropy(histograms[0].data_, self->alphabet_size_);
|
|
100
100
|
last_entropy[1] = last_entropy[0];
|
|
101
101
|
++self->num_blocks_;
|
|
102
102
|
++split->num_types;
|
|
@@ -105,8 +105,8 @@ static void FN(BlockSplitterFinishBlock)(
|
|
|
105
105
|
FN(HistogramClear)(&histograms[self->curr_histogram_ix_]);
|
|
106
106
|
self->block_size_ = 0;
|
|
107
107
|
} else if (self->block_size_ > 0) {
|
|
108
|
-
double entropy =
|
|
109
|
-
|
|
108
|
+
double entropy = BrotliBitsEntropy(
|
|
109
|
+
histograms[self->curr_histogram_ix_].data_, self->alphabet_size_);
|
|
110
110
|
double combined_entropy[2];
|
|
111
111
|
double diff[2];
|
|
112
112
|
size_t j;
|
|
@@ -115,7 +115,7 @@ static void FN(BlockSplitterFinishBlock)(
|
|
|
115
115
|
self->combined_histo[j] = histograms[self->curr_histogram_ix_];
|
|
116
116
|
FN(HistogramAddHistogram)(&self->combined_histo[j],
|
|
117
117
|
&histograms[last_histogram_ix]);
|
|
118
|
-
combined_entropy[j] =
|
|
118
|
+
combined_entropy[j] = BrotliBitsEntropy(
|
|
119
119
|
&self->combined_histo[j].data_[0], self->alphabet_size_);
|
|
120
120
|
diff[j] = combined_entropy[j] - entropy - last_entropy[j];
|
|
121
121
|
}
|
|
@@ -10,9 +10,8 @@
|
|
|
10
10
|
#ifndef BROTLI_ENC_QUALITY_H_
|
|
11
11
|
#define BROTLI_ENC_QUALITY_H_
|
|
12
12
|
|
|
13
|
-
#include <brotli/encode.h>
|
|
14
|
-
|
|
15
13
|
#include "../common/platform.h"
|
|
14
|
+
#include <brotli/encode.h>
|
|
16
15
|
#include "params.h"
|
|
17
16
|
|
|
18
17
|
#define FAST_ONE_PASS_COMPRESSION_QUALITY 0
|
|
@@ -128,16 +127,16 @@ static BROTLI_INLINE size_t LiteralSpreeLengthForSparseSearch(
|
|
|
128
127
|
- q04: h04 (longest_match_quickly), b17, l5
|
|
129
128
|
- q04: h54 (longest_match_quickly), b20, l7 | for large files
|
|
130
129
|
|
|
131
|
-
- q05:
|
|
132
|
-
- q05:
|
|
130
|
+
- q05: h58 (longest_match_simd ), b14, l4
|
|
131
|
+
- q05: h68 (longest_match64_simd ), b15, l5 | for large files
|
|
133
132
|
- q05: h40 (forgetful_chain ), b15, l4 | for small window
|
|
134
133
|
|
|
135
|
-
- q06:
|
|
136
|
-
- q06:
|
|
134
|
+
- q06: h58 (longest_match_simd ), b14, l4
|
|
135
|
+
- q06: h68 (longest_match64_simd ), b15, l5 | for large files
|
|
137
136
|
- q06: h40 (forgetful_chain ), b15, l4 | for small window
|
|
138
137
|
|
|
139
|
-
- q07:
|
|
140
|
-
- q07:
|
|
138
|
+
- q07: h58 (longest_match_simd ), b15, l4
|
|
139
|
+
- q07: h68 (longest_match64_simd ), b15, l5 | for large files
|
|
141
140
|
- q07: h41 (forgetful_chain ), b15, l4 | for small window
|
|
142
141
|
|
|
143
142
|
- q08: h05 (longest_match ), b15, l4
|
|
@@ -165,7 +164,11 @@ static BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params,
|
|
|
165
164
|
} else if (params->lgwin <= 16) {
|
|
166
165
|
hparams->type = params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42;
|
|
167
166
|
} else if (params->size_hint >= (1 << 20) && params->lgwin >= 19) {
|
|
167
|
+
#if defined(BROTLI_MAX_SIMD_QUALITY)
|
|
168
|
+
hparams->type = params->quality <= BROTLI_MAX_SIMD_QUALITY ? 68 : 6;
|
|
169
|
+
#else
|
|
168
170
|
hparams->type = 6;
|
|
171
|
+
#endif
|
|
169
172
|
hparams->block_bits = params->quality - 1;
|
|
170
173
|
hparams->bucket_bits = 15;
|
|
171
174
|
hparams->num_last_distances_to_check =
|
|
@@ -173,7 +176,11 @@ static BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params,
|
|
|
173
176
|
} else {
|
|
174
177
|
/* TODO(eustas): often previous setting (H6) is faster and denser; consider
|
|
175
178
|
adding an option to use it. */
|
|
179
|
+
#if defined(BROTLI_MAX_SIMD_QUALITY)
|
|
180
|
+
hparams->type = params->quality <= BROTLI_MAX_SIMD_QUALITY ? 58 : 5;
|
|
181
|
+
#else
|
|
176
182
|
hparams->type = 5;
|
|
183
|
+
#endif
|
|
177
184
|
hparams->block_bits = params->quality - 1;
|
|
178
185
|
hparams->bucket_bits = params->quality < 7 ? 14 : 15;
|
|
179
186
|
hparams->num_last_distances_to_check =
|
|
@@ -186,14 +193,14 @@ static BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params,
|
|
|
186
193
|
hasher already works well with large window. So the changes are:
|
|
187
194
|
H3 --> H35: for quality 3.
|
|
188
195
|
H54 --> H55: for quality 4 with size hint > 1MB
|
|
189
|
-
H6 --> H65: for qualities 5, 6, 7, 8, 9. */
|
|
196
|
+
H6/H68 --> H65: for qualities 5, 6, 7, 8, 9. */
|
|
190
197
|
if (hparams->type == 3) {
|
|
191
198
|
hparams->type = 35;
|
|
192
199
|
}
|
|
193
200
|
if (hparams->type == 54) {
|
|
194
201
|
hparams->type = 55;
|
|
195
202
|
}
|
|
196
|
-
if (hparams->type == 6) {
|
|
203
|
+
if (hparams->type == 6 || hparams->type == 68) {
|
|
197
204
|
hparams->type = 65;
|
|
198
205
|
}
|
|
199
206
|
}
|
|
@@ -9,12 +9,9 @@
|
|
|
9
9
|
#ifndef BROTLI_ENC_RINGBUFFER_H_
|
|
10
10
|
#define BROTLI_ENC_RINGBUFFER_H_
|
|
11
11
|
|
|
12
|
-
#include <string.h> /* memcpy */
|
|
13
|
-
|
|
14
|
-
#include <brotli/types.h>
|
|
15
|
-
|
|
16
12
|
#include "../common/platform.h"
|
|
17
13
|
#include "memory.h"
|
|
14
|
+
#include "params.h"
|
|
18
15
|
#include "quality.h"
|
|
19
16
|
|
|
20
17
|
#if defined(__cplusplus) || defined(c_plusplus)
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
#ifndef BROTLI_ENC_STATE_H_
|
|
10
10
|
#define BROTLI_ENC_STATE_H_
|
|
11
11
|
|
|
12
|
-
#include
|
|
13
|
-
|
|
12
|
+
#include "../common/constants.h"
|
|
13
|
+
#include "../common/platform.h"
|
|
14
14
|
#include "command.h"
|
|
15
15
|
#include "compress_fragment.h"
|
|
16
16
|
#include "compress_fragment_two_pass.h"
|