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

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

Issue 1194703002: onGetScanlines and onSkipScanlines for interlaced pngs (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fixing size_t to int conversion warning Created 5 years, 6 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
« no previous file with comments | « src/codec/SkCodec_libpng.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 630 matching lines...) Expand 10 before | Expand all | Expand 10 after
641 641
642 private: 642 private:
643 SkPngCodec* fCodec; // Unowned. 643 SkPngCodec* fCodec; // Unowned.
644 bool fHasAlpha; 644 bool fHasAlpha;
645 SkAutoMalloc fStorage; 645 SkAutoMalloc fStorage;
646 uint8_t* fSrcRow; 646 uint8_t* fSrcRow;
647 647
648 typedef SkScanlineDecoder INHERITED; 648 typedef SkScanlineDecoder INHERITED;
649 }; 649 };
650 650
651
652 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder {
653 public:
654 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec )
655 : INHERITED(dstInfo)
656 , fCodec(codec)
657 , fHasAlpha(false)
658 , fCurrentRow(0)
659 , fHeight(dstInfo.height())
660 , fSrcRowBytes(dstInfo.minRowBytes())
661 , fRewindNeeded(false)
662 {
663 fGarbageRow.reset(fSrcRowBytes);
664 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
665 }
666
667 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t dstRowB ytes) override {
668 //rewind stream if have previously called onGetScanlines,
669 //since we need entire progressive image to get scanlines
670 if (fRewindNeeded) {
671 if(false == fCodec->handleRewind()) {
672 return SkImageGenerator::kCouldNotRewind;
673 }
674 } else {
675 fRewindNeeded = true;
676 }
677 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) {
678 SkCodecPrintf("setjmp long jump!\n");
679 return SkImageGenerator::kInvalidInput;
680 }
681 const int number_passes = png_set_interlace_handling(fCodec->fPng_ptr);
682 SkAutoMalloc storage(count * fSrcRowBytes);
683 uint8_t* storagePtr = static_cast<uint8_t*>(storage.get());
684 uint8_t* srcRow;
685 for (int i = 0; i < number_passes; i++) {
686 //read rows we planned to skip into garbage row
687 for (int y = 0; y < fCurrentRow; y++){
688 png_read_rows(fCodec->fPng_ptr, &fGarbageRowPtr, png_bytepp_NULL , 1);
689 }
690 //read rows we care about into buffer
691 srcRow = storagePtr;
692 for (int y = 0; y < count; y++) {
693 png_read_rows(fCodec->fPng_ptr, &srcRow, png_bytepp_NULL, 1);
694 srcRow += fSrcRowBytes;
695 }
696 //read rows we don't want into garbage buffer
697 for (int y = 0; y < fHeight - fCurrentRow - count; y++) {
698 png_read_rows(fCodec->fPng_ptr, &fGarbageRowPtr, png_bytepp_NULL , 1);
699 }
700 }
701 //swizzle the rows we care about
702 srcRow = storagePtr;
703 for (int y = 0; y < count; y++) {
704 fCodec->fSwizzler->setDstRow(dst);
705 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(srcRow));
706 dst = SkTAddOffset<void>(dst, dstRowBytes);
707 srcRow += fSrcRowBytes;
708 }
709 fCurrentRow += count;
710 return SkImageGenerator::kSuccess;
711 }
712
713 SkImageGenerator::Result onSkipScanlines(int count) override {
714 //when ongetScanlines is called it will skip to fCurrentRow
715 fCurrentRow += count;
716 return SkImageGenerator::kSuccess;
717 }
718
719 void onFinish() override {
720 fCodec->finish();
721 }
722
723 bool onReallyHasAlpha() const override { return fHasAlpha; }
724
725 private:
726 SkPngCodec* fCodec; // Unowned.
727 bool fHasAlpha;
728 int fCurrentRow;
729 int fHeight;
730 size_t fSrcRowBytes;
731 bool fRewindNeeded;
732 SkAutoMalloc fGarbageRow;
733 uint8_t* fGarbageRowPtr;
734
735
736
737
738
739 typedef SkScanlineDecoder INHERITED;
740 };
741
742
651 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 743 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
652 const Options& options, SkPMColor ctable[], int* ctableCount) { 744 const Options& options, SkPMColor ctable[], int* ctableCount) {
653 if (!this->handleRewind()) { 745 if (!this->handleRewind()) {
654 return NULL; 746 return NULL;
655 } 747 }
656 748
657 // Check to see if scaling was requested. 749 // Check to see if scaling was requested.
658 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 750 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
659 return NULL; 751 return NULL;
660 } 752 }
661 753
662 if (!conversion_possible(dstInfo, this->getInfo())) { 754 if (!conversion_possible(dstInfo, this->getInfo())) {
663 SkCodecPrintf("no conversion possible\n"); 755 SkCodecPrintf("no conversion possible\n");
664 return NULL; 756 return NULL;
665 } 757 }
666 758
667 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded, 759 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded,
668 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to 760 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to
669 // be at least dstInfo.minRowBytes. 761 // be at least dstInfo.minRowBytes.
670 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable, 762 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable,
671 ctableCount) != kSuccess) { 763 ctableCount) != kSuccess) {
672 SkCodecPrintf("failed to initialize the swizzler.\n"); 764 SkCodecPrintf("failed to initialize the swizzler.\n");
673 return NULL; 765 return NULL;
674 } 766 }
675 767
676 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); 768 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES);
677 if (fNumberPasses > 1) { 769 if (fNumberPasses > 1) {
678 // We cannot efficiently do scanline decoding. 770 // interlaced image
679 return NULL; 771 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, this));
680 } 772 }
681 773
682 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); 774 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this));
683 } 775 }
684 776
OLDNEW
« no previous file with comments | « src/codec/SkCodec_libpng.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698