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

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

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase around clang-cl fix Created 4 years, 12 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
OLDNEW
1 // Copyright 2010 Google Inc. All Rights Reserved. 1 // Copyright 2010 Google Inc. All Rights Reserved.
2 // 2 //
3 // Use of this source code is governed by a BSD-style license 3 // Use of this source code is governed by a BSD-style license
4 // that can be found in the COPYING file in the root of the source 4 // that can be found in the COPYING file in the root of the source
5 // tree. An additional intellectual property rights grant can be found 5 // tree. An additional intellectual property rights grant can be found
6 // in the file PATENTS. All contributing project authors may 6 // in the file PATENTS. All contributing project authors may
7 // be found in the AUTHORS file in the root of the source tree. 7 // be found in the AUTHORS file in the root of the source tree.
8 // ----------------------------------------------------------------------------- 8 // -----------------------------------------------------------------------------
9 // 9 //
10 // Boolean decoder non-inlined methods 10 // Boolean decoder non-inlined methods
11 // 11 //
12 // Author: Skal (pascal.massimino@gmail.com) 12 // Author: Skal (pascal.massimino@gmail.com)
13 13
14 #ifdef HAVE_CONFIG_H 14 #ifdef HAVE_CONFIG_H
15 #include "../webp/config.h" 15 #include "../webp/config.h"
16 #endif 16 #endif
17 17
18 #include "./bit_reader_inl.h" 18 #include "./bit_reader_inl.h"
19 19
20 //------------------------------------------------------------------------------ 20 //------------------------------------------------------------------------------
21 // VP8BitReader 21 // VP8BitReader
22 22
23 void VP8BitReaderSetBuffer(VP8BitReader* const br,
24 const uint8_t* const start,
25 size_t size) {
26 br->buf_ = start;
27 br->buf_end_ = start + size;
28 br->buf_max_ =
29 (size >= sizeof(lbit_t)) ? start + size - sizeof(lbit_t) + 1
30 : start;
31 }
32
23 void VP8InitBitReader(VP8BitReader* const br, 33 void VP8InitBitReader(VP8BitReader* const br,
24 const uint8_t* const start, const uint8_t* const end) { 34 const uint8_t* const start, size_t size) {
25 assert(br != NULL); 35 assert(br != NULL);
26 assert(start != NULL); 36 assert(start != NULL);
27 assert(start <= end); 37 assert(size < (1u << 31)); // limit ensured by format and upstream checks
28 br->range_ = 255 - 1; 38 br->range_ = 255 - 1;
29 br->buf_ = start;
30 br->buf_end_ = end;
31 br->value_ = 0; 39 br->value_ = 0;
32 br->bits_ = -8; // to load the very first 8bits 40 br->bits_ = -8; // to load the very first 8bits
33 br->eof_ = 0; 41 br->eof_ = 0;
42 VP8BitReaderSetBuffer(br, start, size);
34 VP8LoadNewBytes(br); 43 VP8LoadNewBytes(br);
35 } 44 }
36 45
37 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) { 46 void VP8RemapBitReader(VP8BitReader* const br, ptrdiff_t offset) {
38 if (br->buf_ != NULL) { 47 if (br->buf_ != NULL) {
39 br->buf_ += offset; 48 br->buf_ += offset;
40 br->buf_end_ += offset; 49 br->buf_end_ += offset;
50 br->buf_max_ += offset;
41 } 51 }
42 } 52 }
43 53
44 const uint8_t kVP8Log2Range[128] = { 54 const uint8_t kVP8Log2Range[128] = {
45 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 55 7, 6, 6, 5, 5, 5, 5, 4, 4, 4, 4, 4, 4, 4, 4,
46 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 56 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
47 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 57 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
48 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 58 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
49 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 59 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
50 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 60 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
51 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 61 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
52 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 62 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
53 0 63 0
54 }; 64 };
55 65
56 // range = ((range - 1) << kVP8Log2Range[range]) + 1 66 // range = ((range - 1) << kVP8Log2Range[range]) + 1
57 const range_t kVP8NewRange[128] = { 67 const uint8_t kVP8NewRange[128] = {
58 127, 127, 191, 127, 159, 191, 223, 127, 68 127, 127, 191, 127, 159, 191, 223, 127,
59 143, 159, 175, 191, 207, 223, 239, 127, 69 143, 159, 175, 191, 207, 223, 239, 127,
60 135, 143, 151, 159, 167, 175, 183, 191, 70 135, 143, 151, 159, 167, 175, 183, 191,
61 199, 207, 215, 223, 231, 239, 247, 127, 71 199, 207, 215, 223, 231, 239, 247, 127,
62 131, 135, 139, 143, 147, 151, 155, 159, 72 131, 135, 139, 143, 147, 151, 155, 159,
63 163, 167, 171, 175, 179, 183, 187, 191, 73 163, 167, 171, 175, 179, 183, 187, 191,
64 195, 199, 203, 207, 211, 215, 219, 223, 74 195, 199, 203, 207, 211, 215, 219, 223,
65 227, 231, 235, 239, 243, 247, 251, 127, 75 227, 231, 235, 239, 243, 247, 251, 127,
66 129, 131, 133, 135, 137, 139, 141, 143, 76 129, 131, 133, 135, 137, 139, 141, 143,
67 145, 147, 149, 151, 153, 155, 157, 159, 77 145, 147, 149, 151, 153, 155, 157, 159,
68 161, 163, 165, 167, 169, 171, 173, 175, 78 161, 163, 165, 167, 169, 171, 173, 175,
69 177, 179, 181, 183, 185, 187, 189, 191, 79 177, 179, 181, 183, 185, 187, 189, 191,
70 193, 195, 197, 199, 201, 203, 205, 207, 80 193, 195, 197, 199, 201, 203, 205, 207,
71 209, 211, 213, 215, 217, 219, 221, 223, 81 209, 211, 213, 215, 217, 219, 221, 223,
72 225, 227, 229, 231, 233, 235, 237, 239, 82 225, 227, 229, 231, 233, 235, 237, 239,
73 241, 243, 245, 247, 249, 251, 253, 127 83 241, 243, 245, 247, 249, 251, 253, 127
74 }; 84 };
75 85
76 void VP8LoadFinalBytes(VP8BitReader* const br) { 86 void VP8LoadFinalBytes(VP8BitReader* const br) {
77 assert(br != NULL && br->buf_ != NULL); 87 assert(br != NULL && br->buf_ != NULL);
78 // Only read 8bits at a time 88 // Only read 8bits at a time
79 if (br->buf_ < br->buf_end_) { 89 if (br->buf_ < br->buf_end_) {
80 br->bits_ += 8; 90 br->bits_ += 8;
81 br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8); 91 br->value_ = (bit_t)(*br->buf_++) | (br->value_ << 8);
82 } else if (!br->eof_) { 92 } else if (!br->eof_) {
83 br->value_ <<= 8; 93 br->value_ <<= 8;
84 br->bits_ += 8; 94 br->bits_ += 8;
85 br->eof_ = 1; 95 br->eof_ = 1;
96 } else {
97 br->bits_ = 0; // This is to avoid undefined behaviour with shifts.
86 } 98 }
87 } 99 }
88 100
89 //------------------------------------------------------------------------------ 101 //------------------------------------------------------------------------------
90 // Higher-level calls 102 // Higher-level calls
91 103
92 uint32_t VP8GetValue(VP8BitReader* const br, int bits) { 104 uint32_t VP8GetValue(VP8BitReader* const br, int bits) {
93 uint32_t v = 0; 105 uint32_t v = 0;
94 while (bits-- > 0) { 106 while (bits-- > 0) {
95 v |= VP8GetBit(br, 0x80) << bits; 107 v |= VP8GetBit(br, 0x80) << bits;
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
129 size_t i; 141 size_t i;
130 vp8l_val_t value = 0; 142 vp8l_val_t value = 0;
131 assert(br != NULL); 143 assert(br != NULL);
132 assert(start != NULL); 144 assert(start != NULL);
133 assert(length < 0xfffffff8u); // can't happen with a RIFF chunk. 145 assert(length < 0xfffffff8u); // can't happen with a RIFF chunk.
134 146
135 br->len_ = length; 147 br->len_ = length;
136 br->val_ = 0; 148 br->val_ = 0;
137 br->bit_pos_ = 0; 149 br->bit_pos_ = 0;
138 br->eos_ = 0; 150 br->eos_ = 0;
139 br->error_ = 0;
140 151
141 if (length > sizeof(br->val_)) { 152 if (length > sizeof(br->val_)) {
142 length = sizeof(br->val_); 153 length = sizeof(br->val_);
143 } 154 }
144 for (i = 0; i < length; ++i) { 155 for (i = 0; i < length; ++i) {
145 value |= (vp8l_val_t)start[i] << (8 * i); 156 value |= (vp8l_val_t)start[i] << (8 * i);
146 } 157 }
147 br->val_ = value; 158 br->val_ = value;
148 br->pos_ = length; 159 br->pos_ = length;
149 br->buf_ = start; 160 br->buf_ = start;
150 } 161 }
151 162
152 void VP8LBitReaderSetBuffer(VP8LBitReader* const br, 163 void VP8LBitReaderSetBuffer(VP8LBitReader* const br,
153 const uint8_t* const buf, size_t len) { 164 const uint8_t* const buf, size_t len) {
154 assert(br != NULL); 165 assert(br != NULL);
155 assert(buf != NULL); 166 assert(buf != NULL);
156 assert(len < 0xfffffff8u); // can't happen with a RIFF chunk. 167 assert(len < 0xfffffff8u); // can't happen with a RIFF chunk.
157 br->buf_ = buf; 168 br->buf_ = buf;
158 br->len_ = len; 169 br->len_ = len;
159 // pos_ > len_ should be considered a param error. 170 // pos_ > len_ should be considered a param error.
160 br->error_ = (br->pos_ > br->len_); 171 br->eos_ = (br->pos_ > br->len_) || VP8LIsEndOfStream(br);
161 br->eos_ = br->error_ || VP8LIsEndOfStream(br); 172 }
173
174 static void VP8LSetEndOfStream(VP8LBitReader* const br) {
175 br->eos_ = 1;
176 br->bit_pos_ = 0; // To avoid undefined behaviour with shifts.
162 } 177 }
163 178
164 // If not at EOS, reload up to VP8L_LBITS byte-by-byte 179 // If not at EOS, reload up to VP8L_LBITS byte-by-byte
165 static void ShiftBytes(VP8LBitReader* const br) { 180 static void ShiftBytes(VP8LBitReader* const br) {
166 while (br->bit_pos_ >= 8 && br->pos_ < br->len_) { 181 while (br->bit_pos_ >= 8 && br->pos_ < br->len_) {
167 br->val_ >>= 8; 182 br->val_ >>= 8;
168 br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8); 183 br->val_ |= ((vp8l_val_t)br->buf_[br->pos_]) << (VP8L_LBITS - 8);
169 ++br->pos_; 184 ++br->pos_;
170 br->bit_pos_ -= 8; 185 br->bit_pos_ -= 8;
171 } 186 }
172 br->eos_ = VP8LIsEndOfStream(br); 187 if (VP8LIsEndOfStream(br)) {
188 VP8LSetEndOfStream(br);
189 }
173 } 190 }
174 191
175 void VP8LDoFillBitWindow(VP8LBitReader* const br) { 192 void VP8LDoFillBitWindow(VP8LBitReader* const br) {
176 assert(br->bit_pos_ >= VP8L_WBITS); 193 assert(br->bit_pos_ >= VP8L_WBITS);
177 // TODO(jzern): given the fixed read size it may be possible to force 194 // TODO(jzern): given the fixed read size it may be possible to force
178 // alignment in this block. 195 // alignment in this block.
179 #if defined(VP8L_USE_UNALIGNED_LOAD) 196 #if defined(VP8L_USE_UNALIGNED_LOAD)
180 if (br->pos_ + sizeof(br->val_) < br->len_) { 197 if (br->pos_ + sizeof(br->val_) < br->len_) {
181 br->val_ >>= VP8L_WBITS; 198 br->val_ >>= VP8L_WBITS;
182 br->bit_pos_ -= VP8L_WBITS; 199 br->bit_pos_ -= VP8L_WBITS;
183 // The expression below needs a little-endian arch to work correctly. 200 // The expression below needs a little-endian arch to work correctly.
184 // This gives a large speedup for decoding speed. 201 // This gives a large speedup for decoding speed.
185 br->val_ |= (vp8l_val_t)*(const uint32_t*)(br->buf_ + br->pos_) << 202 br->val_ |= (vp8l_val_t)WebPMemToUint32(br->buf_ + br->pos_) <<
186 (VP8L_LBITS - VP8L_WBITS); 203 (VP8L_LBITS - VP8L_WBITS);
187 br->pos_ += VP8L_LOG8_WBITS; 204 br->pos_ += VP8L_LOG8_WBITS;
188 return; 205 return;
189 } 206 }
190 #endif 207 #endif
191 ShiftBytes(br); // Slow path. 208 ShiftBytes(br); // Slow path.
192 } 209 }
193 210
194 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) { 211 uint32_t VP8LReadBits(VP8LBitReader* const br, int n_bits) {
195 assert(n_bits >= 0); 212 assert(n_bits >= 0);
196 // Flag an error if end_of_stream or n_bits is more than allowed limit. 213 // Flag an error if end_of_stream or n_bits is more than allowed limit.
197 if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) { 214 if (!br->eos_ && n_bits <= VP8L_MAX_NUM_BIT_READ) {
198 const uint32_t val = 215 const uint32_t val = VP8LPrefetchBits(br) & kBitMask[n_bits];
199 (uint32_t)(br->val_ >> br->bit_pos_) & kBitMask[n_bits];
200 const int new_bits = br->bit_pos_ + n_bits; 216 const int new_bits = br->bit_pos_ + n_bits;
201 br->bit_pos_ = new_bits; 217 br->bit_pos_ = new_bits;
202 ShiftBytes(br); 218 ShiftBytes(br);
203 return val; 219 return val;
204 } else { 220 } else {
205 br->error_ = 1; 221 VP8LSetEndOfStream(br);
206 return 0; 222 return 0;
207 } 223 }
208 } 224 }
209 225
210 //------------------------------------------------------------------------------ 226 //------------------------------------------------------------------------------
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698