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.
Files changed (94) 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 +8 -0
  7. data/ext/brotli/extconf.rb +6 -0
  8. data/lib/brotli/version.rb +1 -1
  9. data/test/brotli_test.rb +14 -1
  10. data/test/test_helper.rb +1 -0
  11. data/vendor/brotli/c/common/constants.c +1 -1
  12. data/vendor/brotli/c/common/constants.h +2 -1
  13. data/vendor/brotli/c/common/context.c +1 -1
  14. data/vendor/brotli/c/common/dictionary.c +5 -3
  15. data/vendor/brotli/c/common/platform.c +2 -1
  16. data/vendor/brotli/c/common/platform.h +60 -113
  17. data/vendor/brotli/c/common/shared_dictionary.c +521 -0
  18. data/vendor/brotli/c/common/shared_dictionary_internal.h +75 -0
  19. data/vendor/brotli/c/common/transform.c +1 -1
  20. data/vendor/brotli/c/common/version.h +31 -6
  21. data/vendor/brotli/c/dec/bit_reader.c +10 -8
  22. data/vendor/brotli/c/dec/bit_reader.h +172 -100
  23. data/vendor/brotli/c/dec/decode.c +467 -200
  24. data/vendor/brotli/c/dec/huffman.c +7 -4
  25. data/vendor/brotli/c/dec/huffman.h +2 -1
  26. data/vendor/brotli/c/dec/prefix.h +2 -1
  27. data/vendor/brotli/c/dec/state.c +33 -9
  28. data/vendor/brotli/c/dec/state.h +70 -35
  29. data/vendor/brotli/c/enc/backward_references.c +81 -19
  30. data/vendor/brotli/c/enc/backward_references.h +5 -4
  31. data/vendor/brotli/c/enc/backward_references_hq.c +148 -52
  32. data/vendor/brotli/c/enc/backward_references_hq.h +6 -5
  33. data/vendor/brotli/c/enc/backward_references_inc.h +31 -5
  34. data/vendor/brotli/c/enc/bit_cost.c +8 -7
  35. data/vendor/brotli/c/enc/bit_cost.h +5 -4
  36. data/vendor/brotli/c/enc/block_splitter.c +37 -14
  37. data/vendor/brotli/c/enc/block_splitter.h +5 -4
  38. data/vendor/brotli/c/enc/block_splitter_inc.h +86 -45
  39. data/vendor/brotli/c/enc/brotli_bit_stream.c +132 -110
  40. data/vendor/brotli/c/enc/brotli_bit_stream.h +11 -6
  41. data/vendor/brotli/c/enc/cluster.c +10 -9
  42. data/vendor/brotli/c/enc/cluster.h +7 -6
  43. data/vendor/brotli/c/enc/cluster_inc.h +25 -20
  44. data/vendor/brotli/c/enc/command.c +1 -1
  45. data/vendor/brotli/c/enc/command.h +5 -4
  46. data/vendor/brotli/c/enc/compound_dictionary.c +207 -0
  47. data/vendor/brotli/c/enc/compound_dictionary.h +74 -0
  48. data/vendor/brotli/c/enc/compress_fragment.c +93 -83
  49. data/vendor/brotli/c/enc/compress_fragment.h +32 -7
  50. data/vendor/brotli/c/enc/compress_fragment_two_pass.c +99 -87
  51. data/vendor/brotli/c/enc/compress_fragment_two_pass.h +21 -3
  52. data/vendor/brotli/c/enc/dictionary_hash.c +3 -1
  53. data/vendor/brotli/c/enc/encode.c +473 -404
  54. data/vendor/brotli/c/enc/encoder_dict.c +611 -4
  55. data/vendor/brotli/c/enc/encoder_dict.h +117 -3
  56. data/vendor/brotli/c/enc/entropy_encode.c +3 -2
  57. data/vendor/brotli/c/enc/entropy_encode.h +2 -1
  58. data/vendor/brotli/c/enc/entropy_encode_static.h +5 -2
  59. data/vendor/brotli/c/enc/fast_log.c +1 -1
  60. data/vendor/brotli/c/enc/fast_log.h +2 -1
  61. data/vendor/brotli/c/enc/find_match_length.h +15 -22
  62. data/vendor/brotli/c/enc/hash.h +285 -45
  63. data/vendor/brotli/c/enc/hash_composite_inc.h +26 -11
  64. data/vendor/brotli/c/enc/hash_forgetful_chain_inc.h +20 -18
  65. data/vendor/brotli/c/enc/hash_longest_match64_inc.h +34 -39
  66. data/vendor/brotli/c/enc/hash_longest_match_inc.h +6 -10
  67. data/vendor/brotli/c/enc/hash_longest_match_quickly_inc.h +4 -4
  68. data/vendor/brotli/c/enc/hash_rolling_inc.h +4 -4
  69. data/vendor/brotli/c/enc/hash_to_binary_tree_inc.h +6 -5
  70. data/vendor/brotli/c/enc/histogram.c +4 -4
  71. data/vendor/brotli/c/enc/histogram.h +7 -6
  72. data/vendor/brotli/c/enc/literal_cost.c +20 -15
  73. data/vendor/brotli/c/enc/literal_cost.h +4 -2
  74. data/vendor/brotli/c/enc/memory.c +29 -5
  75. data/vendor/brotli/c/enc/memory.h +19 -2
  76. data/vendor/brotli/c/enc/metablock.c +72 -58
  77. data/vendor/brotli/c/enc/metablock.h +9 -8
  78. data/vendor/brotli/c/enc/metablock_inc.h +8 -6
  79. data/vendor/brotli/c/enc/params.h +4 -3
  80. data/vendor/brotli/c/enc/prefix.h +3 -2
  81. data/vendor/brotli/c/enc/quality.h +40 -3
  82. data/vendor/brotli/c/enc/ringbuffer.h +4 -3
  83. data/vendor/brotli/c/enc/state.h +104 -0
  84. data/vendor/brotli/c/enc/static_dict.c +60 -4
  85. data/vendor/brotli/c/enc/static_dict.h +3 -2
  86. data/vendor/brotli/c/enc/static_dict_lut.h +2 -0
  87. data/vendor/brotli/c/enc/utf8_util.c +1 -1
  88. data/vendor/brotli/c/enc/utf8_util.h +2 -1
  89. data/vendor/brotli/c/enc/write_bits.h +2 -1
  90. data/vendor/brotli/c/include/brotli/decode.h +67 -2
  91. data/vendor/brotli/c/include/brotli/encode.h +55 -2
  92. data/vendor/brotli/c/include/brotli/port.h +28 -11
  93. data/vendor/brotli/c/include/brotli/shared_dictionary.h +100 -0
  94. 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)