OLD | NEW |
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 // main entry for the decoder | 10 // main entry for the decoder |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
68 | 68 |
69 void VP8Delete(VP8Decoder* const dec) { | 69 void VP8Delete(VP8Decoder* const dec) { |
70 if (dec != NULL) { | 70 if (dec != NULL) { |
71 VP8Clear(dec); | 71 VP8Clear(dec); |
72 WebPSafeFree(dec); | 72 WebPSafeFree(dec); |
73 } | 73 } |
74 } | 74 } |
75 | 75 |
76 int VP8SetError(VP8Decoder* const dec, | 76 int VP8SetError(VP8Decoder* const dec, |
77 VP8StatusCode error, const char* const msg) { | 77 VP8StatusCode error, const char* const msg) { |
78 // TODO This check would be unnecessary if alpha decompression was separated | 78 // The oldest error reported takes precedence over the new one. |
79 // from VP8ProcessRow/FinishRow. This avoids setting 'dec->status_' to | |
80 // something other than VP8_STATUS_BITSTREAM_ERROR on alpha decompression | |
81 // failure. | |
82 if (dec->status_ == VP8_STATUS_OK) { | 79 if (dec->status_ == VP8_STATUS_OK) { |
83 dec->status_ = error; | 80 dec->status_ = error; |
84 dec->error_msg_ = msg; | 81 dec->error_msg_ = msg; |
85 dec->ready_ = 0; | 82 dec->ready_ = 0; |
86 } | 83 } |
87 return 0; | 84 return 0; |
88 } | 85 } |
89 | 86 |
90 //------------------------------------------------------------------------------ | 87 //------------------------------------------------------------------------------ |
91 | 88 |
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
186 // unavailable memory. | 183 // unavailable memory. |
187 // 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 |
188 // is returned, and this is an unrecoverable error. | 185 // is returned, and this is an unrecoverable error. |
189 // If the partitions were positioned ok, VP8_STATUS_OK is returned. | 186 // If the partitions were positioned ok, VP8_STATUS_OK is returned. |
190 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, | 187 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, |
191 const uint8_t* buf, size_t size) { | 188 const uint8_t* buf, size_t size) { |
192 VP8BitReader* const br = &dec->br_; | 189 VP8BitReader* const br = &dec->br_; |
193 const uint8_t* sz = buf; | 190 const uint8_t* sz = buf; |
194 const uint8_t* buf_end = buf + size; | 191 const uint8_t* buf_end = buf + size; |
195 const uint8_t* part_start; | 192 const uint8_t* part_start; |
196 int last_part; | 193 size_t size_left = size; |
197 int p; | 194 size_t last_part; |
| 195 size_t p; |
198 | 196 |
199 dec->num_parts_ = 1 << VP8GetValue(br, 2); | 197 dec->num_parts_ = 1 << VP8GetValue(br, 2); |
200 last_part = dec->num_parts_ - 1; | 198 last_part = dec->num_parts_ - 1; |
201 part_start = buf + last_part * 3; | 199 if (size < 3 * last_part) { |
202 if (buf_end < part_start) { | |
203 // we can't even read the sizes with sz[]! That's a failure. | 200 // we can't even read the sizes with sz[]! That's a failure. |
204 return VP8_STATUS_NOT_ENOUGH_DATA; | 201 return VP8_STATUS_NOT_ENOUGH_DATA; |
205 } | 202 } |
| 203 part_start = buf + last_part * 3; |
| 204 size_left -= last_part * 3; |
206 for (p = 0; p < last_part; ++p) { | 205 for (p = 0; p < last_part; ++p) { |
207 const uint32_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); | 206 size_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); |
208 const uint8_t* part_end = part_start + psize; | 207 if (psize > size_left) psize = size_left; |
209 if (part_end > buf_end) part_end = buf_end; | 208 VP8InitBitReader(dec->parts_ + p, part_start, psize); |
210 VP8InitBitReader(dec->parts_ + p, part_start, part_end); | 209 part_start += psize; |
211 part_start = part_end; | 210 size_left -= psize; |
212 sz += 3; | 211 sz += 3; |
213 } | 212 } |
214 VP8InitBitReader(dec->parts_ + last_part, part_start, buf_end); | 213 VP8InitBitReader(dec->parts_ + last_part, part_start, size_left); |
215 return (part_start < buf_end) ? VP8_STATUS_OK : | 214 return (part_start < buf_end) ? VP8_STATUS_OK : |
216 VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data | 215 VP8_STATUS_SUSPENDED; // Init is ok, but there's not enough data |
217 } | 216 } |
218 | 217 |
219 // Paragraph 9.4 | 218 // Paragraph 9.4 |
220 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { | 219 static int ParseFilterHeader(VP8BitReader* br, VP8Decoder* const dec) { |
221 VP8FilterHeader* const hdr = &dec->filter_hdr_; | 220 VP8FilterHeader* const hdr = &dec->filter_hdr_; |
222 hdr->simple_ = VP8Get(br); | 221 hdr->simple_ = VP8Get(br); |
223 hdr->level_ = VP8GetValue(br, 6); | 222 hdr->level_ = VP8GetValue(br, 6); |
224 hdr->sharpness_ = VP8GetValue(br, 3); | 223 hdr->sharpness_ = VP8GetValue(br, 3); |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
321 } | 320 } |
322 | 321 |
323 // Check if we have all the partition #0 available, and initialize dec->br_ | 322 // Check if we have all the partition #0 available, and initialize dec->br_ |
324 // to read this partition (and this partition only). | 323 // to read this partition (and this partition only). |
325 if (frm_hdr->partition_length_ > buf_size) { | 324 if (frm_hdr->partition_length_ > buf_size) { |
326 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, | 325 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, |
327 "bad partition length"); | 326 "bad partition length"); |
328 } | 327 } |
329 | 328 |
330 br = &dec->br_; | 329 br = &dec->br_; |
331 VP8InitBitReader(br, buf, buf + frm_hdr->partition_length_); | 330 VP8InitBitReader(br, buf, frm_hdr->partition_length_); |
332 buf += frm_hdr->partition_length_; | 331 buf += frm_hdr->partition_length_; |
333 buf_size -= frm_hdr->partition_length_; | 332 buf_size -= frm_hdr->partition_length_; |
334 | 333 |
335 if (frm_hdr->key_frame_) { | 334 if (frm_hdr->key_frame_) { |
336 pic_hdr->colorspace_ = VP8Get(br); | 335 pic_hdr->colorspace_ = VP8Get(br); |
337 pic_hdr->clamp_type_ = VP8Get(br); | 336 pic_hdr->clamp_type_ = VP8Get(br); |
338 } | 337 } |
339 if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { | 338 if (!ParseSegmentHeader(br, &dec->segment_hdr_, &dec->proba_)) { |
340 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, | 339 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, |
341 "cannot parse segment header"); | 340 "cannot parse segment header"); |
(...skipping 22 matching lines...) Expand all Loading... |
364 VP8ParseProba(br, dec); | 363 VP8ParseProba(br, dec); |
365 | 364 |
366 // sanitized state | 365 // sanitized state |
367 dec->ready_ = 1; | 366 dec->ready_ = 1; |
368 return 1; | 367 return 1; |
369 } | 368 } |
370 | 369 |
371 //------------------------------------------------------------------------------ | 370 //------------------------------------------------------------------------------ |
372 // Residual decoding (Paragraph 13.2 / 13.3) | 371 // Residual decoding (Paragraph 13.2 / 13.3) |
373 | 372 |
374 static const int kBands[16 + 1] = { | |
375 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7, | |
376 0 // extra entry as sentinel | |
377 }; | |
378 | |
379 static const uint8_t kCat3[] = { 173, 148, 140, 0 }; | 373 static const uint8_t kCat3[] = { 173, 148, 140, 0 }; |
380 static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; | 374 static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; |
381 static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; | 375 static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; |
382 static const uint8_t kCat6[] = | 376 static const uint8_t kCat6[] = |
383 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; | 377 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; |
384 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; | 378 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; |
385 static const uint8_t kZigzag[16] = { | 379 static const uint8_t kZigzag[16] = { |
386 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 | 380 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 |
387 }; | 381 }; |
388 | 382 |
(...skipping 23 matching lines...) Expand all Loading... |
412 for (tab = kCat3456[cat]; *tab; ++tab) { | 406 for (tab = kCat3456[cat]; *tab; ++tab) { |
413 v += v + VP8GetBit(br, *tab); | 407 v += v + VP8GetBit(br, *tab); |
414 } | 408 } |
415 v += 3 + (8 << cat); | 409 v += 3 + (8 << cat); |
416 } | 410 } |
417 } | 411 } |
418 return v; | 412 return v; |
419 } | 413 } |
420 | 414 |
421 // Returns the position of the last non-zero coeff plus one | 415 // Returns the position of the last non-zero coeff plus one |
422 static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob, | 416 static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob[], |
423 int ctx, const quant_t dq, int n, int16_t* out) { | 417 int ctx, const quant_t dq, int n, int16_t* out) { |
424 // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'. | 418 const uint8_t* p = prob[n]->probas_[ctx]; |
425 const uint8_t* p = prob[n].probas_[ctx]; | |
426 for (; n < 16; ++n) { | 419 for (; n < 16; ++n) { |
427 if (!VP8GetBit(br, p[0])) { | 420 if (!VP8GetBit(br, p[0])) { |
428 return n; // previous coeff was last non-zero coeff | 421 return n; // previous coeff was last non-zero coeff |
429 } | 422 } |
430 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs | 423 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs |
431 p = prob[kBands[++n]].probas_[0]; | 424 p = prob[++n]->probas_[0]; |
432 if (n == 16) return 16; | 425 if (n == 16) return 16; |
433 } | 426 } |
434 { // non zero coeff | 427 { // non zero coeff |
435 const VP8ProbaArray* const p_ctx = &prob[kBands[n + 1]].probas_[0]; | 428 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; |
436 int v; | 429 int v; |
437 if (!VP8GetBit(br, p[2])) { | 430 if (!VP8GetBit(br, p[2])) { |
438 v = 1; | 431 v = 1; |
439 p = p_ctx[1]; | 432 p = p_ctx[1]; |
440 } else { | 433 } else { |
441 v = GetLargeValue(br, p); | 434 v = GetLargeValue(br, p); |
442 p = p_ctx[2]; | 435 p = p_ctx[2]; |
443 } | 436 } |
444 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; | 437 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; |
445 } | 438 } |
446 } | 439 } |
447 return 16; | 440 return 16; |
448 } | 441 } |
449 | 442 |
450 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { | 443 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { |
451 nz_coeffs <<= 2; | 444 nz_coeffs <<= 2; |
452 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; | 445 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; |
453 return nz_coeffs; | 446 return nz_coeffs; |
454 } | 447 } |
455 | 448 |
456 static int ParseResiduals(VP8Decoder* const dec, | 449 static int ParseResiduals(VP8Decoder* const dec, |
457 VP8MB* const mb, VP8BitReader* const token_br) { | 450 VP8MB* const mb, VP8BitReader* const token_br) { |
458 VP8BandProbas (* const bands)[NUM_BANDS] = dec->proba_.bands_; | 451 const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_; |
459 const VP8BandProbas* ac_proba; | 452 const VP8BandProbas* const * ac_proba; |
460 VP8MBData* const block = dec->mb_data_ + dec->mb_x_; | 453 VP8MBData* const block = dec->mb_data_ + dec->mb_x_; |
461 const VP8QuantMatrix* const q = &dec->dqm_[block->segment_]; | 454 const VP8QuantMatrix* const q = &dec->dqm_[block->segment_]; |
462 int16_t* dst = block->coeffs_; | 455 int16_t* dst = block->coeffs_; |
463 VP8MB* const left_mb = dec->mb_info_ - 1; | 456 VP8MB* const left_mb = dec->mb_info_ - 1; |
464 uint8_t tnz, lnz; | 457 uint8_t tnz, lnz; |
465 uint32_t non_zero_y = 0; | 458 uint32_t non_zero_y = 0; |
466 uint32_t non_zero_uv = 0; | 459 uint32_t non_zero_uv = 0; |
467 int x, y, ch; | 460 int x, y, ch; |
468 uint32_t out_t_nz, out_l_nz; | 461 uint32_t out_t_nz, out_l_nz; |
469 int first; | 462 int first; |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
660 dec->alph_dec_ = NULL; | 653 dec->alph_dec_ = NULL; |
661 WebPSafeFree(dec->mem_); | 654 WebPSafeFree(dec->mem_); |
662 dec->mem_ = NULL; | 655 dec->mem_ = NULL; |
663 dec->mem_size_ = 0; | 656 dec->mem_size_ = 0; |
664 memset(&dec->br_, 0, sizeof(dec->br_)); | 657 memset(&dec->br_, 0, sizeof(dec->br_)); |
665 dec->ready_ = 0; | 658 dec->ready_ = 0; |
666 } | 659 } |
667 | 660 |
668 //------------------------------------------------------------------------------ | 661 //------------------------------------------------------------------------------ |
669 | 662 |
OLD | NEW |