brotli 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (93) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/main.yml +6 -3
  3. data/.github/workflows/publish.yml +7 -17
  4. data/.gitmodules +1 -1
  5. data/README.md +2 -2
  6. data/ext/brotli/brotli.c +1 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +4 -1
  10. data/vendor/brotli/c/common/constants.c +1 -1
  11. data/vendor/brotli/c/common/constants.h +2 -1
  12. data/vendor/brotli/c/common/context.c +1 -1
  13. data/vendor/brotli/c/common/dictionary.c +5 -3
  14. data/vendor/brotli/c/common/platform.c +2 -1
  15. data/vendor/brotli/c/common/platform.h +60 -113
  16. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  17. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  18. data/vendor/brotli/c/common/transform.c +1 -1
  19. data/vendor/brotli/c/common/version.h +31 -6
  20. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  21. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  22. data/vendor/brotli/c/dec/decode.c +467 -200
  23. data/vendor/brotli/c/dec/huffman.c +7 -4
  24. data/vendor/brotli/c/dec/huffman.h +2 -1
  25. data/vendor/brotli/c/dec/prefix.h +2 -1
  26. data/vendor/brotli/c/dec/state.c +33 -9
  27. data/vendor/brotli/c/dec/state.h +70 -35
  28. data/vendor/brotli/c/enc/backward_references.c +81 -19
  29. data/vendor/brotli/c/enc/backward_references.h +5 -4
  30. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  31. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  32. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  33. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  34. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  35. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  36. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  37. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  38. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  39. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  40. data/vendor/brotli/c/enc/cluster.c +10 -9
  41. data/vendor/brotli/c/enc/cluster.h +7 -6
  42. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  43. data/vendor/brotli/c/enc/command.c +1 -1
  44. data/vendor/brotli/c/enc/command.h +5 -4
  45. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  46. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  47. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  48. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  49. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  51. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  52. data/vendor/brotli/c/enc/encode.c +473 -404
  53. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  54. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  55. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  56. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  57. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  58. data/vendor/brotli/c/enc/fast_log.c +1 -1
  59. data/vendor/brotli/c/enc/fast_log.h +2 -1
  60. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  61. data/vendor/brotli/c/enc/hash.h +285 -45
  62. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  63. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  64. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  65. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  66. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  67. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  69. data/vendor/brotli/c/enc/histogram.c +4 -4
  70. data/vendor/brotli/c/enc/histogram.h +7 -6
  71. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  72. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  73. data/vendor/brotli/c/enc/memory.c +29 -5
  74. data/vendor/brotli/c/enc/memory.h +19 -2
  75. data/vendor/brotli/c/enc/metablock.c +72 -58
  76. data/vendor/brotli/c/enc/metablock.h +9 -8
  77. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  78. data/vendor/brotli/c/enc/params.h +4 -3
  79. data/vendor/brotli/c/enc/prefix.h +3 -2
  80. data/vendor/brotli/c/enc/quality.h +40 -3
  81. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  82. data/vendor/brotli/c/enc/state.h +104 -0
  83. data/vendor/brotli/c/enc/static_dict.c +60 -4
  84. data/vendor/brotli/c/enc/static_dict.h +3 -2
  85. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  86. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  87. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  88. data/vendor/brotli/c/enc/write_bits.h +2 -1
  89. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  90. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  91. data/vendor/brotli/c/include/brotli/port.h +28 -11
  92. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  93. metadata +9 -3
@@ -6,16 +6,17 @@
6
6
 
7
7
  /* Bit reading helpers */
8
8
 
9
- #include "./bit_reader.h"
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 uint32_t kBrotliBitMask[33] = { 0x00000000,
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_ = sizeof(br->val_) << 3;
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 (!BROTLI_ALIGNED_READ) {
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
- uint32_t n_bits, uint32_t* val) {
59
- uint32_t low_val;
60
- uint32_t high_val;
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
- BROTLI_INTERNAL extern const uint32_t kBrotliBitMask[33];
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 uint32_t BitMask(uint32_t n) {
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 ~((0xFFFFFFFFu) << n);
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
- uint32_t bit_pos_; /* current bit-reading position in val_ */
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
- size_t avail_in;
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
- uint32_t bit_pos_;
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* const br);
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 BROTLI_ALIGNED_READ this function also prepares bit reader for aligned
57
- reading. */
58
- BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);
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* const br, uint32_t n_bits, uint32_t* val);
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->avail_in;
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->avail_in = from->avail_in;
100
+ BrotliBitReaderSetInput(to, from->next_in, from->avail_in);
80
101
  }
