OLD | NEW |
(Empty) | |
| 1 // Copyright 2010 Google Inc. |
| 2 // |
| 3 // This code is licensed under the same terms as WebM: |
| 4 // Software License Agreement: http://www.webmproject.org/license/software/ |
| 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ |
| 6 // ----------------------------------------------------------------------------- |
| 7 // |
| 8 // Boolean decoder |
| 9 // |
| 10 // Author: Skal (pascal.massimino@gmail.com) |
| 11 |
| 12 #ifndef WEBP_DECODE_BITS_H_ |
| 13 #define WEBP_DECODE_BITS_H_ |
| 14 |
| 15 #include <assert.h> |
| 16 #include "webp/decode_vp8.h" |
| 17 |
| 18 #if defined(__cplusplus) || defined(c_plusplus) |
| 19 extern "C" { |
| 20 #endif |
| 21 |
| 22 //----------------------------------------------------------------------------- |
| 23 // Bitreader and code-tree reader |
| 24 |
| 25 typedef struct { |
| 26 const uint8_t* buf_; // next byte to be read |
| 27 const uint8_t* buf_end_; // end of read buffer |
| 28 int eof_; // true if input is exhausted |
| 29 |
| 30 // boolean decoder |
| 31 uint32_t range_; // current range minus 1. In [127, 254] interval. |
| 32 uint32_t value_; // current value |
| 33 int left_; // how many unused bits (negated) |
| 34 } VP8BitReader; |
| 35 |
| 36 // Initialize the bit reader and the boolean decoder. Return true if ok. |
| 37 int VP8Init(VP8BitReader* const br, const uint8_t* buf, uint32_t size); |
| 38 |
| 39 // return the next value made of 'num_bits' bits |
| 40 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); |
| 41 static inline uint32_t VP8Get(VP8BitReader* const br) { |
| 42 return VP8GetValue(br, 1); |
| 43 } |
| 44 |
| 45 // return the next value with sign-extension. |
| 46 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); |
| 47 |
| 48 // Read a bit with proba 'prob'. Speed-critical function! |
| 49 extern const uint8_t kVP8Log2Range[128]; |
| 50 extern const uint8_t kVP8NewRange[128]; |
| 51 static inline uint32_t VP8GetByte(VP8BitReader* const br) { |
| 52 assert(br); |
| 53 if (br->buf_ < br->buf_end_) { |
| 54 assert(br->buf_); |
| 55 return *br->buf_++; |
| 56 } |
| 57 br->eof_ = 1; |
| 58 return 0x80; |
| 59 } |
| 60 |
| 61 static inline void VP8Shift(VP8BitReader* const br) { |
| 62 // range_ is in [0..127] interval here. |
| 63 const int shift = kVP8Log2Range[br->range_]; |
| 64 br->range_ = kVP8NewRange[br->range_]; |
| 65 br->value_ <<= shift; |
| 66 br->left_ += shift; |
| 67 if (br->left_ > 0) { |
| 68 br->value_ |= VP8GetByte(br) << br->left_; |
| 69 br->left_ -= 8; |
| 70 } |
| 71 } |
| 72 |
| 73 static inline uint32_t VP8GetBit(VP8BitReader* const br, int prob) { |
| 74 const uint32_t split = (br->range_ * prob) >> 8; |
| 75 const uint32_t bit = ((br->value_ >> 8) > split); |
| 76 if (bit) { |
| 77 br->range_ -= split + 1; |
| 78 br->value_ -= (split + 1) << 8; |
| 79 } else { |
| 80 br->range_ = split; |
| 81 } |
| 82 if (br->range_ < 0x7f) { |
| 83 VP8Shift(br); |
| 84 } |
| 85 return bit; |
| 86 } |
| 87 |
| 88 static inline int VP8GetSigned(VP8BitReader* const br, int v) { |
| 89 const uint32_t split = br->range_ >> 1; |
| 90 const uint32_t bit = ((br->value_ >> 8) > split); |
| 91 if (bit) { |
| 92 br->range_ -= split + 1; |
| 93 br->value_ -= (split + 1) << 8; |
| 94 v = -v; |
| 95 } else { |
| 96 br->range_ = split; |
| 97 } |
| 98 VP8Shift(br); |
| 99 return v; |
| 100 } |
| 101 |
| 102 #if defined(__cplusplus) || defined(c_plusplus) |
| 103 } // extern "C" |
| 104 #endif |
| 105 |
| 106 #endif // WEBP_DECODE_BITS_H_ |
OLD | NEW |