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