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

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: Works for jpeg 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"
(...skipping 453 matching lines...) Expand 10 before | Expand all | Expand 10 after
464 } 464 }
465 break; 465 break;
466 default: 466 default:
467 //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
468 SkASSERT(false); 468 SkASSERT(false);
469 } 469 }
470 470
471 // 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
472 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); 472 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount);
473 473
474 int sampleX = this->getInfo().width() / requestedInfo.width();
scroggo 2015/07/30 17:53:01 This should also be in some central place, to be s
475
474 // Create the swizzler. SkPngCodec retains ownership of the color table. 476 // Create the swizzler. SkPngCodec retains ownership of the color table.
475 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL; 477 const SkPMColor* colors = fColorTable ? fColorTable->readColors() : NULL;
476 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo , 478 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo ,
477 dst, rowBytes, options.fZeroInitialized)); 479 dst, rowBytes, options.fZeroInitialized, sampleX));
478 if (!fSwizzler) { 480 if (!fSwizzler) {
479 // FIXME: CreateSwizzler could fail for another reason. 481 // FIXME: CreateSwizzler could fail for another reason.
480 return kUnimplemented; 482 return kUnimplemented;
481 } 483 }
482 return kSuccess; 484 return kSuccess;
483 } 485 }
484 486
485 487
486 bool SkPngCodec::handleRewind() { 488 bool SkPngCodec::handleRewind() {
487 switch (this->rewindIfNeeded()) { 489 switch (this->rewindIfNeeded()) {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 return kSuccess; 592 return kSuccess;
591 } 593 }
592 594
593 class SkPngScanlineDecoder : public SkScanlineDecoder { 595 class SkPngScanlineDecoder : public SkScanlineDecoder {
594 public: 596 public:
595 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) 597 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec)
596 : INHERITED(dstInfo) 598 : INHERITED(dstInfo)
597 , fCodec(codec) 599 , fCodec(codec)
598 , fHasAlpha(false) 600 , fHasAlpha(false)
599 { 601 {
600 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig)); 602 fStorage.reset(fCodec->getInfo().width() * SkSwizzler::BytesPerPixel(fCo dec->fSrcConfig));
601 fSrcRow = static_cast<uint8_t*>(fStorage.get()); 603 fSrcRow = static_cast<uint8_t*>(fStorage.get());
602 } 604 }
603 605
604 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { 606 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de {
605 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { 607 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) {
606 SkCodecPrintf("setjmp long jump!\n"); 608 SkCodecPrintf("setjmp long jump!\n");
607 return SkCodec::kInvalidInput; 609 return SkCodec::kInvalidInput;
608 } 610 }
609 611
610 for (int i = 0; i < count; i++) { 612 for (int i = 0; i < count; i++) {
(...skipping 16 matching lines...) Expand all
627 //calling png_read_rows in a loop is insignificantly slower than calling it once with count 629 //calling png_read_rows in a loop is insignificantly slower than calling it once with count
628 //as png_read_rows has it's own loop which calls png_read_row count time s. 630 //as png_read_rows has it's own loop which calls png_read_row count time s.
629 for (int i = 0; i < count; i++) { 631 for (int i = 0; i < count; i++) {
630 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); 632 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1);
631 } 633 }
632 return SkCodec::kSuccess; 634 return SkCodec::kSuccess;
633 } 635 }
634 636
635 bool onReallyHasAlpha() const override { return fHasAlpha; } 637 bool onReallyHasAlpha() const override { return fHasAlpha; }
636 638
639 bool onIsHardToSample() override {
640 return false;
641 }
642
637 private: 643 private:
638 SkAutoTDelete<SkPngCodec> fCodec; 644 SkAutoTDelete<SkPngCodec> fCodec;
639 bool fHasAlpha; 645 bool fHasAlpha;
640 SkAutoMalloc fStorage; 646 SkAutoMalloc fStorage;
641 uint8_t* fSrcRow; 647 uint8_t* fSrcRow;
642 648
643 typedef SkScanlineDecoder INHERITED; 649 typedef SkScanlineDecoder INHERITED;
644 }; 650 };
645 651
646 652
647 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { 653 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder {
648 public: 654 public:
649 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec ) 655 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec )
650 : INHERITED(dstInfo) 656 : INHERITED(dstInfo)
651 , fCodec(codec) 657 , fCodec(codec)
652 , fHasAlpha(false) 658 , fHasAlpha(false)
653 , fCurrentRow(0) 659 , fCurrentRow(0)
654 , fHeight(dstInfo.height()) 660 , fHeight(dstInfo.height())
655 { 661 {
656 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig); 662 fSrcRowBytes = codec->getInfo().width() * SkSwizzler::BytesPerPixel(fCod ec->fSrcConfig);
657 fGarbageRow.reset(fSrcRowBytes); 663 fGarbageRow.reset(fSrcRowBytes);
658 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); 664 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get());
659 } 665 }
660 666
661 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { 667 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride {
662 //rewind stream if have previously called onGetScanlines, 668 //rewind stream if have previously called onGetScanlines,
663 //since we need entire progressive image to get scanlines 669 //since we need entire progressive image to get scanlines
664 if (!fCodec->handleRewind()) { 670 if (!fCodec->handleRewind()) {
665 return SkCodec::kCouldNotRewind; 671 return SkCodec::kCouldNotRewind;
666 } 672 }
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
701 } 707 }
702 708
703 SkCodec::Result onSkipScanlines(int count) override { 709 SkCodec::Result onSkipScanlines(int count) override {
704 //when ongetScanlines is called it will skip to fCurrentRow 710 //when ongetScanlines is called it will skip to fCurrentRow
705 fCurrentRow += count; 711 fCurrentRow += count;
706 return SkCodec::kSuccess; 712 return SkCodec::kSuccess;
707 } 713 }
708 714
709 bool onReallyHasAlpha() const override { return fHasAlpha; } 715 bool onReallyHasAlpha() const override { return fHasAlpha; }
710 716
717 bool onIsHardToSample() override {
718 return true;
719 }
720
711 private: 721 private:
712 SkAutoTDelete<SkPngCodec> fCodec; 722 SkAutoTDelete<SkPngCodec> fCodec;
713 bool fHasAlpha; 723 bool fHasAlpha;
714 int fCurrentRow; 724 int fCurrentRow;
715 int fHeight; 725 int fHeight;
716 size_t fSrcRowBytes; 726 size_t fSrcRowBytes;
717 SkAutoMalloc fGarbageRow; 727 SkAutoMalloc fGarbageRow;
718 uint8_t* fGarbageRowPtr; 728 uint8_t* fGarbageRowPtr;
719 729
720 typedef SkScanlineDecoder INHERITED; 730 typedef SkScanlineDecoder INHERITED;
721 }; 731 };
722 732
723 733
724 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, 734 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo,
725 const Options& options, SkPMColor ctable[], int* ctableCount) { 735 const Options& options, SkPMColor ctable[], int* ctableCount) {
726 if (!conversion_possible(dstInfo, this->getInfo())) { 736 if (!conversion_possible(dstInfo, this->getInfo())) {
727 SkCodecPrintf("no conversion possible\n"); 737 SkCodecPrintf("no conversion possible\n");
728 return NULL; 738 return NULL;
729 } 739 }
740 Options scaledOptions = options;
scroggo 2015/07/30 17:53:01 It looks like we do not modify scaledOptions, so w
emmaleer 2015/07/30 22:27:55 Acknowledged.
730 // Check to see if scaling was requested. 741 // Check to see if scaling was requested.
731 if (dstInfo.dimensions() != this->getInfo().dimensions()) { 742 if(dstInfo.dimensions() != this->getInfo().dimensions()) {
732 return NULL; 743 // the caller is sampling
744 // heights must be equal as SkCodec_libpng has no native y sampling
scroggo 2015/07/30 17:53:01 What about widths? We don't want them to request a
emmaleer 2015/07/30 22:27:55 Good point. I've added a check to only allow small
745 if (dstInfo.height() != this->getInfo().height()) {
746 return NULL;
747 }
733 } 748 }
734 // Create a new SkPngCodec, to be owned by the scanline decoder. 749 // Create a new SkPngCodec, to be owned by the scanline decoder.
735 SkStream* stream = this->stream()->duplicate(); 750 SkStream* stream = this->stream()->duplicate();
736 if (!stream) { 751 if (!stream) {
737 return NULL; 752 return NULL;
738 } 753 }
739 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); 754 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream)));
740 if (!codec) { 755 if (!codec) {
741 return NULL; 756 return NULL;
742 } 757 }
743 758
744 // 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,
745 // 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
746 // be at least dstInfo.minRowBytes. 761 // be at least dstInfo.minRowBytes.
747 if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable, 762 if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), scaledOp tions, ctable,
748 ctableCount) != kSuccess) { 763 ctableCount) != kSuccess) {
749 SkCodecPrintf("failed to initialize the swizzler.\n"); 764 SkCodecPrintf("failed to initialize the swizzler.\n");
750 return NULL; 765 return NULL;
751 } 766 }
752 767
753 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); 768 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES);
754 if (codec->fNumberPasses > 1) { 769 if (codec->fNumberPasses > 1) {
755 // interlaced image 770 // interlaced image
756 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); 771 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ()));
757 } 772 }
758 773
759 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); 774 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach()));
760 } 775 }
761 776
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698