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

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

Issue 1546003002: libwebp: update to 0.5.0 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebase around clang-cl fix Created 5 years 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
OLDNEW
1 // Copyright 2011 Google Inc. All Rights Reserved. 1 // Copyright 2011 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 // Incremental decoding 10 // Incremental decoding
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
123 int p; 123 int p;
124 for (p = 0; p <= last_part; ++p) { 124 for (p = 0; p <= last_part; ++p) {
125 VP8RemapBitReader(dec->parts_ + p, offset); 125 VP8RemapBitReader(dec->parts_ + p, offset);
126 } 126 }
127 // Remap partition #0 data pointer to new offset, but only in MAP 127 // Remap partition #0 data pointer to new offset, but only in MAP
128 // mode (in APPEND mode, partition #0 is copied into a fixed memory). 128 // mode (in APPEND mode, partition #0 is copied into a fixed memory).
129 if (mem->mode_ == MEM_MODE_MAP) { 129 if (mem->mode_ == MEM_MODE_MAP) {
130 VP8RemapBitReader(&dec->br_, offset); 130 VP8RemapBitReader(&dec->br_, offset);
131 } 131 }
132 } 132 }
133 assert(last_part >= 0); 133 {
134 dec->parts_[last_part].buf_end_ = mem->buf_ + mem->end_; 134 const uint8_t* const last_start = dec->parts_[last_part].buf_;
135 assert(last_part >= 0);
136 VP8BitReaderSetBuffer(&dec->parts_[last_part], last_start,
137 mem->buf_ + mem->end_ - last_start);
138 }
135 if (NeedCompressedAlpha(idec)) { 139 if (NeedCompressedAlpha(idec)) {
136 ALPHDecoder* const alph_dec = dec->alph_dec_; 140 ALPHDecoder* const alph_dec = dec->alph_dec_;
137 dec->alpha_data_ += offset; 141 dec->alpha_data_ += offset;
138 if (alph_dec != NULL) { 142 if (alph_dec != NULL) {
139 if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) { 143 if (alph_dec->method_ == ALPHA_LOSSLESS_COMPRESSION) {
140 VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_; 144 VP8LDecoder* const alph_vp8l_dec = alph_dec->vp8l_dec_;
141 assert(alph_vp8l_dec != NULL); 145 assert(alph_vp8l_dec != NULL);
142 assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN); 146 assert(dec->alpha_data_size_ >= ALPHA_HEADER_LEN);
143 VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_, 147 VP8LBitReaderSetBuffer(&alph_vp8l_dec->br_,
144 dec->alpha_data_ + ALPHA_HEADER_LEN, 148 dec->alpha_data_ + ALPHA_HEADER_LEN,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
233 mem->mode_ = expected; // switch to the expected mode 237 mem->mode_ = expected; // switch to the expected mode
234 } else if (mem->mode_ != expected) { 238 } else if (mem->mode_ != expected) {
235 return 0; // we mixed the modes => error 239 return 0; // we mixed the modes => error
236 } 240 }
237 assert(mem->mode_ == expected); // mode is ok 241 assert(mem->mode_ == expected); // mode is ok
238 return 1; 242 return 1;
239 } 243 }
240 244
241 // To be called last. 245 // To be called last.
242 static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) { 246 static VP8StatusCode FinishDecoding(WebPIDecoder* const idec) {
243 #if WEBP_DECODER_ABI_VERSION > 0x0203
244 const WebPDecoderOptions* const options = idec->params_.options; 247 const WebPDecoderOptions* const options = idec->params_.options;
245 WebPDecBuffer* const output = idec->params_.output; 248 WebPDecBuffer* const output = idec->params_.output;
246 249
247 idec->state_ = STATE_DONE; 250 idec->state_ = STATE_DONE;
248 if (options != NULL && options->flip) { 251 if (options != NULL && options->flip) {
249 return WebPFlipBuffer(output); 252 return WebPFlipBuffer(output);
253 } else {
254 return VP8_STATUS_OK;
250 } 255 }
251 #endif
252 idec->state_ = STATE_DONE;
253 return VP8_STATUS_OK;
254 } 256 }
255 257
256 //------------------------------------------------------------------------------ 258 //------------------------------------------------------------------------------
257 // Macroblock-decoding contexts 259 // Macroblock-decoding contexts
258 260
259 static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br, 261 static void SaveContext(const VP8Decoder* dec, const VP8BitReader* token_br,
260 MBContext* const context) { 262 MBContext* const context) {
261 context->left_ = dec->mb_info_[-1]; 263 context->left_ = dec->mb_info_[-1];
262 context->info_ = dec->mb_info_[dec->mb_x_]; 264 context->info_ = dec->mb_info_[dec->mb_x_];
263 context->token_br_ = *token_br; 265 context->token_br_ = *token_br;
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
370 return VP8_STATUS_BITSTREAM_ERROR; 372 return VP8_STATUS_BITSTREAM_ERROR;
371 } 373 }
372 if (mem->mode_ == MEM_MODE_APPEND) { 374 if (mem->mode_ == MEM_MODE_APPEND) {
373 // We copy and grab ownership of the partition #0 data. 375 // We copy and grab ownership of the partition #0 data.
374 uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size); 376 uint8_t* const part0_buf = (uint8_t*)WebPSafeMalloc(1ULL, part_size);
375 if (part0_buf == NULL) { 377 if (part0_buf == NULL) {
376 return VP8_STATUS_OUT_OF_MEMORY; 378 return VP8_STATUS_OUT_OF_MEMORY;
377 } 379 }
378 memcpy(part0_buf, br->buf_, part_size); 380 memcpy(part0_buf, br->buf_, part_size);
379 mem->part0_buf_ = part0_buf; 381 mem->part0_buf_ = part0_buf;
380 br->buf_ = part0_buf; 382 VP8BitReaderSetBuffer(br, part0_buf, part_size);
381 br->buf_end_ = part0_buf + part_size;
382 } else { 383 } else {
383 // Else: just keep pointers to the partition #0's data in dec_->br_. 384 // Else: just keep pointers to the partition #0's data in dec_->br_.
384 } 385 }
385 mem->start_ += part_size; 386 mem->start_ += part_size;
386 return VP8_STATUS_OK; 387 return VP8_STATUS_OK;
387 } 388 }
388 389
389 static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) { 390 static VP8StatusCode DecodePartition0(WebPIDecoder* const idec) {
390 VP8Decoder* const dec = (VP8Decoder*)idec->dec_; 391 VP8Decoder* const dec = (VP8Decoder*)idec->dec_;
391 VP8Io* const io = &idec->io_; 392 VP8Io* const io = &idec->io_;
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) { 500 static VP8StatusCode DecodeVP8LHeader(WebPIDecoder* const idec) {
500 VP8Io* const io = &idec->io_; 501 VP8Io* const io = &idec->io_;
501 VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_; 502 VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
502 const WebPDecParams* const params = &idec->params_; 503 const WebPDecParams* const params = &idec->params_;
503 WebPDecBuffer* const output = params->output; 504 WebPDecBuffer* const output = params->output;
504 size_t curr_size = MemDataSize(&idec->mem_); 505 size_t curr_size = MemDataSize(&idec->mem_);
505 assert(idec->is_lossless_); 506 assert(idec->is_lossless_);
506 507
507 // Wait until there's enough data for decoding header. 508 // Wait until there's enough data for decoding header.
508 if (curr_size < (idec->chunk_size_ >> 3)) { 509 if (curr_size < (idec->chunk_size_ >> 3)) {
509 return VP8_STATUS_SUSPENDED; 510 dec->status_ = VP8_STATUS_SUSPENDED;
511 return ErrorStatusLossless(idec, dec->status_);
510 } 512 }
513
511 if (!VP8LDecodeHeader(dec, io)) { 514 if (!VP8LDecodeHeader(dec, io)) {
515 if (dec->status_ == VP8_STATUS_BITSTREAM_ERROR &&
516 curr_size < idec->chunk_size_) {
517 dec->status_ = VP8_STATUS_SUSPENDED;
518 }
512 return ErrorStatusLossless(idec, dec->status_); 519 return ErrorStatusLossless(idec, dec->status_);
513 } 520 }
514 // Allocate/verify output buffer now. 521 // Allocate/verify output buffer now.
515 dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options, 522 dec->status_ = WebPAllocateDecBuffer(io->width, io->height, params->options,
516 output); 523 output);
517 if (dec->status_ != VP8_STATUS_OK) { 524 if (dec->status_ != VP8_STATUS_OK) {
518 return IDecError(idec, dec->status_); 525 return IDecError(idec, dec->status_);
519 } 526 }
520 527
521 idec->state_ = STATE_VP8L_DATA; 528 idec->state_ = STATE_VP8L_DATA;
522 return VP8_STATUS_OK; 529 return VP8_STATUS_OK;
523 } 530 }
524 531
525 static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) { 532 static VP8StatusCode DecodeVP8LData(WebPIDecoder* const idec) {
526 VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_; 533 VP8LDecoder* const dec = (VP8LDecoder*)idec->dec_;
527 const size_t curr_size = MemDataSize(&idec->mem_); 534 const size_t curr_size = MemDataSize(&idec->mem_);
528 assert(idec->is_lossless_); 535 assert(idec->is_lossless_);
529 536
530 // At present Lossless decoder can't decode image incrementally. So wait till 537 // Switch to incremental decoding if we don't have all the bytes available.
531 // all the image data is aggregated before image can be decoded. 538 dec->incremental_ = (curr_size < idec->chunk_size_);
532 if (curr_size < idec->chunk_size_) {
533 return VP8_STATUS_SUSPENDED;
534 }
535 539
536 if (!VP8LDecodeImage(dec)) { 540 if (!VP8LDecodeImage(dec)) {
537 // The decoding is called after all the data-bytes are aggregated. Change
538 // the error to VP8_BITSTREAM_ERROR in case lossless decoder fails to decode
539 // all the pixels (VP8_STATUS_SUSPENDED).
540 if (dec->status_ == VP8_STATUS_SUSPENDED) {
541 dec->status_ = VP8_STATUS_BITSTREAM_ERROR;
542 }
543 return ErrorStatusLossless(idec, dec->status_); 541 return ErrorStatusLossless(idec, dec->status_);
544 } 542 }
545 543 assert(dec->status_ == VP8_STATUS_OK || dec->status_ == VP8_STATUS_SUSPENDED);
546 return FinishDecoding(idec); 544 return (dec->status_ == VP8_STATUS_SUSPENDED) ? dec->status_
545 : FinishDecoding(idec);
547 } 546 }
548 547
549 // Main decoding loop 548 // Main decoding loop
550 static VP8StatusCode IDecode(WebPIDecoder* idec) { 549 static VP8StatusCode IDecode(WebPIDecoder* idec) {
551 VP8StatusCode status = VP8_STATUS_SUSPENDED; 550 VP8StatusCode status = VP8_STATUS_SUSPENDED;
552 551
553 if (idec->state_ == STATE_WEBP_HEADER) { 552 if (idec->state_ == STATE_WEBP_HEADER) {
554 status = DecodeWebPHeaders(idec); 553 status = DecodeWebPHeaders(idec);
555 } else { 554 } else {
556 if (idec->dec_ == NULL) { 555 if (idec->dec_ == NULL) {
(...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after
786 } 785 }
787 return idec->params_.output; 786 return idec->params_.output;
788 } 787 }
789 788
790 const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec, 789 const WebPDecBuffer* WebPIDecodedArea(const WebPIDecoder* idec,
791 int* left, int* top, 790 int* left, int* top,
792 int* width, int* height) { 791 int* width, int* height) {
793 const WebPDecBuffer* const src = GetOutputBuffer(idec); 792 const WebPDecBuffer* const src = GetOutputBuffer(idec);
794 if (left != NULL) *left = 0; 793 if (left != NULL) *left = 0;
795 if (top != NULL) *top = 0; 794 if (top != NULL) *top = 0;
796 // TODO(skal): later include handling of rotations.
797 if (src) { 795 if (src) {
798 if (width != NULL) *width = src->width; 796 if (width != NULL) *width = src->width;
799 if (height != NULL) *height = idec->params_.last_y; 797 if (height != NULL) *height = idec->params_.last_y;
800 } else { 798 } else {
801 if (width != NULL) *width = 0; 799 if (width != NULL) *width = 0;
802 if (height != NULL) *height = 0; 800 if (height != NULL) *height = 0;
803 } 801 }
804 return src; 802 return src;
805 } 803 }
806 804
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
852 return 0; 850 return 0;
853 } 851 }
854 852
855 idec->io_.put = put; 853 idec->io_.put = put;
856 idec->io_.setup = setup; 854 idec->io_.setup = setup;
857 idec->io_.teardown = teardown; 855 idec->io_.teardown = teardown;
858 idec->io_.opaque = user_data; 856 idec->io_.opaque = user_data;
859 857
860 return 1; 858 return 1;
861 } 859 }
862
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698