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

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

Issue 1260673002: SkScaledCodec class (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix sample function for 565 images 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"
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
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
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 16 matching lines...) Expand all
629 //calling png_read_rows in a loop is insignificantly slower than calling it once with count 630 //calling png_read_rows in a loop is insignificantly slower than calling it once with count
630 //as png_read_rows has it's own loop which calls png_read_row count time s. 631 //as png_read_rows has it's own loop which calls png_read_row count time s.
631 for (int i = 0; i < count; i++) { 632 for (int i = 0; i < count; i++) {
632 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); 633 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1);
633 } 634 }
634 return SkCodec::kSuccess; 635 return SkCodec::kSuccess;
635 } 636 }
636 637
637 bool onReallyHasAlpha() const override { return fHasAlpha; } 638 bool onReallyHasAlpha() const override { return fHasAlpha; }
638 639
640 bool onIsHardToSample() override {
641 return false;
642 }
643
639 private: 644 private:
640 SkAutoTDelete<SkPngCodec> fCodec; 645 SkAutoTDelete<SkPngCodec> fCodec;
641 bool fHasAlpha; 646 bool fHasAlpha;
642 SkAutoMalloc fStorage; 647 SkAutoMalloc fStorage;
643 uint8_t* fSrcRow; 648 uint8_t* fSrcRow;
644 649
645 typedef SkScanlineDecoder INHERITED; 650 typedef SkScanlineDecoder INHERITED;
646 }; 651 };
647 652
648 653
649 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { 654 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder {
650 public: 655 public:
651 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec ) 656 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec )
652 : INHERITED(dstInfo) 657 : INHERITED(dstInfo)
653 , fCodec(codec) 658 , fCodec(codec)
654 , fHasAlpha(false) 659 , fHasAlpha(false)
655 , fCurrentRow(0) 660 , fCurrentRow(0)
656 , fHeight(dstInfo.height()) 661 , fHeight(dstInfo.height())
657 { 662 {
658 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig); 663 fSrcRowBytes = codec->getInfo().width() * SkSwizzler::BytesPerPixel(fCod ec->fSrcConfig);
659 fGarbageRow.reset(fSrcRowBytes); 664 fGarbageRow.reset(fSrcRowBytes);
660 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); 665 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
661 } 666 }
662 667
663 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { 668 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride {
664 //rewind stream if have previously called onGetScanlines, 669 //rewind stream if have previously called onGetScanlines,
665 //since we need entire progressive image to get scanlines 670 //since we need entire progressive image to get scanlines
666 if (!fCodec->handleRewind()) { 671 if (!fCodec->handleRewind()) {
667 return SkCodec::kCouldNotRewind; 672 return SkCodec::kCouldNotRewind;
668 } 673 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 } 708 }
704 709
705 SkCodec::Result onSkipScanlines(int count) override { 710 SkCodec::Result onSkipScanlines(int count) override {
706 //when ongetScanlines is called it will skip to fCurrentRow 711 //when ongetScanlines is called it will skip to fCurrentRow
707 fCurrentRow += count; 712 fCurrentRow += count;
708 return SkCodec::kSuccess; 713 return SkCodec::kSuccess;
709 } 714 }
710 715
711 bool onReallyHasAlpha() const override { return fHasAlpha; } 716 bool onReallyHasAlpha() const override { return fHasAlpha; }
712 717
718 bool onIsHardToSample() override {
719 return true;
720 }
721
713 private: 722 private:
714 SkAutoTDelete<SkPngCodec> fCodec; 723 SkAutoTDelete<SkPngCodec> fCodec;
715 bool fHasAlpha; 724 bool fHasAlpha;
716 int fCurrentRow; 725 int fCurrentRow;
717 int fHeight; 726 int fHeight;
718 size_t fSrcRowBytes; 727 size_t fSrcRowBytes;
719 SkAutoMalloc fGarbageRow; 728 SkAutoMalloc fGarbageRow;
720 uint8_t* fGarbageRowPtr; 729 uint8_t* fGarbageRowPtr;
721 730
722 typedef SkScanlineDecoder INHERITED; 731 typedef SkScanlineDecoder INHERITED;
723 }; 732 };
724 733
725 734
726 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 735 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
727 const Options& options, SkPMColor ctable[], int* ctableCount) { 736 const Options& options, SkPMColor ctable[], int* ctableCount) {
728 if (!conversion_possible(dstInfo, this->getInfo())) { 737 if (!conversion_possible(dstInfo, this->getInfo())) {
729 SkCodecPrintf("no conversion possible\n"); 738 SkCodecPrintf("no conversion possible\n");
730 return NULL; 739 return NULL;
731 } 740 }
732 // Check to see if scaling was requested. 741 // Check to see if scaling was requested.
733 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 742 if (dstInfo.dimensions() != this->getInfo().dimensions()) {
734 return NULL; 743 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstI nfo)) {
744 return NULL;
745 }
735 } 746 }
736 // Create a new SkPngCodec, to be owned by the scanline decoder. 747 // Create a new SkPngCodec, to be owned by the scanline decoder.
737 SkStream* stream = this->stream()->duplicate(); 748 SkStream* stream = this->stream()->duplicate();
738 if (!stream) { 749 if (!stream) {
739 return NULL; 750 return NULL;
740 } 751 }
741 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); 752 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream)));
742 if (!codec) { 753 if (!codec) {
743 return NULL; 754 return NULL;
744 } 755 }
745 756
746 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc cess) { 757 if (codec->initializeSwizzler(dstInfo, options, ctable, ctableCount) != kSuc cess) {
747 SkCodecPrintf("failed to initialize the swizzler.\n"); 758 SkCodecPrintf("failed to initialize the swizzler.\n");
748 return NULL; 759 return NULL;
749 } 760 }
750 761
751 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); 762 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES);
752 if (codec->fNumberPasses > 1) { 763 if (codec->fNumberPasses > 1) {
753 // interlaced image 764 // interlaced image
754 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); 765 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ()));
755 } 766 }
756 767
757 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); 768 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach()));
758 } 769 }
759 770
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698