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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
43 } | 43 } |
44 return 1; | 44 return 1; |
45 } | 45 } |
46 | 46 |
47 VP8Decoder* VP8New(void) { | 47 VP8Decoder* VP8New(void) { |
48 VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); | 48 VP8Decoder* const dec = (VP8Decoder*)WebPSafeCalloc(1ULL, sizeof(*dec)); |
49 if (dec != NULL) { | 49 if (dec != NULL) { |
50 SetOk(dec); | 50 SetOk(dec); |
51 WebPGetWorkerInterface()->Init(&dec->worker_); | 51 WebPGetWorkerInterface()->Init(&dec->worker_); |
52 dec->ready_ = 0; | 52 dec->ready_ = 0; |
53 dec->num_parts_ = 1; | 53 dec->num_parts_minus_one_ = 0; |
54 } | 54 } |
55 return dec; | 55 return dec; |
56 } | 56 } |
57 | 57 |
58 VP8StatusCode VP8Status(VP8Decoder* const dec) { | 58 VP8StatusCode VP8Status(VP8Decoder* const dec) { |
59 if (!dec) return VP8_STATUS_INVALID_PARAM; | 59 if (!dec) return VP8_STATUS_INVALID_PARAM; |
60 return dec->status_; | 60 return dec->status_; |
61 } | 61 } |
62 | 62 |
63 const char* VP8StatusMessage(VP8Decoder* const dec) { | 63 const char* VP8StatusMessage(VP8Decoder* const dec) { |
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, | 187 static VP8StatusCode ParsePartitions(VP8Decoder* const dec, |
188 const uint8_t* buf, size_t size) { | 188 const uint8_t* buf, size_t size) { |
189 VP8BitReader* const br = &dec->br_; | 189 VP8BitReader* const br = &dec->br_; |
190 const uint8_t* sz = buf; | 190 const uint8_t* sz = buf; |
191 const uint8_t* buf_end = buf + size; | 191 const uint8_t* buf_end = buf + size; |
192 const uint8_t* part_start; | 192 const uint8_t* part_start; |
193 size_t size_left = size; | 193 size_t size_left = size; |
194 size_t last_part; | 194 size_t last_part; |
195 size_t p; | 195 size_t p; |
196 | 196 |
197 dec->num_parts_ = 1 << VP8GetValue(br, 2); | 197 dec->num_parts_minus_one_ = (1 << VP8GetValue(br, 2)) - 1; |
198 last_part = dec->num_parts_ - 1; | 198 last_part = dec->num_parts_minus_one_; |
199 if (size < 3 * last_part) { | 199 if (size < 3 * last_part) { |
200 // 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. |
201 return VP8_STATUS_NOT_ENOUGH_DATA; | 201 return VP8_STATUS_NOT_ENOUGH_DATA; |
202 } | 202 } |
203 part_start = buf + last_part * 3; | 203 part_start = buf + last_part * 3; |
204 size_left -= last_part * 3; | 204 size_left -= last_part * 3; |
205 for (p = 0; p < last_part; ++p) { | 205 for (p = 0; p < last_part; ++p) { |
206 size_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); | 206 size_t psize = sz[0] | (sz[1] << 8) | (sz[2] << 16); |
207 if (psize > size_left) psize = size_left; | 207 if (psize > size_left) psize = size_left; |
208 VP8InitBitReader(dec->parts_ + p, part_start, psize); | 208 VP8InitBitReader(dec->parts_ + p, part_start, psize); |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
296 } | 296 } |
297 pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; | 297 pic_hdr->width_ = ((buf[4] << 8) | buf[3]) & 0x3fff; |
298 pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 | 298 pic_hdr->xscale_ = buf[4] >> 6; // ratio: 1, 5/4 5/3 or 2 |
299 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; | 299 pic_hdr->height_ = ((buf[6] << 8) | buf[5]) & 0x3fff; |
300 pic_hdr->yscale_ = buf[6] >> 6; | 300 pic_hdr->yscale_ = buf[6] >> 6; |
301 buf += 7; | 301 buf += 7; |
302 buf_size -= 7; | 302 buf_size -= 7; |
303 | 303 |
304 dec->mb_w_ = (pic_hdr->width_ + 15) >> 4; | 304 dec->mb_w_ = (pic_hdr->width_ + 15) >> 4; |
305 dec->mb_h_ = (pic_hdr->height_ + 15) >> 4; | 305 dec->mb_h_ = (pic_hdr->height_ + 15) >> 4; |
| 306 |
306 // Setup default output area (can be later modified during io->setup()) | 307 // Setup default output area (can be later modified during io->setup()) |
307 io->width = pic_hdr->width_; | 308 io->width = pic_hdr->width_; |
308 io->height = pic_hdr->height_; | 309 io->height = pic_hdr->height_; |
309 io->use_scaling = 0; | 310 // IMPORTANT! use some sane dimensions in crop_* and scaled_* fields. |
| 311 // So they can be used interchangeably without always testing for |
| 312 // 'use_cropping'. |
310 io->use_cropping = 0; | 313 io->use_cropping = 0; |
311 io->crop_top = 0; | 314 io->crop_top = 0; |
312 io->crop_left = 0; | 315 io->crop_left = 0; |
313 io->crop_right = io->width; | 316 io->crop_right = io->width; |
314 io->crop_bottom = io->height; | 317 io->crop_bottom = io->height; |
| 318 io->use_scaling = 0; |
| 319 io->scaled_width = io->width; |
| 320 io->scaled_height = io->height; |
| 321 |
315 io->mb_w = io->width; // sanity check | 322 io->mb_w = io->width; // sanity check |
316 io->mb_h = io->height; // ditto | 323 io->mb_h = io->height; // ditto |
317 | 324 |
318 VP8ResetProba(&dec->proba_); | 325 VP8ResetProba(&dec->proba_); |
319 ResetSegmentHeader(&dec->segment_hdr_); | 326 ResetSegmentHeader(&dec->segment_hdr_); |
320 } | 327 } |
321 | 328 |
322 // Check if we have all the partition #0 available, and initialize dec->br_ | 329 // Check if we have all the partition #0 available, and initialize dec->br_ |
323 // to read this partition (and this partition only). | 330 // to read this partition (and this partition only). |
324 if (frm_hdr->partition_length_ > buf_size) { | 331 if (frm_hdr->partition_length_ > buf_size) { |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 left->nz_ = 0; | 579 left->nz_ = 0; |
573 left->nz_dc_ = 0; | 580 left->nz_dc_ = 0; |
574 memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); | 581 memset(dec->intra_l_, B_DC_PRED, sizeof(dec->intra_l_)); |
575 dec->mb_x_ = 0; | 582 dec->mb_x_ = 0; |
576 } | 583 } |
577 | 584 |
578 static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { | 585 static int ParseFrame(VP8Decoder* const dec, VP8Io* io) { |
579 for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { | 586 for (dec->mb_y_ = 0; dec->mb_y_ < dec->br_mb_y_; ++dec->mb_y_) { |
580 // Parse bitstream for this row. | 587 // Parse bitstream for this row. |
581 VP8BitReader* const token_br = | 588 VP8BitReader* const token_br = |
582 &dec->parts_[dec->mb_y_ & (dec->num_parts_ - 1)]; | 589 &dec->parts_[dec->mb_y_ & dec->num_parts_minus_one_]; |
583 if (!VP8ParseIntraModeRow(&dec->br_, dec)) { | 590 if (!VP8ParseIntraModeRow(&dec->br_, dec)) { |
584 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, | 591 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, |
585 "Premature end-of-partition0 encountered."); | 592 "Premature end-of-partition0 encountered."); |
586 } | 593 } |
587 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { | 594 for (; dec->mb_x_ < dec->mb_w_; ++dec->mb_x_) { |
588 if (!VP8DecodeMB(dec, token_br)) { | 595 if (!VP8DecodeMB(dec, token_br)) { |
589 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, | 596 return VP8SetError(dec, VP8_STATUS_NOT_ENOUGH_DATA, |
590 "Premature end-of-file encountered."); | 597 "Premature end-of-file encountered."); |
591 } | 598 } |
592 } | 599 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
642 | 649 |
643 dec->ready_ = 0; | 650 dec->ready_ = 0; |
644 return ok; | 651 return ok; |
645 } | 652 } |
646 | 653 |
647 void VP8Clear(VP8Decoder* const dec) { | 654 void VP8Clear(VP8Decoder* const dec) { |
648 if (dec == NULL) { | 655 if (dec == NULL) { |
649 return; | 656 return; |
650 } | 657 } |
651 WebPGetWorkerInterface()->End(&dec->worker_); | 658 WebPGetWorkerInterface()->End(&dec->worker_); |
652 ALPHDelete(dec->alph_dec_); | 659 WebPDeallocateAlphaMemory(dec); |
653 dec->alph_dec_ = NULL; | |
654 WebPSafeFree(dec->mem_); | 660 WebPSafeFree(dec->mem_); |
655 dec->mem_ = NULL; | 661 dec->mem_ = NULL; |
656 dec->mem_size_ = 0; | 662 dec->mem_size_ = 0; |
657 memset(&dec->br_, 0, sizeof(dec->br_)); | 663 memset(&dec->br_, 0, sizeof(dec->br_)); |
658 dec->ready_ = 0; | 664 dec->ready_ = 0; |
659 } | 665 } |
660 | 666 |
661 //------------------------------------------------------------------------------ | 667 //------------------------------------------------------------------------------ |
662 | |
OLD | NEW |