81
102
 
82
- static BROTLI_INLINE uint32_t BrotliGetAvailableBits(
103
+ static BROTLI_INLINE brotli_reg_t BrotliGetAvailableBits(
83
104
  const BrotliBitReader* br) {
84
- return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;
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
- if (br->avail_in > kCap) return kCap;
93
- return br->avail_in + (BrotliGetAvailableBits(br) >> 3);
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, size_t num) {
100
- return TO_BROTLI_BOOL(br->avail_in >= num);
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, uint32_t n_bits) {
141
+ BrotliBitReader* const br, brotli_reg_t n_bits) {
109
142
  #if (BROTLI_64_BITS)
110
- if (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
111
- if (br->bit_pos_ >= 56) {
112
- br->val_ >>= 56;
113
- br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */
114
- br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 8;
115
- br->avail_in -= 7;
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
- !BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 16)) {
120
- if (br->bit_pos_ >= 48) {
121
- br->val_ >>= 48;
122
- br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */
123
- br->val_ |= BROTLI_UNALIGNED_LOAD64LE(br->next_in) << 16;
124
- br->avail_in -= 6;
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
- if (br->bit_pos_ >= 32) {
129
- br->val_ >>= 32;
130
- br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */
131
- br->val_ |= ((uint64_t)BROTLI_UNALIGNED_LOAD32LE(br->next_in)) << 32;
132
- br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
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 (!BROTLI_ALIGNED_READ && BROTLI_IS_CONSTANT(n_bits) && (n_bits <= 8)) {
138
- if (br->bit_pos_ >= 24) {
139
- br->val_ >>= 24;
140
- br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */
141
- br->val_ |= BROTLI_UNALIGNED_LOAD32LE(br->next_in) << 8;
142
- br->avail_in -= 3;
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
- if (br->bit_pos_ >= 16) {
147
- br->val_ >>= 16;
148
- br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */
149
- br->val_ |= ((uint32_t)BROTLI_UNALIGNED_LOAD16LE(br->next_in)) << 16;
150
- br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;
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->avail_in == 0) {
201
+ if (br->next_in == br->last_in) {
167
202
  return BROTLI_FALSE;
168
203
  }
169
- br->val_ >>= 8;
170
- #if (BROTLI_64_BITS)
171
- br->val_ |= ((uint64_t)*br->next_in) << 56;
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_ >> br->bit_pos_;
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 uint32_t BrotliGet16BitsUnmasked(
220
+ static BROTLI_INLINE brotli_reg_t BrotliGet16BitsUnmasked(
191
221
  BrotliBitReader* const br) {
192
222
  BrotliFillBitWindow(br, 16);
193
- return (uint32_t)BrotliGetBitsUnmasked(br);
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 uint32_t BrotliGetBits(
199
- BrotliBitReader* const br, uint32_t n_bits) {
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 (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
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, uint32_t n_bits, uint32_t* val) {
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 = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
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, uint32_t n_bits) {
220
- br->bit_pos_ += n_bits;
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
- static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {
224
- uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;
225
- uint32_t unused_bits = unused_bytes << 3;
226
- br->avail_in += unused_bytes;
227
- br->next_in -= unused_bytes;
228
- if (unused_bits == sizeof(br->val_) << 3) {
229
- br->val_ = 0;
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
- br->bit_pos_ += unused_bits;
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
- BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {
240
- *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);
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
- (int)br->avail_in, (int)br->bit_pos_, (int)n_bits, (int)*val));
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 uint32_t BrotliReadBits24(
250
- BrotliBitReader* const br, uint32_t n_bits) {
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
- uint32_t val;
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
- uint32_t low_val;
259
- uint32_t high_val;
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 uint32_t BrotliReadBits32(
270
- BrotliBitReader* const br, uint32_t n_bits) {
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
- uint32_t val;
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
- uint32_t low_val;
279
- uint32_t high_val;
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, uint32_t n_bits, uint32_t* val) {
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, uint32_t n_bits, uint32_t* val) {
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
- uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;
324
- uint32_t pad_bits = 0;
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
- memcpy(dest, br->next_in, num);
343
- br->avail_in -= num;
344
- br->next_in += num;
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)