1 // Copyright 2010 Google Inc. All Rights Reserved.
3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree.
8 // -----------------------------------------------------------------------------
10 // Boolean decoder non-inlined methods
12 // Author: Skal (pascal.massimino@gmail.com)
15 #include "../webp/config.h"
18 #include "./bit_reader_inl.h"
20 //------------------------------------------------------------------------------
23 void VP8InitBitReader(VP8BitReader
* const br
,
24 const uint8_t* const start
, const uint8_t* const end
) {
26 assert(start
!= NULL
);
32 br
->bits_
= -8; // to load the very first 8bits
37 void VP8RemapBitReader(VP8BitReader
* const br
, ptrdiff_t offset
) {
38 if (br
->buf_
!= NULL
) {
40 br
->buf_end_
+= offset
;
44 const uint8_t kVP8Log2Range
[128] = {
45 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
46 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
47 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
48 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
49 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
50 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
51 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
56 // range = ((range - 1) << kVP8Log2Range[range]) + 1
57 const range_t kVP8NewRange
[128] = {
58 127, 127, 191, 127, 159, 191, 223, 127,
59 143, 159, 175, 191, 207, 223, 239, 127,
60 135, 143, 151, 159, 167, 175, 183, 191,
61 199, 207, 215, 223, 231, 239, 247, 127,
62 131, 135, 139, 143, 147, 151, 155, 159,
63 163, 167, 171, 175, 179, 183, 187, 191,
64 195, 199, 203, 207, 211, 215, 219, 223,
65 227, 231, 235, 239, 243, 247, 251, 127,
66 129, 131, 133, 135, 137, 139, 141, 143,
67 145, 147, 149, 151, 153, 155, 157, 159,
68 161, 163, 165, 167, 169, 171, 173, 175,
69 177, 179, 181, 183, 185, 187, 189, 191,
70 193, 195, 197, 199, 201, 203, 205, 207,
71 209, 211, 213, 215, 217, 219, 221, 223,
72 225, 227, 229, 231, 233, 235, 237, 239,
73 241, 243, 245, 247, 249, 251, 253, 127
76 void VP8LoadFinalBytes(VP8BitReader
* const br
) {
77 assert(br
!= NULL
&& br
->buf_
!= NULL
);
78 // Only read 8bits at a time
79 if (br
->buf_
< br
->buf_end_
) {
81 br
->value_
= (bit_t
)(*br
->buf_
++) | (br
->value_
<< 8);
82 } else if (!br
->eof_
) {
89 //------------------------------------------------------------------------------
92 uint32_t VP8GetValue(VP8BitReader
* const br
, int bits
) {
95 v
|= VP8GetBit(br
, 0x80) << bits
;
100 int32_t VP8GetSignedValue(VP8BitReader
* const br
, int bits
) {
101 const int value
= VP8GetValue(br
, bits
);
102 return VP8Get(br
) ? -value
: value
;
105 //------------------------------------------------------------------------------
108 #define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits.
110 #if !defined(WEBP_FORCE_ALIGNED) && \
111 (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
112 defined(__i386__) || defined(_M_IX86) || \
113 defined(__x86_64__) || defined(_M_X64))
114 #define VP8L_USE_UNALIGNED_LOAD
117 static const uint32_t kBitMask
[VP8L_MAX_NUM_BIT_READ
+ 1] = {
119 0x000001, 0x000003, 0x000007, 0x00000f,
120 0x00001f, 0x00003f, 0x00007f, 0x0000ff,
121 0x0001ff, 0x0003ff, 0x0007ff, 0x000fff,
122 0x001fff, 0x003fff, 0x007fff, 0x00ffff,
123 0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,
124 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff
127 void VP8LInitBitReader(VP8LBitReader
* const br
, const uint8_t* const start
,
130 vp8l_val_t value
= 0;
132 assert(start
!= NULL
);
133 assert(length
< 0xfffffff8u
); // can't happen with a RIFF chunk.
141 if (length
> sizeof(br
->val_
)) {
142 length
= sizeof(br
->val_
);
144 for (i
= 0; i
< length
; ++i
) {
145 value
|= (vp8l_val_t
)start
[i
] << (8 * i
);
152 void VP8LBitReaderSetBuffer(VP8LBitReader
* const br
,
153 const uint8_t* const buf
, size_t len
) {
156 assert(len
< 0xfffffff8u
); // can't happen with a RIFF chunk.
159 // pos_ > len_ should be considered a param error.
160 br
->error_
= (br
->pos_
> br
->len_
);
161 br
->eos_
= br
->error_
|| VP8LIsEndOfStream(br
);
164 // If not at EOS, reload up to VP8L_LBITS byte-by-byte
165 static void ShiftBytes(VP8LBitReader
* const br
) {
166 while (br
->bit_pos_
>= 8 && br
->pos_
< br
->len_
) {
168 br
->val_
|= ((vp8l_val_t
)br
->buf_
[br
->pos_
]) << (VP8L_LBITS
- 8);
172 br
->eos_
= VP8LIsEndOfStream(br
);
175 void VP8LDoFillBitWindow(VP8LBitReader
* const br
) {
176 assert(br
->bit_pos_
>= VP8L_WBITS
);
177 // TODO(jzern): given the fixed read size it may be possible to force
178 // alignment in this block.
179 #if defined(VP8L_USE_UNALIGNED_LOAD)
180 if (br
->pos_
+ sizeof(br
->val_
) < br
->len_
) {
181 br
->val_
>>= VP8L_WBITS
;
182 br
->bit_pos_
-= VP8L_WBITS
;
183 // The expression below needs a little-endian arch to work correctly.
184 // This gives a large speedup for decoding speed.
185 br
->val_
|= (vp8l_val_t
)*(const uint32_t*)(br
->buf_
+ br
->pos_
) <<
186 (VP8L_LBITS
- VP8L_WBITS
);
187 br
->pos_
+= VP8L_LOG8_WBITS
;
191 ShiftBytes(br
); // Slow path.
194 uint32_t VP8LReadBits(VP8LBitReader
* const br
, int n_bits
) {
196 // Flag an error if end_of_stream or n_bits is more than allowed limit.
197 if (!br
->eos_
&& n_bits
<= VP8L_MAX_NUM_BIT_READ
) {
199 (uint32_t)(br
->val_
>> br
->bit_pos_
) & kBitMask
[n_bits
];
200 const int new_bits
= br
->bit_pos_
+ n_bits
;
201 br
->bit_pos_
= new_bits
;
210 //------------------------------------------------------------------------------