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_libgif.h" | 8 #include "SkCodec_libgif.h" |
9 #include "SkCodecPriv.h" | 9 #include "SkCodecPriv.h" |
10 #include "SkColorPriv.h" | 10 #include "SkColorPriv.h" |
(...skipping 564 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
575 height - y, fFillIndex, colorPtr, opts.fZeroInitialized) ; | 575 height - y, fFillIndex, colorPtr, opts.fZeroInitialized) ; |
576 return gif_error("Could not decode line\n", kIncompleteInput); | 576 return gif_error("Could not decode line\n", kIncompleteInput); |
577 } | 577 } |
578 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); | 578 fSwizzler->swizzle(dstRow, fSrcBuffer.get()); |
579 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); | 579 dstRow = SkTAddOffset<void>(dstRow, dstRowBytes); |
580 } | 580 } |
581 } | 581 } |
582 return kSuccess; | 582 return kSuccess; |
583 } | 583 } |
584 | 584 |
585 // TODO (msarett): skbug.com/3582 | 585 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo, |
586 // Should we implement reallyHasAlpha? Or should we read extens ion blocks in the | 586 const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColor Count) { |
587 // header? Or should we do both? | 587 Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCoun t, |
588 | 588 this->options()); |
589 class SkGifScanlineDecoder : public SkScanlineDecoder { | 589 if (kSuccess != result) { |
590 public: | 590 return result; |
591 SkGifScanlineDecoder(const SkImageInfo& srcInfo, SkGifCodec* codec) | |
592 : INHERITED(srcInfo) | |
593 , fCodec(codec) | |
594 {} | |
595 | |
596 SkEncodedFormat onGetEncodedFormat() const override { | |
597 return kGIF_SkEncodedFormat; | |
598 } | 591 } |
599 | 592 |
600 SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options& opts, | 593 // Check to see if scaling was requested. |
601 SkPMColor inputColorPtr[], int* inputColorCount) ove rride { | 594 if (dstInfo.dimensions() != this->getInfo().dimensions()) { |
602 SkCodec::Result result = fCodec->prepareToDecode(dstInfo, inputColorPtr, inputColorCount, | 595 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstI nfo)) { |
603 this->options()); | 596 return gif_error("Scaling not supported.\n", SkCodec::kInvalidScale) ; |
604 if (SkCodec::kSuccess != result) { | |
605 return result; | |
606 } | |
607 | |
608 // Check to see if scaling was requested. | |
609 if (dstInfo.dimensions() != this->getInfo().dimensions()) { | |
610 if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) { | |
611 return gif_error("Scaling not supported.\n", SkCodec::kInvalidSc ale); | |
612 } | |
613 } | |
614 | |
615 // Initialize the swizzler | |
616 if (fCodec->fFrameIsSubset) { | |
617 int sampleX; | |
618 SkScaledCodec::ComputeSampleSize(dstInfo, fCodec->getInfo(), &sample X, NULL); | |
619 const SkImageInfo subsetDstInfo = dstInfo.makeWH( | |
620 get_scaled_dimension(fCodec->fFrameDims.width(), sampleX), | |
621 fCodec->fFrameDims.height()); | |
622 if (SkCodec::kSuccess != fCodec->initializeSwizzler(subsetDstInfo, | |
623 opts.fZeroInitialized)) { | |
624 return gif_error("Could not initialize swizzler.\n", SkCodec::kU nimplemented); | |
625 } | |
626 } else { | |
627 if (SkCodec::kSuccess != fCodec->initializeSwizzler(dstInfo, opts.fZ eroInitialized)) { | |
628 return gif_error("Could not initialize swizzler.\n", SkCodec::kU nimplemented); | |
629 } | |
630 } | |
631 | |
632 return SkCodec::kSuccess; | |
633 } | |
634 | |
635 SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) overri de { | |
636 if (fCodec->fFrameIsSubset) { | |
637 // Fill the requested rows | |
638 const SkPMColor* colorPtr = get_color_ptr(fCodec->fColorTable.get()) ; | |
639 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count, fCodec->fFil lIndex, | |
640 colorPtr, this->options().fZeroInitialized); | |
641 | |
642 // Do nothing for rows before the image frame | |
643 int rowsBeforeFrame = fCodec->fFrameDims.top() - INHERITED::getY(); | |
644 if (rowsBeforeFrame > 0) { | |
645 count = SkTMin(0, count - rowsBeforeFrame); | |
646 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame); | |
647 } | |
648 | |
649 // Do nothing for rows after the image frame | |
650 int rowsAfterFrame = INHERITED::getY() + count - fCodec->fFrameDims. bottom(); | |
651 if (rowsAfterFrame > 0) { | |
652 count = SkTMin(0, count - rowsAfterFrame); | |
653 } | |
654 | |
655 // Adjust dst pointer for left offset | |
656 dst = SkTAddOffset<void>(dst, SkColorTypeBytesPerPixel( | |
657 this->dstInfo().colorType()) * fCodec->fFrameDims.left()); | |
658 } | |
659 | |
660 for (int i = 0; i < count; i++) { | |
661 if (SkCodec::kSuccess != fCodec->readRow()) { | |
662 const SkPMColor* colorPtr = get_color_ptr(fCodec->fColorTable.ge t()); | |
663 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, | |
664 count - i, fCodec->fFillIndex, colorPtr, | |
665 this->options().fZeroInitialized); | |
666 return gif_error("Could not decode line\n", SkCodec::kIncomplete Input); | |
667 } | |
668 fCodec->fSwizzler->swizzle(dst, fCodec->fSrcBuffer.get()); | |
669 dst = SkTAddOffset<void>(dst, rowBytes); | |
670 } | |
671 return SkCodec::kSuccess; | |
672 } | |
673 | |
674 SkScanlineOrder onGetScanlineOrder() const override { | |
675 if (fCodec->fGif->Image.Interlace) { | |
676 return kOutOfOrder_SkScanlineOrder; | |
677 } else { | |
678 return kTopDown_SkScanlineOrder; | |
679 } | 597 } |
680 } | 598 } |
681 | 599 |
682 int onGetY() const override { | 600 // Initialize the swizzler |
683 if (fCodec->fGif->Image.Interlace) { | 601 if (fFrameIsSubset) { |
684 return get_output_row_interlaced(INHERITED::onGetY(), this->dstInfo( ).height()); | 602 int sampleX; |
685 } else { | 603 SkScaledCodec::ComputeSampleSize(dstInfo, this->getInfo(), &sampleX, NUL L); |
686 return INHERITED::onGetY(); | 604 const SkImageInfo subsetDstInfo = dstInfo.makeWH( |
605 get_scaled_dimension(fFrameDims.width(), sampleX), | |
606 fFrameDims.height()); | |
607 if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitia lized)) { | |
608 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ; | |
609 } | |
610 } else { | |
611 if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized) ) { | |
612 return gif_error("Could not initialize swizzler.\n", kUnimplemented) ; | |
687 } | 613 } |
688 } | 614 } |
689 | 615 |
690 private: | 616 return kSuccess; |
691 SkAutoTDelete<SkGifCodec> fCodec; | 617 } |
692 | 618 |
693 typedef SkScanlineDecoder INHERITED; | 619 SkCodec::Result SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes ) { |
694 }; | 620 if (fFrameIsSubset) { |
621 // Fill the requested rows | |
622 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | |
623 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count, fFillIndex, | |
624 colorPtr, this->options().fZeroInitialized); | |
695 | 625 |
696 SkScanlineDecoder* SkGifCodec::NewSDFromStream(SkStream* stream) { | 626 // Do nothing for rows before the image frame |
697 SkAutoTDelete<SkGifCodec> codec (static_cast<SkGifCodec*>(SkGifCodec::NewFro mStream(stream))); | 627 // FIXME: nextScanline is not virtual, so using "INHERITED" does not cha nge |
scroggo
2015/09/30 13:32:20
Matt, I noticed this when I did the search and rep
msarett
2015/09/30 13:53:30
My intention was to call INHERITED::onNextScanline
| |
698 if (!codec) { | 628 // behavior. Was the intent to call this->INHERITED::onNextScanline()? S ame |
699 return NULL; | 629 // for the next call down below. |
630 int rowsBeforeFrame = fFrameDims.top() - this->INHERITED::nextScanline() ; | |
631 if (rowsBeforeFrame > 0) { | |
632 count = SkTMin(0, count - rowsBeforeFrame); | |
633 dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame); | |
634 } | |
635 | |
636 // Do nothing for rows after the image frame | |
637 int rowsAfterFrame = this->INHERITED::nextScanline() + count - fFrameDim s.bottom(); | |
638 if (rowsAfterFrame > 0) { | |
639 count = SkTMin(0, count - rowsAfterFrame); | |
640 } | |
641 | |
642 // Adjust dst pointer for left offset | |
643 int bpp = SkColorTypeBytesPerPixel(this->dstInfo().colorType()) * fFrame Dims.left(); | |
644 dst = SkTAddOffset<void>(dst, bpp); | |
700 } | 645 } |
701 | 646 |
702 const SkImageInfo& srcInfo = codec->getInfo(); | 647 for (int i = 0; i < count; i++) { |
648 if (kSuccess != this->readRow()) { | |
649 const SkPMColor* colorPtr = get_color_ptr(fColorTable.get()); | |
650 SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count - i, fFillInd ex, colorPtr, | |
651 this->options().fZeroInitialized); | |
652 return gif_error("Could not decode line\n", SkCodec::kIncompleteInpu t); | |
653 } | |
654 fSwizzler->swizzle(dst, fSrcBuffer.get()); | |
655 dst = SkTAddOffset<void>(dst, rowBytes); | |
656 } | |
657 return SkCodec::kSuccess; | |
658 } | |
703 | 659 |
704 return new SkGifScanlineDecoder(srcInfo, codec.detach()); | 660 SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const { |
661 if (fGif->Image.Interlace) { | |
662 return kOutOfOrder_SkScanlineOrder; | |
663 } else { | |
664 return kTopDown_SkScanlineOrder; | |
665 } | |
705 } | 666 } |
667 | |
668 int SkGifCodec::onNextScanline() const { | |
669 if (fGif->Image.Interlace) { | |
670 return get_output_row_interlaced(this->INHERITED::onNextScanline(), this ->dstInfo().height()); | |
671 } else { | |
672 return this->INHERITED::onNextScanline(); | |
673 } | |
674 } | |
675 | |
OLD | NEW |