brotli 0.2.0 → 0.4.0
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 +5 -5
- data/.github/workflows/main.yml +34 -0
- data/.github/workflows/publish.yml +34 -0
- data/Gemfile +6 -2
- data/Rakefile +18 -6
- data/bin/before_install.sh +9 -0
- data/brotli.gemspec +7 -13
- data/ext/brotli/brotli.c +209 -11
- data/ext/brotli/buffer.c +1 -7
- data/ext/brotli/buffer.h +1 -1
- data/ext/brotli/extconf.rb +45 -26
- data/lib/brotli/version.rb +1 -1
- data/smoke.sh +1 -1
- data/test/brotli_test.rb +104 -0
- data/test/brotli_writer_test.rb +36 -0
- data/test/test_helper.rb +8 -0
- data/vendor/brotli/c/common/constants.c +15 -0
- data/vendor/brotli/c/common/constants.h +149 -6
- data/vendor/brotli/c/{dec/context.h → common/context.c} +91 -186
- data/vendor/brotli/c/common/context.h +113 -0
- data/vendor/brotli/c/common/dictionary.bin +0 -0
- data/vendor/brotli/c/common/dictionary.bin.br +0 -0
- data/vendor/brotli/c/common/dictionary.c +11 -2
- data/vendor/brotli/c/common/dictionary.h +4 -4
- data/vendor/brotli/c/common/platform.c +22 -0
- data/vendor/brotli/c/common/platform.h +594 -0
- data/vendor/brotli/c/common/transform.c +291 -0
- data/vendor/brotli/c/common/transform.h +85 -0
- data/vendor/brotli/c/common/version.h +8 -1
- data/vendor/brotli/c/dec/bit_reader.c +29 -1
- data/vendor/brotli/c/dec/bit_reader.h +91 -100
- data/vendor/brotli/c/dec/decode.c +665 -437
- data/vendor/brotli/c/dec/huffman.c +65 -84
- data/vendor/brotli/c/dec/huffman.h +67 -14
- data/vendor/brotli/c/dec/prefix.h +1 -20
- data/vendor/brotli/c/dec/state.c +32 -45
- data/vendor/brotli/c/dec/state.h +173 -55
- data/vendor/brotli/c/enc/backward_references.c +27 -16
- data/vendor/brotli/c/enc/backward_references.h +7 -7
- data/vendor/brotli/c/enc/backward_references_hq.c +155 -116
- data/vendor/brotli/c/enc/backward_references_hq.h +22 -23
- data/vendor/brotli/c/enc/backward_references_inc.h +32 -22
- data/vendor/brotli/c/enc/bit_cost.c +1 -1
- data/vendor/brotli/c/enc/bit_cost.h +5 -5
- data/vendor/brotli/c/enc/block_encoder_inc.h +7 -6
- data/vendor/brotli/c/enc/block_splitter.c +5 -6
- data/vendor/brotli/c/enc/block_splitter.h +1 -1
- data/vendor/brotli/c/enc/block_splitter_inc.h +26 -17
- data/vendor/brotli/c/enc/brotli_bit_stream.c +107 -123
- data/vendor/brotli/c/enc/brotli_bit_stream.h +19 -38
- data/vendor/brotli/c/enc/cluster.c +1 -1
- data/vendor/brotli/c/enc/cluster.h +1 -1
- data/vendor/brotli/c/enc/cluster_inc.h +6 -3
- data/vendor/brotli/c/enc/command.c +28 -0
- data/vendor/brotli/c/enc/command.h +52 -42
- data/vendor/brotli/c/enc/compress_fragment.c +21 -22
- data/vendor/brotli/c/enc/compress_fragment.h +1 -1
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +102 -69
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +1 -1
- data/vendor/brotli/c/enc/dictionary_hash.c +1827 -1101
- data/vendor/brotli/c/enc/dictionary_hash.h +2 -1
- data/vendor/brotli/c/enc/encode.c +358 -195
- data/vendor/brotli/c/enc/encoder_dict.c +33 -0
- data/vendor/brotli/c/enc/encoder_dict.h +43 -0
- data/vendor/brotli/c/enc/entropy_encode.c +16 -14
- data/vendor/brotli/c/enc/entropy_encode.h +7 -7
- data/vendor/brotli/c/enc/entropy_encode_static.h +3 -3
- data/vendor/brotli/c/enc/fast_log.c +105 -0
- data/vendor/brotli/c/enc/fast_log.h +20 -99
- data/vendor/brotli/c/enc/find_match_length.h +5 -6
- data/vendor/brotli/c/enc/hash.h +145 -103
- data/vendor/brotli/c/enc/hash_composite_inc.h +125 -0
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +93 -53
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +54 -53
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +58 -54
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +95 -63
- data/vendor/brotli/c/enc/hash_rolling_inc.h +212 -0
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +46 -43
- data/vendor/brotli/c/enc/histogram.c +9 -6
- data/vendor/brotli/c/enc/histogram.h +6 -3
- data/vendor/brotli/c/enc/histogram_inc.h +1 -1
- data/vendor/brotli/c/enc/literal_cost.c +5 -5
- data/vendor/brotli/c/enc/literal_cost.h +2 -2
- data/vendor/brotli/c/enc/memory.c +5 -16
- data/vendor/brotli/c/enc/memory.h +52 -1
- data/vendor/brotli/c/enc/metablock.c +171 -36
- data/vendor/brotli/c/enc/metablock.h +13 -8
- data/vendor/brotli/c/enc/metablock_inc.h +2 -2
- data/vendor/brotli/c/enc/params.h +46 -0
- data/vendor/brotli/c/enc/prefix.h +3 -4
- data/vendor/brotli/c/enc/quality.h +29 -24
- data/vendor/brotli/c/enc/ringbuffer.h +19 -12
- data/vendor/brotli/c/enc/static_dict.c +49 -45
- data/vendor/brotli/c/enc/static_dict.h +4 -3
- data/vendor/brotli/c/enc/static_dict_lut.h +1 -1
- data/vendor/brotli/c/enc/utf8_util.c +21 -21
- data/vendor/brotli/c/enc/utf8_util.h +1 -1
- data/vendor/brotli/c/enc/write_bits.h +35 -38
- data/vendor/brotli/c/include/brotli/decode.h +13 -8
- data/vendor/brotli/c/include/brotli/encode.h +54 -8
- data/vendor/brotli/c/include/brotli/port.h +225 -83
- data/vendor/brotli/c/include/brotli/types.h +0 -7
- metadata +28 -87
- data/.travis.yml +0 -30
- data/spec/brotli_spec.rb +0 -88
- data/spec/inflate_spec.rb +0 -75
- data/spec/spec_helper.rb +0 -4
- data/vendor/brotli/c/dec/port.h +0 -168
- data/vendor/brotli/c/dec/transform.h +0 -300
- data/vendor/brotli/c/enc/context.h +0 -184
- data/vendor/brotli/c/enc/port.h +0 -184
@@ -24,8 +24,8 @@ static BROTLI_INLINE size_t FN(StoreLookahead)(void) {
|
|
24
24
|
return MAX_TREE_COMP_LENGTH;
|
25
25
|
}
|
26
26
|
|
27
|
-
static uint32_t FN(HashBytes)(const uint8_t
|
28
|
-
uint32_t h =
|
27
|
+
static uint32_t FN(HashBytes)(const uint8_t* BROTLI_RESTRICT data) {
|
28
|
+
uint32_t h = BROTLI_UNALIGNED_LOAD32LE(data) * kHashMul32;
|
29
29
|
/* The higher bits contain more mixture from the multiplication,
|
30
30
|
so we take our results from there. */
|
31
31
|
return h >> (32 - BUCKET_BITS);
|
@@ -38,7 +38,7 @@ typedef struct HashToBinaryTree {
|
|
38
38
|
/* Hash table that maps the 4-byte hashes of the sequence to the last
|
39
39
|
position where this hash was found, which is the root of the binary
|
40
40
|
tree of sequences that share this hash bucket. */
|
41
|
-
uint32_t buckets_[BUCKET_SIZE];
|
41
|
+
uint32_t* buckets_; /* uint32_t[BUCKET_SIZE]; */
|
42
42
|
|
43
43
|
/* A position used to mark a non-existent sequence, i.e. a tree is empty if
|
44
44
|
its root is at invalid_pos_ and a node is a leaf if both its children
|
@@ -51,34 +51,30 @@ typedef struct HashToBinaryTree {
|
|
51
51
|
corresponding to a hash is a sequence starting at buckets_[hash] and
|
52
52
|
the left and right children of a sequence starting at pos are
|
53
53
|
forest_[2 * pos] and forest_[2 * pos + 1]. */
|
54
|
-
/* uint32_t
|
54
|
+
uint32_t* forest_; /* uint32_t[2 * num_nodes] */
|
55
55
|
} HashToBinaryTree;
|
56
56
|
|
57
|
-
static BROTLI_INLINE HashToBinaryTree* FN(Self)(HasherHandle handle) {
|
58
|
-
return (HashToBinaryTree*)&(GetHasherCommon(handle)[1]);
|
59
|
-
}
|
60
|
-
|
61
|
-
static BROTLI_INLINE uint32_t* FN(Forest)(HashToBinaryTree* self) {
|
62
|
-
return (uint32_t*)(&self[1]);
|
63
|
-
}
|
64
|
-
|
65
57
|
static void FN(Initialize)(
|
66
|
-
|
67
|
-
|
58
|
+
HasherCommon* common, HashToBinaryTree* BROTLI_RESTRICT self,
|
59
|
+
const BrotliEncoderParams* params) {
|
60
|
+
self->buckets_ = (uint32_t*)common->extra;
|
61
|
+
self->forest_ = &self->buckets_[BUCKET_SIZE];
|
62
|
+
|
68
63
|
self->window_mask_ = (1u << params->lgwin) - 1u;
|
69
64
|
self->invalid_pos_ = (uint32_t)(0 - self->window_mask_);
|
70
65
|
}
|
71
66
|
|
72
|
-
static void FN(Prepare)
|
73
|
-
|
74
|
-
|
67
|
+
static void FN(Prepare)
|
68
|
+
(HashToBinaryTree* BROTLI_RESTRICT self, BROTLI_BOOL one_shot,
|
69
|
+
size_t input_size, const uint8_t* BROTLI_RESTRICT data) {
|
75
70
|
uint32_t invalid_pos = self->invalid_pos_;
|
76
71
|
uint32_t i;
|
72
|
+
uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
|
77
73
|
BROTLI_UNUSED(data);
|
78
74
|
BROTLI_UNUSED(one_shot);
|
79
75
|
BROTLI_UNUSED(input_size);
|
80
76
|
for (i = 0; i < BUCKET_SIZE; i++) {
|
81
|
-
|
77
|
+
buckets[i] = invalid_pos;
|
82
78
|
}
|
83
79
|
}
|
84
80
|
|
@@ -89,15 +85,17 @@ static BROTLI_INLINE size_t FN(HashMemAllocInBytes)(
|
|
89
85
|
if (one_shot && input_size < num_nodes) {
|
90
86
|
num_nodes = input_size;
|
91
87
|
}
|
92
|
-
return sizeof(
|
88
|
+
return sizeof(uint32_t) * BUCKET_SIZE + 2 * sizeof(uint32_t) * num_nodes;
|
93
89
|
}
|
94
90
|
|
95
|
-
static BROTLI_INLINE size_t FN(LeftChildIndex)(
|
91
|
+
static BROTLI_INLINE size_t FN(LeftChildIndex)(
|
92
|
+
HashToBinaryTree* BROTLI_RESTRICT self,
|
96
93
|
const size_t pos) {
|
97
94
|
return 2 * (pos & self->window_mask_);
|
98
95
|
}
|
99
96
|
|
100
|
-
static BROTLI_INLINE size_t FN(RightChildIndex)(
|
97
|
+
static BROTLI_INLINE size_t FN(RightChildIndex)(
|
98
|
+
HashToBinaryTree* BROTLI_RESTRICT self,
|
101
99
|
const size_t pos) {
|
102
100
|
return 2 * (pos & self->window_mask_) + 1;
|
103
101
|
}
|
@@ -113,7 +111,7 @@ static BROTLI_INLINE size_t FN(RightChildIndex)(HashToBinaryTree* self,
|
|
113
111
|
|
114
112
|
This function must be called with increasing cur_ix positions. */
|
115
113
|
static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
116
|
-
HashToBinaryTree* self, const uint8_t*
|
114
|
+
HashToBinaryTree* BROTLI_RESTRICT self, const uint8_t* BROTLI_RESTRICT data,
|
117
115
|
const size_t cur_ix, const size_t ring_buffer_mask, const size_t max_length,
|
118
116
|
const size_t max_backward, size_t* const BROTLI_RESTRICT best_len,
|
119
117
|
BackwardMatch* BROTLI_RESTRICT matches) {
|
@@ -123,8 +121,9 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
|
123
121
|
const BROTLI_BOOL should_reroot_tree =
|
124
122
|
TO_BROTLI_BOOL(max_length >= MAX_TREE_COMP_LENGTH);
|
125
123
|
const uint32_t key = FN(HashBytes)(&data[cur_ix_masked]);
|
126
|
-
uint32_t*
|
127
|
-
|
124
|
+
uint32_t* BROTLI_RESTRICT buckets = self->buckets_;
|
125
|
+
uint32_t* BROTLI_RESTRICT forest = self->forest_;
|
126
|
+
size_t prev_ix = buckets[key];
|
128
127
|
/* The forest index of the rightmost node of the left subtree of the new
|
129
128
|
root, updated as we traverse and re-root the tree of the hash bucket. */
|
130
129
|
size_t node_left = FN(LeftChildIndex)(self, cur_ix);
|
@@ -139,7 +138,7 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
|
139
138
|
size_t best_len_right = 0;
|
140
139
|
size_t depth_remaining;
|
141
140
|
if (should_reroot_tree) {
|
142
|
-
|
141
|
+
buckets[key] = (uint32_t)cur_ix;
|
143
142
|
}
|
144
143
|
for (depth_remaining = MAX_TREE_SEARCH_DEPTH; ; --depth_remaining) {
|
145
144
|
const size_t backward = cur_ix - prev_ix;
|
@@ -154,12 +153,13 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
|
154
153
|
{
|
155
154
|
const size_t cur_len = BROTLI_MIN(size_t, best_len_left, best_len_right);
|
156
155
|
size_t len;
|
157
|
-
|
156
|
+
BROTLI_DCHECK(cur_len <= MAX_TREE_COMP_LENGTH);
|
158
157
|
len = cur_len +
|
159
158
|
FindMatchLengthWithLimit(&data[cur_ix_masked + cur_len],
|
160
159
|
&data[prev_ix_masked + cur_len],
|
161
160
|
max_length - cur_len);
|
162
|
-
|
161
|
+
BROTLI_DCHECK(
|
162
|
+
0 == memcmp(&data[cur_ix_masked], &data[prev_ix_masked], len));
|
163
163
|
if (matches && len > *best_len) {
|
164
164
|
*best_len = len;
|
165
165
|
InitBackwardMatch(matches++, backward, len);
|
@@ -198,11 +198,14 @@ static BROTLI_INLINE BackwardMatch* FN(StoreAndFindMatches)(
|
|
198
198
|
matches in matches[0] to matches[*num_matches - 1]. The matches will be
|
199
199
|
sorted by strictly increasing length and (non-strictly) increasing
|
200
200
|
distance. */
|
201
|
-
static BROTLI_INLINE size_t FN(FindAllMatches)(
|
202
|
-
|
201
|
+
static BROTLI_INLINE size_t FN(FindAllMatches)(
|
202
|
+
HashToBinaryTree* BROTLI_RESTRICT self,
|
203
|
+
const BrotliEncoderDictionary* dictionary,
|
204
|
+
const uint8_t* BROTLI_RESTRICT data,
|
203
205
|
const size_t ring_buffer_mask, const size_t cur_ix,
|
204
|
-
const size_t max_length, const size_t max_backward,
|
205
|
-
const BrotliEncoderParams* params,
|
206
|
+
const size_t max_length, const size_t max_backward,
|
207
|
+
const size_t dictionary_distance, const BrotliEncoderParams* params,
|
208
|
+
BackwardMatch* matches) {
|
206
209
|
BackwardMatch* const orig_matches = matches;
|
207
210
|
const size_t cur_ix_masked = cur_ix & ring_buffer_mask;
|
208
211
|
size_t best_len = 1;
|
@@ -234,7 +237,7 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
|
|
234
237
|
}
|
235
238
|
}
|
236
239
|
if (best_len < max_length) {
|
237
|
-
matches = FN(StoreAndFindMatches)(
|
240
|
+
matches = FN(StoreAndFindMatches)(self, data, cur_ix,
|
238
241
|
ring_buffer_mask, max_length, max_backward, &best_len, matches);
|
239
242
|
}
|
240
243
|
for (i = 0; i <= BROTLI_MAX_STATIC_DICTIONARY_MATCH_LEN; ++i) {
|
@@ -250,8 +253,8 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
|
|
250
253
|
for (l = minlen; l <= maxlen; ++l) {
|
251
254
|
uint32_t dict_id = dict_matches[l];
|
252
255
|
if (dict_id < kInvalidMatch) {
|
253
|
-
size_t distance =
|
254
|
-
if (distance
|
256
|
+
size_t distance = dictionary_distance + (dict_id >> 5) + 1;
|
257
|
+
if (distance <= params->dist.max_distance) {
|
255
258
|
InitDictionaryBackwardMatch(matches++, distance, l, dict_id & 31);
|
256
259
|
}
|
257
260
|
}
|
@@ -264,18 +267,18 @@ static BROTLI_INLINE size_t FN(FindAllMatches)(HasherHandle handle,
|
|
264
267
|
/* Stores the hash of the next 4 bytes and re-roots the binary tree at the
|
265
268
|
current sequence, without returning any matches.
|
266
269
|
REQUIRES: ix + MAX_TREE_COMP_LENGTH <= end-of-current-block */
|
267
|
-
static BROTLI_INLINE void FN(Store)(
|
270
|
+
static BROTLI_INLINE void FN(Store)(HashToBinaryTree* BROTLI_RESTRICT self,
|
271
|
+
const uint8_t* BROTLI_RESTRICT data,
|
268
272
|
const size_t mask, const size_t ix) {
|
269
|
-
HashToBinaryTree* self = FN(Self)(handle);
|
270
273
|
/* Maximum distance is window size - 16, see section 9.1. of the spec. */
|
271
274
|
const size_t max_backward = self->window_mask_ - BROTLI_WINDOW_GAP + 1;
|
272
275
|
FN(StoreAndFindMatches)(self, data, ix, mask, MAX_TREE_COMP_LENGTH,
|
273
276
|
max_backward, NULL, NULL);
|
274
277
|
}
|
275
278
|
|
276
|
-
static BROTLI_INLINE void FN(StoreRange)(
|
277
|
-
const uint8_t
|
278
|
-
const size_t ix_end) {
|
279
|
+
static BROTLI_INLINE void FN(StoreRange)(HashToBinaryTree* BROTLI_RESTRICT self,
|
280
|
+
const uint8_t* BROTLI_RESTRICT data, const size_t mask,
|
281
|
+
const size_t ix_start, const size_t ix_end) {
|
279
282
|
size_t i = ix_start;
|
280
283
|
size_t j = ix_start;
|
281
284
|
if (ix_start + 63 <= ix_end) {
|
@@ -283,18 +286,18 @@ static BROTLI_INLINE void FN(StoreRange)(HasherHandle handle,
|
|
283
286
|
}
|
284
287
|
if (ix_start + 512 <= i) {
|
285
288
|
for (; j < i; j += 8) {
|
286
|
-
FN(Store)(
|
289
|
+
FN(Store)(self, data, mask, j);
|
287
290
|
}
|
288
291
|
}
|
289
292
|
for (; i < ix_end; ++i) {
|
290
|
-
FN(Store)(
|
293
|
+
FN(Store)(self, data, mask, i);
|
291
294
|
}
|
292
295
|
}
|
293
296
|
|
294
|
-
static BROTLI_INLINE void FN(StitchToPreviousBlock)(
|
297
|
+
static BROTLI_INLINE void FN(StitchToPreviousBlock)(
|
298
|
+
HashToBinaryTree* BROTLI_RESTRICT self,
|
295
299
|
size_t num_bytes, size_t position, const uint8_t* ringbuffer,
|
296
300
|
size_t ringbuffer_mask) {
|
297
|
-
HashToBinaryTree* self = FN(Self)(handle);
|
298
301
|
if (num_bytes >= FN(HashTypeLength)() - 1 &&
|
299
302
|
position >= MAX_TREE_COMP_LENGTH) {
|
300
303
|
/* Store the last `MAX_TREE_COMP_LENGTH - 1` positions in the hasher.
|
@@ -8,9 +8,9 @@
|
|
8
8
|
|
9
9
|
#include "./histogram.h"
|
10
10
|
|
11
|
+
#include "../common/context.h"
|
11
12
|
#include "./block_splitter.h"
|
12
13
|
#include "./command.h"
|
13
|
-
#include "./context.h"
|
14
14
|
|
15
15
|
#if defined(__cplusplus) || defined(c_plusplus)
|
16
16
|
extern "C" {
|
@@ -63,13 +63,16 @@ void BrotliBuildHistogramsWithContext(
|
|
63
63
|
BlockSplitIteratorNext(&insert_and_copy_it);
|
64
64
|
HistogramAddCommand(&insert_and_copy_histograms[insert_and_copy_it.type_],
|
65
65
|
cmd->cmd_prefix_);
|
66
|
+
/* TODO: unwrap iterator blocks. */
|
66
67
|
for (j = cmd->insert_len_; j != 0; --j) {
|
67
68
|
size_t context;
|
68
69
|
BlockSplitIteratorNext(&literal_it);
|
69
|
-
context =
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
context = literal_it.type_;
|
71
|
+
if (context_modes) {
|
72
|
+
ContextLut lut = BROTLI_CONTEXT_LUT(context_modes[context]);
|
73
|
+
context = (context << BROTLI_LITERAL_CONTEXT_BITS) +
|
74
|
+
BROTLI_CONTEXT(prev_byte, prev_byte2, lut);
|
75
|
+
}
|
73
76
|
HistogramAddLiteral(&literal_histograms[context],
|
74
77
|
ringbuffer[pos & mask]);
|
75
78
|
prev_byte2 = prev_byte;
|
@@ -86,7 +89,7 @@ void BrotliBuildHistogramsWithContext(
|
|
86
89
|
context = (dist_it.type_ << BROTLI_DISTANCE_CONTEXT_BITS) +
|
87
90
|
CommandDistanceContext(cmd);
|
88
91
|
HistogramAddDistance(©_dist_histograms[context],
|
89
|
-
cmd->dist_prefix_);
|
92
|
+
cmd->dist_prefix_ & 0x3FF);
|
90
93
|
}
|
91
94
|
}
|
92
95
|
}
|
@@ -12,16 +12,19 @@
|
|
12
12
|
#include <string.h> /* memset */
|
13
13
|
|
14
14
|
#include "../common/constants.h"
|
15
|
+
#include "../common/context.h"
|
16
|
+
#include "../common/platform.h"
|
15
17
|
#include <brotli/types.h>
|
16
18
|
#include "./block_splitter.h"
|
17
19
|
#include "./command.h"
|
18
|
-
#include "./context.h"
|
19
|
-
#include "./port.h"
|
20
20
|
|
21
21
|
#if defined(__cplusplus) || defined(c_plusplus)
|
22
22
|
extern "C" {
|
23
23
|
#endif
|
24
24
|
|
25
|
+
/* The distance symbols effectively used by "Large Window Brotli" (32-bit). */
|
26
|
+
#define BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS 544
|
27
|
+
|
25
28
|
#define FN(X) X ## Literal
|
26
29
|
#define DATA_SIZE BROTLI_NUM_LITERAL_SYMBOLS
|
27
30
|
#define DataType uint8_t
|
@@ -38,7 +41,7 @@ extern "C" {
|
|
38
41
|
#undef FN
|
39
42
|
|
40
43
|
#define FN(X) X ## Distance
|
41
|
-
#define DATA_SIZE
|
44
|
+
#define DATA_SIZE BROTLI_NUM_HISTOGRAM_DISTANCE_SYMBOLS
|
42
45
|
#include "./histogram_inc.h" /* NOLINT(build/include) */
|
43
46
|
#undef DataType
|
44
47
|
#undef DATA_SIZE
|
@@ -33,7 +33,7 @@ static BROTLI_INLINE void FN(HistogramAdd)(FN(Histogram)* self, size_t val) {
|
|
33
33
|
}
|
34
34
|
|
35
35
|
static BROTLI_INLINE void FN(HistogramAddVector)(FN(Histogram)* self,
|
36
|
-
const DataType
|
36
|
+
const DataType* p, size_t n) {
|
37
37
|
self->total_count_ += n;
|
38
38
|
n += 1;
|
39
39
|
while (--n) ++self->data_[*p++];
|
@@ -9,9 +9,9 @@
|
|
9
9
|
|
10
10
|
#include "./literal_cost.h"
|
11
11
|
|
12
|
+
#include "../common/platform.h"
|
12
13
|
#include <brotli/types.h>
|
13
14
|
#include "./fast_log.h"
|
14
|
-
#include "./port.h"
|
15
15
|
#include "./utf8_util.h"
|
16
16
|
|
17
17
|
#if defined(__cplusplus) || defined(c_plusplus)
|
@@ -25,7 +25,7 @@ static size_t UTF8Position(size_t last, size_t c, size_t clamp) {
|
|
25
25
|
return BROTLI_MIN(size_t, 1, clamp);
|
26
26
|
} else {
|
27
27
|
/* Let's decide over the last byte if this ends the sequence. */
|
28
|
-
if (last <
|
28
|
+
if (last < 0xE0) {
|
29
29
|
return 0; /* Completed two or three byte coding. */
|
30
30
|
} else { /* Next one is the 'Byte 3' of utf-8 encoding. */
|
31
31
|
return BROTLI_MIN(size_t, 2, clamp);
|
@@ -34,7 +34,7 @@ static size_t UTF8Position(size_t last, size_t c, size_t clamp) {
|
|
34
34
|
}
|
35
35
|
|
36
36
|
static size_t DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask,
|
37
|
-
const uint8_t
|
37
|
+
const uint8_t* data) {
|
38
38
|
size_t counts[3] = { 0 };
|
39
39
|
size_t max_utf8 = 1; /* should be 2, but 1 compresses better. */
|
40
40
|
size_t last_c = 0;
|
@@ -54,7 +54,7 @@ static size_t DecideMultiByteStatsLevel(size_t pos, size_t len, size_t mask,
|
|
54
54
|
}
|
55
55
|
|
56
56
|
static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask,
|
57
|
-
const uint8_t
|
57
|
+
const uint8_t* data, float* cost) {
|
58
58
|
/* max_utf8 is 0 (normal ASCII single byte modeling),
|
59
59
|
1 (for 2-byte UTF-8 modeling), or 2 (for 3-byte UTF-8 modeling). */
|
60
60
|
const size_t max_utf8 = DecideMultiByteStatsLevel(pos, len, mask, data);
|
@@ -125,7 +125,7 @@ static void EstimateBitCostsForLiteralsUTF8(size_t pos, size_t len, size_t mask,
|
|
125
125
|
}
|
126
126
|
|
127
127
|
void BrotliEstimateBitCostsForLiterals(size_t pos, size_t len, size_t mask,
|
128
|
-
const uint8_t
|
128
|
+
const uint8_t* data, float* cost) {
|
129
129
|
if (BrotliIsMostlyUTF8(data, pos, mask, len, kMinUTF8Ratio)) {
|
130
130
|
EstimateBitCostsForLiteralsUTF8(pos, len, mask, data, cost);
|
131
131
|
return;
|
@@ -10,8 +10,8 @@
|
|
10
10
|
#ifndef BROTLI_ENC_LITERAL_COST_H_
|
11
11
|
#define BROTLI_ENC_LITERAL_COST_H_
|
12
12
|
|
13
|
+
#include "../common/platform.h"
|
13
14
|
#include <brotli/types.h>
|
14
|
-
#include "./port.h"
|
15
15
|
|
16
16
|
#if defined(__cplusplus) || defined(c_plusplus)
|
17
17
|
extern "C" {
|
@@ -21,7 +21,7 @@ extern "C" {
|
|
21
21
|
ring-buffer (data, mask) will take entropy coded and writes these estimates
|
22
22
|
to the cost[0..len) array. */
|
23
23
|
BROTLI_INTERNAL void BrotliEstimateBitCostsForLiterals(
|
24
|
-
size_t pos, size_t len, size_t mask, const uint8_t
|
24
|
+
size_t pos, size_t len, size_t mask, const uint8_t* data, float* cost);
|
25
25
|
|
26
26
|
#if defined(__cplusplus) || defined(c_plusplus)
|
27
27
|
} /* extern "C" */
|
@@ -9,12 +9,11 @@
|
|
9
9
|
|
10
10
|
#include "./memory.h"
|
11
11
|
|
12
|
-
#include <assert.h>
|
13
12
|
#include <stdlib.h> /* exit, free, malloc */
|
14
13
|
#include <string.h> /* memcpy */
|
15
14
|
|
15
|
+
#include "../common/platform.h"
|
16
16
|
#include <brotli/types.h>
|
17
|
-
#include "./port.h"
|
18
17
|
|
19
18
|
#if defined(__cplusplus) || defined(c_plusplus)
|
20
19
|
extern "C" {
|
@@ -28,22 +27,12 @@ extern "C" {
|
|
28
27
|
#define NEW_ALLOCATED_OFFSET MAX_PERM_ALLOCATED
|
29
28
|
#define NEW_FREED_OFFSET (MAX_PERM_ALLOCATED + MAX_NEW_ALLOCATED)
|
30
29
|
|
31
|
-
static void* DefaultAllocFunc(void* opaque, size_t size) {
|
32
|
-
BROTLI_UNUSED(opaque);
|
33
|
-
return malloc(size);
|
34
|
-
}
|
35
|
-
|
36
|
-
static void DefaultFreeFunc(void* opaque, void* address) {
|
37
|
-
BROTLI_UNUSED(opaque);
|
38
|
-
free(address);
|
39
|
-
}
|
40
|
-
|
41
30
|
void BrotliInitMemoryManager(
|
42
31
|
MemoryManager* m, brotli_alloc_func alloc_func, brotli_free_func free_func,
|
43
32
|
void* opaque) {
|
44
33
|
if (!alloc_func) {
|
45
|
-
m->alloc_func =
|
46
|
-
m->free_func =
|
34
|
+
m->alloc_func = BrotliDefaultAllocFunc;
|
35
|
+
m->free_func = BrotliDefaultFreeFunc;
|
47
36
|
m->opaque = 0;
|
48
37
|
} else {
|
49
38
|
m->alloc_func = alloc_func;
|
@@ -132,11 +121,11 @@ static void CollectGarbagePointers(MemoryManager* m) {
|
|
132
121
|
m->pointers + NEW_FREED_OFFSET, m->new_freed);
|
133
122
|
m->perm_allocated -= annihilated;
|
134
123
|
m->new_freed -= annihilated;
|
135
|
-
|
124
|
+
BROTLI_DCHECK(m->new_freed == 0);
|
136
125
|
}
|
137
126
|
|
138
127
|
if (m->new_allocated != 0) {
|
139
|
-
|
128
|
+
BROTLI_DCHECK(m->perm_allocated + m->new_allocated <= MAX_PERM_ALLOCATED);
|
140
129
|
memcpy(m->pointers + PERM_ALLOCATED_OFFSET + m->perm_allocated,
|
141
130
|
m->pointers + NEW_ALLOCATED_OFFSET,
|
142
131
|
sizeof(void*) * m->new_allocated);
|
@@ -9,8 +9,10 @@
|
|
9
9
|
#ifndef BROTLI_ENC_MEMORY_H_
|
10
10
|
#define BROTLI_ENC_MEMORY_H_
|
11
11
|
|
12
|
+
#include <string.h> /* memcpy */
|
13
|
+
|
14
|
+
#include "../common/platform.h"
|
12
15
|
#include <brotli/types.h>
|
13
|
-
#include "./port.h"
|
14
16
|
|
15
17
|
#if defined(__cplusplus) || defined(c_plusplus)
|
16
18
|
extern "C" {
|
@@ -54,8 +56,57 @@ BROTLI_INTERNAL void BrotliFree(MemoryManager* m, void* p);
|
|
54
56
|
#define BROTLI_IS_OOM(M) (!!(M)->is_oom)
|
55
57
|
#endif /* BROTLI_ENCODER_EXIT_ON_OOM */
|
56
58
|
|
59
|
+
/*
|
60
|
+
BROTLI_IS_NULL is a fake check, BROTLI_IS_OOM does the heavy lifting.
|
61
|
+
The only purpose of it is to explain static analyzers the state of things.
|
62
|
+
NB: use ONLY together with BROTLI_IS_OOM
|
63
|
+
AND ONLY for allocations in the current scope.
|
64
|
+
*/
|
65
|
+
#if defined(__clang_analyzer__) && !defined(BROTLI_ENCODER_EXIT_ON_OOM)
|
66
|
+
#define BROTLI_IS_NULL(A) ((A) == nullptr)
|
67
|
+
#else /* defined(__clang_analyzer__) */
|
68
|
+
#define BROTLI_IS_NULL(A) (!!0)
|
69
|
+
#endif /* defined(__clang_analyzer__) */
|
70
|
+
|
57
71
|
BROTLI_INTERNAL void BrotliWipeOutMemoryManager(MemoryManager* m);
|
58
72
|
|
73
|
+
/*
|
74
|
+
Dynamically grows array capacity to at least the requested size
|
75
|
+
M: MemoryManager
|
76
|
+
T: data type
|
77
|
+
A: array
|
78
|
+
C: capacity
|
79
|
+
R: requested size
|
80
|
+
*/
|
81
|
+
#define BROTLI_ENSURE_CAPACITY(M, T, A, C, R) { \
|
82
|
+
if (C < (R)) { \
|
83
|
+
size_t _new_size = (C == 0) ? (R) : C; \
|
84
|
+
T* new_array; \
|
85
|
+
while (_new_size < (R)) _new_size *= 2; \
|
86
|
+
new_array = BROTLI_ALLOC((M), T, _new_size); \
|
87
|
+
if (!BROTLI_IS_OOM(M) && !BROTLI_IS_NULL(new_array) && C != 0) \
|
88
|
+
memcpy(new_array, A, C * sizeof(T)); \
|
89
|
+
BROTLI_FREE((M), A); \
|
90
|
+
A = new_array; \
|
91
|
+
C = _new_size; \
|
92
|
+
} \
|
93
|
+
}
|
94
|
+
|
95
|
+
/*
|
96
|
+
Appends value and dynamically grows array capacity when needed
|
97
|
+
M: MemoryManager
|
98
|
+
T: data type
|
99
|
+
A: array
|
100
|
+
C: array capacity
|
101
|
+
S: array size
|
102
|
+
V: value to append
|
103
|
+
*/
|
104
|
+
#define BROTLI_ENSURE_CAPACITY_APPEND(M, T, A, C, S, V) { \
|
105
|
+
(S)++; \
|
106
|
+
BROTLI_ENSURE_CAPACITY(M, T, A, C, S); \
|
107
|
+
A[(S) - 1] = (V); \
|
108
|
+
}
|
109
|
+
|
59
110
|
#if defined(__cplusplus) || defined(c_plusplus)
|
60
111
|
} /* extern "C" */
|
61
112
|
#endif
|