]>
Commit | Line | Data |
---|---|---|
36ff6d80 SB |
1 | /* Copyright 2013 Google Inc. All Rights Reserved.\r |
2 | \r | |
3 | Distributed under MIT license.\r | |
4 | See file LICENSE for detail or copy at https://opensource.org/licenses/MIT\r | |
5 | */\r | |
6 | \r | |
7 | /* Bit reading helpers */\r | |
8 | \r | |
9 | #ifndef BROTLI_DEC_BIT_READER_H_\r | |
10 | #define BROTLI_DEC_BIT_READER_H_\r | |
11 | \r | |
12 | #include <string.h> /* memcpy */\r | |
13 | \r | |
14 | #include "../common/types.h"\r | |
15 | #include "./port.h"\r | |
16 | \r | |
17 | #if defined(__cplusplus) || defined(c_plusplus)\r | |
18 | extern "C" {\r | |
19 | #endif\r | |
20 | \r | |
21 | #if (BROTLI_64_BITS)\r | |
22 | #define BROTLI_SHORT_FILL_BIT_WINDOW_READ 4\r | |
23 | typedef uint64_t reg_t;\r | |
24 | #else\r | |
25 | #define BROTLI_SHORT_FILL_BIT_WINDOW_READ 2\r | |
26 | typedef uint32_t reg_t;\r | |
27 | #endif\r | |
28 | \r | |
29 | static const uint32_t kBitMask[33] = { 0x0000,\r | |
30 | 0x00000001, 0x00000003, 0x00000007, 0x0000000F,\r | |
31 | 0x0000001F, 0x0000003F, 0x0000007F, 0x000000FF,\r | |
32 | 0x000001FF, 0x000003FF, 0x000007FF, 0x00000FFF,\r | |
33 | 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF,\r | |
34 | 0x0001FFFF, 0x0003FFFF, 0x0007FFFF, 0x000FFFFF,\r | |
35 | 0x001FFFFF, 0x003FFFFF, 0x007FFFFF, 0x00FFFFFF,\r | |
36 | 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF,\r | |
37 | 0x1FFFFFFF, 0x3FFFFFFF, 0x7FFFFFFF, 0xFFFFFFFF\r | |
38 | };\r | |
39 | \r | |
40 | static BROTLI_INLINE uint32_t BitMask(uint32_t n) {\r | |
41 | if (IS_CONSTANT(n) || BROTLI_HAS_UBFX) {\r | |
42 | /* Masking with this expression turns to a single\r | |
43 | "Unsigned Bit Field Extract" UBFX instruction on ARM. */\r | |
44 | return ~((0xffffffffU) << n);\r | |
45 | } else {\r | |
46 | return kBitMask[n];\r | |
47 | }\r | |
48 | }\r | |
49 | \r | |
50 | typedef struct {\r | |
51 | reg_t val_; /* pre-fetched bits */\r | |
52 | uint32_t bit_pos_; /* current bit-reading position in val_ */\r | |
53 | const uint8_t* next_in; /* the byte we're reading from */\r | |
54 | size_t avail_in;\r | |
55 | } BrotliBitReader;\r | |
56 | \r | |
57 | typedef struct {\r | |
58 | reg_t val_;\r | |
59 | uint32_t bit_pos_;\r | |
60 | const uint8_t* next_in;\r | |
61 | size_t avail_in;\r | |
62 | } BrotliBitReaderState;\r | |
63 | \r | |
64 | /* Initializes the bitreader fields. */\r | |
65 | BROTLI_INTERNAL void BrotliInitBitReader(BrotliBitReader* const br);\r | |
66 | \r | |
67 | /* Ensures that accumulator is not empty. May consume one byte of input.\r | |
68 | Returns 0 if data is required but there is no input available.\r | |
69 | For BROTLI_ALIGNED_READ this function also prepares bit reader for aligned\r | |
70 | reading. */\r | |
71 | BROTLI_INTERNAL BROTLI_BOOL BrotliWarmupBitReader(BrotliBitReader* const br);\r | |
72 | \r | |
73 | static BROTLI_INLINE void BrotliBitReaderSaveState(\r | |
74 | BrotliBitReader* const from, BrotliBitReaderState* to) {\r | |
75 | to->val_ = from->val_;\r | |
76 | to->bit_pos_ = from->bit_pos_;\r | |
77 | to->next_in = from->next_in;\r | |
78 | to->avail_in = from->avail_in;\r | |
79 | }\r | |
80 | \r | |
81 | static BROTLI_INLINE void BrotliBitReaderRestoreState(\r | |
82 | BrotliBitReader* const to, BrotliBitReaderState* from) {\r | |
83 | to->val_ = from->val_;\r | |
84 | to->bit_pos_ = from->bit_pos_;\r | |
85 | to->next_in = from->next_in;\r | |
86 | to->avail_in = from->avail_in;\r | |
87 | }\r | |
88 | \r | |
89 | static BROTLI_INLINE uint32_t BrotliGetAvailableBits(\r | |
90 | const BrotliBitReader* br) {\r | |
91 | return (BROTLI_64_BITS ? 64 : 32) - br->bit_pos_;\r | |
92 | }\r | |
93 | \r | |
94 | /* Returns amount of unread bytes the bit reader still has buffered from the\r | |
95 | BrotliInput, including whole bytes in br->val_. */\r | |
96 | static BROTLI_INLINE size_t BrotliGetRemainingBytes(BrotliBitReader* br) {\r | |
97 | return br->avail_in + (BrotliGetAvailableBits(br) >> 3);\r | |
98 | }\r | |
99 | \r | |
100 | /* Checks if there is at least num bytes left in the input ringbuffer (excluding\r | |
101 | the bits remaining in br->val_). */\r | |
102 | static BROTLI_INLINE BROTLI_BOOL BrotliCheckInputAmount(\r | |
103 | BrotliBitReader* const br, size_t num) {\r | |
104 | return TO_BROTLI_BOOL(br->avail_in >= num);\r | |
105 | }\r | |
106 | \r | |
107 | static BROTLI_INLINE uint16_t BrotliLoad16LE(const uint8_t* in) {\r | |
108 | if (BROTLI_LITTLE_ENDIAN) {\r | |
109 | return *((const uint16_t*)in);\r | |
110 | } else if (BROTLI_BIG_ENDIAN) {\r | |
111 | uint16_t value = *((const uint16_t*)in);\r | |
112 | return (uint16_t)(((value & 0xFFU) << 8) | ((value & 0xFF00U) >> 8));\r | |
113 | } else {\r | |
114 | return (uint16_t)(in[0] | (in[1] << 8));\r | |
115 | }\r | |
116 | }\r | |
117 | \r | |
118 | static BROTLI_INLINE uint32_t BrotliLoad32LE(const uint8_t* in) {\r | |
119 | if (BROTLI_LITTLE_ENDIAN) {\r | |
120 | return *((const uint32_t*)in);\r | |
121 | } else if (BROTLI_BIG_ENDIAN) {\r | |
122 | uint32_t value = *((const uint32_t*)in);\r | |
123 | return ((value & 0xFFU) << 24) | ((value & 0xFF00U) << 8) |\r | |
124 | ((value & 0xFF0000U) >> 8) | ((value & 0xFF000000U) >> 24);\r | |
125 | } else {\r | |
126 | uint32_t value = (uint32_t)(*(in++));\r | |
127 | value |= (uint32_t)(*(in++)) << 8;\r | |
128 | value |= (uint32_t)(*(in++)) << 16;\r | |
129 | value |= (uint32_t)(*(in++)) << 24;\r | |
130 | return value;\r | |
131 | }\r | |
132 | }\r | |
133 | \r | |
134 | #if (BROTLI_64_BITS)\r | |
135 | static BROTLI_INLINE uint64_t BrotliLoad64LE(const uint8_t* in) {\r | |
136 | if (BROTLI_LITTLE_ENDIAN) {\r | |
137 | return *((const uint64_t*)in);\r | |
138 | } else if (BROTLI_BIG_ENDIAN) {\r | |
139 | uint64_t value = *((const uint64_t*)in);\r | |
140 | return\r | |
141 | ((value & 0xFFU) << 56) |\r | |
142 | ((value & 0xFF00U) << 40) |\r | |
143 | ((value & 0xFF0000U) << 24) |\r | |
144 | ((value & 0xFF000000U) << 8) |\r | |
145 | ((value & 0xFF00000000U) >> 8) |\r | |
146 | ((value & 0xFF0000000000U) >> 24) |\r | |
147 | ((value & 0xFF000000000000U) >> 40) |\r | |
148 | ((value & 0xFF00000000000000U) >> 56);\r | |
149 | } else {\r | |
150 | uint64_t value = (uint64_t)(*(in++));\r | |
151 | value |= (uint64_t)(*(in++)) << 8;\r | |
152 | value |= (uint64_t)(*(in++)) << 16;\r | |
153 | value |= (uint64_t)(*(in++)) << 24;\r | |
154 | value |= (uint64_t)(*(in++)) << 32;\r | |
155 | value |= (uint64_t)(*(in++)) << 40;\r | |
156 | value |= (uint64_t)(*(in++)) << 48;\r | |
157 | value |= (uint64_t)(*(in++)) << 56;\r | |
158 | return value;\r | |
159 | }\r | |
160 | }\r | |
161 | #endif\r | |
162 | \r | |
163 | /* Guarantees that there are at least n_bits + 1 bits in accumulator.\r | |
164 | Precondition: accumulator contains at least 1 bit.\r | |
165 | n_bits should be in the range [1..24] for regular build. For portable\r | |
166 | non-64-bit little endian build only 16 bits are safe to request. */\r | |
167 | static BROTLI_INLINE void BrotliFillBitWindow(\r | |
168 | BrotliBitReader* const br, uint32_t n_bits) {\r | |
169 | #if (BROTLI_64_BITS)\r | |
170 | if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {\r | |
171 | if (br->bit_pos_ >= 56) {\r | |
172 | br->val_ >>= 56;\r | |
173 | br->bit_pos_ ^= 56; /* here same as -= 56 because of the if condition */\r | |
174 | br->val_ |= BrotliLoad64LE(br->next_in) << 8;\r | |
175 | br->avail_in -= 7;\r | |
176 | br->next_in += 7;\r | |
177 | }\r | |
178 | } else if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 16)) {\r | |
179 | if (br->bit_pos_ >= 48) {\r | |
180 | br->val_ >>= 48;\r | |
181 | br->bit_pos_ ^= 48; /* here same as -= 48 because of the if condition */\r | |
182 | br->val_ |= BrotliLoad64LE(br->next_in) << 16;\r | |
183 | br->avail_in -= 6;\r | |
184 | br->next_in += 6;\r | |
185 | }\r | |
186 | } else {\r | |
187 | if (br->bit_pos_ >= 32) {\r | |
188 | br->val_ >>= 32;\r | |
189 | br->bit_pos_ ^= 32; /* here same as -= 32 because of the if condition */\r | |
190 | br->val_ |= ((uint64_t)BrotliLoad32LE(br->next_in)) << 32;\r | |
191 | br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;\r | |
192 | br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;\r | |
193 | }\r | |
194 | }\r | |
195 | #else\r | |
196 | if (!BROTLI_ALIGNED_READ && IS_CONSTANT(n_bits) && (n_bits <= 8)) {\r | |
197 | if (br->bit_pos_ >= 24) {\r | |
198 | br->val_ >>= 24;\r | |
199 | br->bit_pos_ ^= 24; /* here same as -= 24 because of the if condition */\r | |
200 | br->val_ |= BrotliLoad32LE(br->next_in) << 8;\r | |
201 | br->avail_in -= 3;\r | |
202 | br->next_in += 3;\r | |
203 | }\r | |
204 | } else {\r | |
205 | if (br->bit_pos_ >= 16) {\r | |
206 | br->val_ >>= 16;\r | |
207 | br->bit_pos_ ^= 16; /* here same as -= 16 because of the if condition */\r | |
208 | br->val_ |= ((uint32_t)BrotliLoad16LE(br->next_in)) << 16;\r | |
209 | br->avail_in -= BROTLI_SHORT_FILL_BIT_WINDOW_READ;\r | |
210 | br->next_in += BROTLI_SHORT_FILL_BIT_WINDOW_READ;\r | |
211 | }\r | |
212 | }\r | |
213 | #endif\r | |
214 | }\r | |
215 | \r | |
216 | /* Mosltly like BrotliFillBitWindow, but guarantees only 16 bits and reads no\r | |
217 | more than BROTLI_SHORT_FILL_BIT_WINDOW_READ bytes of input. */\r | |
218 | static BROTLI_INLINE void BrotliFillBitWindow16(BrotliBitReader* const br) {\r | |
219 | BrotliFillBitWindow(br, 17);\r | |
220 | }\r | |
221 | \r | |
222 | /* Pulls one byte of input to accumulator. */\r | |
223 | static BROTLI_INLINE BROTLI_BOOL BrotliPullByte(BrotliBitReader* const br) {\r | |
224 | if (br->avail_in == 0) {\r | |
225 | return BROTLI_FALSE;\r | |
226 | }\r | |
227 | br->val_ >>= 8;\r | |
228 | #if (BROTLI_64_BITS)\r | |
229 | br->val_ |= ((uint64_t)*br->next_in) << 56;\r | |
230 | #else\r | |
231 | br->val_ |= ((uint32_t)*br->next_in) << 24;\r | |
232 | #endif\r | |
233 | br->bit_pos_ -= 8;\r | |
234 | --br->avail_in;\r | |
235 | ++br->next_in;\r | |
236 | return BROTLI_TRUE;\r | |
237 | }\r | |
238 | \r | |
239 | /* Returns currently available bits.\r | |
240 | The number of valid bits could be calclulated by BrotliGetAvailableBits. */\r | |
241 | static BROTLI_INLINE reg_t BrotliGetBitsUnmasked(BrotliBitReader* const br) {\r | |
242 | return br->val_ >> br->bit_pos_;\r | |
243 | }\r | |
244 | \r | |
245 | /* Like BrotliGetBits, but does not mask the result.\r | |
246 | The result contains at least 16 valid bits. */\r | |
247 | static BROTLI_INLINE uint32_t BrotliGet16BitsUnmasked(\r | |
248 | BrotliBitReader* const br) {\r | |
249 | BrotliFillBitWindow(br, 16);\r | |
250 | return (uint32_t)BrotliGetBitsUnmasked(br);\r | |
251 | }\r | |
252 | \r | |
253 | /* Returns the specified number of bits from br without advancing bit pos. */\r | |
254 | static BROTLI_INLINE uint32_t BrotliGetBits(\r | |
255 | BrotliBitReader* const br, uint32_t n_bits) {\r | |
256 | BrotliFillBitWindow(br, n_bits);\r | |
257 | return (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);\r | |
258 | }\r | |
259 | \r | |
260 | /* Tries to peek the specified amount of bits. Returns 0, if there is not\r | |
261 | enough input. */\r | |
262 | static BROTLI_INLINE BROTLI_BOOL BrotliSafeGetBits(\r | |
263 | BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {\r | |
264 | while (BrotliGetAvailableBits(br) < n_bits) {\r | |
265 | if (!BrotliPullByte(br)) {\r | |
266 | return BROTLI_FALSE;\r | |
267 | }\r | |
268 | }\r | |
269 | *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);\r | |
270 | return BROTLI_TRUE;\r | |
271 | }\r | |
272 | \r | |
273 | /* Advances the bit pos by n_bits. */\r | |
274 | static BROTLI_INLINE void BrotliDropBits(\r | |
275 | BrotliBitReader* const br, uint32_t n_bits) {\r | |
276 | br->bit_pos_ += n_bits;\r | |
277 | }\r | |
278 | \r | |
279 | static BROTLI_INLINE void BrotliBitReaderUnload(BrotliBitReader* br) {\r | |
280 | uint32_t unused_bytes = BrotliGetAvailableBits(br) >> 3;\r | |
281 | uint32_t unused_bits = unused_bytes << 3;\r | |
282 | br->avail_in += unused_bytes;\r | |
283 | br->next_in -= unused_bytes;\r | |
284 | if (unused_bits == sizeof(br->val_) << 3) {\r | |
285 | br->val_ = 0;\r | |
286 | } else {\r | |
287 | br->val_ <<= unused_bits;\r | |
288 | }\r | |
289 | br->bit_pos_ += unused_bits;\r | |
290 | }\r | |
291 | \r | |
292 | /* Reads the specified number of bits from br and advances the bit pos.\r | |
293 | Precondition: accumulator MUST contain at least n_bits. */\r | |
294 | static BROTLI_INLINE void BrotliTakeBits(\r | |
295 | BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {\r | |
296 | *val = (uint32_t)BrotliGetBitsUnmasked(br) & BitMask(n_bits);\r | |
297 | BROTLI_LOG(("[BrotliReadBits] %d %d %d val: %6x\n",\r | |
298 | (int)br->avail_in, (int)br->bit_pos_, n_bits, (int)*val));\r | |
299 | BrotliDropBits(br, n_bits);\r | |
300 | }\r | |
301 | \r | |
302 | /* Reads the specified number of bits from br and advances the bit pos.\r | |
303 | Assumes that there is enough input to perform BrotliFillBitWindow. */\r | |
304 | static BROTLI_INLINE uint32_t BrotliReadBits(\r | |
305 | BrotliBitReader* const br, uint32_t n_bits) {\r | |
306 | if (BROTLI_64_BITS || (n_bits <= 16)) {\r | |
307 | uint32_t val;\r | |
308 | BrotliFillBitWindow(br, n_bits);\r | |
309 | BrotliTakeBits(br, n_bits, &val);\r | |
310 | return val;\r | |
311 | } else {\r | |
312 | uint32_t low_val;\r | |
313 | uint32_t high_val;\r | |
314 | BrotliFillBitWindow(br, 16);\r | |
315 | BrotliTakeBits(br, 16, &low_val);\r | |
316 | BrotliFillBitWindow(br, 8);\r | |
317 | BrotliTakeBits(br, n_bits - 16, &high_val);\r | |
318 | return low_val | (high_val << 16);\r | |
319 | }\r | |
320 | }\r | |
321 | \r | |
322 | /* Tries to read the specified amount of bits. Returns 0, if there is not\r | |
323 | enough input. n_bits MUST be positive. */\r | |
324 | static BROTLI_INLINE BROTLI_BOOL BrotliSafeReadBits(\r | |
325 | BrotliBitReader* const br, uint32_t n_bits, uint32_t* val) {\r | |
326 | while (BrotliGetAvailableBits(br) < n_bits) {\r | |
327 | if (!BrotliPullByte(br)) {\r | |
328 | return BROTLI_FALSE;\r | |
329 | }\r | |
330 | }\r | |
331 | BrotliTakeBits(br, n_bits, val);\r | |
332 | return BROTLI_TRUE;\r | |
333 | }\r | |
334 | \r | |
335 | /* Advances the bit reader position to the next byte boundary and verifies\r | |
336 | that any skipped bits are set to zero. */\r | |
337 | static BROTLI_INLINE BROTLI_BOOL BrotliJumpToByteBoundary(BrotliBitReader* br) {\r | |
338 | uint32_t pad_bits_count = BrotliGetAvailableBits(br) & 0x7;\r | |
339 | uint32_t pad_bits = 0;\r | |
340 | if (pad_bits_count != 0) {\r | |
341 | BrotliTakeBits(br, pad_bits_count, &pad_bits);\r | |
342 | }\r | |
343 | return TO_BROTLI_BOOL(pad_bits == 0);\r | |
344 | }\r | |
345 | \r | |
346 | /* Peeks a byte at specified offset.\r | |
347 | Precondition: bit reader is parked to a byte boundary.\r | |
348 | Returns -1 if operation is not feasible. */\r | |
349 | static BROTLI_INLINE int BrotliPeekByte(BrotliBitReader* br, size_t offset) {\r | |
350 | uint32_t available_bits = BrotliGetAvailableBits(br);\r | |
351 | size_t bytes_left = available_bits >> 3;\r | |
352 | BROTLI_DCHECK((available_bits & 7) == 0);\r | |
353 | if (offset < bytes_left) {\r | |
354 | return (BrotliGetBitsUnmasked(br) >> (unsigned)(offset << 3)) & 0xFF;\r | |
355 | }\r | |
356 | offset -= bytes_left;\r | |
357 | if (offset < br->avail_in) {\r | |
358 | return br->next_in[offset];\r | |
359 | }\r | |
360 | return -1;\r | |
361 | }\r | |
362 | \r | |
363 | /* Copies remaining input bytes stored in the bit reader to the output. Value\r | |
364 | num may not be larger than BrotliGetRemainingBytes. The bit reader must be\r | |
365 | warmed up again after this. */\r | |
366 | static BROTLI_INLINE void BrotliCopyBytes(uint8_t* dest,\r | |
367 | BrotliBitReader* br, size_t num) {\r | |
368 | while (BrotliGetAvailableBits(br) >= 8 && num > 0) {\r | |
369 | *dest = (uint8_t)BrotliGetBitsUnmasked(br);\r | |
370 | BrotliDropBits(br, 8);\r | |
371 | ++dest;\r | |
372 | --num;\r | |
373 | }\r | |
374 | memcpy(dest, br->next_in, num);\r | |
375 | br->avail_in -= num;\r | |
376 | br->next_in += num;\r | |
377 | }\r | |
378 | \r | |
379 | #if defined(__cplusplus) || defined(c_plusplus)\r | |
380 | } /* extern "C" */\r | |
381 | #endif\r | |
382 | \r | |
383 | #endif /* BROTLI_DEC_BIT_READER_H_ */\r |