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

Side by Side Diff: third_party/libwebp/dec/vp8.c

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 // main entry for the decoder 8 // main entry for the decoder
9 // 9 //
10 // Author: Skal (pascal.massimino@gmail.com) 10 // Author: Skal (pascal.massimino@gmail.com)
11 11
12 #include <stdlib.h> 12 #include <stdlib.h>
13 #include "vp8i.h" 13
14 #include "webpi.h" 14 #include "./vp8i.h"
15 #include "./vp8li.h"
16 #include "./webpi.h"
17 #include "../utils/bit_reader.h"
15 18
16 #if defined(__cplusplus) || defined(c_plusplus) 19 #if defined(__cplusplus) || defined(c_plusplus)
17 extern "C" { 20 extern "C" {
18 #endif 21 #endif
19 22
20 //------------------------------------------------------------------------------ 23 //------------------------------------------------------------------------------
21 24
22 int WebPGetDecoderVersion(void) { 25 int WebPGetDecoderVersion(void) {
23 return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION; 26 return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION;
24 } 27 }
25 28
26 //------------------------------------------------------------------------------ 29 //------------------------------------------------------------------------------
27 // VP8Decoder 30 // VP8Decoder
28 31
29 static void SetOk(VP8Decoder* const dec) { 32 static void SetOk(VP8Decoder* const dec) {
30 dec->status_ = VP8_STATUS_OK; 33 dec->status_ = VP8_STATUS_OK;
31 dec->error_msg_ = "OK"; 34 dec->error_msg_ = "OK";
32 } 35 }
33 36
34 int VP8InitIoInternal(VP8Io* const io, int version) { 37 int VP8InitIoInternal(VP8Io* const io, int version) {
35 if (version != WEBP_DECODER_ABI_VERSION) 38 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
36 return 0; // mismatch error 39 return 0; // mismatch error
37 if (io) { 40 }
41 if (io != NULL) {
38 memset(io, 0, sizeof(*io)); 42 memset(io, 0, sizeof(*io));
39 } 43 }
40 return 1; 44 return 1;
41 } 45 }
42 46
43 VP8Decoder* VP8New(void) { 47 VP8Decoder* VP8New(void) {
44 VP8Decoder* dec = (VP8Decoder*)calloc(1, sizeof(VP8Decoder)); 48 VP8Decoder* const dec = (VP8Decoder*)calloc(1, sizeof(*dec));
45 if (dec) { 49 if (dec != NULL) {
46 SetOk(dec); 50 SetOk(dec);
47 WebPWorkerInit(&dec->worker_); 51 WebPWorkerInit(&dec->worker_);
48 dec->ready_ = 0; 52 dec->ready_ = 0;
49 dec->num_parts_ = 1; 53 dec->num_parts_ = 1;
50 } 54 }
51 return dec; 55 return dec;
52 } 56 }
53 57
54 VP8StatusCode VP8Status(VP8Decoder* const dec) { 58 VP8StatusCode VP8Status(VP8Decoder* const dec) {
55 if (!dec) return VP8_STATUS_INVALID_PARAM; 59 if (!dec) return VP8_STATUS_INVALID_PARAM;
56 return dec->status_; 60 return dec->status_;
57 } 61 }
58 62
59 const char* VP8StatusMessage(VP8Decoder* const dec) { 63 const char* VP8StatusMessage(VP8Decoder* const dec) {
60 if (!dec) return "no object"; 64 if (dec == NULL) return "no object";
61 if (!dec->error_msg_) return "OK"; 65 if (!dec->error_msg_) return "OK";
62 return dec->error_msg_; 66 return dec->error_msg_;
63 } 67 }
64 68
65 void VP8Delete(VP8Decoder* const dec) { 69 void VP8Delete(VP8Decoder* const dec) {
66 if (dec) { 70 if (dec != NULL) {
67 VP8Clear(dec); 71 VP8Clear(dec);
68 free(dec); 72 free(dec);
69 } 73 }
70 } 74 }
71 75
72 int VP8SetError(VP8Decoder* const dec, 76 int VP8SetError(VP8Decoder* const dec,
73 VP8StatusCode error, const char * const msg) { 77 VP8StatusCode error, const char* const msg) {
74 dec->status_ = error; 78 // TODO This check would be unnecessary if alpha decompression was separated
75 dec->error_msg_ = msg; 79 // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to
76 dec->ready_ = 0; 80 // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression
81 // failure.
82 if (dec->status_ == VP8_STATUS_OK) {
83 dec->status_ = error;
84 dec->error_msg_ = msg;
85 dec->ready_ = 0;
86 }
77 return 0; 87 return 0;
78 } 88 }
79 89
80 //------------------------------------------------------------------------------ 90 //------------------------------------------------------------------------------
81 91
82 int VP8GetInfo(const uint8_t* data, uint32_t data_size, uint32_t chunk_size, 92 int VP8CheckSignature(const uint8_t* const data, size_t data_size) {
83 int* width, int* height, int* has_alpha) { 93 return (data_size >= 3 &&
84 if (data_size < 10) { 94 data[0] == 0x9d && data[1] == 0x01 && data[2] == 0x2a);
95 }
96
97 int VP8GetInfo(const uint8_t* data, size_t data_size, size_t chunk_size,
98 int* const width, int* const height) {
99 if (data == NULL || data_size < VP8_FRAME_HEADER_SIZE) {
85 return 0; // not enough data 100 return 0; // not enough data
86 } 101 }
87 // check signature 102 // check signature
88 if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) { 103 if (!VP8CheckSignature(data + 3, data_size - 3)) {
89 return 0; // Wrong signature. 104 return 0; // Wrong signature.
90 } else { 105 } else {
91 const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16); 106 const uint32_t bits = data[0] | (data[1] << 8) | (data[2] << 16);
92 const int key_frame = !(bits & 1); 107 const int key_frame = !(bits & 1);
93 const int w = ((data[7] << 8) | data[6]) & 0x3fff; 108 const int w = ((data[7] << 8) | data[6]) & 0x3fff;
94 const int h = ((data[9] << 8) | data[8]) & 0x3fff; 109 const int h = ((data[9] << 8) | data[8]) & 0x3fff;
95 110
96 if (has_alpha) {
97 #ifdef WEBP_EXPERIMENTAL_FEATURES
98 if (data_size < 11) return 0;
99 *has_alpha = !!(data[10] & 0x80); // the colorspace_ bit
100 #else
101 *has_alpha = 0;
102 #endif
103 }
104 if (!key_frame) { // Not a keyframe. 111 if (!key_frame) { // Not a keyframe.
105 return 0; 112 return 0;
106 } 113 }
107 114
108 if (((bits >> 1) & 7) > 3) { 115 if (((bits >> 1) & 7) > 3) {
109 return 0; // unknown profile 116 return 0; // unknown profile
110 } 117 }
111 if (!((bits >> 4) & 1)) { 118 if (!((bits >> 4) & 1)) {
112 return 0; // first frame is invisible! 119 return 0; // first frame is invisible!
113 } 120 }
114 if (((bits >> 5)) >= chunk_size) { // partition_length 121 if (((bits >> 5)) >= chunk_size) { // partition_length
115 return 0; // inconsistent size information. 122 return 0; // inconsistent size information.
116 } 123 }
117 124
118 if (width) { 125 if (width) {
119 *width = w; 126 *width = w;
120 } 127 }
121 if (height) { 128 if (height) {
122 *height = h; 129 *height = h;
123 } 130 }
124 131
125 return 1; 132 return 1;
126 } 133 }
127 } 134 }
128 135
129 //------------------------------------------------------------------------------ 136 //------------------------------------------------------------------------------
130 // Header parsing 137 // Header parsing
131 138
132 static void ResetSegmentHeader(VP8SegmentHeader* const hdr) { 139 static void ResetSegmentHeader(VP8SegmentHeader* const hdr) {
133 assert(hdr); 140 assert(hdr != NULL);
134 hdr->use_segment_ = 0; 141 hdr->use_segment_ = 0;
135 hdr->update_map_ = 0; 142 hdr->update_map_ = 0;
136 hdr->absolute_delta_ = 1; 143 hdr->absolute_delta_ = 1;
137 memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_)); 144 memset(hdr->quantizer_, 0, sizeof(hdr->quantizer_));
138 memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_)); 145 memset(hdr->filter_strength_, 0, sizeof(hdr->filter_strength_));
139 } 146 }
140 147
141 // Paragraph 9.3 148 // Paragraph 9.3
142 static int ParseSegmentHeader(VP8BitReader* br, 149 static int ParseSegmentHeader(VP8BitReader* br,
143 VP8SegmentHeader* hdr, VP8Proba* proba) { 150 VP8SegmentHeader* hdr, VP8Proba* proba) {
144 assert(br); 151 assert(br != NULL);
145 assert(hdr); 152 assert(hdr != NULL);
146 hdr->use_segment_ = VP8Get(br); 153 hdr->use_segment_ = VP8Get(br);
147 if (hdr->use_segment_) { 154 if (hdr->use_segment_) {
148 hdr->update_map_ = VP8Get(br); 155 hdr->update_map_ = VP8Get(br);
149 if (VP8Get(br)) { // update data 156 if (VP8Get(br)) { // update data
150 int s; 157 int s;
151 hdr->absolute_delta_ = VP8Get(br); 158 hdr->absolute_delta_ = VP8Get(br);
152 for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 159 for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
153 hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0; 160 hdr->quantizer_[s] = VP8Get(br) ? VP8GetSignedValue(br, 7) : 0;
154 } 161 }
155 for (s = 0; s < NUM_MB_SEGMENTS; ++s) { 162 for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
(...skipping 15 matching lines...) Expand all
171 // Paragraph 9.5 178 // Paragraph 9.5
172 // This function returns VP8_STATUS_SUSPENDED if we don't have all the 179 // This function returns VP8_STATUS_SUSPENDED if we don't have all the
173 // necessary data in 'buf'. 180 // necessary data in 'buf'.
174 // This case is not necessarily an error (for incremental decoding). 181 // This case is not necessarily an error (for incremental decoding).
175 // Still, no bitreader is ever initialized to make it possible to read 182 // Still, no bitreader is ever initialized to make it possible to read
176 // unavailable memory. 183 // unavailable memory.
177 // If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA 184 // If we don't even have the partitions' sizes, than VP8_STATUS_NOT_ENOUGH_DATA
178 // is returned, and this is an unrecoverable error. 185 // is returned, and this is an unrecoverable error.
179 // If the partitions were positioned ok, VP8_STATUS_OK is returned. 186 // If the partitions were positioned ok, VP8_STATUS_OK is returned.
180 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, 187 static VP8StatusCode ParsePartitions(VP8Decoder* const dec,
181 const uint8_t* buf, uint32_t size) { 188 const uint8_t* buf, size_t size) {
182 VP8BitReader* const br = &dec->br_; 189 VP8BitReader* const br = &dec->br_;
183 const uint8_t* sz = buf; 190 const uint8_t* sz = buf;
184 const uint8_t* buf_end = buf + size; 191 const uint8_t* buf_end = buf + size;
185 const uint8_t* part_start; 192 const uint8_t* part_start;
186 int last_part; 193 int last_part;
187 int p; 194 int p;
188 195
189 dec->num_parts_ = 1 << VP8GetValue(br, 2); 196 dec->num_parts_ = 1 << VP8GetValue(br, 2);
190 last_part = dec->num_parts_ - 1; 197 last_part = dec->num_parts_ - 1;
191 part_start = buf + last_part * 3; 198 part_start = buf + last_part * 3;
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } else { 249 } else {
243 dec->filter_levels_[0] = hdr->level_; 250 dec->filter_levels_[0] = hdr->level_;
244 } 251 }
245 } 252 }
246 return !br->eof_; 253 return !br->eof_;
247 } 254 }
248 255
249 // Topmost call 256 // Topmost call
250 int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { 257 int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
251 const uint8_t* buf; 258 const uint8_t* buf;
252 uint32_t buf_size; 259 size_t buf_size;
253 uint32_t vp8_chunk_size;
254 uint32_t bytes_skipped;
255 VP8FrameHeader* frm_hdr; 260 VP8FrameHeader* frm_hdr;
256 VP8PictureHeader* pic_hdr; 261 VP8PictureHeader* pic_hdr;
257 VP8BitReader* br; 262 VP8BitReader* br;
258 VP8StatusCode status; 263 VP8StatusCode status;
264 WebPHeaderStructure headers;
259 265
260 if (dec == NULL) { 266 if (dec == NULL) {
261 return 0; 267 return 0;
262 } 268 }
263 SetOk(dec); 269 SetOk(dec);
264 if (io == NULL) { 270 if (io == NULL) {
265 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 271 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
266 "null VP8Io passed to VP8GetHeaders()"); 272 "null VP8Io passed to VP8GetHeaders()");
267 } 273 }
268 274
269 buf = io->data;
270 buf_size = io->data_size;
271
272 // Process Pre-VP8 chunks. 275 // Process Pre-VP8 chunks.
273 status = WebPParseHeaders(&buf, &buf_size, &vp8_chunk_size, &bytes_skipped); 276 headers.data = io->data;
277 headers.data_size = io->data_size;
278 status = WebPParseHeaders(&headers);
274 if (status != VP8_STATUS_OK) { 279 if (status != VP8_STATUS_OK) {
275 return VP8SetError(dec, status, "Incorrect/incomplete header."); 280 return VP8SetError(dec, status, "Incorrect/incomplete header.");
276 } 281 }
282 if (headers.is_lossless) {
283 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
284 "Unexpected lossless format encountered.");
285 }
286
287 if (dec->alpha_data_ == NULL) {
288 assert(dec->alpha_data_size_ == 0);
289 // We have NOT set alpha data yet. Set it now.
290 // (This is to ensure that dec->alpha_data_ is NOT reset to NULL if
291 // WebPParseHeaders() is called more than once, as in incremental decoding
292 // case.)
293 dec->alpha_data_ = headers.alpha_data;
294 dec->alpha_data_size_ = headers.alpha_data_size;
295 }
277 296
278 // Process the VP8 frame header. 297 // Process the VP8 frame header.
298 buf = headers.data + headers.offset;
299 buf_size = headers.data_size - headers.offset;
300 assert(headers.data_size >= headers.offset); // WebPParseHeaders' guarantee
279 if (buf_size < 4) { 301 if (buf_size < 4) {
280 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 302 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
281 "Truncated header."); 303 "Truncated header.");
282 } 304 }
283 305
284 // Paragraph 9.1 306 // Paragraph 9.1
285 { 307 {
286 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 308 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
287 frm_hdr = &dec->frm_hdr_; 309 frm_hdr = &dec->frm_hdr_;
288 frm_hdr->key_frame_ = !(bits & 1); 310 frm_hdr->key_frame_ = !(bits & 1);
(...skipping 10 matching lines...) Expand all
299 buf_size -= 3; 321 buf_size -= 3;
300 } 322 }
301 323
302 pic_hdr = &dec->pic_hdr_; 324 pic_hdr = &dec->pic_hdr_;
303 if (frm_hdr->key_frame_) { 325 if (frm_hdr->key_frame_) {
304 // Paragraph 9.2 326 // Paragraph 9.2
305 if (buf_size < 7) { 327 if (buf_size < 7) {
306 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 328 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
307 "cannot parse picture header"); 329 "cannot parse picture header");
308 } 330 }
309 if (buf[0] != 0x9d || buf[1] != 0x01 || buf[2] != 0x2a) { 331 if (!VP8CheckSignature(buf, buf_size)) {
310 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 332 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
311 "Bad code word"); 333 "Bad code word");
312 } 334 }
313 pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; 335 pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff;
314 pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 336 pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2
315 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; 337 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff;
316 pic_hdr->yscale_ = buf[6] >> 6; 338 pic_hdr->yscale_ = buf[6] >> 6;
317 buf += 7; 339 buf += 7;
318 buf_size -= 7; 340 buf_size -= 7;
319 341
(...skipping 16 matching lines...) Expand all
336 dec->segment_ = 0; // default for intra 358 dec->segment_ = 0; // default for intra
337 } 359 }
338 360
339 // Check if we have all the partition #0 available, and initialize dec->br_ 361 // Check if we have all the partition #0 available, and initialize dec->br_
340 // to read this partition (and this partition only). 362 // to read this partition (and this partition only).
341 if (frm_hdr->partition_length_ > buf_size) { 363 if (frm_hdr->partition_length_ > buf_size) {
342 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 364 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
343 "bad partition length"); 365 "bad partition length");
344 } 366 }
345 367
346 dec->alpha_data_ = NULL;
347 dec->alpha_data_size_ = 0;
348
349 br = &dec->br_; 368 br = &dec->br_;
350 VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_); 369 VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_);
351 buf += frm_hdr->partition_length_; 370 buf += frm_hdr->partition_length_;
352 buf_size -= frm_hdr->partition_length_; 371 buf_size -= frm_hdr->partition_length_;
353 372
354 if (frm_hdr->key_frame_) { 373 if (frm_hdr->key_frame_) {
355 pic_hdr->colorspace_ = VP8Get(br); 374 pic_hdr->colorspace_ = VP8Get(br);
356 pic_hdr->clamp_type_ = VP8Get(br); 375 pic_hdr->clamp_type_ = VP8Get(br);
357 } 376 }
358 if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { 377 if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) {
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
412 #ifdef WEBP_EXPERIMENTAL_FEATURES 431 #ifdef WEBP_EXPERIMENTAL_FEATURES
413 // Extensions 432 // Extensions
414 if (dec->pic_hdr_.colorspace_) { 433 if (dec->pic_hdr_.colorspace_) {
415 const size_t kTrailerSize = 8; 434 const size_t kTrailerSize = 8;
416 const uint8_t kTrailerMarker = 0x01; 435 const uint8_t kTrailerMarker = 0x01;
417 const uint8_t* ext_buf = buf - kTrailerSize; 436 const uint8_t* ext_buf = buf - kTrailerSize;
418 size_t size; 437 size_t size;
419 438
420 if (frm_hdr->partition_length_ < kTrailerSize || 439 if (frm_hdr->partition_length_ < kTrailerSize ||
421 ext_buf[kTrailerSize - 1] != kTrailerMarker) { 440 ext_buf[kTrailerSize - 1] != kTrailerMarker) {
422 Error:
423 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 441 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
424 "RIFF: Inconsistent extra information."); 442 "RIFF: Inconsistent extra information.");
425 } 443 }
426 // Alpha
427 size = (ext_buf[4] << 0) | (ext_buf[5] << 8) | (ext_buf[6] << 16);
428 if (frm_hdr->partition_length_ < size + kTrailerSize) {
429 goto Error;
430 }
431 dec->alpha_data_ = (size > 0) ? ext_buf - size : NULL;
432 dec->alpha_data_size_ = size;
433 444
434 // Layer 445 // Layer
435 size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16); 446 size = (ext_buf[0] << 0) | (ext_buf[1] << 8) | (ext_buf[2] << 16);
436 dec->layer_data_size_ = size; 447 dec->layer_data_size_ = size;
437 dec->layer_data_ = NULL; // will be set later 448 dec->layer_data_ = NULL; // will be set later
438 dec->layer_colorspace_ = ext_buf[3]; 449 dec->layer_colorspace_ = ext_buf[3];
439 } 450 }
440 #endif 451 #endif
441 452
442 // sanitized state 453 // sanitized state
(...skipping 17 matching lines...) Expand all
460 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; 471 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
461 static const uint8_t kZigzag[16] = { 472 static const uint8_t kZigzag[16] = {
462 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 473 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
463 }; 474 };
464 475
465 typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting 476 typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting
466 477
467 // Returns the position of the last non-zero coeff plus one 478 // Returns the position of the last non-zero coeff plus one
468 // (and 0 if there's no coeff at all) 479 // (and 0 if there's no coeff at all)
469 static int GetCoeffs(VP8BitReader* const br, ProbaArray prob, 480 static int GetCoeffs(VP8BitReader* const br, ProbaArray prob,
470 int ctx, const uint16_t dq[2], int n, int16_t* out) { 481 int ctx, const quant_t dq, int n, int16_t* out) {
471 const uint8_t* p = prob[kBands[n]][ctx]; 482 // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'.
483 const uint8_t* p = prob[n][ctx];
472 if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit. 484 if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit.
473 return 0; 485 return 0;
474 } 486 }
475 while (1) { 487 while (1) {
476 ++n; 488 ++n;
477 if (!VP8GetBit(br, p[1])) { 489 if (!VP8GetBit(br, p[1])) {
478 p = prob[kBands[n]][0]; 490 p = prob[kBands[n]][0];
479 } else { // non zero coeff 491 } else { // non zero coeff
480 int v, j; 492 int v, j;
481 if (!VP8GetBit(br, p[2])) { 493 if (!VP8GetBit(br, p[2])) {
(...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after
742 // Exit. 754 // Exit.
743 ok &= VP8ExitCritical(dec, io); 755 ok &= VP8ExitCritical(dec, io);
744 } 756 }
745 757
746 if (!ok) { 758 if (!ok) {
747 VP8Clear(dec); 759 VP8Clear(dec);
748 return 0; 760 return 0;
749 } 761 }
750 762
751 dec->ready_ = 0; 763 dec->ready_ = 0;
752 return 1; 764 return ok;
753 } 765 }
754 766
755 void VP8Clear(VP8Decoder* const dec) { 767 void VP8Clear(VP8Decoder* const dec) {
756 if (dec == NULL) { 768 if (dec == NULL) {
757 return; 769 return;
758 } 770 }
759 if (dec->use_threads_) { 771 if (dec->use_threads_) {
760 WebPWorkerEnd(&dec->worker_); 772 WebPWorkerEnd(&dec->worker_);
761 } 773 }
762 if (dec->mem_) { 774 if (dec->mem_) {
763 free(dec->mem_); 775 free(dec->mem_);
764 } 776 }
765 dec->mem_ = NULL; 777 dec->mem_ = NULL;
766 dec->mem_size_ = 0; 778 dec->mem_size_ = 0;
767 memset(&dec->br_, 0, sizeof(dec->br_)); 779 memset(&dec->br_, 0, sizeof(dec->br_));
768 dec->ready_ = 0; 780 dec->ready_ = 0;
769 } 781 }
770 782
771 //------------------------------------------------------------------------------ 783 //------------------------------------------------------------------------------
772 784
773 #if defined(__cplusplus) || defined(c_plusplus) 785 #if defined(__cplusplus) || defined(c_plusplus)
774 } // extern "C" 786 } // extern "C"
775 #endif 787 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698