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