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 |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 | |
OLD | NEW |