Home | History | Annotate | Download | only in dec
      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