brotli 0.4.0 → 0.6.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 +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 +8 -0
- data/ext/brotli/extconf.rb +6 -0
- data/lib/brotli/version.rb +1 -1
- data/test/brotli_test.rb +14 -1
- data/test/test_helper.rb +1 -0
- 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)
|