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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
587 return kSuccess; | 587 return kSuccess; |
588 } | 588 } |
589 | 589 |
590 // read rest of file, and get additional comment and time chunks in info_ptr | 590 // read rest of file, and get additional comment and time chunks in info_ptr |
591 png_read_end(fPng_ptr, fInfo_ptr); | 591 png_read_end(fPng_ptr, fInfo_ptr); |
592 return kSuccess; | 592 return kSuccess; |
593 } | 593 } |
594 | 594 |
595 class SkPngScanlineDecoder : public SkScanlineDecoder { | 595 class SkPngScanlineDecoder : public SkScanlineDecoder { |
596 public: | 596 public: |
597 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) | 597 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
598 : INHERITED(dstInfo) | 598 : INHERITED(srcInfo) |
599 , fCodec(codec) | 599 , fCodec(codec) |
600 , fHasAlpha(false) | 600 , fHasAlpha(false) |
601 {} | |
602 | |
603 SkCodec::Result onReset(const SkImageInfo& dstInfo, | |
emmaleer
2015/07/29 22:40:48
Is reset required to be called, for the ScanlineDe
msarett
2015/07/30 12:58:46
NewSDFromStream sets an SkImageInfo with the recom
scroggo
2015/07/30 15:11:35
Yes. I considered making reset unnecessary, but if
msarett
2015/07/30 15:37:55
Did you have thoughts on having both a start() and
emmaleer
2015/07/30 15:49:48
I think calling reset to start is less intuitive t
scroggo
2015/07/30 16:48:48
FWIW, I do not think setInfo is a good name. It se
| |
604 const SkCodec::Options& options, | |
605 SkPMColor ctable[], int* ctableCount) override | |
601 { | 606 { |
607 if (!fCodec->handleRewind()) { | |
608 return SkCodec::kCouldNotRewind; | |
609 } | |
610 | |
611 if (!conversion_possible(dstInfo, this->getInfo())) { | |
612 return SkCodec::kInvalidConversion; | |
613 } | |
614 | |
615 // Check to see if scaling was requested. | |
616 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | |
617 return SkCodec::kInvalidScale; | |
618 } | |
619 | |
620 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio ns, ctable, | |
621 ctableCount); | |
622 if (result != SkCodec::kSuccess) { | |
623 return result; | |
624 } | |
625 | |
626 fHasAlpha = false; | |
602 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig)); | 627 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig)); |
603 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 628 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
629 | |
630 return SkCodec::kSuccess; | |
604 } | 631 } |
605 | 632 |
606 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { | 633 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { |
607 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 634 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
608 SkCodecPrintf("setjmp long jump!\n"); | 635 SkCodecPrintf("setjmp long jump!\n"); |
609 return SkCodec::kInvalidInput; | 636 return SkCodec::kInvalidInput; |
610 } | 637 } |
611 | 638 |
612 void* dstRow = dst; | 639 void* dstRow = dst; |
613 for (int i = 0; i < count; i++) { | 640 for (int i = 0; i < count; i++) { |
(...skipping 27 matching lines...) Expand all Loading... | |
641 bool fHasAlpha; | 668 bool fHasAlpha; |
642 SkAutoMalloc fStorage; | 669 SkAutoMalloc fStorage; |
643 uint8_t* fSrcRow; | 670 uint8_t* fSrcRow; |
644 | 671 |
645 typedef SkScanlineDecoder INHERITED; | 672 typedef SkScanlineDecoder INHERITED; |
646 }; | 673 }; |
647 | 674 |
648 | 675 |
649 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { | 676 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { |
650 public: | 677 public: |
651 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec ) | 678 SkPngInterlacedScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec ) |
652 : INHERITED(dstInfo) | 679 : INHERITED(srcInfo) |
653 , fCodec(codec) | 680 , fCodec(codec) |
654 , fHasAlpha(false) | 681 , fHasAlpha(false) |
655 , fCurrentRow(0) | 682 , fCurrentRow(0) |
656 , fHeight(dstInfo.height()) | 683 , fHeight(srcInfo.height()) |
684 {} | |
685 | |
686 SkCodec::Result onReset(const SkImageInfo& dstInfo, | |
687 const SkCodec::Options& options, | |
688 SkPMColor ctable[], int* ctableCount) override | |
657 { | 689 { |
690 // No need to handleRewind here, since it will be done in each call to | |
691 // getScanlines. | |
692 | |
693 if (!conversion_possible(dstInfo, this->getInfo())) { | |
694 return SkCodec::kInvalidConversion; | |
695 } | |
696 | |
697 // Check to see if scaling was requested. | |
698 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | |
699 return SkCodec::kInvalidScale; | |
700 } | |
701 | |
702 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio ns, ctable, | |
703 ctableCount); | |
704 if (result != SkCodec::kSuccess) { | |
705 return result; | |
706 } | |
707 | |
708 fHasAlpha = false; | |
709 fCurrentRow = 0; | |
710 fHeight = dstInfo.height(); | |
658 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig); | 711 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig); |
659 fGarbageRow.reset(fSrcRowBytes); | 712 fGarbageRow.reset(fSrcRowBytes); |
660 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 713 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
714 | |
715 return SkCodec::kSuccess; | |
661 } | 716 } |
662 | 717 |
663 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { | 718 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { |
664 //rewind stream if have previously called onGetScanlines, | 719 //rewind stream if have previously called onGetScanlines, |
665 //since we need entire progressive image to get scanlines | 720 //since we need entire progressive image to get scanlines |
666 if (!fCodec->handleRewind()) { | 721 if (!fCodec->handleRewind()) { |
667 return SkCodec::kCouldNotRewind; | 722 return SkCodec::kCouldNotRewind; |
668 } | 723 } |
669 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 724 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
670 SkCodecPrintf("setjmp long jump!\n"); | 725 SkCodecPrintf("setjmp long jump!\n"); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
715 bool fHasAlpha; | 770 bool fHasAlpha; |
716 int fCurrentRow; | 771 int fCurrentRow; |
717 int fHeight; | 772 int fHeight; |
718 size_t fSrcRowBytes; | 773 size_t fSrcRowBytes; |
719 SkAutoMalloc fGarbageRow; | 774 SkAutoMalloc fGarbageRow; |
720 uint8_t* fGarbageRowPtr; | 775 uint8_t* fGarbageRowPtr; |
721 | 776 |
722 typedef SkScanlineDecoder INHERITED; | 777 typedef SkScanlineDecoder INHERITED; |
723 }; | 778 }; |
724 | 779 |
725 | 780 SkScanlineDecoder* SkPngCodec::NewSDFromStream(SkStream* stream) { |
726 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | |
727 const Options& options, SkPMColor ctable[], int* ctableCount) { | |
728 if (!conversion_possible(dstInfo, this->getInfo())) { | |
729 SkCodecPrintf("no conversion possible\n"); | |
730 return NULL; | |
731 } | |
732 // Check to see if scaling was requested. | |
733 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | |
734 return NULL; | |
735 } | |
736 // Create a new SkPngCodec, to be owned by the scanline decoder. | |
737 SkStream* stream = this->stream()->duplicate(); | |
738 if (!stream) { | |
739 return NULL; | |
740 } | |
741 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); | 781 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); |
msarett
2015/07/30 12:58:46
I'm noticing that we still need to create a codec
scroggo
2015/07/30 15:11:35
This is an implementation detail, though. We *coul
| |
742 if (!codec) { | 782 if (!codec) { |
743 return NULL; | 783 return NULL; |
744 } | 784 } |
745 | 785 |
746 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc cess) { | 786 codec->fNumberPasses = png_set_interlace_handling(codec->fPng_ptr); |
747 SkCodecPrintf("failed to initialize the swizzler.\n"); | 787 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); |
748 return NULL; | 788 |
789 const SkImageInfo& srcInfo = codec->getInfo(); | |
790 if (codec->fNumberPasses > 1) { | |
791 // interlaced image | |
792 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach ())); | |
749 } | 793 } |
750 | 794 |
751 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); | 795 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); |
752 if (codec->fNumberPasses > 1) { | |
753 // interlaced image | |
754 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); | |
755 } | |
756 | |
757 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); | |
758 } | 796 } |
759 | 797 |
OLD | NEW |