| 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" |
| 11 #include "SkColorTable.h" | 11 #include "SkColorTable.h" |
| 12 #include "SkBitmap.h" | 12 #include "SkBitmap.h" |
| 13 #include "SkMath.h" | 13 #include "SkMath.h" |
| 14 #include "SkScaledCodec.h" |
| 14 #include "SkScanlineDecoder.h" | 15 #include "SkScanlineDecoder.h" |
| 15 #include "SkSize.h" | 16 #include "SkSize.h" |
| 16 #include "SkStream.h" | 17 #include "SkStream.h" |
| 17 #include "SkSwizzler.h" | 18 #include "SkSwizzler.h" |
| 18 | 19 |
| 19 /////////////////////////////////////////////////////////////////////////////// | 20 /////////////////////////////////////////////////////////////////////////////// |
| 20 // Helper macros | 21 // Helper macros |
| 21 /////////////////////////////////////////////////////////////////////////////// | 22 /////////////////////////////////////////////////////////////////////////////// |
| 22 | 23 |
| 23 #ifndef png_jmpbuf | 24 #ifndef png_jmpbuf |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 468 //would have exited before now if the colorType was supported by png | 469 //would have exited before now if the colorType was supported by png |
| 469 SkASSERT(false); | 470 SkASSERT(false); |
| 470 } | 471 } |
| 471 | 472 |
| 472 // Copy the color table to the client if they request kIndex8 mode | 473 // Copy the color table to the client if they request kIndex8 mode |
| 473 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 474 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
| 474 | 475 |
| 475 // Create the swizzler. SkPngCodec retains ownership of the color table. | 476 // Create the swizzler. SkPngCodec retains ownership of the color table. |
| 476 const SkPMColor* colors = get_color_ptr(fColorTable.get()); | 477 const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
| 477 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, | 478 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, |
| 478 options.fZeroInitialized)); | 479 options.fZeroInitialized, this->getInfo().width())); |
| 479 if (!fSwizzler) { | 480 if (!fSwizzler) { |
| 480 // FIXME: CreateSwizzler could fail for another reason. | 481 // FIXME: CreateSwizzler could fail for another reason. |
| 481 return kUnimplemented; | 482 return kUnimplemented; |
| 482 } | 483 } |
| 483 return kSuccess; | 484 return kSuccess; |
| 484 } | 485 } |
| 485 | 486 |
| 486 | 487 |
| 487 bool SkPngCodec::handleRewind() { | 488 bool SkPngCodec::handleRewind() { |
| 488 switch (this->rewindIfNeeded()) { | 489 switch (this->rewindIfNeeded()) { |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 597 class SkPngScanlineDecoder : public SkScanlineDecoder { | 598 class SkPngScanlineDecoder : public SkScanlineDecoder { |
| 598 public: | 599 public: |
| 599 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) | 600 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
| 600 : INHERITED(srcInfo) | 601 : INHERITED(srcInfo) |
| 601 , fCodec(codec) | 602 , fCodec(codec) |
| 602 , fHasAlpha(false) | 603 , fHasAlpha(false) |
| 603 {} | 604 {} |
| 604 | 605 |
| 605 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 606 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
| 606 const SkCodec::Options& options, | 607 const SkCodec::Options& options, |
| 607 SkPMColor ctable[], int* ctableCount) override | 608 SkPMColor ctable[], int* ctableCount) override { |
| 608 { | |
| 609 if (!fCodec->handleRewind()) { | 609 if (!fCodec->handleRewind()) { |
| 610 return SkCodec::kCouldNotRewind; | 610 return SkCodec::kCouldNotRewind; |
| 611 } | 611 } |
| 612 | 612 |
| 613 if (!conversion_possible(dstInfo, this->getInfo())) { | 613 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 614 return SkCodec::kInvalidConversion; | 614 return SkCodec::kInvalidConversion; |
| 615 } | 615 } |
| 616 | 616 |
| 617 // Check to see if scaling was requested. | 617 // Check to see if scaling was requested. |
| 618 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 618 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 619 return SkCodec::kInvalidScale; | 619 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
| 620 return SkCodec::kInvalidScale; |
| 621 } |
| 620 } | 622 } |
| 621 | 623 |
| 622 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, | 624 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, |
| 623 ctableCount); | 625 ctableCount); |
| 624 if (result != SkCodec::kSuccess) { | 626 if (result != SkCodec::kSuccess) { |
| 625 return result; | 627 return result; |
| 626 } | 628 } |
| 627 | 629 |
| 628 fHasAlpha = false; | 630 fHasAlpha = false; |
| 629 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig)); | 631 fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(fCode
c->fSrcConfig)); |
| 630 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 632 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| 631 | 633 |
| 632 return SkCodec::kSuccess; | 634 return SkCodec::kSuccess; |
| 633 } | 635 } |
| 634 | 636 |
| 635 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { | 637 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { |
| 636 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 638 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
| 637 SkCodecPrintf("setjmp long jump!\n"); | 639 SkCodecPrintf("setjmp long jump!\n"); |
| 638 return SkCodec::kInvalidInput; | 640 return SkCodec::kInvalidInput; |
| 639 } | 641 } |
| (...skipping 18 matching lines...) Expand all Loading... |
| 658 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count | 660 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count |
| 659 //as png_read_rows has it's own loop which calls png_read_row count time
s. | 661 //as png_read_rows has it's own loop which calls png_read_row count time
s. |
| 660 for (int i = 0; i < count; i++) { | 662 for (int i = 0; i < count; i++) { |
| 661 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); | 663 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); |
| 662 } | 664 } |
| 663 return SkCodec::kSuccess; | 665 return SkCodec::kSuccess; |
| 664 } | 666 } |
| 665 | 667 |
| 666 bool onReallyHasAlpha() const override { return fHasAlpha; } | 668 bool onReallyHasAlpha() const override { return fHasAlpha; } |
| 667 | 669 |
| 670 SkEncodedFormat onGetEncodedFormat() const override { |
| 671 return kPNG_SkEncodedFormat; |
| 672 } |
| 673 |
| 674 |
| 668 private: | 675 private: |
| 669 SkAutoTDelete<SkPngCodec> fCodec; | 676 SkAutoTDelete<SkPngCodec> fCodec; |
| 670 bool fHasAlpha; | 677 bool fHasAlpha; |
| 671 SkAutoMalloc fStorage; | 678 SkAutoMalloc fStorage; |
| 672 uint8_t* fSrcRow; | 679 uint8_t* fSrcRow; |
| 673 | 680 |
| 674 typedef SkScanlineDecoder INHERITED; | 681 typedef SkScanlineDecoder INHERITED; |
| 675 }; | 682 }; |
| 676 | 683 |
| 677 | 684 |
| (...skipping 10 matching lines...) Expand all Loading... |
| 688 | 695 |
| 689 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 696 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
| 690 const SkCodec::Options& options, | 697 const SkCodec::Options& options, |
| 691 SkPMColor ctable[], int* ctableCount) override | 698 SkPMColor ctable[], int* ctableCount) override |
| 692 { | 699 { |
| 693 if (!fCodec->handleRewind()) { | 700 if (!fCodec->handleRewind()) { |
| 694 return SkCodec::kCouldNotRewind; | 701 return SkCodec::kCouldNotRewind; |
| 695 } | 702 } |
| 696 | 703 |
| 697 if (!conversion_possible(dstInfo, this->getInfo())) { | 704 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 698 return SkCodec::kInvalidConversion; | 705 return SkCodec::kInvalidConversion; |
| 699 } | 706 } |
| 700 | 707 |
| 701 // Check to see if scaling was requested. | 708 // Check to see if scaling was requested. |
| 702 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 709 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 703 return SkCodec::kInvalidScale; | 710 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
| 711 return SkCodec::kInvalidScale; |
| 712 } |
| 704 } | 713 } |
| 705 | 714 |
| 706 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, | 715 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, |
| 707 ctableCount); | 716 ctableCount); |
| 708 if (result != SkCodec::kSuccess) { | 717 if (result != SkCodec::kSuccess) { |
| 709 return result; | 718 return result; |
| 710 } | 719 } |
| 711 | 720 |
| 712 fHasAlpha = false; | 721 fHasAlpha = false; |
| 713 fCurrentRow = 0; | 722 fCurrentRow = 0; |
| 714 fHeight = dstInfo.height(); | 723 fHeight = dstInfo.height(); |
| 715 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig); | 724 fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(fCode
c->fSrcConfig); |
| 716 fGarbageRow.reset(fSrcRowBytes); | 725 fGarbageRow.reset(fSrcRowBytes); |
| 717 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 726 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
| 718 fCanSkipRewind = true; | 727 fCanSkipRewind = true; |
| 719 | 728 |
| 720 return SkCodec::kSuccess; | 729 return SkCodec::kSuccess; |
| 721 } | 730 } |
| 722 | 731 |
| 723 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { | 732 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { |
| 724 // rewind stream if have previously called onGetScanlines, | 733 // rewind stream if have previously called onGetScanlines, |
| 725 // since we need entire progressive image to get scanlines | 734 // since we need entire progressive image to get scanlines |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 } | 777 } |
| 769 | 778 |
| 770 SkCodec::Result onSkipScanlines(int count) override { | 779 SkCodec::Result onSkipScanlines(int count) override { |
| 771 //when ongetScanlines is called it will skip to fCurrentRow | 780 //when ongetScanlines is called it will skip to fCurrentRow |
| 772 fCurrentRow += count; | 781 fCurrentRow += count; |
| 773 return SkCodec::kSuccess; | 782 return SkCodec::kSuccess; |
| 774 } | 783 } |
| 775 | 784 |
| 776 bool onReallyHasAlpha() const override { return fHasAlpha; } | 785 bool onReallyHasAlpha() const override { return fHasAlpha; } |
| 777 | 786 |
| 787 bool onRequiresPostYSampling() override { |
| 788 return true; |
| 789 } |
| 790 |
| 791 SkEncodedFormat onGetEncodedFormat() const override { |
| 792 return kPNG_SkEncodedFormat; |
| 793 } |
| 794 |
| 778 private: | 795 private: |
| 779 SkAutoTDelete<SkPngCodec> fCodec; | 796 SkAutoTDelete<SkPngCodec> fCodec; |
| 780 bool fHasAlpha; | 797 bool fHasAlpha; |
| 781 int fCurrentRow; | 798 int fCurrentRow; |
| 782 int fHeight; | 799 int fHeight; |
| 783 size_t fSrcRowBytes; | 800 size_t fSrcRowBytes; |
| 784 SkAutoMalloc fGarbageRow; | 801 SkAutoMalloc fGarbageRow; |
| 785 uint8_t* fGarbageRowPtr; | 802 uint8_t* fGarbageRowPtr; |
| 786 // FIXME: This imitates behavior in SkCodec::rewindIfNeeded. That function | 803 // FIXME: This imitates behavior in SkCodec::rewindIfNeeded. That function |
| 787 // is called whenever some action is taken that reads the stream and | 804 // is called whenever some action is taken that reads the stream and |
| (...skipping 19 matching lines...) Expand all Loading... |
| 807 | 824 |
| 808 const SkImageInfo& srcInfo = codec->getInfo(); | 825 const SkImageInfo& srcInfo = codec->getInfo(); |
| 809 if (codec->fNumberPasses > 1) { | 826 if (codec->fNumberPasses > 1) { |
| 810 // interlaced image | 827 // interlaced image |
| 811 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); | 828 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); |
| 812 } | 829 } |
| 813 | 830 |
| 814 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); | 831 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); |
| 815 } | 832 } |
| 816 | 833 |
| OLD | NEW |