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

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

Issue 12942006: libwebp: update snapshot to v0.3.0-rc6 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 9 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
« no previous file with comments | « third_party/libwebp/libwebp.gyp ('k') | third_party/libwebp/utils/bit_reader.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2010 Google Inc. All Rights Reserved. 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 // Vikas Arora (vikaas.arora@gmail.com)
12 12
13 #ifndef WEBP_UTILS_BIT_READER_H_ 13 #ifndef WEBP_UTILS_BIT_READER_H_
14 #define WEBP_UTILS_BIT_READER_H_ 14 #define WEBP_UTILS_BIT_READER_H_
15 15
16 #include <assert.h> 16 #include <assert.h>
17 #ifdef _MSC_VER 17 #ifdef _MSC_VER
18 #include <stdlib.h> // _byteswap_ulong 18 #include <stdlib.h> // _byteswap_ulong
19 #endif 19 #endif
20 #include <string.h> // For memcpy 20 #include <string.h> // For memcpy
21 #include "../webp/types.h" 21 #include "../webp/types.h"
22 22
23 #if defined(__cplusplus) || defined(c_plusplus) 23 #if defined(__cplusplus) || defined(c_plusplus)
24 extern "C" { 24 extern "C" {
25 #endif 25 #endif
26 26
27 #define BITS 32 // can be 32, 16 or 8 27 // The Boolean decoder needs to maintain infinite precision on the value_ field.
28 #define MASK ((((bit_t)1) << (BITS)) - 1) 28 // However, since range_ is only 8bit, we only need an active window of 8 bits
29 #if (BITS == 32) 29 // for value_. Left bits (MSB) gets zeroed and shifted away when value_ falls
30 typedef uint64_t bit_t; // natural register type 30 // below 128, range_ is updated, and fresh bits read from the bitstream are
31 typedef uint32_t lbit_t; // natural type for memory I/O 31 // brought in as LSB.
32 // To avoid reading the fresh bits one by one (slow), we cache a few of them
33 // ahead (actually, we cache BITS of them ahead. See below). There's two
34 // strategies regarding how to shift these looked-ahead fresh bits into the
35 // 8bit window of value_: either we shift them in, while keeping the position of
36 // the window fixed. Or we slide the window to the right while keeping the cache
37 // bits at a fixed, right-justified, position.
38 //
39 // Example, for BITS=16: here is the content of value_ for both strategies:
40 //
41 // !USE_RIGHT_JUSTIFY || USE_RIGHT_JUSTIFY
42 // ||
43 // <- 8b -><- 8b -><- BITS bits -> || <- 8b+3b -><- 8b -><- 13 bits ->
44 // [unused][value_][cached bits][0] || [unused...][value_][cached bits]
45 // [........00vvvvvvBBBBBBBBBBBBB000]LSB || [...........00vvvvvvBBBBBBBBBBBBB]
46 // ||
47 // After calling VP8Shift(), where we need to shift away two zeros:
48 // [........vvvvvvvvBBBBBBBBBBB00000]LSB || [.............vvvvvvvvBBBBBBBBBBB]
49 // ||
50 // Just before we need to call VP8LoadNewBytes(), the situation is:
51 // [........vvvvvv000000000000000000]LSB || [..........................vvvvvv]
52 // ||
53 // And just after calling VP8LoadNewBytes():
54 // [........vvvvvvvvBBBBBBBBBBBBBBBB]LSB || [........vvvvvvvvBBBBBBBBBBBBBBBB]
55 //
56 // -> we're back to height active 'value_' bits (marked 'v') and BITS cached
57 // bits (marked 'B')
58 //
59 // The right-justify strategy tends to use less shifts and is often faster.
60
61 //------------------------------------------------------------------------------
62 // BITS can be any multiple of 8 from 8 to 56 (inclusive).
63 // Pick values that fit natural register size.
64
65 #if !defined(WEBP_REFERENCE_IMPLEMENTATION)
66
67 #define USE_RIGHT_JUSTIFY
68
69 #if defined(__i386__) || defined(_M_IX86) // x86 32bit
70 #define BITS 16
71 #elif defined(__x86_64__) || defined(_M_X64) // x86 64bit
72 #define BITS 56
73 #elif defined(__arm__) || defined(_M_ARM) // ARM
74 #define BITS 24
75 #else // reasonable default
76 #define BITS 24
77 #endif
78
79 #else // reference choices
80
81 #define USE_RIGHT_JUSTIFY
82 #define BITS 8
83
84 #endif
85
86 //------------------------------------------------------------------------------
87 // Derived types and constants
88
89 // bit_t = natural register type
90 // lbit_t = natural type for memory I/O
91
92 #if (BITS > 32)
93 typedef uint64_t bit_t;
94 typedef uint64_t lbit_t;
95 #elif (BITS == 32)
96 typedef uint64_t bit_t;
97 typedef uint32_t lbit_t;
98 #elif (BITS == 24)
99 typedef uint32_t bit_t;
100 typedef uint32_t lbit_t;
32 #elif (BITS == 16) 101 #elif (BITS == 16)
33 typedef uint32_t bit_t; 102 typedef uint32_t bit_t;
34 typedef uint16_t lbit_t; 103 typedef uint16_t lbit_t;
35 #else 104 #else
36 typedef uint32_t bit_t; 105 typedef uint32_t bit_t;
37 typedef uint8_t lbit_t; 106 typedef uint8_t lbit_t;
38 #endif 107 #endif
39 108
109 #ifndef USE_RIGHT_JUSTIFY
110 typedef bit_t range_t; // type for storing range_
111 #define MASK ((((bit_t)1) << (BITS)) - 1)
112 #else
113 typedef uint32_t range_t; // range_ only uses 8bits here. No need for bit_t.
114 #endif
115
40 //------------------------------------------------------------------------------ 116 //------------------------------------------------------------------------------
41 // Bitreader and code-tree reader 117 // Bitreader
42 118
43 typedef struct VP8BitReader VP8BitReader; 119 typedef struct VP8BitReader VP8BitReader;
44 struct VP8BitReader { 120 struct VP8BitReader {
45 const uint8_t* buf_; // next byte to be read 121 const uint8_t* buf_; // next byte to be read
46 const uint8_t* buf_end_; // end of read buffer 122 const uint8_t* buf_end_; // end of read buffer
47 int eof_; // true if input is exhausted 123 int eof_; // true if input is exhausted
48 124
49 // boolean decoder 125 // boolean decoder
50 bit_t range_; // current range minus 1. In [127, 254] interval. 126 range_t range_; // current range minus 1. In [127, 254] interval.
51 bit_t value_; // current value 127 bit_t value_; // current value
52 int missing_; // number of missing bits in value_ (8bit) 128 int bits_; // number of valid bits left
53 }; 129 };
54 130
55 // Initialize the bit reader and the boolean decoder. 131 // Initialize the bit reader and the boolean decoder.
56 void VP8InitBitReader(VP8BitReader* const br, 132 void VP8InitBitReader(VP8BitReader* const br,
57 const uint8_t* const start, const uint8_t* const end); 133 const uint8_t* const start, const uint8_t* const end);
58 134
59 // return the next value made of 'num_bits' bits 135 // return the next value made of 'num_bits' bits
60 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits); 136 uint32_t VP8GetValue(VP8BitReader* const br, int num_bits);
61 static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) { 137 static WEBP_INLINE uint32_t VP8Get(VP8BitReader* const br) {
62 return VP8GetValue(br, 1); 138 return VP8GetValue(br, 1);
63 } 139 }
64 140
65 // return the next value with sign-extension. 141 // return the next value with sign-extension.
66 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits); 142 int32_t VP8GetSignedValue(VP8BitReader* const br, int num_bits);
67 143
68 // Read a bit with proba 'prob'. Speed-critical function! 144 // Read a bit with proba 'prob'. Speed-critical function!
69 extern const uint8_t kVP8Log2Range[128]; 145 extern const uint8_t kVP8Log2Range[128];
70 extern const bit_t kVP8NewRange[128]; 146 extern const range_t kVP8NewRange[128];
71 147
72 void VP8LoadFinalBytes(VP8BitReader* const br); // special case for the tail 148 void VP8LoadFinalBytes(VP8BitReader* const br); // special case for the tail
73 149
74 static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) { 150 static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
75 assert(br && br->buf_); 151 assert(br != NULL && br->buf_ != NULL);
76 // Read 'BITS' bits at a time if possible. 152 // Read 'BITS' bits at a time if possible.
77 if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) { 153 if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) {
78 // convert memory type to register type (with some zero'ing!) 154 // convert memory type to register type (with some zero'ing!)
79 bit_t bits; 155 bit_t bits;
80 lbit_t in_bits = *(lbit_t*)br->buf_; 156 lbit_t in_bits = *(lbit_t*)br->buf_;
81 br->buf_ += (BITS) >> 3; 157 br->buf_ += (BITS) >> 3;
82 #if !defined(__BIG_ENDIAN__) 158 #if !defined(__BIG_ENDIAN__)
83 #if (BITS == 32) 159 #if (BITS > 32)
160 // gcc 4.3 has builtin functions for swap32/swap64
161 #if defined(__GNUC__) && \
162 (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3))
163 bits = (bit_t)__builtin_bswap64(in_bits);
164 #elif defined(_MSC_VER)
165 bits = (bit_t)_byteswap_uint64(in_bits);
166 #elif defined(__x86_64__)
167 __asm__ volatile("bswapq %0" : "=r"(bits) : "0"(in_bits));
168 #else // generic code for swapping 64-bit values (suggested by bdb@)
169 bits = (bit_t)in_bits;
170 bits = ((bits & 0xffffffff00000000ull) >> 32) |
171 ((bits & 0x00000000ffffffffull) << 32);
172 bits = ((bits & 0xffff0000ffff0000ull) >> 16) |
173 ((bits & 0x0000ffff0000ffffull) << 16);
174 bits = ((bits & 0xff00ff00ff00ff00ull) >> 8) |
175 ((bits & 0x00ff00ff00ff00ffull) << 8);
176 #endif
177 bits >>= 64 - BITS;
178 #elif (BITS >= 24)
84 #if defined(__i386__) || defined(__x86_64__) 179 #if defined(__i386__) || defined(__x86_64__)
85 __asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits)); 180 __asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits));
86 bits = (bit_t)in_bits; // 32b -> 64b zero-extension 181 bits = (bit_t)in_bits; // 24b/32b -> 32b/64b zero-extension
87 #elif defined(_MSC_VER) 182 #elif defined(_MSC_VER)
88 bits = _byteswap_ulong(in_bits); 183 bits = (bit_t)_byteswap_ulong(in_bits);
89 #else 184 #else
90 bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00) 185 bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00)
91 | ((in_bits << 8) & 0xff0000) | (in_bits << 24); 186 | ((in_bits << 8) & 0xff0000) | (in_bits << 24);
92 #endif // x86 187 #endif // x86
188 bits >>= (32 - BITS);
93 #elif (BITS == 16) 189 #elif (BITS == 16)
94 // gcc will recognize a 'rorw $8, ...' here: 190 // gcc will recognize a 'rorw $8, ...' here:
95 bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8); 191 bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
96 #endif 192 #else // BITS == 8
97 #else // LITTLE_ENDIAN
98 bits = (bit_t)in_bits; 193 bits = (bit_t)in_bits;
99 #endif 194 #endif
100 br->value_ |= bits << br->missing_; 195 #else // BIG_ENDIAN
101 br->missing_ -= (BITS); 196 bits = (bit_t)in_bits;
197 #endif
198 #ifndef USE_RIGHT_JUSTIFY
199 br->value_ |= bits << (-br->bits_);
200 #else
201 br->value_ = bits | (br->value_ << (BITS));
202 #endif
203 br->bits_ += (BITS);
102 } else { 204 } else {
103 VP8LoadFinalBytes(br); // no need to be inlined 205 VP8LoadFinalBytes(br); // no need to be inlined
104 } 206 }
105 } 207 }
106 208
107 static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, bit_t split) { 209 static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, range_t split) {
108 const bit_t value_split = split | (MASK); 210 if (br->bits_ < 0) { // Make sure we have a least BITS bits in 'value_'
109 if (br->missing_ > 0) { // Make sure we have a least BITS bits in 'value_'
110 VP8LoadNewBytes(br); 211 VP8LoadNewBytes(br);
111 } 212 }
112 if (br->value_ > value_split) { 213 #ifndef USE_RIGHT_JUSTIFY
113 br->range_ -= value_split + 1; 214 split |= (MASK);
114 br->value_ -= value_split + 1; 215 if (br->value_ > split) {
216 br->range_ -= split + 1;
217 br->value_ -= split + 1;
115 return 1; 218 return 1;
116 } else { 219 } else {
117 br->range_ = value_split; 220 br->range_ = split;
118 return 0; 221 return 0;
119 } 222 }
223 #else
224 {
225 const int pos = br->bits_;
226 const range_t value = (range_t)(br->value_ >> pos);
227 if (value > split) {
228 br->range_ -= split + 1;
229 br->value_ -= (bit_t)(split + 1) << pos;
230 return 1;
231 } else {
232 br->range_ = split;
233 return 0;
234 }
235 }
236 #endif
120 } 237 }
121 238
122 static WEBP_INLINE void VP8Shift(VP8BitReader* const br) { 239 static WEBP_INLINE void VP8Shift(VP8BitReader* const br) {
240 #ifndef USE_RIGHT_JUSTIFY
123 // range_ is in [0..127] interval here. 241 // range_ is in [0..127] interval here.
124 const int idx = br->range_ >> (BITS); 242 const bit_t idx = br->range_ >> (BITS);
125 const int shift = kVP8Log2Range[idx]; 243 const int shift = kVP8Log2Range[idx];
126 br->range_ = kVP8NewRange[idx]; 244 br->range_ = kVP8NewRange[idx];
127 br->value_ <<= shift; 245 br->value_ <<= shift;
128 br->missing_ += shift; 246 br->bits_ -= shift;
247 #else
248 const int shift = kVP8Log2Range[br->range_];
249 assert(br->range_ < (range_t)128);
250 br->range_ = kVP8NewRange[br->range_];
251 br->bits_ -= shift;
252 #endif
129 } 253 }
130
131 static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) { 254 static WEBP_INLINE int VP8GetBit(VP8BitReader* const br, int prob) {
255 #ifndef USE_RIGHT_JUSTIFY
132 // It's important to avoid generating a 64bit x 64bit multiply here. 256 // It's important to avoid generating a 64bit x 64bit multiply here.
133 // We just need an 8b x 8b after all. 257 // We just need an 8b x 8b after all.
134 const bit_t split = 258 const range_t split =
135 (bit_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8); 259 (range_t)((uint32_t)(br->range_ >> (BITS)) * prob) << ((BITS) - 8);
136 const int bit = VP8BitUpdate(br, split); 260 const int bit = VP8BitUpdate(br, split);
137 if (br->range_ <= (((bit_t)0x7e << (BITS)) | (MASK))) { 261 if (br->range_ <= (((range_t)0x7e << (BITS)) | (MASK))) {
138 VP8Shift(br); 262 VP8Shift(br);
139 } 263 }
140 return bit; 264 return bit;
265 #else
266 const range_t split = (br->range_ * prob) >> 8;
267 const int bit = VP8BitUpdate(br, split);
268 if (br->range_ <= (range_t)0x7e) {
269 VP8Shift(br);
270 }
271 return bit;
272 #endif
141 } 273 }
142 274
143 static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) { 275 static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) {
144 const bit_t split = (br->range_ >> 1); 276 const range_t split = (br->range_ >> 1);
145 const int bit = VP8BitUpdate(br, split); 277 const int bit = VP8BitUpdate(br, split);
146 VP8Shift(br); 278 VP8Shift(br);
147 return bit ? -v : v; 279 return bit ? -v : v;
148 } 280 }
149 281
150 282
151 // ----------------------------------------------------------------------------- 283 // -----------------------------------------------------------------------------
152 // Bitreader 284 // Bitreader for lossless format
285
286 typedef uint64_t vp8l_val_t; // right now, this bit-reader can only use 64bit.
153 287
154 typedef struct { 288 typedef struct {
155 uint64_t val_; 289 vp8l_val_t val_; // pre-fetched bits
156 const uint8_t* buf_; 290 const uint8_t* buf_; // input byte buffer
157 size_t len_; 291 size_t len_; // buffer length
158 size_t pos_; 292 size_t pos_; // byte position in buf_
159 int bit_pos_; 293 int bit_pos_; // current bit-reading position in val_
160 int eos_; 294 int eos_; // bitstream is finished
161 int error_; 295 int error_; // an error occurred (buffer overflow attempt...)
162 } VP8LBitReader; 296 } VP8LBitReader;
163 297
164 void VP8LInitBitReader(VP8LBitReader* const br, 298 void VP8LInitBitReader(VP8LBitReader* const br,
165 const uint8_t* const start, 299 const uint8_t* const start,
166 size_t length); 300 size_t length);
167 301
168 // Sets a new data buffer. 302 // Sets a new data buffer.
169 void VP8LBitReaderSetBuffer(VP8LBitReader* const br, 303 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
170 const uint8_t* const buffer, size_t length); 304 const uint8_t* const buffer, size_t length);
171 305
172 // Reads the specified number of bits from Read Buffer. 306 // 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. 307 // 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. 308 // Flags eos if this read attempt is going to cross the read buffer.
175 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits); 309 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits);
176 310
177 // Reads one bit from Read Buffer. Flags an error in case end_of_stream. 311 // Return the prefetched bits, so they can be looked up.
178 // Flags eos after reading last bit from the buffer. 312 static WEBP_INLINE uint32_t VP8LPrefetchBits(VP8LBitReader* const br) {
179 uint32_t VP8LReadOneBit(VP8LBitReader* const br); 313 return (uint32_t)(br->val_ >> br->bit_pos_);
314 }
180 315
181 // VP8LReadOneBitUnsafe is faster than VP8LReadOneBit, but it can be called only 316 // Discard 'num_bits' bits from the cache.
182 // 32 times after the last VP8LFillBitWindow. Any subsequent calls 317 static WEBP_INLINE void VP8LDiscardBits(VP8LBitReader* const br, int num_bits) {
183 // (without VP8LFillBitWindow) will return invalid data. 318 br->bit_pos_ += num_bits;
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 } 319 }
189 320
190 // Advances the Read buffer by 4 bytes to make room for reading next 32 bits. 321 // Advances the Read buffer by 4 bytes to make room for reading next 32 bits.
191 void VP8LFillBitWindow(VP8LBitReader* const br); 322 void VP8LFillBitWindow(VP8LBitReader* const br);
192 323
193 #if defined(__cplusplus) || defined(c_plusplus) 324 #if defined(__cplusplus) || defined(c_plusplus)
194 } // extern "C" 325 } // extern "C"
195 #endif 326 #endif
196 327
197 #endif /* WEBP_UTILS_BIT_READER_H_ */ 328 #endif /* WEBP_UTILS_BIT_READER_H_ */
OLDNEW
« no previous file with comments | « third_party/libwebp/libwebp.gyp ('k') | third_party/libwebp/utils/bit_reader.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698