OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkCodec_libpng.h" | 8 #include "SkCodec_libpng.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 354 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
365 png_structp png_ptr, png_infop info_ptr) | 365 png_structp png_ptr, png_infop info_ptr) |
366 : INHERITED(info, stream) | 366 : INHERITED(info, stream) |
367 , fPng_ptr(png_ptr) | 367 , fPng_ptr(png_ptr) |
368 , fInfo_ptr(info_ptr) | 368 , fInfo_ptr(info_ptr) |
369 , fSrcConfig(SkSwizzler::kUnknown) | 369 , fSrcConfig(SkSwizzler::kUnknown) |
370 , fNumberPasses(INVALID_NUMBER_PASSES) | 370 , fNumberPasses(INVALID_NUMBER_PASSES) |
371 , fReallyHasAlpha(false) | 371 , fReallyHasAlpha(false) |
372 {} | 372 {} |
373 | 373 |
374 SkPngCodec::~SkPngCodec() { | 374 SkPngCodec::~SkPngCodec() { |
| 375 // First, ensure that the scanline decoder is left in a finished state. |
| 376 SkAutoTDelete<SkScanlineDecoder> decoder(this->detachScanlineDecoder()); |
| 377 if (NULL != decoder) { |
| 378 this->finish(); |
| 379 } |
| 380 |
375 this->destroyReadStruct(); | 381 this->destroyReadStruct(); |
376 } | 382 } |
377 | 383 |
378 void SkPngCodec::destroyReadStruct() { | 384 void SkPngCodec::destroyReadStruct() { |
379 if (fPng_ptr) { | 385 if (fPng_ptr) { |
380 // We will never have a NULL fInfo_ptr with a non-NULL fPng_ptr | 386 // We will never have a NULL fInfo_ptr with a non-NULL fPng_ptr |
381 SkASSERT(fInfo_ptr); | 387 SkASSERT(fInfo_ptr); |
382 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); | 388 png_destroy_read_struct(&fPng_ptr, &fInfo_ptr, png_infopp_NULL); |
383 fPng_ptr = NULL; | 389 fPng_ptr = NULL; |
384 fInfo_ptr = NULL; | 390 fInfo_ptr = NULL; |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
507 } | 513 } |
508 default: | 514 default: |
509 SkASSERT(false); | 515 SkASSERT(false); |
510 return false; | 516 return false; |
511 } | 517 } |
512 } | 518 } |
513 | 519 |
514 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, | 520 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void*
dst, |
515 size_t rowBytes, const Options& options, | 521 size_t rowBytes, const Options& options, |
516 SkPMColor ctable[], int* ctableCount) { | 522 SkPMColor ctable[], int* ctableCount) { |
| 523 // Do not allow a regular decode if the caller has asked for a scanline deco
der |
| 524 if (NULL != this->scanlineDecoder()) { |
| 525 SkCodecPrintf("cannot getPixels() if a scanline decoder has been created
\n"); |
| 526 return kInvalidParameters; |
| 527 } |
| 528 |
517 if (!this->handleRewind()) { | 529 if (!this->handleRewind()) { |
518 return kCouldNotRewind; | 530 return kCouldNotRewind; |
519 } | 531 } |
520 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { | 532 if (requestedInfo.dimensions() != this->getInfo().dimensions()) { |
521 return kInvalidScale; | 533 return kInvalidScale; |
522 } | 534 } |
523 if (!conversion_possible(requestedInfo, this->getInfo())) { | 535 if (!conversion_possible(requestedInfo, this->getInfo())) { |
524 return kInvalidConversion; | 536 return kInvalidConversion; |
525 } | 537 } |
526 | 538 |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
626 } | 638 } |
627 //there is a potential tradeoff of memory vs speed created by putting th
is in a loop. | 639 //there is a potential tradeoff of memory vs speed created by putting th
is in a loop. |
628 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count | 640 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count |
629 //as png_read_rows has it's own loop which calls png_read_row count time
s. | 641 //as png_read_rows has it's own loop which calls png_read_row count time
s. |
630 for (int i = 0; i < count; i++) { | 642 for (int i = 0; i < count; i++) { |
631 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); | 643 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); |
632 } | 644 } |
633 return SkImageGenerator::kSuccess; | 645 return SkImageGenerator::kSuccess; |
634 } | 646 } |
635 | 647 |
636 void onFinish() override { | |
637 fCodec->finish(); | |
638 } | |
639 | |
640 bool onReallyHasAlpha() const override { return fHasAlpha; } | 648 bool onReallyHasAlpha() const override { return fHasAlpha; } |
641 | 649 |
642 private: | 650 private: |
643 SkPngCodec* fCodec; // Unowned. | 651 SkPngCodec* fCodec; // Unowned. |
644 bool fHasAlpha; | 652 bool fHasAlpha; |
645 SkAutoMalloc fStorage; | 653 SkAutoMalloc fStorage; |
646 uint8_t* fSrcRow; | 654 uint8_t* fSrcRow; |
647 | 655 |
648 typedef SkScanlineDecoder INHERITED; | 656 typedef SkScanlineDecoder INHERITED; |
649 }; | 657 }; |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
709 fCurrentRow += count; | 717 fCurrentRow += count; |
710 return SkImageGenerator::kSuccess; | 718 return SkImageGenerator::kSuccess; |
711 } | 719 } |
712 | 720 |
713 SkImageGenerator::Result onSkipScanlines(int count) override { | 721 SkImageGenerator::Result onSkipScanlines(int count) override { |
714 //when ongetScanlines is called it will skip to fCurrentRow | 722 //when ongetScanlines is called it will skip to fCurrentRow |
715 fCurrentRow += count; | 723 fCurrentRow += count; |
716 return SkImageGenerator::kSuccess; | 724 return SkImageGenerator::kSuccess; |
717 } | 725 } |
718 | 726 |
719 void onFinish() override { | |
720 fCodec->finish(); | |
721 } | |
722 | |
723 bool onReallyHasAlpha() const override { return fHasAlpha; } | 727 bool onReallyHasAlpha() const override { return fHasAlpha; } |
724 | 728 |
725 private: | 729 private: |
726 SkPngCodec* fCodec; // Unowned. | 730 SkPngCodec* fCodec; // Unowned. |
727 bool fHasAlpha; | 731 bool fHasAlpha; |
728 int fCurrentRow; | 732 int fCurrentRow; |
729 int fHeight; | 733 int fHeight; |
730 size_t fSrcRowBytes; | 734 size_t fSrcRowBytes; |
731 bool fRewindNeeded; | 735 bool fRewindNeeded; |
732 SkAutoMalloc fGarbageRow; | 736 SkAutoMalloc fGarbageRow; |
733 uint8_t* fGarbageRowPtr; | 737 uint8_t* fGarbageRowPtr; |
734 | 738 |
735 | 739 |
736 | 740 |
737 | |
738 | 741 |
| 742 |
739 typedef SkScanlineDecoder INHERITED; | 743 typedef SkScanlineDecoder INHERITED; |
740 }; | 744 }; |
741 | 745 |
742 | 746 |
743 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | 747 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, |
744 const Options& options, SkPMColor ctable[], int* ctableCount) { | 748 const Options& options, SkPMColor ctable[], int* ctableCount) { |
745 if (!this->handleRewind()) { | 749 if (!this->handleRewind()) { |
746 return NULL; | 750 return NULL; |
747 } | 751 } |
748 | 752 |
(...skipping 18 matching lines...) Expand all Loading... |
767 | 771 |
768 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); | 772 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); |
769 if (fNumberPasses > 1) { | 773 if (fNumberPasses > 1) { |
770 // interlaced image | 774 // interlaced image |
771 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, this)); | 775 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, this)); |
772 } | 776 } |
773 | 777 |
774 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); | 778 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); |
775 } | 779 } |
776 | 780 |
OLD | NEW |