1 /* Copyright 2013 Google Inc. All Rights Reserved.
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
7 http://www.apache.org/licenses/LICENSE-2.0
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
18 #ifndef BROTLI_DEC_BIT_READER_H_
19 #define BROTLI_DEC_BIT_READER_H_
22 #include "./streams.h"
25 #if defined(__cplusplus) || defined(c_plusplus)
29 #define BROTLI_MAX_NUM_BIT_READ 25
30 #define BROTLI_READ_SIZE 4096
31 #define BROTLI_IBUF_SIZE (2 * BROTLI_READ_SIZE + 32)
32 #define BROTLI_IBUF_MASK (2 * BROTLI_READ_SIZE - 1)
34 #define UNALIGNED_COPY64(dst, src) memcpy(dst, src, 8)
35 #define UNALIGNED_MOVE64(dst, src) memmove(dst, src, 8)
37 static const uint32_t kBitMask
[BROTLI_MAX_NUM_BIT_READ
] = {
38 0, 1, 3, 7, 15, 31, 63, 127, 255, 511, 1023, 2047, 4095, 8191, 16383, 32767,
39 65535, 131071, 262143, 524287, 1048575, 2097151, 4194303, 8388607, 16777215
43 /* Input byte buffer, consist of a ringbuffer and a "slack" region where */
44 /* bytes from the start of the ringbuffer are copied. */
45 uint8_t buf_
[BROTLI_IBUF_SIZE
];
46 uint8_t* buf_ptr_
; /* next input will write here */
47 BrotliInput input_
; /* input callback */
48 uint64_t val_
; /* pre-fetched bits */
49 uint32_t pos_
; /* byte position in stream */
50 uint32_t bit_pos_
; /* current bit-reading position in val_ */
51 uint32_t bit_end_pos_
; /* bit-reading end position from LSB of val_ */
52 int eos_
; /* input stream is finished */
55 int BrotliInitBitReader(BrotliBitReader
* const br
, BrotliInput input
);
57 /* Return the prefetched bits, so they can be looked up. */
58 static BROTLI_INLINE
uint32_t BrotliPrefetchBits(BrotliBitReader
* const br
) {
59 return (uint32_t)(br
->val_
>> br
->bit_pos_
);
62 /* For jumping over a number of bits in the bit stream when accessed with */
63 /* BrotliPrefetchBits and BrotliFillBitWindow. */
64 static BROTLI_INLINE
void BrotliSetBitPos(BrotliBitReader
* const br
,
66 #ifdef BROTLI_DECODE_DEBUG
67 uint32_t n_bits
= val
- br
->bit_pos_
;
68 const uint32_t bval
= (uint32_t)(br
->val_
>> br
->bit_pos_
) & kBitMask
[n_bits
];
69 printf("[BrotliReadBits] %010d %2d val: %6x\n",
70 (br
->pos_
<< 3) + br
->bit_pos_
- 64, n_bits
, bval
);
75 /* Reload up to 64 bits byte-by-byte */
76 static BROTLI_INLINE
void ShiftBytes(BrotliBitReader
* const br
) {
77 while (br
->bit_pos_
>= 8) {
79 br
->val_
|= ((uint64_t)br
->buf_
[br
->pos_
& BROTLI_IBUF_MASK
]) << 56;
82 br
->bit_end_pos_
-= 8;
86 /* Fills up the input ringbuffer by calling the input callback.
88 Does nothing if there are at least 32 bytes present after current position.
91 - the input callback returned an error, or
92 - there is no more input and the position is past the end of the stream.
94 After encountering the end of the input stream, 32 additional zero bytes are
95 copied to the ringbuffer, therefore it is safe to call this function after
96 every 32 bytes of input is read.
98 static BROTLI_INLINE
int BrotliReadMoreInput(BrotliBitReader
* const br
) {
99 if (br
->bit_end_pos_
> 256) {
101 } else if (br
->eos_
) {
102 return br
->bit_pos_
<= br
->bit_end_pos_
;
104 uint8_t* dst
= br
->buf_ptr_
;
105 int bytes_read
= BrotliRead(br
->input_
, dst
, BROTLI_READ_SIZE
);
106 if (bytes_read
< 0) {
109 if (bytes_read
< BROTLI_READ_SIZE
) {
111 /* Store 32 bytes of zero after the stream end. */
112 #if (defined(__x86_64__) || defined(_M_X64))
113 *(uint64_t*)(dst
+ bytes_read
) = 0;
114 *(uint64_t*)(dst
+ bytes_read
+ 8) = 0;
115 *(uint64_t*)(dst
+ bytes_read
+ 16) = 0;
116 *(uint64_t*)(dst
+ bytes_read
+ 24) = 0;
118 memset(dst
+ bytes_read
, 0, 32);
121 if (dst
== br
->buf_
) {
122 /* Copy the head of the ringbuffer to the slack region. */
123 #if (defined(__x86_64__) || defined(_M_X64))
124 UNALIGNED_COPY64(br
->buf_
+ BROTLI_IBUF_SIZE
- 32, br
->buf_
);
125 UNALIGNED_COPY64(br
->buf_
+ BROTLI_IBUF_SIZE
- 24, br
->buf_
+ 8);
126 UNALIGNED_COPY64(br
->buf_
+ BROTLI_IBUF_SIZE
- 16, br
->buf_
+ 16);
127 UNALIGNED_COPY64(br
->buf_
+ BROTLI_IBUF_SIZE
- 8, br
->buf_
+ 24);
129 memcpy(br
->buf_
+ (BROTLI_READ_SIZE
<< 1), br
->buf_
, 32);
131 br
->buf_ptr_
= br
->buf_
+ BROTLI_READ_SIZE
;
133 br
->buf_ptr_
= br
->buf_
;
135 br
->bit_end_pos_
+= ((uint32_t)bytes_read
<< 3);
140 /* Advances the Read buffer by 5 bytes to make room for reading next 24 bits. */
141 static BROTLI_INLINE
void BrotliFillBitWindow(BrotliBitReader
* const br
) {
142 if (br
->bit_pos_
>= 40) {
143 #if (defined(__x86_64__) || defined(_M_X64))
145 /* The expression below needs a little-endian arch to work correctly. */
146 /* This gives a large speedup for decoding speed. */
147 br
->val_
|= *(const uint64_t*)(
148 br
->buf_
+ (br
->pos_
& BROTLI_IBUF_MASK
)) << 24;
151 br
->bit_end_pos_
-= 40;
158 /* Reads the specified number of bits from Read Buffer. */
159 static BROTLI_INLINE
uint32_t BrotliReadBits(
160 BrotliBitReader
* const br
, int n_bits
) {
162 BrotliFillBitWindow(br
);
163 val
= (uint32_t)(br
->val_
>> br
->bit_pos_
) & kBitMask
[n_bits
];
164 #ifdef BROTLI_DECODE_DEBUG
165 printf("[BrotliReadBits] %010d %2d val: %6x\n",
166 (br
->pos_
<< 3) + br
->bit_pos_
- 64, n_bits
, val
);
168 br
->bit_pos_
+= (uint32_t)n_bits
;
172 #if defined(__cplusplus) || defined(c_plusplus)
176 #endif /* BROTLI_DEC_BIT_READER_H_ */