• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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)
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);
VP8Get(VP8BitReader * const br)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];
VP8GetByte(VP8BitReader * const br)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 
VP8BitUpdate(VP8BitReader * const br,uint32_t split)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 
VP8Shift(VP8BitReader * const br)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 
VP8GetBit(VP8BitReader * const br,int prob)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 
VP8GetSigned(VP8BitReader * const br,int v)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