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 "src/webp/config.h"
16 #endif
17 
18 #include "src/utils/bit_reader_inl_utils.h"
19 #include "src/utils/utils.h"
20 
21 //------------------------------------------------------------------------------
22 // VP8BitReader
23 
VP8BitReaderSetBuffer(VP8BitReader * const br,const uint8_t * const start,size_t size)24 void VP8BitReaderSetBuffer(VP8BitReader* const br,
25                            const uint8_t* const start,
26                            size_t size) {
27   br->buf_     = start;
28   br->buf_end_ = start + size;
29   br->buf_max_ =
30       (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
31                                : start;
32 }
33 
VP8InitBitReader(VP8BitReader * const br,const uint8_t * const start,size_t size)34 void VP8InitBitReader(VP8BitReader* const br,
35                       const uint8_t* const start, size_t size) {
36   assert(br != NULL);
37   assert(start != NULL);
38   assert(size < (1u << 31));   // limit ensured by format and upstream checks
39   br->range_   = 255 - 1;
40   br->value_   = 0;
41   br->bits_    = -8;   // to load the very first 8bits
42   br->eof_     = 0;
43   VP8BitReaderSetBuffer(br, start, size);
44   VP8LoadNewBytes(br);
45 }
46 
VP8RemapBitReader(VP8BitReader * const br,ptrdiff_t offset)47 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
48   if (br->buf_ != NULL) {
49     br->buf_ += offset;
50     br->buf_end_ += offset;
51     br->buf_max_ += offset;
52   }
53 }
54 
55 const uint8_t kVP8Log2Range[128] = {
56      7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
57   3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
58   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
59   2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
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   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
64   0
65 };
66 
67 // range = ((range - 1) << kVP8Log2Range[range]) + 1
68 const uint8_t kVP8NewRange[128] = {
69   127, 127, 191, 127, 159, 191, 223, 127,
70   143, 159, 175, 191, 207, 223, 239, 127,
71   135, 143, 151, 159, 167, 175, 183, 191,
72   199, 207, 215, 223, 231, 239, 247, 127,
73   131, 135, 139, 143, 147, 151, 155, 159,
74   163, 167, 171, 175, 179, 183, 187, 191,
75   195, 199, 203, 207, 211, 215, 219, 223,
76   227, 231, 235, 239, 243, 247, 251, 127,
77   129, 131, 133, 135, 137, 139, 141, 143,
78   145, 147, 149, 151, 153, 155, 157, 159,
79   161, 163, 165, 167, 169, 171, 173, 175,
80   177, 179, 181, 183, 185, 187, 189, 191,
81   193, 195, 197, 199, 201, 203, 205, 207,
82   209, 211, 213, 215, 217, 219, 221, 223,
83   225, 227, 229, 231, 233, 235, 237, 239,
84   241, 243, 245, 247, 249, 251, 253, 127
85 };
86 
VP8LoadFinalBytes(VP8BitReader * const br)87 void VP8LoadFinalBytes(VP8BitReader* const br) {
88   assert(br != NULL && br->buf_ != NULL);
89   // Only read 8bits at a time
90   if (br->buf_ < br->buf_end_) {
91     br->bits_ += 8;
92     br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
93   } else if (!br->eof_) {
94     br->value_ <<= 8;
95     br->bits_ += 8;
96     br->eof_ = 1;
97   } else {
98     br->bits_ = 0;  // This is to avoid undefined behaviour with shifts.
99   }
100 }
101 
102 //------------------------------------------------------------------------------
103 // Higher-level calls
104 
VP8GetValue(VP8BitReader * const br,int bits)105 uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
106   uint32_t v = 0;
107   while (bits-- > 0) {
108     v |= VP8GetBit(br, 0x80) << bits;
109   }
110   return v;
111 }
112 
VP8GetSignedValue(VP8BitReader * const br,int bits)113 int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) {
114   const int value = VP8GetValue(br, bits);
115   return VP8Get(br) ? -value : value;
116 }
117 
118 //------------------------------------------------------------------------------
119 // VP8LBitReader
120 
121 #define VP8L_LOG8_WBITS 4  // Number of bytes needed to store VP8L_WBITS bits.
122 
123 #if defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \
124     defined(__i386__) || defined(_M_IX86) || \
125     defined(__x86_64__) || defined(_M_X64)
126 #define VP8L_USE_FAST_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 #if defined(VP8L_USE_FAST_LOAD)
195   if (br->pos_ + sizeof(br->val_) < br->len_) {
196     br->val_ >>= VP8L_WBITS;
197     br->bit_pos_ -= VP8L_WBITS;
198     br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) <<
199                 (VP8L_LBITS - VP8L_WBITS);
200     br->pos_ += VP8L_LOG8_WBITS;
201     return;
202   }
203 #endif
204   ShiftBytes(br);       // Slow path.
205 }
206 
VP8LReadBits(VP8LBitReader * const br,int n_bits)207 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
208   assert(n_bits >= 0);
209   // Flag an error if end_of_stream or n_bits is more than allowed limit.
210   if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
211     const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
212     const int new_bits = br->bit_pos_ + n_bits;
213     br->bit_pos_ = new_bits;
214     ShiftBytes(br);
215     return val;
216   } else {
217     VP8LSetEndOfStream(br);
218     return 0;
219   }
220 }
221 
222 //------------------------------------------------------------------------------
223