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

Side by Side Diff: src/codec/SkCodec_libpng.cpp

Issue 1267583002: Create a scanline decoder without creating a codec (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Fix bugs. Created 5 years, 4 months 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 /* 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698