brotli 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/main.yml +6 -3
- data/.github/workflows/publish.yml +7 -17
- data/.gitmodules +1 -1
- data/README.md +2 -2
- data/ext/brotli/brotli.c +1 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +4 -1
- data/vendor/brotli/c/common/constants.c +1 -1
- data/vendor/brotli/c/common/constants.h +2 -1
- data/vendor/brotli/c/common/context.c +1 -1
- data/vendor/brotli/c/common/dictionary.c +5 -3
- data/vendor/brotli/c/common/platform.c +2 -1
- data/vendor/brotli/c/common/platform.h +60 -113
- data/vendor/brotli/c/common/shared_dictionary.c +521 -0
- data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
- data/vendor/brotli/c/common/transform.c +1 -1
- data/vendor/brotli/c/common/version.h +31 -6
- data/vendor/brotli/c/dec/bit_reader.c +10 -8
- data/vendor/brotli/c/dec/bit_reader.h +172 -100
- data/vendor/brotli/c/dec/decode.c +467 -200
- data/vendor/brotli/c/dec/huffman.c +7 -4
- data/vendor/brotli/c/dec/huffman.h +2 -1
- data/vendor/brotli/c/dec/prefix.h +2 -1
- data/vendor/brotli/c/dec/state.c +33 -9
- data/vendor/brotli/c/dec/state.h +70 -35
- data/vendor/brotli/c/enc/backward_references.c +81 -19
- data/vendor/brotli/c/enc/backward_references.h +5 -4
- data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
- data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
- data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
- data/vendor/brotli/c/enc/bit_cost.c +8 -7
- data/vendor/brotli/c/enc/bit_cost.h +5 -4
- data/vendor/brotli/c/enc/block_splitter.c +37 -14
- data/vendor/brotli/c/enc/block_splitter.h +5 -4
- data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
- data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
- data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
- data/vendor/brotli/c/enc/cluster.c +10 -9
- data/vendor/brotli/c/enc/cluster.h +7 -6
- data/vendor/brotli/c/enc/cluster_inc.h +25 -20
- data/vendor/brotli/c/enc/command.c +1 -1
- data/vendor/brotli/c/enc/command.h +5 -4
- data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
- data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
- data/vendor/brotli/c/enc/compress_fragment.c +93 -83
- data/vendor/brotli/c/enc/compress_fragment.h +32 -7
- data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
- data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
- data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
- data/vendor/brotli/c/enc/encode.c +473 -404
- data/vendor/brotli/c/enc/encoder_dict.c +611 -4
- data/vendor/brotli/c/enc/encoder_dict.h +117 -3
- data/vendor/brotli/c/enc/entropy_encode.c +3 -2
- data/vendor/brotli/c/enc/entropy_encode.h +2 -1
- data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
- data/vendor/brotli/c/enc/fast_log.c +1 -1
- data/vendor/brotli/c/enc/fast_log.h +2 -1
- data/vendor/brotli/c/enc/find_match_length.h +15 -22
- data/vendor/brotli/c/enc/hash.h +285 -45
- data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
- data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
- data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
- data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
- data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
- data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
- data/vendor/brotli/c/enc/histogram.c +4 -4
- data/vendor/brotli/c/enc/histogram.h +7 -6
- data/vendor/brotli/c/enc/literal_cost.c +20 -15
- data/vendor/brotli/c/enc/literal_cost.h +4 -2
- data/vendor/brotli/c/enc/memory.c +29 -5
- data/vendor/brotli/c/enc/memory.h +19 -2
- data/vendor/brotli/c/enc/metablock.c +72 -58
- data/vendor/brotli/c/enc/metablock.h +9 -8
- data/vendor/brotli/c/enc/metablock_inc.h +8 -6
- data/vendor/brotli/c/enc/params.h +4 -3
- data/vendor/brotli/c/enc/prefix.h +3 -2
- data/vendor/brotli/c/enc/quality.h +40 -3
- data/vendor/brotli/c/enc/ringbuffer.h +4 -3
- data/vendor/brotli/c/enc/state.h +104 -0
- data/vendor/brotli/c/enc/static_dict.c +60 -4
- data/vendor/brotli/c/enc/static_dict.h +3 -2
- data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
- data/vendor/brotli/c/enc/utf8_util.c +1 -1
- data/vendor/brotli/c/enc/utf8_util.h +2 -1
- data/vendor/brotli/c/enc/write_bits.h +2 -1
- data/vendor/brotli/c/include/brotli/decode.h +67 -2
- data/vendor/brotli/c/include/brotli/encode.h +55 -2
- data/vendor/brotli/c/include/brotli/port.h +28 -11
- data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
- metadata +9 -3
@@ -6,16 +6,17 @@
|
|
6
6
|
|
7
7
|
/* Bit reading helpers */
|
8
8
|
|
9
|
-
#include "
|
9
|
+
#include "bit_reader.h"
|
10
10
|
|
11
|
-
#include "../common/platform.h"
|
12
11
|
#include <brotli/types.h>
|
13
12
|
|
13
|
+
#include "../common/platform.h"
|
14
|
+
|
14
15
|
#if defined(__cplusplus) || defined(c_plusplus)
|
15
16
|
extern "C" {
|
16
17
|
#endif
|
17
18
|
|
18
|
-
const
|
19
|
+
const brotli_reg_t kBrotliBitMask[33] = { 0x00000000,
|
19
20
|
0x00000001, 0x00000003, 0x00000007, 0x0000000F,
|
20
21
|
0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,
|
21
22
|
0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,
|
@@ -28,7 +29,7 @@ const uint32_t kBrotliBitMask[33] = { 0x00000000,
|
|
28
29
|
|
29
30
|
void BrotliInitBitReader(BrotliBitReader* const br) {
|
30
31
|
br->val_ = 0;
|
31
|
-
br->bit_pos_ =
|
32
|
+
br->bit_pos_ = 0;
|
32
33
|
}
|
33
34
|
|
34
35
|
BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
@@ -36,10 +37,11 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
36
37
|
/* Fixing alignment after unaligned BrotliFillWindow would result accumulator
|
37
38
|
overflow. If unalignment is caused by BrotliSafeReadBits, then there is
|
38
39
|
enough space in accumulator to fix alignment. */
|
39
|
-
if (
|
40
|
+
if (BROTLI_UNALIGNED_READ_FAST) {
|
40
41
|
aligned_read_mask = 0;
|
41
42
|
}
|
42
43
|
if (BrotliGetAvailableBits(br) == 0) {
|
44
|
+
br->val_ = 0;
|
43
45
|
if (!BrotliPullByte(br)) {
|
44
46
|
return BROTLI_FALSE;
|
45
47
|
}
|
@@ -55,9 +57,9 @@ BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br) {
|
|
55
57
|
}
|
56
58
|
|
57
59
|
BROTLI_BOOL BrotliSafeReadBits32Slow(BrotliBitReader* const br,
|
58
|
-
|
59
|
-
|
60
|
-
|
60
|
+
brotli_reg_t n_bits, brotli_reg_t* val) {
|
61
|
+
brotli_reg_t low_val;
|
62
|
+
brotli_reg_t high_val;
|
61
63
|
BrotliBitReaderState memento;
|
62
64
|
BROTLI_DCHECK(n_bits <= 32);
|
63
65
|
BROTLI_DCHECK(n_bits > 24);
|
@@ -11,9 +11,10 @@
|
|
11
11
|
|
12
12
|
#include <string.h> /* memcpy */
|
13
13
|
|
14
|
+
#include <brotli/types.h>
|
15
|
+
|
14
16
|
#include "../common/constants.h"
|
15
17
|
#include "../common/platform.h"
|
16
|
-
#include <brotli/types.h>
|
17
18
|
|
18
19
|
#if defined(__cplusplus) || defined(c_plusplus)
|
19
20
|
extern "C" {
|
@@ -21,13 +22,16 @@ extern "C" {
|
|
21
22
|
|
22
23
|
#define BROTLI_SHORT_FILL_BIT_WINDOW_READ (sizeof(brotli_reg_t) >> 1)
|
23
24
|
|
24
|
-
|
25
|
+
/* 162 bits + 7 bytes */
|
26
|
+
#define BROTLI_FAST_INPUT_SLACK 28
|
27
|
+
|
28
|
+
BROTLI_INTERNAL extern const brotli_reg_t kBrotliBitMask[33];
|
25
29
|
|
26
|
-
static BROTLI_INLINE
|
30
|
+
static BROTLI_INLINE brotli_reg_t BitMask(brotli_reg_t n) {
|
27
31
|
if (BROTLI_IS_CONSTANT(n) || BROTLI_HAS_UBFX) {
|
28
32
|
/* Masking with this expression turns to a single
|
29
33
|
"Unsigned Bit Field Extract" UBFX instruction on ARM. */
|
30
|
-
return ~((
|
34
|
+
return ~(~((brotli_reg_t)0) << n);
|
31
35
|
} else {
|
32
36
|
return kBrotliBitMask[n];
|
33
37
|
}
|
@@ -35,40 +39,57 @@ static BROTLI_INLINE uint32_t BitMask(uint32_t n) {
|
|
35
39
|
|
36
40
|
typedef struct {
|
37
41
|
brotli_reg_t val_; /* pre-fetched bits */
|
38
|
-
|
42
|
+
brotli_reg_t bit_pos_; /* current bit-reading position in val_ */
|
39
43
|
const uint8_t* next_in; /* the byte we're reading from */
|
40
|
-
|
44
|
+
const uint8_t* guard_in; /* position from which "fast-path" is prohibited */
|
45
|
+
const uint8_t* last_in; /* == next_in + avail_in */
|
41
46
|
} BrotliBitReader;
|
42
47
|
|
43
48
|
typedef struct {
|
44
49
|
brotli_reg_t val_;
|
45
|
-
|
50
|
+
brotli_reg_t bit_pos_;
|
46
51
|
const uint8_t* next_in;
|
47
52
|
size_t avail_in;
|
48
53
|
} BrotliBitReaderState;
|
49
54
|
|
50
55
|
/* Initializes the BrotliBitReader fields. */
|
51
|
-
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader*
|
56
|
+
BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* br);
|
52
57
|
|
53
58
|
/* Ensures that accumulator is not empty.
|
54
59
|
May consume up to sizeof(brotli_reg_t) - 1 bytes of input.
|
55
60
|
Returns BROTLI_FALSE if data is required but there is no input available.
|
56
|
-
For
|
57
|
-
reading. */
|
58
|
-
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader*
|
61
|
+
For !BROTLI_UNALIGNED_READ_FAST this function also prepares bit reader for
|
62
|
+
aligned reading. */
|
63
|
+
BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* br);
|
59
64
|
|
60
65
|
/* Fallback for BrotliSafeReadBits32. Extracted as noninlined method to unburden
|
61
66
|
the main code-path. Never called for RFC brotli streams, required only for
|
62
67
|
"large-window" mode and other extensions. */
|
63
68
|
BROTLI_INTERNAL BROTLI_NOINLINE BROTLI_BOOL BrotliSafeReadBits32Slow(
|
64
|
-
BrotliBitReader*
|
69
|
+
BrotliBitReader* br, brotli_reg_t n_bits, brotli_reg_t* val);
|
70
|
+
|
71
|
+
static BROTLI_INLINE size_t
|
72
|
+
BrotliBitReaderGetAvailIn(BrotliBitReader* const br) {
|
73
|
+
return (size_t)(br->last_in - br->next_in);
|
74
|
+
}
|
65
75
|
|
66
76
|
static BROTLI_INLINE void BrotliBitReaderSaveState(
|
67
77
|
BrotliBitReader* const from, BrotliBitReaderState* to) {
|
68
78
|
to->val_ = from->val_;
|
69
79
|
to->bit_pos_ = from->bit_pos_;
|
70
80
|
to->next_in = from->next_in;
|
71
|
-
to->avail_in = from
|
81
|
+
to->avail_in = BrotliBitReaderGetAvailIn(from);
|
82
|
+
}
|
83
|
+
|
84
|
+
static BROTLI_INLINE void BrotliBitReaderSetInput(
|
85
|
+
BrotliBitReader* const br, const uint8_t* next_in, size_t avail_in) {
|
86
|
+
br->next_in = next_in;
|
87
|
+
br->last_in = (avail_in == 0) ? next_in : (next_in + avail_in);
|
88
|
+
if (avail_in + 1 > BROTLI_FAST_INPUT_SLACK) {
|
89
|
+
br->guard_in = next_in + (avail_in + 1 - BROTLI_FAST_INPUT_SLACK);
|
90
|
+
} else {
|
91
|
+
br->guard_in = next_in;
|
92
|
+
}
|
72
93
|
}
|
73
94
|
|
74
95
|
static BROTLI_INLINE void BrotliBitReaderRestoreState(
|
@@ -76,12 +97,12 @@ static BROTLI_INLINE void BrotliBitReaderRestoreState(
|
|
76
97
|
to->val_ = from->val_;
|
77
98
|
to->bit_pos_ = from->bit_pos_;
|
78
99
|
to->next_in = from->next_in;
|
79
|
-
to->
|
100
|
+
BrotliBitReaderSetInput(to, from->next_in, from->avail_in);
|
80
101
|
}
|
81
102
|
|
82
|
-
static BROTLI_INLINE
|
103
|
+
static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
|
83
104
|
const BrotliBitReader* br) {
|
84
|
-
return
|
105
|
+
return br->bit_pos_;
|
85
106
|
}
|
86
107
|
|
87
108
|
/* Returns amount of unread bytes the bit reader still has buffered from the
|
@@ -89,15 +110,27 @@ static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
|
|
89
110
|
maximal ring-buffer size (larger number won't be utilized anyway). */
|
90
111
|
static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {
|
91
112
|
static const size_t kCap = (size_t)1 << BROTLI_LARGE_MAX_WBITS;
|
92
|
-
|
93
|
-
|
113
|
+
size_t avail_in = BrotliBitReaderGetAvailIn(br);
|
114
|
+
if (avail_in > kCap) return kCap;
|
115
|
+
return avail_in + (BrotliGetAvailableBits(br) >> 3);
|
94
116
|
}
|
95
117
|
|
96
118
|
/* Checks if there is at least |num| bytes left in the input ring-buffer
|
97
119
|
(excluding the bits remaining in br->val_). */
|
98
120
|
static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
99
|
-
BrotliBitReader* const br
|
100
|
-
return TO_BROTLI_BOOL(br->
|
121
|
+
BrotliBitReader* const br) {
|
122
|
+
return TO_BROTLI_BOOL(br->next_in < br->guard_in);
|
123
|
+
}
|
124
|
+
|
125
|
+
/* Load more bits into accumulator. */
|
126
|
+
static BROTLI_INLINE brotli_reg_t BrotliBitReaderLoadBits(brotli_reg_t val,
|
127
|
+
brotli_reg_t new_bits,
|
128
|
+
brotli_reg_t count,
|
129
|
+
brotli_reg_t offset) {
|
130
|
+
BROTLI_DCHECK(
|
131
|
+
!((val >> offset) & ~new_bits & ~(~((brotli_reg_t)0) << count)));
|
132
|
+
(void)count;
|
133
|
+
return val | (new_bits << offset);
|
101
134
|
}
|
102
135
|
|
103
136
|
/* Guarantees that there are at least |n_bits| + 1 bits in accumulator.
|
@@ -105,49 +138,51 @@ static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(
|
|
105
138
|
|n_bits| should be in the range [1..24] for regular build. For portable
|
106
139
|
non-64-bit little-endian build only 16 bits are safe to request. */
|
107
140
|
static BROTLI_INLINE void BrotliFillBitWindow(
|
108
|
-
BrotliBitReader* const br,
|
141
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
109
142
|
#if (BROTLI_64_BITS)
|
110
|
-
if (
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
br->val_
|
115
|
-
|
143
|
+
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
144
|
+
(n_bits <= 8)) {
|
145
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
146
|
+
if (bit_pos <= 8) {
|
147
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
148
|
+
BROTLI_UNALIGNED_LOAD64LE(br->next_in), 56, bit_pos);
|
149
|
+
br->bit_pos_ = bit_pos + 56;
|
116
150
|
br->next_in += 7;
|
117
151
|
}
|
118
|
-
} else if (
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
br->
|
123
|
-
|
124
|
-
br->
|
152
|
+
} else if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
153
|
+
(n_bits <= 16)) {
|
154
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
155
|
+
if (bit_pos <= 16) {
|
156
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
157
|
+
BROTLI_UNALIGNED_LOAD64LE(br->next_in), 48, bit_pos);
|
158
|
+
br->bit_pos_ = bit_pos + 48;
|
125
159
|
br->next_in += 6;
|
126
160
|
}
|
127
161
|
} else {
|
128
|
-
|
129
|
-
|
130
|
-
br->
|
131
|
-
|
132
|
-
br->
|
162
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
163
|
+
if (bit_pos <= 32) {
|
164
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
165
|
+
(uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in), 32, bit_pos);
|
166
|
+
br->bit_pos_ = bit_pos + 32;
|
133
167
|
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
134
168
|
}
|
135
169
|
}
|
136
170
|
#else
|
137
|
-
if (
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
br->val_
|
142
|
-
|
171
|
+
if (BROTLI_UNALIGNED_READ_FAST && BROTLI_IS_CONSTANT(n_bits) &&
|
172
|
+
(n_bits <= 8)) {
|
173
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
174
|
+
if (bit_pos <= 8) {
|
175
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
176
|
+
BROTLI_UNALIGNED_LOAD32LE(br->next_in), 24, bit_pos);
|
177
|
+
br->bit_pos_ = bit_pos + 24;
|
143
178
|
br->next_in += 3;
|
144
179
|
}
|
145
180
|
} else {
|
146
|
-
|
147
|
-
|
148
|
-
br->
|
149
|
-
|
150
|
-
br->
|
181
|
+
brotli_reg_t bit_pos = br->bit_pos_;
|
182
|
+
if (bit_pos <= 16) {
|
183
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
184
|
+
(uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in), 16, bit_pos);
|
185
|
+
br->bit_pos_ = bit_pos + 16;
|
151
186
|
br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;
|
152
187
|
}
|
153
188
|
}
|
@@ -163,17 +198,12 @@ static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {
|
|
163
198
|
/* Tries to pull one byte of input to accumulator.
|
164
199
|
Returns BROTLI_FALSE if there is no input available. */
|
165
200
|
static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
166
|
-
if (br->
|
201
|
+
if (br->next_in == br->last_in) {
|
167
202
|
return BROTLI_FALSE;
|
168
203
|
}
|
169
|
-
br->val_
|
170
|
-
|
171
|
-
br->
|
172
|
-
#else
|
173
|
-
br->val_ |= ((uint32_t)*br->next_in) << 24;
|
174
|
-
#endif
|
175
|
-
br->bit_pos_ -= 8;
|
176
|
-
--br->avail_in;
|
204
|
+
br->val_ = BrotliBitReaderLoadBits(br->val_,
|
205
|
+
(brotli_reg_t)*br->next_in, 8, br->bit_pos_);
|
206
|
+
br->bit_pos_ += 8;
|
177
207
|
++br->next_in;
|
178
208
|
return BROTLI_TRUE;
|
179
209
|
}
|
@@ -182,81 +212,90 @@ static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {
|
|
182
212
|
The number of valid bits could be calculated by BrotliGetAvailableBits. */
|
183
213
|
static BROTLI_INLINE brotli_reg_t BrotliGetBitsUnmasked(
|
184
214
|
BrotliBitReader* const br) {
|
185
|
-
return br->val_
|
215
|
+
return br->val_;
|
186
216
|
}
|
187
217
|
|
188
218
|
/* Like BrotliGetBits, but does not mask the result.
|
189
219
|
The result contains at least 16 valid bits. */
|
190
|
-
static BROTLI_INLINE
|
220
|
+
static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
|
191
221
|
BrotliBitReader* const br) {
|
192
222
|
BrotliFillBitWindow(br, 16);
|
193
|
-
return (
|
223
|
+
return (brotli_reg_t)BrotliGetBitsUnmasked(br);
|
194
224
|
}
|
195
225
|
|
196
226
|
/* Returns the specified number of bits from |br| without advancing bit
|
197
227
|
position. */
|
198
|
-
static BROTLI_INLINE
|
199
|
-
BrotliBitReader* const br,
|
228
|
+
static BROTLI_INLINE brotli_reg_t BrotliGetBits(
|
229
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
200
230
|
BrotliFillBitWindow(br, n_bits);
|
201
|
-
return
|
231
|
+
return BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
202
232
|
}
|
203
233
|
|
204
234
|
/* Tries to peek the specified amount of bits. Returns BROTLI_FALSE, if there
|
205
235
|
is not enough input. */
|
206
236
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(
|
207
|
-
BrotliBitReader* const br,
|
237
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
208
238
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
209
239
|
if (!BrotliPullByte(br)) {
|
210
240
|
return BROTLI_FALSE;
|
211
241
|
}
|
212
242
|
}
|
213
|
-
*val =
|
243
|
+
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
214
244
|
return BROTLI_TRUE;
|
215
245
|
}
|
216
246
|
|
217
247
|
/* Advances the bit pos by |n_bits|. */
|
218
248
|
static BROTLI_INLINE void BrotliDropBits(
|
219
|
-
BrotliBitReader* const br,
|
220
|
-
br->bit_pos_
|
249
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
250
|
+
br->bit_pos_ -= n_bits;
|
251
|
+
br->val_ >>= n_bits;
|
221
252
|
}
|
222
253
|
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
br->
|
228
|
-
if (
|
229
|
-
br->val_
|
230
|
-
} else {
|
231
|
-
br->val_ <<= unused_bits;
|
254
|
+
/* Make sure that there are no spectre bits in accumulator.
|
255
|
+
This is important for the cases when some bytes are skipped
|
256
|
+
(i.e. never placed into accumulator). */
|
257
|
+
static BROTLI_INLINE void BrotliBitReaderNormalize(BrotliBitReader* br) {
|
258
|
+
/* Actually, it is enough to normalize when br->bit_pos_ == 0 */
|
259
|
+
if (br->bit_pos_ < (sizeof(brotli_reg_t) << 3u)) {
|
260
|
+
br->val_ &= (((brotli_reg_t)1) << br->bit_pos_) - 1;
|
232
261
|
}
|
233
|
-
|
262
|
+
}
|
263
|
+
|
264
|
+
static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
|
265
|
+
brotli_reg_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
|
266
|
+
brotli_reg_t unused_bits = unused_bytes << 3;
|
267
|
+
br->next_in =
|
268
|
+
(unused_bytes == 0) ? br->next_in : (br->next_in - unused_bytes);
|
269
|
+
br->bit_pos_ -= unused_bits;
|
270
|
+
BrotliBitReaderNormalize(br);
|
234
271
|
}
|
235
272
|
|
236
273
|
/* Reads the specified number of bits from |br| and advances the bit pos.
|
237
274
|
Precondition: accumulator MUST contain at least |n_bits|. */
|
238
|
-
static BROTLI_INLINE void BrotliTakeBits(
|
239
|
-
|
240
|
-
|
275
|
+
static BROTLI_INLINE void BrotliTakeBits(BrotliBitReader* const br,
|
276
|
+
brotli_reg_t n_bits,
|
277
|
+
brotli_reg_t* val) {
|
278
|
+
*val = BrotliGetBitsUnmasked(br) & BitMask(n_bits);
|
241
279
|
BROTLI_LOG(("[BrotliTakeBits] %d %d %d val: %6x\n",
|
242
|
-
|
280
|
+
(int)BrotliBitReaderGetAvailIn(br), (int)br->bit_pos_,
|
281
|
+
(int)n_bits, (int)*val));
|
243
282
|
BrotliDropBits(br, n_bits);
|
244
283
|
}
|
245
284
|
|
246
285
|
/* Reads the specified number of bits from |br| and advances the bit pos.
|
247
286
|
Assumes that there is enough input to perform BrotliFillBitWindow.
|
248
287
|
Up to 24 bits are allowed to be requested from this method. */
|
249
|
-
static BROTLI_INLINE
|
250
|
-
BrotliBitReader* const br,
|
288
|
+
static BROTLI_INLINE brotli_reg_t BrotliReadBits24(
|
289
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
251
290
|
BROTLI_DCHECK(n_bits <= 24);
|
252
291
|
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
253
|
-
|
292
|
+
brotli_reg_t val;
|
254
293
|
BrotliFillBitWindow(br, n_bits);
|
255
294
|
BrotliTakeBits(br, n_bits, &val);
|
256
295
|
return val;
|
257
296
|
} else {
|
258
|
-
|
259
|
-
|
297
|
+
brotli_reg_t low_val;
|
298
|
+
brotli_reg_t high_val;
|
260
299
|
BrotliFillBitWindow(br, 16);
|
261
300
|
BrotliTakeBits(br, 16, &low_val);
|
262
301
|
BrotliFillBitWindow(br, 8);
|
@@ -266,17 +305,17 @@ static BROTLI_INLINE uint32_t BrotliReadBits24(
|
|
266
305
|
}
|
267
306
|
|
268
307
|
/* Same as BrotliReadBits24, but allows reading up to 32 bits. */
|
269
|
-
static BROTLI_INLINE
|
270
|
-
BrotliBitReader* const br,
|
308
|
+
static BROTLI_INLINE brotli_reg_t BrotliReadBits32(
|
309
|
+
BrotliBitReader* const br, brotli_reg_t n_bits) {
|
271
310
|
BROTLI_DCHECK(n_bits <= 32);
|
272
311
|
if (BROTLI_64_BITS || (n_bits <= 16)) {
|
273
|
-
|
312
|
+
brotli_reg_t val;
|
274
313
|
BrotliFillBitWindow(br, n_bits);
|
275
314
|
BrotliTakeBits(br, n_bits, &val);
|
276
315
|
return val;
|
277
316
|
} else {
|
278
|
-
|
279
|
-
|
317
|
+
brotli_reg_t low_val;
|
318
|
+
brotli_reg_t high_val;
|
280
319
|
BrotliFillBitWindow(br, 16);
|
281
320
|
BrotliTakeBits(br, 16, &low_val);
|
282
321
|
BrotliFillBitWindow(br, 16);
|
@@ -289,7 +328,7 @@ static BROTLI_INLINE uint32_t BrotliReadBits32(
|
|
289
328
|
is not enough input. |n_bits| MUST be positive.
|
290
329
|
Up to 24 bits are allowed to be requested from this method. */
|
291
330
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
292
|
-
BrotliBitReader* const br,
|
331
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
293
332
|
BROTLI_DCHECK(n_bits <= 24);
|
294
333
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
295
334
|
if (!BrotliPullByte(br)) {
|
@@ -302,7 +341,7 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(
|
|
302
341
|
|
303
342
|
/* Same as BrotliSafeReadBits, but allows reading up to 32 bits. */
|
304
343
|
static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
305
|
-
BrotliBitReader* const br,
|
344
|
+
BrotliBitReader* const br, brotli_reg_t n_bits, brotli_reg_t* val) {
|
306
345
|
BROTLI_DCHECK(n_bits <= 32);
|
307
346
|
if (BROTLI_64_BITS || (n_bits <= 24)) {
|
308
347
|
while (BrotliGetAvailableBits(br) < n_bits) {
|
@@ -320,14 +359,22 @@ static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits32(
|
|
320
359
|
/* Advances the bit reader position to the next byte boundary and verifies
|
321
360
|
that any skipped bits are set to zero. */
|
322
361
|
static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {
|
323
|
-
|
324
|
-
|
362
|
+
brotli_reg_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
|
363
|
+
brotli_reg_t pad_bits = 0;
|
325
364
|
if (pad_bits_count != 0) {
|
326
365
|
BrotliTakeBits(br, pad_bits_count, &pad_bits);
|
327
366
|
}
|
367
|
+
BrotliBitReaderNormalize(br);
|
328
368
|
return TO_BROTLI_BOOL(pad_bits == 0);
|
329
369
|
}
|
330
370
|
|
371
|
+
static BROTLI_INLINE void BrotliDropBytes(BrotliBitReader* br, size_t num) {
|
372
|
+
/* Check detour is legal: accumulator must to be empty. */
|
373
|
+
BROTLI_DCHECK(br->bit_pos_ == 0);
|
374
|
+
BROTLI_DCHECK(br->val_ == 0);
|
375
|
+
br->next_in += num;
|
376
|
+
}
|
377
|
+
|
331
378
|
/* Copies remaining input bytes stored in the bit reader to the output. Value
|
332
379
|
|num| may not be larger than BrotliGetRemainingBytes. The bit reader must be
|
333
380
|
warmed up again after this. */
|
@@ -339,9 +386,34 @@ static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,
|
|
339
386
|
++dest;
|
340
387
|
--num;
|
341
388
|
}
|
342
|
-
|
343
|
-
|
344
|
-
|
389
|
+
BrotliBitReaderNormalize(br);
|
390
|
+
if (num > 0) {
|
391
|
+
memcpy(dest, br->next_in, num);
|
392
|
+
BrotliDropBytes(br, num);
|
393
|
+
}
|
394
|
+
}
|
395
|
+
|
396
|
+
BROTLI_UNUSED_FUNCTION void BrotliBitReaderSuppressUnusedFunctions(void) {
|
397
|
+
BROTLI_UNUSED(&BrotliBitReaderSuppressUnusedFunctions);
|
398
|
+
|
399
|
+
BROTLI_UNUSED(&BrotliBitReaderGetAvailIn);
|
400
|
+
BROTLI_UNUSED(&BrotliBitReaderLoadBits);
|
401
|
+
BROTLI_UNUSED(&BrotliBitReaderRestoreState);
|
402
|
+
BROTLI_UNUSED(&BrotliBitReaderSaveState);
|
403
|
+
BROTLI_UNUSED(&BrotliBitReaderSetInput);
|
404
|
+
BROTLI_UNUSED(&BrotliBitReaderUnload);
|
405
|
+
BROTLI_UNUSED(&BrotliCheckInputAmount);
|
406
|
+
BROTLI_UNUSED(&BrotliCopyBytes);
|
407
|
+
BROTLI_UNUSED(&BrotliFillBitWindow16);
|
408
|
+
BROTLI_UNUSED(&BrotliGet16BitsUnmasked);
|
409
|
+
BROTLI_UNUSED(&BrotliGetBits);
|
410
|
+
BROTLI_UNUSED(&BrotliGetRemainingBytes);
|
411
|
+
BROTLI_UNUSED(&BrotliJumpToByteBoundary);
|
412
|
+
BROTLI_UNUSED(&BrotliReadBits24);
|
413
|
+
BROTLI_UNUSED(&BrotliReadBits32);
|
414
|
+
BROTLI_UNUSED(&BrotliSafeGetBits);
|
415
|
+
BROTLI_UNUSED(&BrotliSafeReadBits);
|
416
|
+
BROTLI_UNUSED(&BrotliSafeReadBits32);
|
345
417
|
}
|
346
418
|
|
347
419
|
#if defined(__cplusplus) || defined(c_plusplus)
|