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

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

Issue 116213006: Update libwebp to 0.4.0 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: After Blink Roll Created 6 years, 11 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/dec/tree.c ('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 "./vp8i.h" 17 #include "./vp8i.h"
17 #include "./vp8li.h" 18 #include "./vp8li.h"
18 #include "./webpi.h" 19 #include "./webpi.h"
19 #include "../utils/bit_reader.h" 20 #include "../utils/bit_reader.h"
20 21
21 #if defined(__cplusplus) || defined(c_plusplus)
22 extern "C" {
23 #endif
24
25 //------------------------------------------------------------------------------ 22 //------------------------------------------------------------------------------
26 23
27 int WebPGetDecoderVersion(void) { 24 int WebPGetDecoderVersion(void) {
28 return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION; 25 return (DEC_MAJ_VERSION << 16) | (DEC_MIN_VERSION << 8) | DEC_REV_VERSION;
29 } 26 }
30 27
31 //------------------------------------------------------------------------------ 28 //------------------------------------------------------------------------------
32 // VP8Decoder 29 // VP8Decoder
33 30
34 static void SetOk(VP8Decoder* const dec) { 31 static void SetOk(VP8Decoder* const dec) {
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 113
117 if (((bits >> 1) & 7) > 3) { 114 if (((bits >> 1) & 7) > 3) {
118 return 0; // unknown profile 115 return 0; // unknown profile
119 } 116 }
120 if (!((bits >> 4) & 1)) { 117 if (!((bits >> 4) & 1)) {
121 return 0; // first frame is invisible! 118 return 0; // first frame is invisible!
122 } 119 }
123 if (((bits >> 5)) >= chunk_size) { // partition_length 120 if (((bits >> 5)) >= chunk_size) { // partition_length
124 return 0; // inconsistent size information. 121 return 0; // inconsistent size information.
125 } 122 }
123 if (w == 0 || h == 0) {
124 return 0; // We don't support both width and height to be zero.
125 }
126 126
127 if (width) { 127 if (width) {
128 *width = w; 128 *width = w;
129 } 129 }
130 if (height) { 130 if (height) {
131 *height = h; 131 *height = h;
132 } 132 }
133 133
134 return 1; 134 return 1;
135 } 135 }
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
242 } 242 }
243 243
244 // Topmost call 244 // Topmost call
245 int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) { 245 int VP8GetHeaders(VP8Decoder* const dec, VP8Io* const io) {
246 const uint8_t* buf; 246 const uint8_t* buf;
247 size_t buf_size; 247 size_t buf_size;
248 VP8FrameHeader* frm_hdr; 248 VP8FrameHeader* frm_hdr;
249 VP8PictureHeader* pic_hdr; 249 VP8PictureHeader* pic_hdr;
250 VP8BitReader* br; 250 VP8BitReader* br;
251 VP8StatusCode status; 251 VP8StatusCode status;
252 WebPHeaderStructure headers;
253 252
254 if (dec == NULL) { 253 if (dec == NULL) {
255 return 0; 254 return 0;
256 } 255 }
257 SetOk(dec); 256 SetOk(dec);
258 if (io == NULL) { 257 if (io == NULL) {
259 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM, 258 return VP8SetError(dec, VP8_STATUS_INVALID_PARAM,
260 "null VP8Io passed to VP8GetHeaders()"); 259 "null VP8Io passed to VP8GetHeaders()");
261 } 260 }
262 261 buf = io->data;
263 // Process Pre-VP8 chunks. 262 buf_size = io->data_size;
264 headers.data = io->data;
265 headers.data_size = io->data_size;
266 status = WebPParseHeaders(&headers);
267 if (status != VP8_STATUS_OK) {
268 return VP8SetError(dec, status, "Incorrect/incomplete header.");
269 }
270 if (headers.is_lossless) {
271 return VP8SetError(dec, VP8_STATUS_BITSTREAM_ERROR,
272 "Unexpected lossless format encountered.");
273 }
274
275 if (dec->alpha_data_ == NULL) {
276 assert(dec->alpha_data_size_ == 0);
277 // We have NOT set alpha data yet. Set it now.
278 // (This is to ensure that dec->alpha_data_ is NOT reset to NULL if
279 // WebPParseHeaders() is called more than once, as in incremental decoding
280 // case.)
281 dec->alpha_data_ = headers.alpha_data;
282 dec->alpha_data_size_ = headers.alpha_data_size;
283 }
284
285 // Process the VP8 frame header.
286 buf = headers.data + headers.offset;
287 buf_size = headers.data_size - headers.offset;
288 assert(headers.data_size >= headers.offset); // WebPParseHeaders' guarantee
289 if (buf_size < 4) { 263 if (buf_size < 4) {
290 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 264 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
291 "Truncated header."); 265 "Truncated header.");
292 } 266 }
293 267
294 // Paragraph 9.1 268 // Paragraph 9.1
295 { 269 {
296 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16); 270 const uint32_t bits = buf[0] | (buf[1] << 8) | (buf[2] << 16);
297 frm_hdr = &dec->frm_hdr_; 271 frm_hdr = &dec->frm_hdr_;
298 frm_hdr->key_frame_ = !(bits & 1); 272 frm_hdr->key_frame_ = !(bits & 1);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 status = ParsePartitions(dec, buf, buf_size); 348 status = ParsePartitions(dec, buf, buf_size);
375 if (status != VP8_STATUS_OK) { 349 if (status != VP8_STATUS_OK) {
376 return VP8SetError(dec, status, "cannot parse partitions"); 350 return VP8SetError(dec, status, "cannot parse partitions");
377 } 351 }
378 352
379 // quantizer change 353 // quantizer change
380 VP8ParseQuant(dec); 354 VP8ParseQuant(dec);
381 355
382 // Frame buffer marking 356 // Frame buffer marking
383 if (!frm_hdr->key_frame_) { 357 if (!frm_hdr->key_frame_) {
384 // Paragraph 9.7
385 #ifndef ONLY_KEYFRAME_CODE
386 dec->buffer_flags_ = VP8Get(br) << 0; // update golden
387 dec->buffer_flags_ |= VP8Get(br) << 1; // update alt ref
388 if (!(dec->buffer_flags_ & 1)) {
389 dec->buffer_flags_ |= VP8GetValue(br, 2) << 2;
390 }
391 if (!(dec->buffer_flags_ & 2)) {
392 dec->buffer_flags_ |= VP8GetValue(br, 2) << 4;
393 }
394 dec->buffer_flags_ |= VP8Get(br) << 6; // sign bias golden
395 dec->buffer_flags_ |= VP8Get(br) << 7; // sign bias alt ref
396 #else
397 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE, 358 return VP8SetError(dec, VP8_STATUS_UNSUPPORTED_FEATURE,
398 "Not a key frame."); 359 "Not a key frame.");
399 #endif
400 } else {
401 dec->buffer_flags_ = 0x003 | 0x100;
402 } 360 }
403 361
404 // Paragraph 9.8 362 VP8Get(br); // ignore the value of update_proba_
405 #ifndef ONLY_KEYFRAME_CODE
406 dec->update_proba_ = VP8Get(br);
407 if (!dec->update_proba_) { // save for later restore
408 dec->proba_saved_ = dec->proba_;
409 }
410 dec->buffer_flags_ &= 1 << 8;
411 dec->buffer_flags_ |=
412 (frm_hdr->key_frame_ || VP8Get(br)) << 8; // refresh last frame
413 #else
414 VP8Get(br); // just ignore the value of update_proba_
415 #endif
416 363
417 VP8ParseProba(br, dec); 364 VP8ParseProba(br, dec);
418 365
419 #ifdef WEBP_EXPERIMENTAL_FEATURES 366 #ifdef WEBP_EXPERIMENTAL_FEATURES
420 // Extensions 367 // Extensions
421 if (dec->pic_hdr_.colorspace_) { 368 if (dec->pic_hdr_.colorspace_) {
422 const size_t kTrailerSize = 8; 369 const size_t kTrailerSize = 8;
423 const uint8_t kTrailerMarker = 0x01; 370 const uint8_t kTrailerMarker = 0x01;
424 const uint8_t* ext_buf = buf - kTrailerSize; 371 const uint8_t* ext_buf = buf - kTrailerSize;
425 size_t size; 372 size_t size;
(...skipping 28 matching lines...) Expand all
454 static const uint8_t kCat3[] = { 173, 148, 140, 0 }; 401 static const uint8_t kCat3[] = { 173, 148, 140, 0 };
455 static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 }; 402 static const uint8_t kCat4[] = { 176, 155, 140, 135, 0 };
456 static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 }; 403 static const uint8_t kCat5[] = { 180, 157, 141, 134, 130, 0 };
457 static const uint8_t kCat6[] = 404 static const uint8_t kCat6[] =
458 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 }; 405 { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0 };
459 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 }; 406 static const uint8_t* const kCat3456[] = { kCat3, kCat4, kCat5, kCat6 };
460 static const uint8_t kZigzag[16] = { 407 static const uint8_t kZigzag[16] = {
461 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 408 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15
462 }; 409 };
463 410
464 typedef const uint8_t (*ProbaArray)[NUM_CTX][NUM_PROBAS]; // for const-casting
465 typedef const uint8_t (*ProbaCtxArray)[NUM_PROBAS];
466
467 // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2 411 // See section 13-2: http://tools.ietf.org/html/rfc6386#section-13.2
468 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) { 412 static int GetLargeValue(VP8BitReader* const br, const uint8_t* const p) {
469 int v; 413 int v;
470 if (!VP8GetBit(br, p[3])) { 414 if (!VP8GetBit(br, p[3])) {
471 if (!VP8GetBit(br, p[4])) { 415 if (!VP8GetBit(br, p[4])) {
472 v = 2; 416 v = 2;
473 } else { 417 } else {
474 v = 3 + VP8GetBit(br, p[5]); 418 v = 3 + VP8GetBit(br, p[5]);
475 } 419 }
476 } else { 420 } else {
(...skipping 13 matching lines...) Expand all
490 for (tab = kCat3456[cat]; *tab; ++tab) { 434 for (tab = kCat3456[cat]; *tab; ++tab) {
491 v += v + VP8GetBit(br, *tab); 435 v += v + VP8GetBit(br, *tab);
492 } 436 }
493 v += 3 + (8 << cat); 437 v += 3 + (8 << cat);
494 } 438 }
495 } 439 }
496 return v; 440 return v;
497 } 441 }
498 442
499 // Returns the position of the last non-zero coeff plus one 443 // Returns the position of the last non-zero coeff plus one
500 // (and 0 if there's no coeff at all) 444 static int GetCoeffs(VP8BitReader* const br, const VP8BandProbas* const prob,
501 static int GetCoeffs(VP8BitReader* const br, ProbaArray prob,
502 int ctx, const quant_t dq, int n, int16_t* out) { 445 int ctx, const quant_t dq, int n, int16_t* out) {
503 // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'. 446 // n is either 0 or 1 here. kBands[n] is not necessary for extracting '*p'.
504 const uint8_t* p = prob[n][ctx]; 447 const uint8_t* p = prob[n].probas_[ctx];
505 if (!VP8GetBit(br, p[0])) { // first EOB is more a 'CBP' bit.
506 return 0;
507 }
508 for (; n < 16; ++n) { 448 for (; n < 16; ++n) {
509 const ProbaCtxArray p_ctx = prob[kBands[n + 1]]; 449 if (!VP8GetBit(br, p[0])) {
510 if (!VP8GetBit(br, p[1])) { 450 return n; // previous coeff was last non-zero coeff
511 p = p_ctx[0]; 451 }
512 } else { // non zero coeff 452 while (!VP8GetBit(br, p[1])) { // sequence of zero coeffs
453 p = prob[kBands[++n]].probas_[0];
454 if (n == 16) return 16;
455 }
456 { // non zero coeff
457 const VP8ProbaArray* const p_ctx = &prob[kBands[n + 1]].probas_[0];
513 int v; 458 int v;
514 if (!VP8GetBit(br, p[2])) { 459 if (!VP8GetBit(br, p[2])) {
515 v = 1; 460 v = 1;
516 p = p_ctx[1]; 461 p = p_ctx[1];
517 } else { 462 } else {
518 v = GetLargeValue(br, p); 463 v = GetLargeValue(br, p);
519 p = p_ctx[2]; 464 p = p_ctx[2];
520 } 465 }
521 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0]; 466 out[kZigzag[n]] = VP8GetSigned(br, v) * dq[n > 0];
522 if (n < 15 && !VP8GetBit(br, p[0])) { // EOB
523 return n + 1;
524 }
525 } 467 }
526 } 468 }
527 return 16; 469 return 16;
528 } 470 }
529 471
530 // Alias-safe way of converting 4bytes to 32bits. 472 static WEBP_INLINE uint32_t NzCodeBits(uint32_t nz_coeffs, int nz, int dc_nz) {
531 typedef union { 473 nz_coeffs <<= 2;
532 uint8_t i8[4]; 474 nz_coeffs |= (nz > 3) ? 3 : (nz > 1) ? 2 : dc_nz;
533 uint32_t i32; 475 return nz_coeffs;
534 } PackedNz; 476 }
535 477
536 // Table to unpack four bits into four bytes 478 static int ParseResiduals(VP8Decoder* const dec,
537 static const PackedNz kUnpackTab[16] = { 479 VP8MB* const mb, VP8BitReader* const token_br) {
538 {{0, 0, 0, 0}}, {{1, 0, 0, 0}}, {{0, 1, 0, 0}}, {{1, 1, 0, 0}}, 480 VP8BandProbas (* const bands)[NUM_BANDS] = dec->proba_.bands_;
539 {{0, 0, 1, 0}}, {{1, 0, 1, 0}}, {{0, 1, 1, 0}}, {{1, 1, 1, 0}}, 481 const VP8BandProbas* ac_proba;
540 {{0, 0, 0, 1}}, {{1, 0, 0, 1}}, {{0, 1, 0, 1}}, {{1, 1, 0, 1}}, 482 const VP8QuantMatrix* const q = &dec->dqm_[dec->segment_];
541 {{0, 0, 1, 1}}, {{1, 0, 1, 1}}, {{0, 1, 1, 1}}, {{1, 1, 1, 1}} }; 483 VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
484 int16_t* dst = block->coeffs_;
485 VP8MB* const left_mb = dec->mb_info_ - 1;
486 uint8_t tnz, lnz;
487 uint32_t non_zero_y = 0;
488 uint32_t non_zero_uv = 0;
489 int x, y, ch;
490 uint32_t out_t_nz, out_l_nz;
491 int first;
542 492
543 // Macro to pack four LSB of four bytes into four bits.
544 #if defined(__PPC__) || defined(_M_PPC) || defined(_ARCH_PPC) || \
545 defined(__BIG_ENDIAN__)
546 #define PACK_CST 0x08040201U
547 #else
548 #define PACK_CST 0x01020408U
549 #endif
550 #define PACK(X, S) ((((X).i32 * PACK_CST) & 0xff000000) >> (S))
551
552 static void ParseResiduals(VP8Decoder* const dec,
553 VP8MB* const mb, VP8BitReader* const token_br) {
554 int out_t_nz, out_l_nz, first;
555 ProbaArray ac_prob;
556 const VP8QuantMatrix* q = &dec->dqm_[dec->segment_];
557 int16_t* dst = dec->coeffs_;
558 VP8MB* const left_mb = dec->mb_info_ - 1;
559 PackedNz nz_ac, nz_dc;
560 PackedNz tnz, lnz;
561 uint32_t non_zero_ac = 0;
562 uint32_t non_zero_dc = 0;
563 int x, y, ch;
564
565 nz_dc.i32 = nz_ac.i32 = 0;
566 memset(dst, 0, 384 * sizeof(*dst)); 493 memset(dst, 0, 384 * sizeof(*dst));
567 if (!dec->is_i4x4_) { // parse DC 494 if (!block->is_i4x4_) { // parse DC
568 int16_t dc[16] = { 0 }; 495 int16_t dc[16] = { 0 };
569 const int ctx = mb->dc_nz_ + left_mb->dc_nz_; 496 const int ctx = mb->nz_dc_ + left_mb->nz_dc_;
570 mb->dc_nz_ = left_mb->dc_nz_ = 497 const int nz = GetCoeffs(token_br, bands[1], ctx, q->y2_mat_, 0, dc);
571 (GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[1], 498 mb->nz_dc_ = left_mb->nz_dc_ = (nz > 0);
572 ctx, q->y2_mat_, 0, dc) > 0); 499 if (nz > 1) { // more than just the DC -> perform the full transform
500 VP8TransformWHT(dc, dst);
501 } else { // only DC is non-zero -> inlined simplified transform
502 int i;
503 const int dc0 = (dc[0] + 3) >> 3;
504 for (i = 0; i < 16 * 16; i += 16) dst[i] = dc0;
505 }
573 first = 1; 506 first = 1;
574 ac_prob = (ProbaArray)dec->proba_.coeffs_[0]; 507 ac_proba = bands[0];
575 VP8TransformWHT(dc, dst);
576 } else { 508 } else {
577 first = 0; 509 first = 0;
578 ac_prob = (ProbaArray)dec->proba_.coeffs_[3]; 510 ac_proba = bands[3];
579 } 511 }
580 512
581 tnz = kUnpackTab[mb->nz_ & 0xf]; 513 tnz = mb->nz_ & 0x0f;
582 lnz = kUnpackTab[left_mb->nz_ & 0xf]; 514 lnz = left_mb->nz_ & 0x0f;
583 for (y = 0; y < 4; ++y) { 515 for (y = 0; y < 4; ++y) {
584 int l = lnz.i8[y]; 516 int l = lnz & 1;
517 uint32_t nz_coeffs = 0;
585 for (x = 0; x < 4; ++x) { 518 for (x = 0; x < 4; ++x) {
586 const int ctx = l + tnz.i8[x]; 519 const int ctx = l + (tnz & 1);
587 const int nz = GetCoeffs(token_br, ac_prob, ctx, 520 const int nz = GetCoeffs(token_br, ac_proba, ctx, q->y1_mat_, first, dst);
588 q->y1_mat_, first, dst); 521 l = (nz > first);
589 tnz.i8[x] = l = (nz > 0); 522 tnz = (tnz >> 1) | (l << 7);
590 nz_dc.i8[x] = (dst[0] != 0); 523 nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
591 nz_ac.i8[x] = (nz > 1);
592 dst += 16; 524 dst += 16;
593 } 525 }
594 lnz.i8[y] = l; 526 tnz >>= 4;
595 non_zero_dc |= PACK(nz_dc, 24 - y * 4); 527 lnz = (lnz >> 1) | (l << 7);
596 non_zero_ac |= PACK(nz_ac, 24 - y * 4); 528 non_zero_y = (non_zero_y << 8) | nz_coeffs;
597 } 529 }
598 out_t_nz = PACK(tnz, 24); 530 out_t_nz = tnz;
599 out_l_nz = PACK(lnz, 24); 531 out_l_nz = lnz >> 4;
600 532
601 tnz = kUnpackTab[mb->nz_ >> 4];
602 lnz = kUnpackTab[left_mb->nz_ >> 4];
603 for (ch = 0; ch < 4; ch += 2) { 533 for (ch = 0; ch < 4; ch += 2) {
534 uint32_t nz_coeffs = 0;
535 tnz = mb->nz_ >> (4 + ch);
536 lnz = left_mb->nz_ >> (4 + ch);
604 for (y = 0; y < 2; ++y) { 537 for (y = 0; y < 2; ++y) {
605 int l = lnz.i8[ch + y]; 538 int l = lnz & 1;
606 for (x = 0; x < 2; ++x) { 539 for (x = 0; x < 2; ++x) {
607 const int ctx = l + tnz.i8[ch + x]; 540 const int ctx = l + (tnz & 1);
608 const int nz = 541 const int nz = GetCoeffs(token_br, bands[2], ctx, q->uv_mat_, 0, dst);
609 GetCoeffs(token_br, (ProbaArray)dec->proba_.coeffs_[2], 542 l = (nz > 0);
610 ctx, q->uv_mat_, 0, dst); 543 tnz = (tnz >> 1) | (l << 3);
611 tnz.i8[ch + x] = l = (nz > 0); 544 nz_coeffs = NzCodeBits(nz_coeffs, nz, dst[0] != 0);
612 nz_dc.i8[y * 2 + x] = (dst[0] != 0);
613 nz_ac.i8[y * 2 + x] = (nz > 1);
614 dst += 16; 545 dst += 16;
615 } 546 }
616 lnz.i8[ch + y] = l; 547 tnz >>= 2;
548 lnz = (lnz >> 1) | (l << 5);
617 } 549 }
618 non_zero_dc |= PACK(nz_dc, 8 - ch * 2); 550 // Note: we don't really need the per-4x4 details for U/V blocks.
619 non_zero_ac |= PACK(nz_ac, 8 - ch * 2); 551 non_zero_uv |= nz_coeffs << (4 * ch);
552 out_t_nz |= (tnz << 4) << ch;
553 out_l_nz |= (lnz & 0xf0) << ch;
620 } 554 }
621 out_t_nz |= PACK(tnz, 20);
622 out_l_nz |= PACK(lnz, 20);
623 mb->nz_ = out_t_nz; 555 mb->nz_ = out_t_nz;
624 left_mb->nz_ = out_l_nz; 556 left_mb->nz_ = out_l_nz;
625 557
626 dec->non_zero_ac_ = non_zero_ac; 558 block->non_zero_y_ = non_zero_y;
627 dec->non_zero_ = non_zero_ac | non_zero_dc; 559 block->non_zero_uv_ = non_zero_uv;
628 mb->skip_ = !dec->non_zero_; 560
561 // We look at the mode-code of each block and check if some blocks have less
562 // than three non-zero coeffs (code < 2). This is to avoid dithering flat and
563 // empty blocks.
564 block->dither_ = (non_zero_uv & 0xaaaa) ? 0 : q->dither_;
565
566 return !(non_zero_y | non_zero_uv); // will be used for further optimization
629 } 567 }
630 #undef PACK
631 568
632 //------------------------------------------------------------------------------ 569 //------------------------------------------------------------------------------
633 // Main loop 570 // Main loop
634 571
635 int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) { 572 int VP8DecodeMB(VP8Decoder* const dec, VP8BitReader* const token_br) {
636 VP8BitReader* const br = &dec->br_; 573 VP8BitReader* const br = &dec->br_;
637 VP8MB* const left = dec->mb_info_ - 1; 574 VP8MB* const left = dec->mb_info_ - 1;
638 VP8MB* const info = dec->mb_info_ + dec->mb_x_; 575 VP8MB* const mb = dec->mb_info_ + dec->mb_x_;
576 VP8MBData* const block = dec->mb_data_ + dec->mb_x_;
577 int skip;
639 578
640 // Note: we don't save segment map (yet), as we don't expect 579 // Note: we don't save segment map (yet), as we don't expect
641 // to decode more than 1 keyframe. 580 // to decode more than 1 keyframe.
642 if (dec->segment_hdr_.update_map_) { 581 if (dec->segment_hdr_.update_map_) {
643 // Hardcoded tree parsing 582 // Hardcoded tree parsing
644 dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ? 583 dec->segment_ = !VP8GetBit(br, dec->proba_.segments_[0]) ?
645 VP8GetBit(br, dec->proba_.segments_[1]) : 584 VP8GetBit(br, dec->proba_.segments_[1]) :
646 2 + VP8GetBit(br, dec->proba_.segments_[2]); 585 2 + VP8GetBit(br, dec->proba_.segments_[2]);
647 } 586 }
648 info->skip_ = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0; 587 skip = dec->use_skip_proba_ ? VP8GetBit(br, dec->skip_p_) : 0;
649 588
650 VP8ParseIntraMode(br, dec); 589 VP8ParseIntraMode(br, dec);
651 if (br->eof_) { 590 if (br->eof_) {
652 return 0; 591 return 0;
653 } 592 }
654 593
655 if (!info->skip_) { 594 if (!skip) {
656 ParseResiduals(dec, info, token_br); 595 skip = ParseResiduals(dec, mb, token_br);
657 } else { 596 } else {
658 left->nz_ = info->nz_ = 0; 597 left->nz_ = mb->nz_ = 0;
659 if (!dec->is_i4x4_) { 598 if (!block->is_i4x4_) {
660 left->dc_nz_ = info->dc_nz_ = 0; 599 left->nz_dc_ = mb->nz_dc_ = 0;
661 } 600 }
662 dec->non_zero_ = 0; 601 block->non_zero_y_ = 0;
663 dec->non_zero_ac_ = 0; 602 block->non_zero_uv_ = 0;
664 } 603 }
665 604
666 if (dec->filter_type_ > 0) { // store filter info 605 if (dec->filter_type_ > 0) { // store filter info
667 VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_; 606 VP8FInfo* const finfo = dec->f_info_ + dec->mb_x_;
668 *finfo = dec->fstrengths_[dec->segment_][dec->is_i4x4_]; 607 *finfo = dec->fstrengths_[dec->segment_][block->is_i4x4_];
669 finfo->f_inner_ = (!info->skip_ || dec->is_i4x4_); 608 finfo->f_inner_ |= !skip;
670 } 609 }
671 610
672 return (!token_br->eof_); 611 return !token_br->eof_;
673 } 612 }
674 613
675 void VP8InitScanline(VP8Decoder* const dec) { 614 void VP8InitScanline(VP8Decoder* const dec) {
676 VP8MB* const left = dec->mb_info_ - 1; 615 VP8MB* const left = dec->mb_info_ - 1;
677 left->nz_ = 0; 616 left->nz_ = 0;
678 left->dc_nz_ = 0; 617 left->nz_dc_ = 0;
679 memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); 618 memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_));
680 dec->filter_row_ = 619 dec->mb_x_ = 0;
681 (dec->filter_type_ > 0) &&
682 (dec->mb_y_ >= dec->tl_mb_y_) && (dec->mb_y_ <= dec->br_mb_y_);
683 } 620 }
684 621
685 static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { 622 static int ParseFrame(VP8Decoder* const dec, VP8Io* io) {
686 for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { 623 for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) {
624 // Parse bitstream for this row.
687 VP8BitReader* const token_br = 625 VP8BitReader* const token_br =
688 &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; 626 &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)];
689 VP8InitScanline(dec); 627 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) {
690 for (dec->mb_x_ = 0; dec->mb_x_ < dec->mb_w_; dec->mb_x_++) {
691 if (!VP8DecodeMB(dec, token_br)) { 628 if (!VP8DecodeMB(dec, token_br)) {
692 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, 629 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA,
693 "Premature end-of-file encountered."); 630 "Premature end-of-file encountered.");
694 } 631 }
695 // Reconstruct and emit samples.
696 VP8ReconstructBlock(dec);
697 } 632 }
633 VP8InitScanline(dec); // Prepare for next scanline
634
635 // Reconstruct, filter and emit the row.
698 if (!VP8ProcessRow(dec, io)) { 636 if (!VP8ProcessRow(dec, io)) {
699 return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted."); 637 return VP8SetError(dec, VP8_STATUS_USER_ABORT, "Output aborted.");
700 } 638 }
701 } 639 }
702 if (dec->use_threads_ && !WebPWorkerSync(&dec->worker_)) { 640 if (dec->mt_method_ > 0) {
703 return 0; 641 if (!WebPWorkerSync(&dec->worker_)) return 0;
704 } 642 }
705 643
706 // Finish 644 // Finish
707 #ifndef ONLY_KEYFRAME_CODE
708 if (!dec->update_proba_) {
709 dec->proba_ = dec->proba_saved_;
710 }
711 #endif
712
713 #ifdef WEBP_EXPERIMENTAL_FEATURES 645 #ifdef WEBP_EXPERIMENTAL_FEATURES
714 if (dec->layer_data_size_ > 0) { 646 if (dec->layer_data_size_ > 0) {
715 if (!VP8DecodeLayer(dec)) { 647 if (!VP8DecodeLayer(dec)) {
716 return 0; 648 return 0;
717 } 649 }
718 } 650 }
719 #endif 651 #endif
720 652
721 return 1; 653 return 1;
722 } 654 }
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
758 } 690 }
759 691
760 dec->ready_ = 0; 692 dec->ready_ = 0;
761 return ok; 693 return ok;
762 } 694 }
763 695
764 void VP8Clear(VP8Decoder* const dec) { 696 void VP8Clear(VP8Decoder* const dec) {
765 if (dec == NULL) { 697 if (dec == NULL) {
766 return; 698 return;
767 } 699 }
768 if (dec->use_threads_) { 700 if (dec->mt_method_ > 0) {
769 WebPWorkerEnd(&dec->worker_); 701 WebPWorkerEnd(&dec->worker_);
770 } 702 }
771 if (dec->mem_) { 703 ALPHDelete(dec->alph_dec_);
772 free(dec->mem_); 704 dec->alph_dec_ = NULL;
773 } 705 free(dec->mem_);
774 dec->mem_ = NULL; 706 dec->mem_ = NULL;
775 dec->mem_size_ = 0; 707 dec->mem_size_ = 0;
776 memset(&dec->br_, 0, sizeof(dec->br_)); 708 memset(&dec->br_, 0, sizeof(dec->br_));
777 dec->ready_ = 0; 709 dec->ready_ = 0;
778 } 710 }
779 711
780 //------------------------------------------------------------------------------ 712 //------------------------------------------------------------------------------
781 713
782 #if defined(__cplusplus) || defined(c_plusplus)
783 } // extern "C"
784 #endif
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/tree.c ('k') | third_party/libwebp/dec/vp8i.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698