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

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

Issue 12942006: libwebp: update snapshot to v0.3.0-rc6 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 9 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/alpha.c ('k') | third_party/libwebp/dec/idec.c » ('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 // 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 // Frame-reconstruction function. Memory allocation. 8 // Frame-reconstruction function. Memory allocation.
9 // 9 //
10 // Author: Skal (pascal.massimino@gmail.com) 10 // Author: Skal (pascal.massimino@gmail.com)
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
90 static void FilterRow(const VP8Decoder* const dec) { 90 static void FilterRow(const VP8Decoder* const dec) {
91 int mb_x; 91 int mb_x;
92 const int mb_y = dec->thread_ctx_.mb_y_; 92 const int mb_y = dec->thread_ctx_.mb_y_;
93 assert(dec->thread_ctx_.filter_row_); 93 assert(dec->thread_ctx_.filter_row_);
94 for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) { 94 for (mb_x = dec->tl_mb_x_; mb_x < dec->br_mb_x_; ++mb_x) {
95 DoFilter(dec, mb_x, mb_y); 95 DoFilter(dec, mb_x, mb_y);
96 } 96 }
97 } 97 }
98 98
99 //------------------------------------------------------------------------------ 99 //------------------------------------------------------------------------------
100 // Precompute the filtering strength for each segment and each i4x4/i16x16 mode.
100 101
101 void VP8StoreBlock(VP8Decoder* const dec) { 102 static void PrecomputeFilterStrengths(VP8Decoder* const dec) {
102 if (dec->filter_type_ > 0) { 103 if (dec->filter_type_ > 0) {
103 VP8FInfo* const info = dec->f_info_ + dec->mb_x_; 104 int s;
104 const int skip = dec->mb_info_[dec->mb_x_].skip_; 105 const VP8FilterHeader* const hdr = &dec->filter_hdr_;
105 int level = dec->filter_levels_[dec->segment_]; 106 for (s = 0; s < NUM_MB_SEGMENTS; ++s) {
106 if (dec->filter_hdr_.use_lf_delta_) { 107 int i4x4;
107 // TODO(skal): only CURRENT is handled for now. 108 // First, compute the initial level
108 level += dec->filter_hdr_.ref_lf_delta_[0]; 109 int base_level;
109 if (dec->is_i4x4_) { 110 if (dec->segment_hdr_.use_segment_) {
110 level += dec->filter_hdr_.mode_lf_delta_[0]; 111 base_level = dec->segment_hdr_.filter_strength_[s];
112 if (!dec->segment_hdr_.absolute_delta_) {
113 base_level += hdr->level_;
114 }
115 } else {
116 base_level = hdr->level_;
111 } 117 }
112 } 118 for (i4x4 = 0; i4x4 <= 1; ++i4x4) {
113 level = (level < 0) ? 0 : (level > 63) ? 63 : level; 119 VP8FInfo* const info = &dec->fstrengths_[s][i4x4];
114 info->f_level_ = level; 120 int level = base_level;
121 if (hdr->use_lf_delta_) {
122 // TODO(skal): only CURRENT is handled for now.
123 level += hdr->ref_lf_delta_[0];
124 if (i4x4) {
125 level += hdr->mode_lf_delta_[0];
126 }
127 }
128 level = (level < 0) ? 0 : (level > 63) ? 63 : level;
129 info->f_level_ = level;
115 130
116 if (dec->filter_hdr_.sharpness_ > 0) { 131 if (hdr->sharpness_ > 0) {
117 if (dec->filter_hdr_.sharpness_ > 4) { 132 if (hdr->sharpness_ > 4) {
118 level >>= 2; 133 level >>= 2;
119 } else { 134 } else {
120 level >>= 1; 135 level >>= 1;
136 }
137 if (level > 9 - hdr->sharpness_) {
138 level = 9 - hdr->sharpness_;
139 }
140 }
141 info->f_ilevel_ = (level < 1) ? 1 : level;
142 info->f_inner_ = 0;
121 } 143 }
122 if (level > 9 - dec->filter_hdr_.sharpness_) {
123 level = 9 - dec->filter_hdr_.sharpness_;
124 }
125 }
126
127 info->f_ilevel_ = (level < 1) ? 1 : level;
128 info->f_inner_ = (!skip || dec->is_i4x4_);
129 }
130 {
131 // Transfer samples to row cache
132 int y;
133 const int y_offset = dec->cache_id_ * 16 * dec->cache_y_stride_;
134 const int uv_offset = dec->cache_id_ * 8 * dec->cache_uv_stride_;
135 uint8_t* const ydst = dec->cache_y_ + dec->mb_x_ * 16 + y_offset;
136 uint8_t* const udst = dec->cache_u_ + dec->mb_x_ * 8 + uv_offset;
137 uint8_t* const vdst = dec->cache_v_ + dec->mb_x_ * 8 + uv_offset;
138 for (y = 0; y < 16; ++y) {
139 memcpy(ydst + y * dec->cache_y_stride_,
140 dec->yuv_b_ + Y_OFF + y * BPS, 16);
141 }
142 for (y = 0; y < 8; ++y) {
143 memcpy(udst + y * dec->cache_uv_stride_,
144 dec->yuv_b_ + U_OFF + y * BPS, 8);
145 memcpy(vdst + y * dec->cache_uv_stride_,
146 dec->yuv_b_ + V_OFF + y * BPS, 8);
147 } 144 }
148 } 145 }
149 } 146 }
150 147
151 //------------------------------------------------------------------------------ 148 //------------------------------------------------------------------------------
152 // This function is called after a row of macroblocks is finished decoding. 149 // This function is called after a row of macroblocks is finished decoding.
153 // It also takes into account the following restrictions: 150 // It also takes into account the following restrictions:
154 // * In case of in-loop filtering, we must hold off sending some of the bottom 151 // * In case of in-loop filtering, we must hold off sending some of the bottom
155 // pixels as they are yet unfiltered. They will be when the next macroblock 152 // pixels as they are yet unfiltered. They will be when the next macroblock
156 // row is decoded. Meanwhile, we must preserve them by rotating them in the 153 // row is decoded. Meanwhile, we must preserve them by rotating them in the
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
332 // We need some 'extra' pixels on the right/bottom. 329 // We need some 'extra' pixels on the right/bottom.
333 dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4; 330 dec->br_mb_y_ = (io->crop_bottom + 15 + extra_pixels) >> 4;
334 dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4; 331 dec->br_mb_x_ = (io->crop_right + 15 + extra_pixels) >> 4;
335 if (dec->br_mb_x_ > dec->mb_w_) { 332 if (dec->br_mb_x_ > dec->mb_w_) {
336 dec->br_mb_x_ = dec->mb_w_; 333 dec->br_mb_x_ = dec->mb_w_;
337 } 334 }
338 if (dec->br_mb_y_ > dec->mb_h_) { 335 if (dec->br_mb_y_ > dec->mb_h_) {
339 dec->br_mb_y_ = dec->mb_h_; 336 dec->br_mb_y_ = dec->mb_h_;
340 } 337 }
341 } 338 }
339 PrecomputeFilterStrengths(dec);
342 return VP8_STATUS_OK; 340 return VP8_STATUS_OK;
343 } 341 }
344 342
345 int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) { 343 int VP8ExitCritical(VP8Decoder* const dec, VP8Io* const io) {
346 int ok = 1; 344 int ok = 1;
347 if (dec->use_threads_) { 345 if (dec->use_threads_) {
348 ok = WebPWorkerSync(&dec->worker_); 346 ok = WebPWorkerSync(&dec->worker_);
349 } 347 }
350 348
351 if (io->teardown) { 349 if (io->teardown) {
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
489 + 16 * num_caches * dec->cache_y_stride_ + extra_uv; 487 + 16 * num_caches * dec->cache_y_stride_ + extra_uv;
490 dec->cache_v_ = dec->cache_u_ 488 dec->cache_v_ = dec->cache_u_
491 + 8 * num_caches * dec->cache_uv_stride_ + extra_uv; 489 + 8 * num_caches * dec->cache_uv_stride_ + extra_uv;
492 dec->cache_id_ = 0; 490 dec->cache_id_ = 0;
493 } 491 }
494 mem += cache_size; 492 mem += cache_size;
495 493
496 // alpha plane 494 // alpha plane
497 dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL; 495 dec->alpha_plane_ = alpha_size ? (uint8_t*)mem : NULL;
498 mem += alpha_size; 496 mem += alpha_size;
497 assert(mem <= (uint8_t*)dec->mem_ + dec->mem_size_);
499 498
500 // note: left-info is initialized once for all. 499 // note: left-info is initialized once for all.
501 memset(dec->mb_info_ - 1, 0, mb_info_size); 500 memset(dec->mb_info_ - 1, 0, mb_info_size);
502 501
503 // initialize top 502 // initialize top
504 memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size); 503 memset(dec->intra_t_, B_DC_PRED, intra_pred_mode_size);
505 504
506 return 1; 505 return 1;
507 } 506 }
508 507
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
544 } 543 }
545 } 544 }
546 return mode; 545 return mode;
547 } 546 }
548 547
549 static WEBP_INLINE void Copy32b(uint8_t* dst, uint8_t* src) { 548 static WEBP_INLINE void Copy32b(uint8_t* dst, uint8_t* src) {
550 *(uint32_t*)dst = *(uint32_t*)src; 549 *(uint32_t*)dst = *(uint32_t*)src;
551 } 550 }
552 551
553 void VP8ReconstructBlock(VP8Decoder* const dec) { 552 void VP8ReconstructBlock(VP8Decoder* const dec) {
553 int j;
554 uint8_t* const y_dst = dec->yuv_b_ + Y_OFF; 554 uint8_t* const y_dst = dec->yuv_b_ + Y_OFF;
555 uint8_t* const u_dst = dec->yuv_b_ + U_OFF; 555 uint8_t* const u_dst = dec->yuv_b_ + U_OFF;
556 uint8_t* const v_dst = dec->yuv_b_ + V_OFF; 556 uint8_t* const v_dst = dec->yuv_b_ + V_OFF;
557 557
558 // Rotate in the left samples from previously decoded block. We move four 558 // Rotate in the left samples from previously decoded block. We move four
559 // pixels at a time for alignment reason, and because of in-loop filter. 559 // pixels at a time for alignment reason, and because of in-loop filter.
560 if (dec->mb_x_ > 0) { 560 if (dec->mb_x_ > 0) {
561 int j;
562 for (j = -1; j < 16; ++j) { 561 for (j = -1; j < 16; ++j) {
563 Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]); 562 Copy32b(&y_dst[j * BPS - 4], &y_dst[j * BPS + 12]);
564 } 563 }
565 for (j = -1; j < 8; ++j) { 564 for (j = -1; j < 8; ++j) {
566 Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]); 565 Copy32b(&u_dst[j * BPS - 4], &u_dst[j * BPS + 4]);
567 Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]); 566 Copy32b(&v_dst[j * BPS - 4], &v_dst[j * BPS + 4]);
568 } 567 }
569 } else { 568 } else {
570 int j;
571 for (j = 0; j < 16; ++j) { 569 for (j = 0; j < 16; ++j) {
572 y_dst[j * BPS - 1] = 129; 570 y_dst[j * BPS - 1] = 129;
573 } 571 }
574 for (j = 0; j < 8; ++j) { 572 for (j = 0; j < 8; ++j) {
575 u_dst[j * BPS - 1] = 129; 573 u_dst[j * BPS - 1] = 129;
576 v_dst[j * BPS - 1] = 129; 574 v_dst[j * BPS - 1] = 129;
577 } 575 }
578 // Init top-left sample on left column too 576 // Init top-left sample on left column too
579 if (dec->mb_y_ > 0) { 577 if (dec->mb_y_ > 0) {
580 y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129; 578 y_dst[-1 - BPS] = u_dst[-1 - BPS] = v_dst[-1 - BPS] = 129;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
663 } 661 }
664 662
665 // stash away top samples for next block 663 // stash away top samples for next block
666 if (dec->mb_y_ < dec->mb_h_ - 1) { 664 if (dec->mb_y_ < dec->mb_h_ - 1) {
667 memcpy(top_y, y_dst + 15 * BPS, 16); 665 memcpy(top_y, y_dst + 15 * BPS, 16);
668 memcpy(top_u, u_dst + 7 * BPS, 8); 666 memcpy(top_u, u_dst + 7 * BPS, 8);
669 memcpy(top_v, v_dst + 7 * BPS, 8); 667 memcpy(top_v, v_dst + 7 * BPS, 8);
670 } 668 }
671 } 669 }
672 } 670 }
671 // Transfer reconstructed samples from yuv_b_ cache to final destination.
672 {
673 const int y_offset = dec->cache_id_ * 16 * dec->cache_y_stride_;
674 const int uv_offset = dec->cache_id_ * 8 * dec->cache_uv_stride_;
675 uint8_t* const y_out = dec->cache_y_ + dec->mb_x_ * 16 + y_offset;
676 uint8_t* const u_out = dec->cache_u_ + dec->mb_x_ * 8 + uv_offset;
677 uint8_t* const v_out = dec->cache_v_ + dec->mb_x_ * 8 + uv_offset;
678 for (j = 0; j < 16; ++j) {
679 memcpy(y_out + j * dec->cache_y_stride_, y_dst + j * BPS, 16);
680 }
681 for (j = 0; j < 8; ++j) {
682 memcpy(u_out + j * dec->cache_uv_stride_, u_dst + j * BPS, 8);
683 memcpy(v_out + j * dec->cache_uv_stride_, v_dst + j * BPS, 8);
684 }
685 }
673 } 686 }
674 687
675 //------------------------------------------------------------------------------ 688 //------------------------------------------------------------------------------
676 689
677 #if defined(__cplusplus) || defined(c_plusplus) 690 #if defined(__cplusplus) || defined(c_plusplus)
678 } // extern "C" 691 } // extern "C"
679 #endif 692 #endif
OLDNEW
« no previous file with comments | « third_party/libwebp/dec/alpha.c ('k') | third_party/libwebp/dec/idec.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698