| 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 442 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 466 //would have exited before now if the colorType was supported by png | 467 //would have exited before now if the colorType was supported by png |
| 467 SkASSERT(false); | 468 SkASSERT(false); |
| 468 } | 469 } |
| 469 | 470 |
| 470 // Copy the color table to the client if they request kIndex8 mode | 471 // Copy the color table to the client if they request kIndex8 mode |
| 471 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 472 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
| 472 | 473 |
| 473 // Create the swizzler. SkPngCodec retains ownership of the color table. | 474 // Create the swizzler. SkPngCodec retains ownership of the color table. |
| 474 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL; | 475 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL; |
| 475 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, | 476 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, |
| 476 options.fZeroInitialized)); | 477 options.fZeroInitialized, this->getInfo().width())); |
| 477 if (!fSwizzler) { | 478 if (!fSwizzler) { |
| 478 // FIXME: CreateSwizzler could fail for another reason. | 479 // FIXME: CreateSwizzler could fail for another reason. |
| 479 return kUnimplemented; | 480 return kUnimplemented; |
| 480 } | 481 } |
| 481 return kSuccess; | 482 return kSuccess; |
| 482 } | 483 } |
| 483 | 484 |
| 484 | 485 |
| 485 bool SkPngCodec::handleRewind() { | 486 bool SkPngCodec::handleRewind() { |
| 486 switch (this->rewindIfNeeded()) { | 487 switch (this->rewindIfNeeded()) { |
| (...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 592 return kSuccess; | 593 return kSuccess; |
| 593 } | 594 } |
| 594 | 595 |
| 595 class SkPngScanlineDecoder : public SkScanlineDecoder { | 596 class SkPngScanlineDecoder : public SkScanlineDecoder { |
| 596 public: | 597 public: |
| 597 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) | 598 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) |
| 598 : INHERITED(dstInfo) | 599 : INHERITED(dstInfo) |
| 599 , fCodec(codec) | 600 , fCodec(codec) |
| 600 , fHasAlpha(false) | 601 , fHasAlpha(false) |
| 601 { | 602 { |
| 602 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig)); | 603 fStorage.reset(fCodec->getInfo().width() * SkSwizzler::BytesPerPixel(fCo
dec->fSrcConfig)); |
| 603 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 604 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
| 604 } | 605 } |
| 605 | 606 |
| 606 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { | 607 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { |
| 607 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 608 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
| 608 SkCodecPrintf("setjmp long jump!\n"); | 609 SkCodecPrintf("setjmp long jump!\n"); |
| 609 return SkCodec::kInvalidInput; | 610 return SkCodec::kInvalidInput; |
| 610 } | 611 } |
| 611 | 612 |
| 612 void* dstRow = dst; | 613 void* dstRow = dst; |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 648 | 649 |
| 649 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { | 650 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { |
| 650 public: | 651 public: |
| 651 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec
) | 652 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec
) |
| 652 : INHERITED(dstInfo) | 653 : INHERITED(dstInfo) |
| 653 , fCodec(codec) | 654 , fCodec(codec) |
| 654 , fHasAlpha(false) | 655 , fHasAlpha(false) |
| 655 , fCurrentRow(0) | 656 , fCurrentRow(0) |
| 656 , fHeight(dstInfo.height()) | 657 , fHeight(dstInfo.height()) |
| 657 { | 658 { |
| 658 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig); | 659 fSrcRowBytes = codec->getInfo().width() * SkSwizzler::BytesPerPixel(fCod
ec->fSrcConfig); |
| 659 fGarbageRow.reset(fSrcRowBytes); | 660 fGarbageRow.reset(fSrcRowBytes); |
| 660 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 661 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
| 661 } | 662 } |
| 662 | 663 |
| 663 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { | 664 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { |
| 664 //rewind stream if have previously called onGetScanlines, | 665 //rewind stream if have previously called onGetScanlines, |
| 665 //since we need entire progressive image to get scanlines | 666 //since we need entire progressive image to get scanlines |
| 666 if (!fCodec->handleRewind()) { | 667 if (!fCodec->handleRewind()) { |
| 667 return SkCodec::kCouldNotRewind; | 668 return SkCodec::kCouldNotRewind; |
| 668 } | 669 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 703 } | 704 } |
| 704 | 705 |
| 705 SkCodec::Result onSkipScanlines(int count) override { | 706 SkCodec::Result onSkipScanlines(int count) override { |
| 706 //when ongetScanlines is called it will skip to fCurrentRow | 707 //when ongetScanlines is called it will skip to fCurrentRow |
| 707 fCurrentRow += count; | 708 fCurrentRow += count; |
| 708 return SkCodec::kSuccess; | 709 return SkCodec::kSuccess; |
| 709 } | 710 } |
| 710 | 711 |
| 711 bool onReallyHasAlpha() const override { return fHasAlpha; } | 712 bool onReallyHasAlpha() const override { return fHasAlpha; } |
| 712 | 713 |
| 714 bool onRequiresPostYSampling() override { |
| 715 return true; |
| 716 } |
| 717 |
| 713 private: | 718 private: |
| 714 SkAutoTDelete<SkPngCodec> fCodec; | 719 SkAutoTDelete<SkPngCodec> fCodec; |
| 715 bool fHasAlpha; | 720 bool fHasAlpha; |
| 716 int fCurrentRow; | 721 int fCurrentRow; |
| 717 int fHeight; | 722 int fHeight; |
| 718 size_t fSrcRowBytes; | 723 size_t fSrcRowBytes; |
| 719 SkAutoMalloc fGarbageRow; | 724 SkAutoMalloc fGarbageRow; |
| 720 uint8_t* fGarbageRowPtr; | 725 uint8_t* fGarbageRowPtr; |
| 721 | 726 |
| 722 typedef SkScanlineDecoder INHERITED; | 727 typedef SkScanlineDecoder INHERITED; |
| 723 }; | 728 }; |
| 724 | 729 |
| 725 | 730 |
| 726 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | 731 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, |
| 727 const Options& options, SkPMColor ctable[], int* ctableCount) { | 732 const Options& options, SkPMColor ctable[], int* ctableCount) { |
| 728 if (!conversion_possible(dstInfo, this->getInfo())) { | 733 if (!conversion_possible(dstInfo, this->getInfo())) { |
| 729 SkCodecPrintf("no conversion possible\n"); | 734 SkCodecPrintf("no conversion possible\n"); |
| 730 return NULL; | 735 return NULL; |
| 731 } | 736 } |
| 732 // Check to see if scaling was requested. | 737 // Check to see if scaling was requested. |
| 733 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 738 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
| 734 return NULL; | 739 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstI
nfo)) { |
| 740 return NULL; |
| 741 } |
| 735 } | 742 } |
| 736 // Create a new SkPngCodec, to be owned by the scanline decoder. | 743 // Create a new SkPngCodec, to be owned by the scanline decoder. |
| 737 SkStream* stream = this->stream()->duplicate(); | 744 SkStream* stream = this->stream()->duplicate(); |
| 738 if (!stream) { | 745 if (!stream) { |
| 739 return NULL; | 746 return NULL; |
| 740 } | 747 } |
| 741 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro
mStream(stream))); | 748 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro
mStream(stream))); |
| 742 if (!codec) { | 749 if (!codec) { |
| 743 return NULL; | 750 return NULL; |
| 744 } | 751 } |
| 745 | 752 |
| 746 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc
cess) { | 753 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc
cess) { |
| 747 SkCodecPrintf("failed to initialize the swizzler.\n"); | 754 SkCodecPrintf("failed to initialize the swizzler.\n"); |
| 748 return NULL; | 755 return NULL; |
| 749 } | 756 } |
| 750 | 757 |
| 751 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); | 758 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); |
| 752 if (codec->fNumberPasses > 1) { | 759 if (codec->fNumberPasses > 1) { |
| 753 // interlaced image | 760 // interlaced image |
| 754 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach
())); | 761 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach
())); |
| 755 } | 762 } |
| 756 | 763 |
| 757 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); | 764 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); |
| 758 } | 765 } |
| 759 | 766 |
| OLD | NEW |