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 (at) gmail.com) 11 12 #ifndef WEBP_DEC_BITS_H_ 13 #define WEBP_DEC_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 missing_; // number of missing bits in value_ (8bit) 34 } VP8BitReader; 35 36 // Initialize the bit reader and the boolean decoder. 37 void VP8InitBitReader(VP8BitReader* const br, 38 const uint8_t* const start, const uint8_t* const end); 39 40 // return the next value made of 'num_bits' bits 41 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); 42 static inline uint32_t VP8Get(VP8BitReader* const br) { 43 return VP8GetValue(br, 1); 44 } 45 46 // return the next value with sign-extension. 47 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); 48 49 // Read a bit with proba 'prob'. Speed-critical function! 50 extern const uint8_t kVP8Log2Range[128]; 51 extern const uint8_t kVP8NewRange[128]; 52 static inline uint32_t VP8GetByte(VP8BitReader* const br) { 53 assert(br); 54 if (br->buf_ < br->buf_end_) { 55 assert(br->buf_); 56 return *br->buf_++; 57 } 58 br->eof_ = 1; 59 return 0xff; 60 } 61 62 static inline uint32_t VP8BitUpdate(VP8BitReader* const br, uint32_t split) { 63 uint32_t bit; 64 const uint32_t value_split = (split + 1) << 8; 65 // Make sure we have a least 8 bits in 'value_' 66 if (br->missing_ > 0) { 67 br->value_ |= VP8GetByte(br) << br->missing_; 68 br->missing_ -= 8; 69 } 70 bit = (br->value_ >= value_split); 71 if (bit) { 72 br->range_ -= split + 1; 73 br->value_ -= value_split; 74 } else { 75 br->range_ = split; 76 } 77 return bit; 78 } 79 80 static inline void VP8Shift(VP8BitReader* const br) { 81 // range_ is in [0..127] interval here. 82 const int shift = kVP8Log2Range[br->range_]; 83 br->range_ = kVP8NewRange[br->range_]; 84 br->value_ <<= shift; 85 br->missing_ += shift; 86 } 87 88 static inline uint32_t VP8GetBit(VP8BitReader* const br, int prob) { 89 const uint32_t split = (br->range_ * prob) >> 8; 90 const uint32_t bit = VP8BitUpdate(br, split); 91 if (br->range_ < 0x7f) { 92 VP8Shift(br); 93 } 94 return bit; 95 } 96 97 static inline int VP8GetSigned(VP8BitReader* const br, int v) { 98 const uint32_t split = br->range_ >> 1; 99 const uint32_t bit = VP8BitUpdate(br, split); 100 VP8Shift(br); 101 return bit ? -v : v; 102 } 103 104 #if defined(__cplusplus) || defined(c_plusplus) 105 } // extern "C" 106 #endif 107 108 #endif // WEBP_DEC_BITS_H_ 109