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 |
11 // | 11 // |
12 // Author: Skal (pascal.massimino@gmail.com) | 12 // Author: Skal (pascal.massimino@gmail.com) |
13 // Vikas Arora (vikaas.arora@gmail.com) | 13 // Vikas Arora (vikaas.arora@gmail.com) |
14 | 14 |
15 #include <assert.h> | 15 #include <assert.h> |
16 #include <string.h> // for memcpy() | 16 #include <string.h> // for memcpy() |
17 #include <stdlib.h> | 17 #include <stdlib.h> |
18 #include "./bit_writer.h" | 18 #include "./bit_writer.h" |
19 | 19 |
20 #if defined(__cplusplus) || defined(c_plusplus) | |
21 extern "C" { | |
22 #endif | |
23 | |
24 //------------------------------------------------------------------------------ | 20 //------------------------------------------------------------------------------ |
25 // VP8BitWriter | 21 // VP8BitWriter |
26 | 22 |
27 static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) { | 23 static int BitWriterResize(VP8BitWriter* const bw, size_t extra_size) { |
28 uint8_t* new_buf; | 24 uint8_t* new_buf; |
29 size_t new_size; | 25 size_t new_size; |
30 const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size; | 26 const uint64_t needed_size_64b = (uint64_t)bw->pos_ + extra_size; |
31 const size_t needed_size = (size_t)needed_size_64b; | 27 const size_t needed_size = (size_t)needed_size_64b; |
32 if (needed_size_64b != needed_size) { | 28 if (needed_size_64b != needed_size) { |
33 bw->error_ = 1; | 29 bw->error_ = 1; |
34 return 0; | 30 return 0; |
35 } | 31 } |
36 if (needed_size <= bw->max_pos_) return 1; | 32 if (needed_size <= bw->max_pos_) return 1; |
37 // If the following line wraps over 32bit, the test just after will catch it. | 33 // If the following line wraps over 32bit, the test just after will catch it. |
38 new_size = 2 * bw->max_pos_; | 34 new_size = 2 * bw->max_pos_; |
39 if (new_size < needed_size) new_size = needed_size; | 35 if (new_size < needed_size) new_size = needed_size; |
40 if (new_size < 1024) new_size = 1024; | 36 if (new_size < 1024) new_size = 1024; |
41 new_buf = (uint8_t*)malloc(new_size); | 37 new_buf = (uint8_t*)malloc(new_size); |
42 if (new_buf == NULL) { | 38 if (new_buf == NULL) { |
43 bw->error_ = 1; | 39 bw->error_ = 1; |
44 return 0; | 40 return 0; |
45 } | 41 } |
46 memcpy(new_buf, bw->buf_, bw->pos_); | 42 if (bw->pos_ > 0) { |
| 43 assert(bw->buf_ != NULL); |
| 44 memcpy(new_buf, bw->buf_, bw->pos_); |
| 45 } |
47 free(bw->buf_); | 46 free(bw->buf_); |
48 bw->buf_ = new_buf; | 47 bw->buf_ = new_buf; |
49 bw->max_pos_ = new_size; | 48 bw->max_pos_ = new_size; |
50 return 1; | 49 return 1; |
51 } | 50 } |
52 | 51 |
53 static void kFlush(VP8BitWriter* const bw) { | 52 static void kFlush(VP8BitWriter* const bw) { |
54 const int s = 8 + bw->nb_bits_; | 53 const int s = 8 + bw->nb_bits_; |
55 const int32_t bits = bw->value_ >> s; | 54 const int32_t bits = bw->value_ >> s; |
56 assert(bw->nb_bits_ >= 0); | 55 assert(bw->nb_bits_ >= 0); |
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
246 uint32_t v = *(const uint32_t*)p; | 245 uint32_t v = *(const uint32_t*)p; |
247 v |= bits << (bw->bit_pos_ & 7); | 246 v |= bits << (bw->bit_pos_ & 7); |
248 *(uint32_t*)p = v; | 247 *(uint32_t*)p = v; |
249 bw->bit_pos_ += n_bits; | 248 bw->bit_pos_ += n_bits; |
250 } | 249 } |
251 #else // BIG_ENDIAN | 250 #else // BIG_ENDIAN |
252 { | 251 { |
253 uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3]; | 252 uint8_t* p = &bw->buf_[bw->bit_pos_ >> 3]; |
254 const int bits_reserved_in_first_byte = bw->bit_pos_ & 7; | 253 const int bits_reserved_in_first_byte = bw->bit_pos_ & 7; |
255 const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte; | 254 const int bits_left_to_write = n_bits - 8 + bits_reserved_in_first_byte; |
256 // implicit & 0xff is assumed for uint8_t arithmetics | 255 // implicit & 0xff is assumed for uint8_t arithmetic |
257 *p++ |= bits << bits_reserved_in_first_byte; | 256 *p++ |= bits << bits_reserved_in_first_byte; |
258 bits >>= 8 - bits_reserved_in_first_byte; | 257 bits >>= 8 - bits_reserved_in_first_byte; |
259 if (bits_left_to_write >= 1) { | 258 if (bits_left_to_write >= 1) { |
260 *p++ = bits; | 259 *p++ = bits; |
261 bits >>= 8; | 260 bits >>= 8; |
262 if (bits_left_to_write >= 9) { | 261 if (bits_left_to_write >= 9) { |
263 *p++ = bits; | 262 *p++ = bits; |
264 bits >>= 8; | 263 bits >>= 8; |
265 } | 264 } |
266 } | 265 } |
267 assert(n_bits <= 25); | 266 assert(n_bits <= 25); |
268 *p = bits; | 267 *p = bits; |
269 bw->bit_pos_ += n_bits; | 268 bw->bit_pos_ += n_bits; |
270 } | 269 } |
271 #endif | 270 #endif |
272 if ((bw->bit_pos_ >> 3) > (bw->max_bytes_ - 8)) { | 271 if ((bw->bit_pos_ >> 3) > (bw->max_bytes_ - 8)) { |
273 const uint64_t extra_size = 32768ULL + bw->max_bytes_; | 272 const uint64_t extra_size = 32768ULL + bw->max_bytes_; |
274 if (extra_size != (size_t)extra_size || | 273 if (extra_size != (size_t)extra_size || |
275 !VP8LBitWriterResize(bw, (size_t)extra_size)) { | 274 !VP8LBitWriterResize(bw, (size_t)extra_size)) { |
276 bw->bit_pos_ = 0; | 275 bw->bit_pos_ = 0; |
277 bw->error_ = 1; | 276 bw->error_ = 1; |
278 } | 277 } |
279 } | 278 } |
280 } | 279 } |
281 | 280 |
282 //------------------------------------------------------------------------------ | 281 //------------------------------------------------------------------------------ |
283 | 282 |
284 #if defined(__cplusplus) || defined(c_plusplus) | |
285 } // extern "C" | |
286 #endif | |
OLD | NEW |