Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(49)

Side by Side Diff: third_party/libwebp/utils/bit_reader.h

Issue 10832153: libwebp: update snapshot to v0.2.0-rc1 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright 2010 Google Inc. 1 // Copyright 2010 Google Inc. All Rights Reserved.
2 // 2 //
3 // This code is licensed under the same terms as WebM: 3 // This code is licensed under the same terms as WebM:
4 // Software License Agreement: http://www.webmproject.org/license/software/ 4 // Software License Agreement: http://www.webmproject.org/license/software/
5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/ 5 // Additional IP Rights Grant: http://www.webmproject.org/license/additional/
6 // ----------------------------------------------------------------------------- 6 // -----------------------------------------------------------------------------
7 // 7 //
8 // Boolean decoder 8 // Boolean decoder
9 // 9 //
10 // Author: Skal (pascal.massimino@gmail.com) 10 // Author: Skal (pascal.massimino@gmail.com)
11 // Vikas Arora (vikaas.arora@gmail.com)
11 12
12 #ifndef WEBP_UTILS_BIT_READER_H_ 13 #ifndef WEBP_UTILS_BIT_READER_H_
13 #define WEBP_UTILS_BIT_READER_H_ 14 #define WEBP_UTILS_BIT_READER_H_
14 15
15 #include <assert.h> 16 #include <assert.h>
16 #include "../webp/decode_vp8.h" 17 #ifdef _MSC_VER
18 #include <stdlib.h> // _byteswap_ulong
19 #endif
20 #include <string.h> // For memcpy
21 #include "../webp/types.h"
17 22
18 #if defined(__cplusplus) || defined(c_plusplus) 23 #if defined(__cplusplus) || defined(c_plusplus)
19 extern "C" { 24 extern "C" {
20 #endif 25 #endif
21 26
27 #define BITS 32 // can be 32, 16 or 8
28 #define MASK ((((bit_t)1) << (BITS)) - 1)
29 #if (BITS == 32)
30 typedef uint64_t bit_t; // natural register type
31 typedef uint32_t lbit_t; // natural type for memory I/O
32 #elif (BITS == 16)
33 typedef uint32_t bit_t;
34 typedef uint16_t lbit_t;
35 #else
36 typedef uint32_t bit_t;
37 typedef uint8_t lbit_t;
38 #endif
39
22 //------------------------------------------------------------------------------ 40 //------------------------------------------------------------------------------
23 // Bitreader and code-tree reader 41 // Bitreader and code-tree reader
24 42
25 typedef struct VP8BitReader VP8BitReader; 43 typedef struct VP8BitReader VP8BitReader;
26 struct VP8BitReader { 44 struct VP8BitReader {
27 const uint8_t* buf_; // next byte to be read 45 const uint8_t* buf_; // next byte to be read
28 const uint8_t* buf_end_; // end of read buffer 46 const uint8_t* buf_end_; // end of read buffer
29 int eof_; // true if input is exhausted 47 int eof_; // true if input is exhausted
30 48
31 // boolean decoder 49 // boolean decoder
32 uint32_t range_; // current range minus 1. In [127, 254] interval. 50 bit_t range_; // current range minus 1. In [127, 254] interval.
33 uint32_t value_; // current value 51 bit_t value_; // current value
34 int missing_; // number of missing bits in value_ (8bit) 52 int missing_; // number of missing bits in value_ (8bit)
35 }; 53 };
36 54
37 // Initialize the bit reader and the boolean decoder. 55 // Initialize the bit reader and the boolean decoder.
38 void VP8InitBitReader(VP8BitReader* const br, 56 void VP8InitBitReader(VP8BitReader* const br,
39 const uint8_t* const start, const uint8_t* const end); 57 const uint8_t* const start, const uint8_t* const end);
40 58
41 // return the next value made of 'num_bits' bits 59 // return the next value made of 'num_bits' bits
42 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); 60 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
43 static inline uint32_t VP8Get(VP8BitReader* const br) { 61 static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
44 return VP8GetValue(br, 1); 62 return VP8GetValue(br, 1);
45 } 63 }
46 64
47 // return the next value with sign-extension. 65 // return the next value with sign-extension.
48 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); 66 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
49 67
50 // Read a bit with proba 'prob'. Speed-critical function! 68 // Read a bit with proba 'prob'. Speed-critical function!
51 extern const uint8_t kVP8Log2Range[128]; 69 extern const uint8_t kVP8Log2Range[128];
52 extern const uint8_t kVP8NewRange[128]; 70 extern const bit_t kVP8NewRange[128];
53 static inline uint32_t VP8GetByte(VP8BitReader* const br) { 71
54 assert(br); 72 void VP8LoadFinalBytes(VP8BitReader* const br); // special case for the tail
55 if (br->buf_ < br->buf_end_) { 73
56 assert(br->buf_); 74 static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
57 return *br->buf_++; 75 assert(br && br->buf_);
76 // Read 'BITS' bits at a time if possible.
77 if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) {
78 // convert memory type to register type (with some zero'ing!)
79 bit_t bits;
80 lbit_t in_bits = *(lbit_t*)br->buf_;
81 br->buf_ += (BITS) >> 3;
82 #if !defined(__BIG_ENDIAN__)
83 #if (BITS == 32)
84 #if defined(__i386__) || defined(__x86_64__)
85 __asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits));
86 bits = (bit_t)in_bits; // 32b -> 64b zero-extension
87 #elif defined(_MSC_VER)
88 bits = _byteswap_ulong(in_bits);
89 #else
90 bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00)
91 | ((in_bits << 8) & 0xff0000) | (in_bits << 24);
92 #endif // x86
93 #elif (BITS == 16)
94 // gcc will recognize a 'rorw $8, ...' here:
95 bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
96 #endif
97 #else // LITTLE_ENDIAN
98 bits = (bit_t)in_bits;
99 #endif
100 br->value_ |= bits << br->missing_;
101 br->missing_ -= (BITS);
102 } else {
103 VP8LoadFinalBytes(br); // no need to be inlined
58 } 104 }
59 br->eof_ = 1;
60 return 0xff;
61 } 105 }
62 106
63 static inline uint32_t VP8BitUpdate(VP8BitReader* const br, uint32_t split) { 107 static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, bit_t split) {
64 uint32_t bit; 108 const bit_t value_split = split | (MASK);
65 const uint32_t value_split = (split + 1) << 8; 109 if (br->missing_ > 0) { // Make sure we have a least BITS bits in 'value_'
66 // Make sure we have a least 8 bits in 'value_' 110 VP8LoadNewBytes(br);
67 if (br->missing_ > 0) {
68 br->value_ |= VP8GetByte(br) << br->missing_;
69 br->missing_ -= 8;
70 } 111 }
71 bit = (br->value_ >= value_split); 112 if (br->value_ > value_split) {
72 if (bit) { 113 br->range_ -= value_split + 1;
73 br->range_ -= split + 1; 114 br->value_ -= value_split + 1;
74 br->value_ -= value_split; 115 return 1;
75 } else { 116 } else {
76 br->range_ = split; 117 br->range_ = value_split;
118 return 0;
77 } 119 }
78 return bit;
79 } 120 }
80 121
81 static inline void VP8Shift(VP8BitReader* const br) { 122 static WEBP_INLINE void VP8Shift(VP8BitReader* const br) {
82 // range_ is in [0..127] interval here. 123 // range_ is in [0..127] interval here.
83 const int shift = kVP8Log2Range[br->range_]; 124 const int idx = br->range_ >> (BITS);
84 br->range_ = kVP8NewRange[br->range_]; 125 const int shift = kVP8Log2Range[idx];
126 br->range_ = kVP8NewRange[idx];
85 br->value_ <<= shift; 127 br->value_ <<= shift;
86 br->missing_ += shift; 128 br->missing_ += shift;
87 } 129 }
88 130
89 static inline uint32_t VP8GetBit(VP8BitReader* const br, int prob) { 131 static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
90 const uint32_t split = (br->range_ * prob) >> 8; 132 // It's important to avoid generating a 64bit x 64bit multiply here.
91 const uint32_t bit = VP8BitUpdate(br, split); 133 // We just need an 8b x 8b after all.
92 if (br->range_ < 0x7f) { 134 const bit_t split =
135 (bit_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8);
136 const int bit = VP8BitUpdate(br, split);
137 if (br->range_ <= (((bit_t)0x7e << (BITS)) | (MASK))) {
93 VP8Shift(br); 138 VP8Shift(br);
94 } 139 }
95 return bit; 140 return bit;
96 } 141 }
97 142
98 static inline int VP8GetSigned(VP8BitReader* const br, int v) { 143 static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) {
99 const uint32_t split = br->range_ >> 1; 144 const bit_t split = (br->range_ >> 1);
100 const uint32_t bit = VP8BitUpdate(br, split); 145 const int bit = VP8BitUpdate(br, split);
101 VP8Shift(br); 146 VP8Shift(br);
102 return bit ? -v : v; 147 return bit ? -v : v;
103 } 148 }
104 149
150
151 // -----------------------------------------------------------------------------
152 // Bitreader
153
154 typedef struct {
155 uint64_t val_;
156 const uint8_t* buf_;
157 size_t len_;
158 size_t pos_;
159 int bit_pos_;
160 int eos_;
161 int error_;
162 } VP8LBitReader;
163
164 void VP8LInitBitReader(VP8LBitReader* const br,
165 const uint8_t* const start,
166 size_t length);
167
168 // Sets a new data buffer.
169 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
170 const uint8_t* const buffer, size_t length);
171
172 // Reads the specified number of bits from Read Buffer.
173 // Flags an error in case end_of_stream or n_bits is more than allowed limit.
174 // Flags eos if this read attempt is going to cross the read buffer.
175 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
176
177 // Reads one bit from Read Buffer. Flags an error in case end_of_stream.
178 // Flags eos after reading last bit from the buffer.
179 uint32_t VP8LReadOneBit(VP8LBitReader* const br);
180
181 // VP8LReadOneBitUnsafe is faster than VP8LReadOneBit, but it can be called only
182 // 32 times after the last VP8LFillBitWindow. Any subsequent calls
183 // (without VP8LFillBitWindow) will return invalid data.
184 static WEBP_INLINE uint32_t VP8LReadOneBitUnsafe(VP8LBitReader* const br) {
185 const uint32_t val = (br->val_ >> br->bit_pos_) & 1;
186 ++br->bit_pos_;
187 return val;
188 }
189
190 // Advances the Read buffer by 4 bytes to make room for reading next 32 bits.
191 void VP8LFillBitWindow(VP8LBitReader* const br);
192
105 #if defined(__cplusplus) || defined(c_plusplus) 193 #if defined(__cplusplus) || defined(c_plusplus)
106 } // extern "C" 194 } // extern "C"
107 #endif 195 #endif
108 196
109 #endif /* WEBP_UTILS_BIT_READER_H_ */ 197 #endif /* WEBP_UTILS_BIT_READER_H_ */
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698