OLD | NEW |
1 // Copyright 2011 Google Inc. All Rights Reserved. | 1 // Copyright 2011 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 // Bit writing and boolean coder | 10 // Bit writing and boolean coder |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
133 } | 133 } |
134 if (bw->range_ < 127) { | 134 if (bw->range_ < 127) { |
135 bw->range_ = kNewRange[bw->range_]; | 135 bw->range_ = kNewRange[bw->range_]; |
136 bw->value_ <<= 1; | 136 bw->value_ <<= 1; |
137 bw->nb_bits_ += 1; | 137 bw->nb_bits_ += 1; |
138 if (bw->nb_bits_ > 0) Flush(bw); | 138 if (bw->nb_bits_ > 0) Flush(bw); |
139 } | 139 } |
140 return bit; | 140 return bit; |
141 } | 141 } |
142 | 142 |
143 void VP8PutValue(VP8BitWriter* const bw, int value, int nb_bits) { | 143 void VP8PutBits(VP8BitWriter* const bw, uint32_t value, int nb_bits) { |
144 int mask; | 144 uint32_t mask; |
145 for (mask = 1 << (nb_bits - 1); mask; mask >>= 1) | 145 assert(nb_bits > 0 && nb_bits < 32); |
| 146 for (mask = 1u << (nb_bits - 1); mask; mask >>= 1) |
146 VP8PutBitUniform(bw, value & mask); | 147 VP8PutBitUniform(bw, value & mask); |
147 } | 148 } |
148 | 149 |
149 void VP8PutSignedValue(VP8BitWriter* const bw, int value, int nb_bits) { | 150 void VP8PutSignedBits(VP8BitWriter* const bw, int value, int nb_bits) { |
150 if (!VP8PutBitUniform(bw, value != 0)) | 151 if (!VP8PutBitUniform(bw, value != 0)) |
151 return; | 152 return; |
152 if (value < 0) { | 153 if (value < 0) { |
153 VP8PutValue(bw, ((-value) << 1) | 1, nb_bits + 1); | 154 VP8PutBits(bw, ((-value) << 1) | 1, nb_bits + 1); |
154 } else { | 155 } else { |
155 VP8PutValue(bw, value << 1, nb_bits + 1); | 156 VP8PutBits(bw, value << 1, nb_bits + 1); |
156 } | 157 } |
157 } | 158 } |
158 | 159 |
159 //------------------------------------------------------------------------------ | 160 //------------------------------------------------------------------------------ |
160 | 161 |
161 int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) { | 162 int VP8BitWriterInit(VP8BitWriter* const bw, size_t expected_size) { |
162 bw->range_ = 255 - 1; | 163 bw->range_ = 255 - 1; |
163 bw->value_ = 0; | 164 bw->value_ = 0; |
164 bw->run_ = 0; | 165 bw->run_ = 0; |
165 bw->nb_bits_ = -8; | 166 bw->nb_bits_ = -8; |
166 bw->pos_ = 0; | 167 bw->pos_ = 0; |
167 bw->max_pos_ = 0; | 168 bw->max_pos_ = 0; |
168 bw->error_ = 0; | 169 bw->error_ = 0; |
169 bw->buf_ = NULL; | 170 bw->buf_ = NULL; |
170 return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1; | 171 return (expected_size > 0) ? BitWriterResize(bw, expected_size) : 1; |
171 } | 172 } |
172 | 173 |
173 uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) { | 174 uint8_t* VP8BitWriterFinish(VP8BitWriter* const bw) { |
174 VP8PutValue(bw, 0, 9 - bw->nb_bits_); | 175 VP8PutBits(bw, 0, 9 - bw->nb_bits_); |
175 bw->nb_bits_ = 0; // pad with zeroes | 176 bw->nb_bits_ = 0; // pad with zeroes |
176 Flush(bw); | 177 Flush(bw); |
177 return bw->buf_; | 178 return bw->buf_; |
178 } | 179 } |
179 | 180 |
180 int VP8BitWriterAppend(VP8BitWriter* const bw, | 181 int VP8BitWriterAppend(VP8BitWriter* const bw, |
181 const uint8_t* data, size_t size) { | 182 const uint8_t* data, size_t size) { |
182 assert(data != NULL); | 183 assert(data != NULL); |
183 if (bw->nb_bits_ != -8) return 0; // Flush() must have been called | 184 if (bw->nb_bits_ != -8) return 0; // Flush() must have been called |
184 if (!BitWriterResize(bw, size)) return 0; | 185 if (!BitWriterResize(bw, size)) return 0; |
185 memcpy(bw->buf_ + bw->pos_, data, size); | 186 memcpy(bw->buf_ + bw->pos_, data, size); |
186 bw->pos_ += size; | 187 bw->pos_ += size; |
187 return 1; | 188 return 1; |
188 } | 189 } |
189 | 190 |
190 void VP8BitWriterWipeOut(VP8BitWriter* const bw) { | 191 void VP8BitWriterWipeOut(VP8BitWriter* const bw) { |
191 if (bw != NULL) { | 192 if (bw != NULL) { |
192 WebPSafeFree(bw->buf_); | 193 WebPSafeFree(bw->buf_); |
193 memset(bw, 0, sizeof(*bw)); | 194 memset(bw, 0, sizeof(*bw)); |
194 } | 195 } |
195 } | 196 } |
196 | 197 |
197 //------------------------------------------------------------------------------ | 198 //------------------------------------------------------------------------------ |
198 // VP8LBitWriter | 199 // VP8LBitWriter |
199 | 200 |
200 // This is the minimum amount of size the memory buffer is guaranteed to grow | 201 // This is the minimum amount of size the memory buffer is guaranteed to grow |
201 // when extra space is needed. | 202 // when extra space is needed. |
202 #define MIN_EXTRA_SIZE (32768ULL) | 203 #define MIN_EXTRA_SIZE (32768ULL) |
203 | 204 |
204 #define VP8L_WRITER_BYTES ((int)sizeof(vp8l_wtype_t)) | |
205 #define VP8L_WRITER_BITS (VP8L_WRITER_BYTES * 8) | |
206 #define VP8L_WRITER_MAX_BITS (8 * (int)sizeof(vp8l_atype_t)) | |
207 | |
208 // Returns 1 on success. | 205 // Returns 1 on success. |
209 static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) { | 206 static int VP8LBitWriterResize(VP8LBitWriter* const bw, size_t extra_size) { |
210 uint8_t* allocated_buf; | 207 uint8_t* allocated_buf; |
211 size_t allocated_size; | 208 size_t allocated_size; |
212 const size_t max_bytes = bw->end_ - bw->buf_; | 209 const size_t max_bytes = bw->end_ - bw->buf_; |
213 const size_t current_size = bw->cur_ - bw->buf_; | 210 const size_t current_size = bw->cur_ - bw->buf_; |
214 const uint64_t size_required_64b = (uint64_t)current_size + extra_size; | 211 const uint64_t size_required_64b = (uint64_t)current_size + extra_size; |
215 const size_t size_required = (size_t)size_required_64b; | 212 const size_t size_required = (size_t)size_required_64b; |
216 if (size_required != size_required_64b) { | 213 if (size_required != size_required_64b) { |
217 bw->error_ = 1; | 214 bw->error_ = 1; |
(...skipping 17 matching lines...) Expand all Loading... |
235 bw->cur_ = bw->buf_ + current_size; | 232 bw->cur_ = bw->buf_ + current_size; |
236 bw->end_ = bw->buf_ + allocated_size; | 233 bw->end_ = bw->buf_ + allocated_size; |
237 return 1; | 234 return 1; |
238 } | 235 } |
239 | 236 |
240 int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) { | 237 int VP8LBitWriterInit(VP8LBitWriter* const bw, size_t expected_size) { |
241 memset(bw, 0, sizeof(*bw)); | 238 memset(bw, 0, sizeof(*bw)); |
242 return VP8LBitWriterResize(bw, expected_size); | 239 return VP8LBitWriterResize(bw, expected_size); |
243 } | 240 } |
244 | 241 |
245 void VP8LBitWriterDestroy(VP8LBitWriter* const bw) { | 242 void VP8LBitWriterWipeOut(VP8LBitWriter* const bw) { |
246 if (bw != NULL) { | 243 if (bw != NULL) { |
247 WebPSafeFree(bw->buf_); | 244 WebPSafeFree(bw->buf_); |
248 memset(bw, 0, sizeof(*bw)); | 245 memset(bw, 0, sizeof(*bw)); |
249 } | 246 } |
250 } | 247 } |
251 | 248 |
252 void VP8LWriteBits(VP8LBitWriter* const bw, int n_bits, uint32_t bits) { | 249 void VP8LPutBitsFlushBits(VP8LBitWriter* const bw) { |
| 250 // If needed, make some room by flushing some bits out. |
| 251 if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { |
| 252 const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; |
| 253 if (extra_size != (size_t)extra_size || |
| 254 !VP8LBitWriterResize(bw, (size_t)extra_size)) { |
| 255 bw->cur_ = bw->buf_; |
| 256 bw->error_ = 1; |
| 257 return; |
| 258 } |
| 259 } |
| 260 *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)bw->bits_); |
| 261 bw->cur_ += VP8L_WRITER_BYTES; |
| 262 bw->bits_ >>= VP8L_WRITER_BITS; |
| 263 bw->used_ -= VP8L_WRITER_BITS; |
| 264 } |
| 265 |
| 266 void VP8LPutBitsInternal(VP8LBitWriter* const bw, uint32_t bits, int n_bits) { |
253 assert(n_bits <= 32); | 267 assert(n_bits <= 32); |
254 // That's the max we can handle: | 268 // That's the max we can handle: |
255 assert(bw->used_ + n_bits <= 2 * VP8L_WRITER_MAX_BITS); | 269 assert(sizeof(vp8l_wtype_t) == 2); |
256 if (n_bits > 0) { | 270 if (n_bits > 0) { |
257 // Local field copy. | |
258 vp8l_atype_t lbits = bw->bits_; | 271 vp8l_atype_t lbits = bw->bits_; |
259 int used = bw->used_; | 272 int used = bw->used_; |
260 // Special case of overflow handling for 32bit accumulator (2-steps flush). | 273 // Special case of overflow handling for 32bit accumulator (2-steps flush). |
261 if (VP8L_WRITER_BITS == 16) { | 274 #if VP8L_WRITER_BITS == 16 |
262 if (used + n_bits >= VP8L_WRITER_MAX_BITS) { | 275 if (used + n_bits >= VP8L_WRITER_MAX_BITS) { |
263 // Fill up all the VP8L_WRITER_MAX_BITS so it can be flushed out below. | 276 // Fill up all the VP8L_WRITER_MAX_BITS so it can be flushed out below. |
264 const int shift = VP8L_WRITER_MAX_BITS - used; | 277 const int shift = VP8L_WRITER_MAX_BITS - used; |
265 lbits |= (vp8l_atype_t)bits << used; | 278 lbits |= (vp8l_atype_t)bits << used; |
266 used = VP8L_WRITER_MAX_BITS; | 279 used = VP8L_WRITER_MAX_BITS; |
267 n_bits -= shift; | 280 n_bits -= shift; |
268 bits >>= shift; | 281 bits >>= shift; |
269 assert(n_bits <= VP8L_WRITER_MAX_BITS); | 282 assert(n_bits <= VP8L_WRITER_MAX_BITS); |
270 } | |
271 } | 283 } |
| 284 #endif |
272 // If needed, make some room by flushing some bits out. | 285 // If needed, make some room by flushing some bits out. |
273 while (used >= VP8L_WRITER_BITS) { | 286 while (used >= VP8L_WRITER_BITS) { |
274 if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { | 287 if (bw->cur_ + VP8L_WRITER_BYTES > bw->end_) { |
275 const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; | 288 const uint64_t extra_size = (bw->end_ - bw->buf_) + MIN_EXTRA_SIZE; |
276 if (extra_size != (size_t)extra_size || | 289 if (extra_size != (size_t)extra_size || |
277 !VP8LBitWriterResize(bw, (size_t)extra_size)) { | 290 !VP8LBitWriterResize(bw, (size_t)extra_size)) { |
278 bw->cur_ = bw->buf_; | 291 bw->cur_ = bw->buf_; |
279 bw->error_ = 1; | 292 bw->error_ = 1; |
280 return; | 293 return; |
281 } | 294 } |
282 } | 295 } |
283 *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits); | 296 *(vp8l_wtype_t*)bw->cur_ = (vp8l_wtype_t)WSWAP((vp8l_wtype_t)lbits); |
284 bw->cur_ += VP8L_WRITER_BYTES; | 297 bw->cur_ += VP8L_WRITER_BYTES; |
285 lbits >>= VP8L_WRITER_BITS; | 298 lbits >>= VP8L_WRITER_BITS; |
286 used -= VP8L_WRITER_BITS; | 299 used -= VP8L_WRITER_BITS; |
287 } | 300 } |
288 // Eventually, insert new bits. | |
289 bw->bits_ = lbits | ((vp8l_atype_t)bits << used); | 301 bw->bits_ = lbits | ((vp8l_atype_t)bits << used); |
290 bw->used_ = used + n_bits; | 302 bw->used_ = used + n_bits; |
291 } | 303 } |
292 } | 304 } |
293 | 305 |
294 uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) { | 306 uint8_t* VP8LBitWriterFinish(VP8LBitWriter* const bw) { |
295 // flush leftover bits | 307 // flush leftover bits |
296 if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) { | 308 if (VP8LBitWriterResize(bw, (bw->used_ + 7) >> 3)) { |
297 while (bw->used_ > 0) { | 309 while (bw->used_ > 0) { |
298 *bw->cur_++ = (uint8_t)bw->bits_; | 310 *bw->cur_++ = (uint8_t)bw->bits_; |
299 bw->bits_ >>= 8; | 311 bw->bits_ >>= 8; |
300 bw->used_ -= 8; | 312 bw->used_ -= 8; |
301 } | 313 } |
302 bw->used_ = 0; | 314 bw->used_ = 0; |
303 } | 315 } |
304 return bw->buf_; | 316 return bw->buf_; |
305 } | 317 } |
306 | 318 |
307 //------------------------------------------------------------------------------ | 319 //------------------------------------------------------------------------------ |
OLD | NEW |