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" |
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 431 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 //would have exited before now if the colorType was supported by png | 456 //would have exited before now if the colorType was supported by png |
456 SkASSERT(false); | 457 SkASSERT(false); |
457 } | 458 } |
458 | 459 |
459 // Copy the color table to the client if they request kIndex8 mode | 460 // Copy the color table to the client if they request kIndex8 mode |
460 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); | 461 copy_color_table(requestedInfo, fColorTable, ctable, ctableCount); |
461 | 462 |
462 // Create the swizzler. SkPngCodec retains ownership of the color table. | 463 // Create the swizzler. SkPngCodec retains ownership of the color table. |
463 const SkPMColor* colors = get_color_ptr(fColorTable.get()); | 464 const SkPMColor* colors = get_color_ptr(fColorTable.get()); |
464 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, | 465 fSwizzler.reset(SkSwizzler::CreateSwizzler(fSrcConfig, colors, requestedInfo
, |
465 options.fZeroInitialized)); | 466 options.fZeroInitialized, this->getInfo())); |
466 if (!fSwizzler) { | 467 if (!fSwizzler) { |
467 // FIXME: CreateSwizzler could fail for another reason. | 468 // FIXME: CreateSwizzler could fail for another reason. |
468 return kUnimplemented; | 469 return kUnimplemented; |
469 } | 470 } |
470 return kSuccess; | 471 return kSuccess; |
471 } | 472 } |
472 | 473 |
473 | 474 |
474 bool SkPngCodec::onRewind() { | 475 bool SkPngCodec::onRewind() { |
475 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header | 476 // This sets fPng_ptr and fInfo_ptr to NULL. If read_header |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
575 class SkPngScanlineDecoder : public SkScanlineDecoder { | 576 class SkPngScanlineDecoder : public SkScanlineDecoder { |
576 public: | 577 public: |
577 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) | 578 SkPngScanlineDecoder(const SkImageInfo& srcInfo, SkPngCodec* codec) |
578 : INHERITED(srcInfo) | 579 : INHERITED(srcInfo) |
579 , fCodec(codec) | 580 , fCodec(codec) |
580 , fHasAlpha(false) | 581 , fHasAlpha(false) |
581 {} | 582 {} |
582 | 583 |
583 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 584 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
584 const SkCodec::Options& options, | 585 const SkCodec::Options& options, |
585 SkPMColor ctable[], int* ctableCount) override | 586 SkPMColor ctable[], int* ctableCount) override { |
586 { | |
587 if (!fCodec->rewindIfNeeded()) { | 587 if (!fCodec->rewindIfNeeded()) { |
588 return SkCodec::kCouldNotRewind; | 588 return SkCodec::kCouldNotRewind; |
589 } | 589 } |
590 | 590 |
591 if (!conversion_possible(dstInfo, this->getInfo())) { | 591 if (!conversion_possible(dstInfo, this->getInfo())) { |
592 return SkCodec::kInvalidConversion; | 592 return SkCodec::kInvalidConversion; |
593 } | 593 } |
594 | 594 |
595 // Check to see if scaling was requested. | 595 // Check to see if scaling was requested. |
596 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 596 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
597 return SkCodec::kInvalidScale; | 597 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
| 598 return SkCodec::kInvalidScale; |
| 599 } |
598 } | 600 } |
599 | 601 |
600 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, | 602 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, |
601 ctableCount); | 603 ctableCount); |
602 if (result != SkCodec::kSuccess) { | 604 if (result != SkCodec::kSuccess) { |
603 return result; | 605 return result; |
604 } | 606 } |
605 | 607 |
606 fHasAlpha = false; | 608 fHasAlpha = false; |
607 fStorage.reset(dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig)); | 609 fStorage.reset(this->getInfo().width() * SkSwizzler::BytesPerPixel(fCode
c->fSrcConfig)); |
608 fSrcRow = static_cast<uint8_t*>(fStorage.get()); | 610 fSrcRow = static_cast<uint8_t*>(fStorage.get()); |
609 | 611 |
610 return SkCodec::kSuccess; | 612 return SkCodec::kSuccess; |
611 } | 613 } |
612 | 614 |
613 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { | 615 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri
de { |
614 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { | 616 if (setjmp(png_jmpbuf(fCodec->fPng_ptr))) { |
615 SkCodecPrintf("setjmp long jump!\n"); | 617 SkCodecPrintf("setjmp long jump!\n"); |
616 return SkCodec::kInvalidInput; | 618 return SkCodec::kInvalidInput; |
617 } | 619 } |
(...skipping 18 matching lines...) Expand all Loading... |
636 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count | 638 //calling png_read_rows in a loop is insignificantly slower than calling
it once with count |
637 //as png_read_rows has it's own loop which calls png_read_row count time
s. | 639 //as png_read_rows has it's own loop which calls png_read_row count time
s. |
638 for (int i = 0; i < count; i++) { | 640 for (int i = 0; i < count; i++) { |
639 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); | 641 png_read_rows(fCodec->fPng_ptr, &fSrcRow, png_bytepp_NULL, 1); |
640 } | 642 } |
641 return SkCodec::kSuccess; | 643 return SkCodec::kSuccess; |
642 } | 644 } |
643 | 645 |
644 bool onReallyHasAlpha() const override { return fHasAlpha; } | 646 bool onReallyHasAlpha() const override { return fHasAlpha; } |
645 | 647 |
| 648 SkEncodedFormat onGetEncodedFormat() const override { |
| 649 return kPNG_SkEncodedFormat; |
| 650 } |
| 651 |
| 652 |
646 private: | 653 private: |
647 SkAutoTDelete<SkPngCodec> fCodec; | 654 SkAutoTDelete<SkPngCodec> fCodec; |
648 bool fHasAlpha; | 655 bool fHasAlpha; |
649 SkAutoMalloc fStorage; | 656 SkAutoMalloc fStorage; |
650 uint8_t* fSrcRow; | 657 uint8_t* fSrcRow; |
651 | 658 |
652 typedef SkScanlineDecoder INHERITED; | 659 typedef SkScanlineDecoder INHERITED; |
653 }; | 660 }; |
654 | 661 |
655 | 662 |
(...skipping 10 matching lines...) Expand all Loading... |
666 | 673 |
667 SkCodec::Result onStart(const SkImageInfo& dstInfo, | 674 SkCodec::Result onStart(const SkImageInfo& dstInfo, |
668 const SkCodec::Options& options, | 675 const SkCodec::Options& options, |
669 SkPMColor ctable[], int* ctableCount) override | 676 SkPMColor ctable[], int* ctableCount) override |
670 { | 677 { |
671 if (!fCodec->rewindIfNeeded()) { | 678 if (!fCodec->rewindIfNeeded()) { |
672 return SkCodec::kCouldNotRewind; | 679 return SkCodec::kCouldNotRewind; |
673 } | 680 } |
674 | 681 |
675 if (!conversion_possible(dstInfo, this->getInfo())) { | 682 if (!conversion_possible(dstInfo, this->getInfo())) { |
676 return SkCodec::kInvalidConversion; | 683 return SkCodec::kInvalidConversion; |
677 } | 684 } |
678 | 685 |
679 // Check to see if scaling was requested. | 686 // Check to see if scaling was requested. |
680 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | 687 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
681 return SkCodec::kInvalidScale; | 688 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(),
dstInfo)) { |
| 689 return SkCodec::kInvalidScale; |
| 690 } |
682 } | 691 } |
683 | 692 |
684 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, | 693 const SkCodec::Result result = fCodec->initializeSwizzler(dstInfo, optio
ns, ctable, |
685 ctableCount); | 694 ctableCount); |
686 if (result != SkCodec::kSuccess) { | 695 if (result != SkCodec::kSuccess) { |
687 return result; | 696 return result; |
688 } | 697 } |
689 | 698 |
690 fHasAlpha = false; | 699 fHasAlpha = false; |
691 fCurrentRow = 0; | 700 fCurrentRow = 0; |
692 fHeight = dstInfo.height(); | 701 fHeight = dstInfo.height(); |
693 fSrcRowBytes = dstInfo.width() * SkSwizzler::BytesPerPixel(fCodec->fSrcC
onfig); | 702 fSrcRowBytes = this->getInfo().width() * SkSwizzler::BytesPerPixel(fCode
c->fSrcConfig); |
694 fGarbageRow.reset(fSrcRowBytes); | 703 fGarbageRow.reset(fSrcRowBytes); |
695 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); | 704 fGarbageRowPtr = static_cast<uint8_t*>(fGarbageRow.get()); |
696 fCanSkipRewind = true; | 705 fCanSkipRewind = true; |
697 | 706 |
698 return SkCodec::kSuccess; | 707 return SkCodec::kSuccess; |
699 } | 708 } |
700 | 709 |
701 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { | 710 SkCodec::Result onGetScanlines(void* dst, int count, size_t dstRowBytes) ove
rride { |
702 // rewind stream if have previously called onGetScanlines, | 711 // rewind stream if have previously called onGetScanlines, |
703 // since we need entire progressive image to get scanlines | 712 // since we need entire progressive image to get scanlines |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
746 } | 755 } |
747 | 756 |
748 SkCodec::Result onSkipScanlines(int count) override { | 757 SkCodec::Result onSkipScanlines(int count) override { |
749 //when ongetScanlines is called it will skip to fCurrentRow | 758 //when ongetScanlines is called it will skip to fCurrentRow |
750 fCurrentRow += count; | 759 fCurrentRow += count; |
751 return SkCodec::kSuccess; | 760 return SkCodec::kSuccess; |
752 } | 761 } |
753 | 762 |
754 bool onReallyHasAlpha() const override { return fHasAlpha; } | 763 bool onReallyHasAlpha() const override { return fHasAlpha; } |
755 | 764 |
| 765 bool onRequiresPostYSampling() override { |
| 766 return true; |
| 767 } |
| 768 |
| 769 SkEncodedFormat onGetEncodedFormat() const override { |
| 770 return kPNG_SkEncodedFormat; |
| 771 } |
| 772 |
756 private: | 773 private: |
757 SkAutoTDelete<SkPngCodec> fCodec; | 774 SkAutoTDelete<SkPngCodec> fCodec; |
758 bool fHasAlpha; | 775 bool fHasAlpha; |
759 int fCurrentRow; | 776 int fCurrentRow; |
760 int fHeight; | 777 int fHeight; |
761 size_t fSrcRowBytes; | 778 size_t fSrcRowBytes; |
762 SkAutoMalloc fGarbageRow; | 779 SkAutoMalloc fGarbageRow; |
763 uint8_t* fGarbageRowPtr; | 780 uint8_t* fGarbageRowPtr; |
764 // FIXME: This imitates behavior in SkCodec::rewindIfNeeded. That function | 781 // FIXME: This imitates behavior in SkCodec::rewindIfNeeded. That function |
765 // is called whenever some action is taken that reads the stream and | 782 // is called whenever some action is taken that reads the stream and |
(...skipping 19 matching lines...) Expand all Loading... |
785 | 802 |
786 const SkImageInfo& srcInfo = codec->getInfo(); | 803 const SkImageInfo& srcInfo = codec->getInfo(); |
787 if (codec->fNumberPasses > 1) { | 804 if (codec->fNumberPasses > 1) { |
788 // interlaced image | 805 // interlaced image |
789 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); | 806 return SkNEW_ARGS(SkPngInterlacedScanlineDecoder, (srcInfo, codec.detach
())); |
790 } | 807 } |
791 | 808 |
792 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); | 809 return SkNEW_ARGS(SkPngScanlineDecoder, (srcInfo, codec.detach())); |
793 } | 810 } |
794 | 811 |
OLD | NEW |