1 // Copyright 2010 Google Inc. All Rights Reserved.
2 //
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 // -----------------------------------------------------------------------------
9 //
10 // Boolean decoder non-inlined methods
11 //
12 // Author: Skal (pascal.massimino@gmail.com)
13
14 #ifdef HAVE_CONFIG_H
15 #include "../webp/config.h"
16 #endif
17
18 #include "./bit_reader_inl.h"
19
20 //------------------------------------------------------------------------------
21 // VP8BitReader
22
VP8BitReaderSetBuffer(VP8BitReader * const br,const uint8_t * const start,size_t size)23 void VP8BitReaderSetBuffer(VP8BitReader* const br,
24 const uint8_t* const start,
25 size_t size) {
26 br->buf_ = start;
27 br->buf_end_ = start + size;
28 br->buf_max_ =
29 (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
30 : start;
31 }
32
VP8InitBitReader(VP8BitReader * const br,const uint8_t * const start,size_t size)33 void VP8InitBitReader(VP8BitReader* const br,
34 const uint8_t* const start, size_t size) {
35 assert(br != NULL);
36 assert(start != NULL);
37 assert(size < (1u << 31)); // limit ensured by format and upstream checks
38 br->range_ = 255 - 1;
39 br->value_ = 0;
40 br->bits_ = -8; // to load the very first 8bits
41 br->eof_ = 0;
42 VP8BitReaderSetBuffer(br, start, size);
43 VP8LoadNewBytes(br);
44 }
45
VP8RemapBitReader(VP8BitReader * const br,ptrdiff_t offset)46 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
47 if (br->buf_ != NULL) {
48 br->buf_ += offset;
49 br->buf_end_ += offset;
50 br->buf_max_ += offset;
51 }
52 }
53
54 const uint8_t kVP8Log2Range[128] = {
55 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
56 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
57 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
58 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
59 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
61 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
62 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
63 0
64 };
65
66 // range = ((range - 1) << kVP8Log2Range[range]) + 1
67 const uint8_t kVP8NewRange[128] = {
68 127, 127, 191, 127, 159, 191, 223, 127,
69 143, 159, 175, 191, 207, 223, 239, 127,
70 135, 143, 151, 159, 167, 175, 183, 191,
71 199, 207, 215, 223, 231, 239, 247, 127,
72 131, 135, 139, 143, 147, 151, 155, 159,
73 163, 167, 171, 175, 179, 183, 187, 191,
74 195, 199, 203, 207, 211, 215, 219, 223,
75 227, 231, 235, 239, 243, 247, 251, 127,
76 129, 131, 133, 135, 137, 139, 141, 143,
77 145, 147, 149, 151, 153, 155, 157, 159,
78 161, 163, 165, 167, 169, 171, 173, 175,
79 177, 179, 181, 183, 185, 187, 189, 191,
80 193, 195, 197, 199, 201, 203, 205, 207,
81 209, 211, 213, 215, 217, 219, 221, 223,
82 225, 227, 229, 231, 233, 235, 237, 239,
83 241, 243, 245, 247, 249, 251, 253, 127
84 };
85
VP8LoadFinalBytes(VP8BitReader * const br)86 void VP8LoadFinalBytes(VP8BitReader* const br) {
87 assert(br != NULL && br->buf_ != NULL);
88 // Only read 8bits at a time
89 if (br->buf_ < br->buf_end_) {
90 br->bits_ += 8;
91 br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
92 } else if (!br->eof_) {
93 br->value_ <<= 8;
94 br->bits_ += 8;
95 br->eof_ = 1;
96 } else {
97 br->bits_ = 0; // This is to avoid undefined behaviour with shifts.
98 }
99 }
100
101 //------------------------------------------------------------------------------
102 // Higher-level calls
103
VP8GetValue(VP8BitReader * const br,int bits)104 uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
105 uint32_t v = 0;
106 while (bits-- > 0) {
107 v |= VP8GetBit(br, 0x80) << bits;
108 }
109 return v;
110 }
111
VP8GetSignedValue(VP8BitReader * const br,int bits)112 int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
113 const int value = VP8GetValue(br, bits);
114 return VP8Get(br) ? -value : value;
115 }
116
117 //------------------------------------------------------------------------------
118 // VP8LBitReader
119
120 #define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits.
121
122 #if !defined(WEBP_FORCE_ALIGNED) && \
123 (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
124 defined(__i386__) || defined(_M_IX86) || \
125 defined(__x86_64__) || defined(_M_X64))
126 #define VP8L_USE_UNALIGNED_LOAD
127 #endif
128
129 static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = {
130 0,
131 0x000001, 0x000003, 0x000007, 0x00000f,
132 0x00001f, 0x00003f, 0x00007f, 0x0000ff,
133 0x0001ff, 0x0003ff, 0x0007ff, 0x000fff,
134 0x001fff, 0x003fff, 0x007fff, 0x00ffff,
135 0x01ffff, 0x03ffff, 0x07ffff, 0x0fffff,
136 0x1fffff, 0x3fffff, 0x7fffff, 0xffffff
137 };
138
VP8LInitBitReader(VP8LBitReader * const br,const uint8_t * const start,size_t length)139 void VP8LInitBitReader(VP8LBitReader* const br, const uint8_t* const start,
140 size_t length) {
141 size_t i;
142 vp8l_val_t value = 0;
143 assert(br != NULL);
144 assert(start != NULL);
145 assert(length < 0xfffffff8u); // can't happen with a RIFF chunk.
146
147 br->len_ = length;
148 br->val_ = 0;
149 br->bit_pos_ = 0;
150 br->eos_ = 0;
151
152 if (length > sizeof(br->val_)) {
153 length = sizeof(br->val_);
154 }
155 for (i = 0; i < length; ++i) {
156 value |= (vp8l_val_t)start[i] << (8 * i);
157 }
158 br->val_ = value;
159 br->pos_ = length;
160 br->buf_ = start;
161 }
162
VP8LBitReaderSetBuffer(VP8LBitReader * const br,const uint8_t * const buf,size_t len)163 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
164 const uint8_t* const buf, size_t len) {
165 assert(br != NULL);
166 assert(buf != NULL);
167 assert(len < 0xfffffff8u); // can't happen with a RIFF chunk.
168 br->buf_ = buf;
169 br->len_ = len;
170 // pos_ > len_ should be considered a param error.
171 br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
172 }
173
VP8LSetEndOfStream(VP8LBitReader * const br)174 static void VP8LSetEndOfStream(VP8LBitReader* const br) {
175 br->eos_ = 1;
176 br->bit_pos_ = 0; // To avoid undefined behaviour with shifts.
177 }
178
179 // If not at EOS, reload up to VP8L_LBITS byte-by-byte
ShiftBytes(VP8LBitReader * const br)180 static void ShiftBytes(VP8LBitReader* const br) {
181 while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
182 br->val_ >>= 8;
183 br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
184 ++br->pos_;
185 br->bit_pos_ -= 8;
186 }
187 if (VP8LIsEndOfStream(br)) {
188 VP8LSetEndOfStream(br);
189 }
190 }
191
VP8LDoFillBitWindow(VP8LBitReader * const br)192 void VP8LDoFillBitWindow(VP8LBitReader* const br) {
193 assert(br->bit_pos_ >= VP8L_WBITS);
194 // TODO(jzern): given the fixed read size it may be possible to force
195 // alignment in this block.
196 #if defined(VP8L_USE_UNALIGNED_LOAD)
197 if (br->pos_ + sizeof(br->val_) < br->len_) {
198 br->val_ >>= VP8L_WBITS;
199 br->bit_pos_ -= VP8L_WBITS;
200 // The expression below needs a little-endian arch to work correctly.
201 // This gives a large speedup for decoding speed.
202 br->val_ |= (vp8l_val_t)WebPMemToUint32(br->buf_ + br->pos_) <<
203 (VP8L_LBITS - VP8L_WBITS);
204 br->pos_ += VP8L_LOG8_WBITS;
205 return;
206 }
207 #endif
208 ShiftBytes(br); // Slow path.
209 }
210
VP8LReadBits(VP8LBitReader * const br,int n_bits)211 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
212 assert(n_bits >= 0);
213 // Flag an error if end_of_stream or n_bits is more than allowed limit.
214 if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
215 const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
216 const int new_bits = br->bit_pos_ + n_bits;
217 br->bit_pos_ = new_bits;
218 ShiftBytes(br);
219 return val;
220 } else {
221 VP8LSetEndOfStream(br);
222 return 0;
223 }
224 }
225
226 //------------------------------------------------------------------------------
227