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

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: changing variable names for clarity, updating constructor 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 {
662 fGarbageRow.reset(fSrcRowBytes);
663 fGarbageRowp = static_cast<uint8_t*>(fGarbageRow.get());
664 }
665
666 SkImageGenerator::Result onGetScanlines(void* dst, int count, size_t dstRowB ytes) override {
667 //rewind stream since we need entire progressive image to get scanlines
668 fCodec->handleRewind();
669 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) {
670 SkCodecPrintf("setjmp long jump!\n");
671 return SkImageGenerator::kInvalidInput;
672 }
673 const int number_passes = png_set_interlace_handling(fCodec->fPng_ptr);
674 fStorage.reset(count * fSrcRowBytes);
675 fStoragep = static_cast<uint8_t*>(fStorage.get());
676
677 for (int i = 0; i < number_passes; i++) {
678 //read rows we planned to skip into garbage row
679 for (int y = 0; y < fCurrentRow; y++){
680 png_read_rows(fCodec->fPng_ptr, &fGarbageRowp, png_bytepp_NULL, 1);
681 }
682 //read rows we care about into buffer
683 fSrcRow = fStoragep;
684 for (int y = 0; y < count; y++) {
685 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1);
686 fSrcRow += fSrcRowBytes;
687 }
688 //read rows we don't want into garbage buffer
689 for (int y = 0; y < fHeight - fCurrentRow - count; y++) {
690 png_read_rows(fCodec->fPng_ptr, &fGarbageRowp, png_bytepp_NULL, 1);
691 }
692 }
693 //swizzle the rows we care about
694 fSrcRow = fStoragep;
695 for (int y = 0; y < count; y++) {
696 fCodec->fSwizzler->setDstRow(dst);
697 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow)) ;
698 dst = SkTAddOffset<void>(dst, dstRowBytes);
699 fSrcRow += fSrcRowBytes;
700 }
701 fCurrentRow += count;
702 return SkImageGenerator::kSuccess;
703 }
704
705 SkImageGenerator::Result onSkipScanlines(int count) override {
706 //when ongetScanlines is called it will skip to fCurrentRow
707 fCurrentRow += count;
708 return SkImageGenerator::kSuccess;
709 }
710
711 void onFinish() override {
712 fCodec->finish();
713 }
714
715 bool onReallyHasAlpha() const override { return fHasAlpha; }
716
717 private:
718 SkPngCodec* fCodec; // Unowned.
719 bool fHasAlpha;
720 int fCurrentRow;
721 int fHeight;
722 int fSrcRowBytes;
723 SkAutoMalloc fStorage;
724 uint8_t* fStoragep;
scroggo 2015/06/19 15:45:53 nit: In Skia, I think we would typically name this
emmaleer 2015/06/19 22:12:20 Acknowledged.
725 SkAutoMalloc fGarbageRow;
726 uint8_t* fGarbageRowp;
727 uint8_t* fSrcRow;
728
729
730
731
732 typedef SkScanlineDecoder INHERITED;
733 };
734
735
651 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 736 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
652 const Options& options, SkPMColor ctable[], int* ctableCount) { 737 const Options& options, SkPMColor ctable[], int* ctableCount) {
653 if (!this->handleRewind()) { 738 if (!this->handleRewind()) {
654 return NULL; 739 return NULL;
655 } 740 }
656 741
657 // Check to see if scaling was requested. 742 // Check to see if scaling was requested.
658 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 743 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
659 return NULL; 744 return NULL;
660 } 745 }
661 746
662 if (!conversion_possible(dstInfo, this->getInfo())) { 747 if (!conversion_possible(dstInfo, this->getInfo())) {
663 SkCodecPrintf("no conversion possible\n"); 748 SkCodecPrintf("no conversion possible\n");
664 return NULL; 749 return NULL;
665 } 750 }
666 751
667 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded, 752 // 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 753 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to
669 // be at least dstInfo.minRowBytes. 754 // be at least dstInfo.minRowBytes.
670 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable, 755 if (this->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable,
671 ctableCount) != kSuccess) { 756 ctableCount) != kSuccess) {
672 SkCodecPrintf("failed to initialize the swizzler.\n"); 757 SkCodecPrintf("failed to initialize the swizzler.\n");
673 return NULL; 758 return NULL;
674 } 759 }
675 760
676 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES); 761 SkASSERT(fNumberPasses != INVALID_NUMBER_PASSES);
677 if (fNumberPasses > 1) { 762 if (fNumberPasses > 1) {
678 // We cannot efficiently do scanline decoding. 763 // interlaced image
679 return NULL; 764 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, this));
680 } 765 }
681 766
682 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this)); 767 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, this));
683 } 768 }
684 769
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