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_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) 19extern "C" { 20#endif 21 22//----------------------------------------------------------------------------- 23// Bitreader and code-tree reader 24 25typedef 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. 37void VP8Init(VP8BitReader* const br, const uint8_t* buf, uint32_t size); 38 39// return the next value made of 'num_bits' bits 40uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); 41static inline uint32_t VP8Get(VP8BitReader* const br) { 42 return VP8GetValue(br, 1); 43} 44 45// return the next value with sign-extension. 46int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); 47 48// Read a bit with proba 'prob'. Speed-critical function! 49extern const uint8_t kVP8Log2Range[128]; 50extern const uint8_t kVP8NewRange[128]; 51static 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 61static 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 73static 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 88static 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_DEC_BITS_H_ 107