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

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

Issue 2651883004: libwebp-0.6.0-rc1 (Closed)
Patch Set: Created 3 years, 10 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
« no previous file with comments | « third_party/libwebp/dec/vp8_dec.h ('k') | third_party/libwebp/dec/vp8i.h » ('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 // 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
11 // 11 //
12 // Author: Skal (pascal.massimino@gmail.com) 12 // Author: Skal (pascal.massimino@gmail.com)
13 13
14 #include <stdlib.h> 14 #include <stdlib.h>
15 15
16 #include "./alphai.h" 16 #include "./alphai_dec.h"
17 #include "./vp8i.h" 17 #include "./vp8i_dec.h"
18 #include "./vp8li.h" 18 #include "./vp8li_dec.h"
19 #include "./webpi.h" 19 #include "./webpi_dec.h"
20 #include "../utils/bit_reader_inl.h" 20 #include "../utils/bit_reader_inl_utils.h"
21 #include "../utils/utils.h" 21 #include "../utils/utils.h"
22 22
23 //------------------------------------------------------------------------------ 23 //------------------------------------------------------------------------------
24 24
25 int WebPGetDecoderVersion(void) { 25 int WebPGetDecoderVersion(void) {
26 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;
27 } 27 }
28 28
29 //------------------------------------------------------------------------------ 29 //------------------------------------------------------------------------------
30 // Signature and pointer-to-function for GetCoeffs() variants below.
31
32 typedef int (*GetCoeffsFunc)(VP8BitReader* const br,
33 const VP8BandProbas* const prob[],
34 int ctx, const quant_t dq, int n, int16_t* out);
35 static volatile GetCoeffsFunc GetCoeffs = NULL;
36
37 static void InitGetCoeffs(void);
38
39 //------------------------------------------------------------------------------
30 // VP8Decoder 40 // VP8Decoder
31 41
32 static void SetOk(VP8Decoder* const dec) { 42 static void SetOk(VP8Decoder* const dec) {
33 dec->status_ = VP8_STATUS_OK; 43 dec->status_ = VP8_STATUS_OK;
34 dec->error_msg_ = "OK"; 44 dec->error_msg_ = "OK";
35 } 45 }
36 46
37 int VP8InitIoInternal(VP8Io* const io, int version) { 47 int VP8InitIoInternal(VP8Io* const io, int version) {
38 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) { 48 if (WEBP_ABI_IS_INCOMPATIBLE(version, WEBP_DECODER_ABI_VERSION)) {
39 return 0; // mismatch error 49 return 0; // mismatch error
40 } 50 }
41 if (io != NULL) { 51 if (io != NULL) {
42 memset(io, 0, sizeof(*io)); 52 memset(io, 0, sizeof(*io));
43 } 53 }
44 return 1; 54 return 1;
45 } 55 }
46 56
47 VP8Decoder* VP8New(void) { 57 VP8Decoder* VP8New(void) {
48 VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); 58 VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec));
49 if (dec != NULL) { 59 if (dec != NULL) {
50 SetOk(dec); 60 SetOk(dec);
51 WebPGetWorkerInterface()->Init(&dec->worker_); 61 WebPGetWorkerInterface()->Init(&dec->worker_);
52 dec->ready_ = 0; 62 dec->ready_ = 0;
53 dec->num_parts_minus_one_ = 0; 63 dec->num_parts_minus_one_ = 0;
64 InitGetCoeffs();
54 } 65 }
55 return dec; 66 return dec;
56 } 67 }
57 68
58 VP8StatusCode VP8Status(VP8Decoder* const dec) { 69 VP8StatusCode VP8Status(VP8Decoder* const dec) {
59 if (!dec) return VP8_STATUS_INVALID_PARAM; 70 if (!dec) return VP8_STATUS_INVALID_PARAM;
60 return dec->status_; 71 return dec->status_;
61 } 72 }
62 73
63 const char* VP8StatusMessage(VP8Decoder* const dec) { 74 const char* VP8StatusMessage(VP8Decoder* const dec) {
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 } 277 }
267 278
268 // Paragraph 9.1 279 // Paragraph 9.1
269 { 280 {
270 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 281 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
271 frm_hdr = &dec->frm_hdr_; 282 frm_hdr = &dec->frm_hdr_;
272 frm_hdr->key_frame_ = !(bits & 1); 283 frm_hdr->key_frame_ = !(bits & 1);
273 frm_hdr->profile_ = (bits >> 1) & 7; 284 frm_hdr->profile_ = (bits >> 1) & 7;
274 frm_hdr->show_ = (bits >> 4) & 1; 285 frm_hdr->show_ = (bits >> 4) & 1;
275 frm_hdr->partition_length_ = (bits >> 5); 286 frm_hdr->partition_length_ = (bits >> 5);
276 if (frm_hdr->profile_ > 3) 287 if (frm_hdr->profile_ > 3) {
277 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR, 288 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
278 "Incorrect keyframe parameters."); 289 "Incorrect keyframe parameters.");
279 if (!frm_hdr->show_) 290 }
291 if (!frm_hdr->show_) {
280 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 292 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
281 "Frame not displayable."); 293 "Frame not displayable.");
294 }
282 buf += 3; 295 buf += 3;
283 buf_size -= 3; 296 buf_size -= 3;
284 } 297 }
285 298
286 pic_hdr = &dec->pic_hdr_; 299 pic_hdr = &dec->pic_hdr_;
287 if (frm_hdr->key_frame_) { 300 if (frm_hdr->key_frame_) {
288 // Paragraph 9.2 301 // Paragraph 9.2
289 if (buf_size < 7) { 302 if (buf_size < 7) {
290 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 303 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
291 "cannot parse picture header"); 304 "cannot parse picture header");
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
413 for (tab = kCat3456[cat]; *tab; ++tab) { 426 for (tab = kCat3456[cat]; *tab; ++tab) {
414 v += v + VP8GetBit(br, *tab); 427 v += v + VP8GetBit(br, *tab);
415 } 428 }
416 v += 3 + (8 << cat); 429 v += 3 + (8 << cat);
417 } 430 }
418 } 431 }
419 return v; 432 return v;
420 } 433 }
421 434
422 // Returns the position of the last non-zero coeff plus one 435 // Returns the position of the last non-zero coeff plus one
423 static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob[], 436 static int GetCoeffsFast(VP8BitReader* const br,
424 int ctx, const quant_t dq, int n, int16_t* out) { 437 const VP8BandProbas* const prob[],
438 int ctx, const quant_t dq, int n, int16_t* out) {
425 const uint8_t* p = prob[n]->probas_[ctx]; 439 const uint8_t* p = prob[n]->probas_[ctx];
426 for (; n < 16; ++n) { 440 for (; n < 16; ++n) {
427 if (!VP8GetBit(br, p[0])) { 441 if (!VP8GetBit(br, p[0])) {
428 return n; // previous coeff was last non-zero coeff 442 return n; // previous coeff was last non-zero coeff
429 } 443 }
430 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs 444 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs
431 p = prob[++n]->probas_[0]; 445 p = prob[++n]->probas_[0];
432 if (n == 16) return 16; 446 if (n == 16) return 16;
433 } 447 }
434 { // non zero coeff 448 { // non zero coeff
435 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0]; 449 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
436 int v; 450 int v;
437 if (!VP8GetBit(br, p[2])) { 451 if (!VP8GetBit(br, p[2])) {
438 v = 1; 452 v = 1;
439 p = p_ctx[1]; 453 p = p_ctx[1];
440 } else { 454 } else {
441 v = GetLargeValue(br, p); 455 v = GetLargeValue(br, p);
442 p = p_ctx[2]; 456 p = p_ctx[2];
443 } 457 }
444 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; 458 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
445 } 459 }
446 } 460 }
447 return 16; 461 return 16;
448 } 462 }
449 463
464 // This version of GetCoeffs() uses VP8GetBitAlt() which is an alternate version
465 // of VP8GetBitAlt() targeting specific platforms.
466 static int GetCoeffsAlt(VP8BitReader* const br,
467 const VP8BandProbas* const prob[],
468 int ctx, const quant_t dq, int n, int16_t* out) {
469 const uint8_t* p = prob[n]->probas_[ctx];
470 for (; n < 16; ++n) {
471 if (!VP8GetBitAlt(br, p[0])) {
472 return n; // previous coeff was last non-zero coeff
473 }
474 while (!VP8GetBitAlt(br, p[1])) { // sequence of zero coeffs
475 p = prob[++n]->probas_[0];
476 if (n == 16) return 16;
477 }
478 { // non zero coeff
479 const VP8ProbaArray* const p_ctx = &prob[n + 1]->probas_[0];
480 int v;
481 if (!VP8GetBitAlt(br, p[2])) {
482 v = 1;
483 p = p_ctx[1];
484 } else {
485 v = GetLargeValue(br, p);
486 p = p_ctx[2];
487 }
488 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
489 }
490 }
491 return 16;
492 }
493
494 WEBP_TSAN_IGNORE_FUNCTION static void InitGetCoeffs(void) {
495 if (GetCoeffs == NULL) {
496 if (VP8GetCPUInfo != NULL && VP8GetCPUInfo(kSlowSSSE3)) {
497 GetCoeffs = GetCoeffsAlt;
498 } else {
499 GetCoeffs = GetCoeffsFast;
500 }
501 }
502 }
503
450 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) { 504 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) {
451 nz_coeffs <<= 2; 505 nz_coeffs <<= 2;
452 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz; 506 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz;
453 return nz_coeffs; 507 return nz_coeffs;
454 } 508 }
455 509
456 static int ParseResiduals(VP8Decoder* const dec, 510 static int ParseResiduals(VP8Decoder* const dec,
457 VP8MB* const mb, VP8BitReader* const token_br) { 511 VP8MB* const mb, VP8BitReader* const token_br) {
458 const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_; 512 const VP8BandProbas* (* const bands)[16 + 1] = dec->proba_.bands_ptr_;
459 const VP8BandProbas* const * ac_proba; 513 const VP8BandProbas* const * ac_proba;
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 WebPGetWorkerInterface()->End(&dec->worker_); 712 WebPGetWorkerInterface()->End(&dec->worker_);
659 WebPDeallocateAlphaMemory(dec); 713 WebPDeallocateAlphaMemory(dec);
660 WebPSafeFree(dec->mem_); 714 WebPSafeFree(dec->mem_);
661 dec->mem_ = NULL; 715 dec->mem_ = NULL;
662 dec->mem_size_ = 0; 716 dec->mem_size_ = 0;
663 memset(&dec->br_, 0, sizeof(dec->br_)); 717 memset(&dec->br_, 0, sizeof(dec->br_));
664 dec->ready_ = 0; 718 dec->ready_ = 0;
665 } 719 }
666 720
667 //------------------------------------------------------------------------------ 721 //------------------------------------------------------------------------------
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/vp8_dec.h ('k') | third_party/libwebp/dec/vp8i.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698