OLD | NEW |
---|---|
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 406 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
417 } | 417 } |
418 // Check for supported color types | 418 // Check for supported color types |
419 switch (dst.colorType()) { | 419 switch (dst.colorType()) { |
420 case kN32_SkColorType: | 420 case kN32_SkColorType: |
421 return true; | 421 return true; |
422 default: | 422 default: |
423 return dst.colorType() == src.colorType(); | 423 return dst.colorType() == src.colorType(); |
424 } | 424 } |
425 } | 425 } |
426 | 426 |
427 bool SkPngCodec::onIsInterlaced() { | |
428 // we cannot depend on fNumberPasses, since it may not have been set yet | |
scroggo
2015/07/27 19:29:57
If we moved this onto the scanline decoder, we wou
emmaleer
2015/07/28 14:19:16
Acknowledged.
| |
429 return 1 != png_set_interlace_handling(fPng_ptr); | |
430 } | |
431 | |
427 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, | 432 SkCodec::Result SkPngCodec::initializeSwizzler(const SkImageInfo& requestedInfo, |
428 void* dst, size_t rowBytes, | 433 void* dst, size_t rowBytes, |
429 const Options& options, | 434 const Options& options, |
430 SkPMColor ctable[], | 435 SkPMColor ctable[], |
431 int* ctableCount) { | 436 int* ctableCount) { |
432 // FIXME: Could we use the return value of setjmp to specify the type of | 437 // FIXME: Could we use the return value of setjmp to specify the type of |
433 // error? | 438 // error? |
434 if (setjmp(png_jmpbuf(fPng_ptr))) { | 439 if (setjmp(png_jmpbuf(fPng_ptr))) { |
435 SkCodecPrintf("setjmp long jump!\n"); | 440 SkCodecPrintf("setjmp long jump!\n"); |
436 return kInvalidInput; | 441 return kInvalidInput; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
586 } | 591 } |
587 | 592 |
588 // read rest of file, and get additional comment and time chunks in info_ptr | 593 // read rest of file, and get additional comment and time chunks in info_ptr |
589 png_read_end(fPng_ptr, fInfo_ptr); | 594 png_read_end(fPng_ptr, fInfo_ptr); |
590 return kSuccess; | 595 return kSuccess; |
591 } | 596 } |
592 | 597 |
593 class SkPngScanlineDecoder : public SkScanlineDecoder { | 598 class SkPngScanlineDecoder : public SkScanlineDecoder { |
594 public: | 599 public: |
595 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) | 600 SkPngScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec) |
596 : INHERITED(dstInfo) | 601 : INHERITED(dstInfo, codec->getInfo()) |
597 , fCodec(codec) | 602 , fCodec(codec) |
598 , fHasAlpha(false) | 603 , fHasAlpha(false) |
599 { | 604 { |
600 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig)); | 605 fStorage.reset(fCodec->getInfo().width() * SkSwizzler::BytesPerPixel(fCo dec->fSrcConfig)); |
601 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 606 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
602 } | 607 } |
603 | 608 |
609 bool onSetSampleX(int sampleX) override { | |
610 fCodec->fSwizzler->setSampleX(sampleX); | |
611 return true; | |
612 } | |
613 | |
604 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { | 614 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { |
605 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 615 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
606 SkCodecPrintf("setjmp long jump!\n"); | 616 SkCodecPrintf("setjmp long jump!\n"); |
607 return SkCodec::kInvalidInput; | 617 return SkCodec::kInvalidInput; |
608 } | 618 } |
609 | 619 |
610 for (int i = 0; i < count; i++) { | 620 for (int i = 0; i < count; i++) { |
611 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); | 621 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); |
612 fCodec->fSwizzler->setDstRow(dst); | 622 fCodec->fSwizzler->setDstRow(dst); |
613 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow)) ; | 623 fHasAlpha |= !SkSwizzler::IsOpaque(fCodec->fSwizzler->next(fSrcRow)) ; |
(...skipping 26 matching lines...) Expand all Loading... | |
640 SkAutoMalloc fStorage; | 650 SkAutoMalloc fStorage; |
641 uint8_t* fSrcRow; | 651 uint8_t* fSrcRow; |
642 | 652 |
643 typedef SkScanlineDecoder INHERITED; | 653 typedef SkScanlineDecoder INHERITED; |
644 }; | 654 }; |
645 | 655 |
646 | 656 |
647 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { | 657 class SkPngInterlacedScanlineDecoder : public SkScanlineDecoder { |
648 public: | 658 public: |
649 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec ) | 659 SkPngInterlacedScanlineDecoder(const SkImageInfo& dstInfo, SkPngCodec* codec ) |
650 : INHERITED(dstInfo) | 660 : INHERITED(dstInfo, codec->getInfo()) |
651 , fCodec(codec) | 661 , fCodec(codec) |
652 , fHasAlpha(false) | 662 , fHasAlpha(false) |
653 , fCurrentRow(0) | 663 , fCurrentRow(0) |
654 , fHeight(dstInfo.height()) | 664 , fHeight(dstInfo.height()) |
655 { | 665 { |
656 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC onfig); | 666 fSrcRowBytes = codec->getInfo().width() * SkSwizzler::BytesPerPixel(fCod ec->fSrcConfig); |
657 fGarbageRow.reset(fSrcRowBytes); | 667 fGarbageRow.reset(fSrcRowBytes); |
658 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 668 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
659 } | 669 } |
660 | 670 |
671 bool onSetSampleX(int sampleX) override { | |
672 fCodec->fSwizzler->setSampleX(sampleX); | |
673 return true; | |
674 } | |
675 | |
661 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { | 676 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove rride { |
662 //rewind stream if have previously called onGetScanlines, | 677 //rewind stream if have previously called onGetScanlines, |
663 //since we need entire progressive image to get scanlines | 678 //since we need entire progressive image to get scanlines |
664 if (!fCodec->handleRewind()) { | 679 if (!fCodec->handleRewind()) { |
665 return SkCodec::kCouldNotRewind; | 680 return SkCodec::kCouldNotRewind; |
666 } | 681 } |
667 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 682 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
668 SkCodecPrintf("setjmp long jump!\n"); | 683 SkCodecPrintf("setjmp long jump!\n"); |
669 return SkCodec::kInvalidInput; | 684 return SkCodec::kInvalidInput; |
670 } | 685 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
721 }; | 736 }; |
722 | 737 |
723 | 738 |
724 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, | 739 SkScanlineDecoder* SkPngCodec::onGetScanlineDecoder(const SkImageInfo& dstInfo, |
725 const Options& options, SkPMColor ctable[], int* ctableCount) { | 740 const Options& options, SkPMColor ctable[], int* ctableCount) { |
726 if (!conversion_possible(dstInfo, this->getInfo())) { | 741 if (!conversion_possible(dstInfo, this->getInfo())) { |
727 SkCodecPrintf("no conversion possible\n"); | 742 SkCodecPrintf("no conversion possible\n"); |
728 return NULL; | 743 return NULL; |
729 } | 744 } |
730 // Check to see if scaling was requested. | 745 // Check to see if scaling was requested. |
731 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 746 if(options.fSampled == false) { |
msarett
2015/07/27 20:42:18
I think we should still be able to check for inval
emmaleer
2015/07/28 14:19:16
Yes, I now check to make sure dstHeight == srcHeig
| |
732 return NULL; | 747 // If the caller is sampling, it is okay for the dimensions to not match |
748 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | |
749 return NULL; | |
750 } | |
733 } | 751 } |
734 // Create a new SkPngCodec, to be owned by the scanline decoder. | 752 // Create a new SkPngCodec, to be owned by the scanline decoder. |
735 SkStream* stream = this->stream()->duplicate(); | 753 SkStream* stream = this->stream()->duplicate(); |
736 if (!stream) { | 754 if (!stream) { |
737 return NULL; | 755 return NULL; |
738 } | 756 } |
739 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); | 757 SkAutoTDelete<SkPngCodec> codec (static_cast<SkPngCodec*>(SkPngCodec::NewFro mStream(stream))); |
740 if (!codec) { | 758 if (!codec) { |
741 return NULL; | 759 return NULL; |
742 } | 760 } |
743 | 761 |
744 // Note: We set dst to NULL since we do not know it yet. rowBytes is not nee ded, | 762 // 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 | 763 // since we'll be manually updating the dstRow, but the SkSwizzler requires it to |
746 // be at least dstInfo.minRowBytes. | 764 // be at least dstInfo.minRowBytes. |
747 if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable, | 765 if (codec->initializeSwizzler(dstInfo, NULL, dstInfo.minRowBytes(), options, ctable, |
748 ctableCount) != kSuccess) { | 766 ctableCount) != kSuccess) { |
749 SkCodecPrintf("failed to initialize the swizzler.\n"); | 767 SkCodecPrintf("failed to initialize the swizzler.\n"); |
750 return NULL; | 768 return NULL; |
751 } | 769 } |
752 | 770 |
753 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); | 771 SkASSERT(codec->fNumberPasses != INVALID_NUMBER_PASSES); |
754 if (codec->fNumberPasses > 1) { | 772 if (codec->fNumberPasses > 1) { |
755 // interlaced image | 773 // interlaced image |
756 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); | 774 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (dstInfo, codec.detach ())); |
757 } | 775 } |
758 | 776 |
759 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); | 777 return SkNEW_ARGS(SkPngScanlineDecoder, (dstInfo, codec.detach())); |
760 } | 778 } |
761 | 779 |
OLD | NEW |