| Index: src/codec/SkCodec_libgif.cpp
|
| diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp
|
| index d8889defafa310fe76f2ad2d18bc1d2b3a73480b..ad7fb5b578d56263a3963aa673ddd021053acda5 100644
|
| --- a/src/codec/SkCodec_libgif.cpp
|
| +++ b/src/codec/SkCodec_libgif.cpp
|
| @@ -582,124 +582,94 @@ SkCodec::Result SkGifCodec::onGetPixels(const SkImageInfo& dstInfo,
|
| return kSuccess;
|
| }
|
|
|
| -// TODO (msarett): skbug.com/3582
|
| -// Should we implement reallyHasAlpha? Or should we read extension blocks in the
|
| -// header? Or should we do both?
|
| -
|
| -class SkGifScanlineDecoder : public SkScanlineDecoder {
|
| -public:
|
| - SkGifScanlineDecoder(const SkImageInfo& srcInfo, SkGifCodec* codec)
|
| - : INHERITED(srcInfo)
|
| - , fCodec(codec)
|
| - {}
|
| -
|
| - SkEncodedFormat onGetEncodedFormat() const override {
|
| - return kGIF_SkEncodedFormat;
|
| - }
|
| -
|
| - SkCodec::Result onStart(const SkImageInfo& dstInfo, const SkCodec::Options& opts,
|
| - SkPMColor inputColorPtr[], int* inputColorCount) override {
|
| - SkCodec::Result result = fCodec->prepareToDecode(dstInfo, inputColorPtr, inputColorCount,
|
| - this->options());
|
| - if (SkCodec::kSuccess != result) {
|
| - return result;
|
| - }
|
| +SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
|
| + const SkCodec::Options& opts, SkPMColor inputColorPtr[], int* inputColorCount) {
|
| + Result result = this->prepareToDecode(dstInfo, inputColorPtr, inputColorCount,
|
| + this->options());
|
| + if (kSuccess != result) {
|
| + return result;
|
| + }
|
|
|
| - // Check to see if scaling was requested.
|
| - if (dstInfo.dimensions() != this->getInfo().dimensions()) {
|
| - if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
|
| - return gif_error("Scaling not supported.\n", SkCodec::kInvalidScale);
|
| - }
|
| + // Check to see if scaling was requested.
|
| + if (dstInfo.dimensions() != this->getInfo().dimensions()) {
|
| + if (!SkScaledCodec::DimensionsSupportedForSampling(this->getInfo(), dstInfo)) {
|
| + return gif_error("Scaling not supported.\n", SkCodec::kInvalidScale);
|
| }
|
| + }
|
|
|
| - // Initialize the swizzler
|
| - if (fCodec->fFrameIsSubset) {
|
| - int sampleX;
|
| - SkScaledCodec::ComputeSampleSize(dstInfo, fCodec->getInfo(), &sampleX, NULL);
|
| - const SkImageInfo subsetDstInfo = dstInfo.makeWH(
|
| - get_scaled_dimension(fCodec->fFrameDims.width(), sampleX),
|
| - fCodec->fFrameDims.height());
|
| - if (SkCodec::kSuccess != fCodec->initializeSwizzler(subsetDstInfo,
|
| - opts.fZeroInitialized)) {
|
| - return gif_error("Could not initialize swizzler.\n", SkCodec::kUnimplemented);
|
| - }
|
| - } else {
|
| - if (SkCodec::kSuccess != fCodec->initializeSwizzler(dstInfo, opts.fZeroInitialized)) {
|
| - return gif_error("Could not initialize swizzler.\n", SkCodec::kUnimplemented);
|
| - }
|
| + // Initialize the swizzler
|
| + if (fFrameIsSubset) {
|
| + int sampleX;
|
| + SkScaledCodec::ComputeSampleSize(dstInfo, this->getInfo(), &sampleX, NULL);
|
| + const SkImageInfo subsetDstInfo = dstInfo.makeWH(
|
| + get_scaled_dimension(fFrameDims.width(), sampleX),
|
| + fFrameDims.height());
|
| + if (kSuccess != this->initializeSwizzler(subsetDstInfo, opts.fZeroInitialized)) {
|
| + return gif_error("Could not initialize swizzler.\n", kUnimplemented);
|
| + }
|
| + } else {
|
| + if (kSuccess != this->initializeSwizzler(dstInfo, opts.fZeroInitialized)) {
|
| + return gif_error("Could not initialize swizzler.\n", kUnimplemented);
|
| }
|
| -
|
| - return SkCodec::kSuccess;
|
| }
|
|
|
| - SkCodec::Result onGetScanlines(void* dst, int count, size_t rowBytes) override {
|
| - if (fCodec->fFrameIsSubset) {
|
| - // Fill the requested rows
|
| - const SkPMColor* colorPtr = get_color_ptr(fCodec->fColorTable.get());
|
| - SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count, fCodec->fFillIndex,
|
| - colorPtr, this->options().fZeroInitialized);
|
| -
|
| - // Do nothing for rows before the image frame
|
| - int rowsBeforeFrame = fCodec->fFrameDims.top() - INHERITED::getY();
|
| - if (rowsBeforeFrame > 0) {
|
| - count = SkTMin(0, count - rowsBeforeFrame);
|
| - dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
|
| - }
|
| -
|
| - // Do nothing for rows after the image frame
|
| - int rowsAfterFrame = INHERITED::getY() + count - fCodec->fFrameDims.bottom();
|
| - if (rowsAfterFrame > 0) {
|
| - count = SkTMin(0, count - rowsAfterFrame);
|
| - }
|
| + return kSuccess;
|
| +}
|
|
|
| - // Adjust dst pointer for left offset
|
| - dst = SkTAddOffset<void>(dst, SkColorTypeBytesPerPixel(
|
| - this->dstInfo().colorType()) * fCodec->fFrameDims.left());
|
| +SkCodec::Result SkGifCodec::onGetScanlines(void* dst, int count, size_t rowBytes) {
|
| + if (fFrameIsSubset) {
|
| + // Fill the requested rows
|
| + const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
|
| + SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count, fFillIndex,
|
| + colorPtr, this->options().fZeroInitialized);
|
| +
|
| + // Do nothing for rows before the image frame
|
| + // FIXME: nextScanline is not virtual, so using "INHERITED" does not change
|
| + // behavior. Was the intent to call this->INHERITED::onNextScanline()? Same
|
| + // for the next call down below.
|
| + int rowsBeforeFrame = fFrameDims.top() - this->INHERITED::nextScanline();
|
| + if (rowsBeforeFrame > 0) {
|
| + count = SkTMin(0, count - rowsBeforeFrame);
|
| + dst = SkTAddOffset<void>(dst, rowBytes * rowsBeforeFrame);
|
| }
|
|
|
| - for (int i = 0; i < count; i++) {
|
| - if (SkCodec::kSuccess != fCodec->readRow()) {
|
| - const SkPMColor* colorPtr = get_color_ptr(fCodec->fColorTable.get());
|
| - SkSwizzler::Fill(dst, this->dstInfo(), rowBytes,
|
| - count - i, fCodec->fFillIndex, colorPtr,
|
| - this->options().fZeroInitialized);
|
| - return gif_error("Could not decode line\n", SkCodec::kIncompleteInput);
|
| - }
|
| - fCodec->fSwizzler->swizzle(dst, fCodec->fSrcBuffer.get());
|
| - dst = SkTAddOffset<void>(dst, rowBytes);
|
| + // Do nothing for rows after the image frame
|
| + int rowsAfterFrame = this->INHERITED::nextScanline() + count - fFrameDims.bottom();
|
| + if (rowsAfterFrame > 0) {
|
| + count = SkTMin(0, count - rowsAfterFrame);
|
| }
|
| - return SkCodec::kSuccess;
|
| - }
|
|
|
| - SkScanlineOrder onGetScanlineOrder() const override {
|
| - if (fCodec->fGif->Image.Interlace) {
|
| - return kOutOfOrder_SkScanlineOrder;
|
| - } else {
|
| - return kTopDown_SkScanlineOrder;
|
| - }
|
| + // Adjust dst pointer for left offset
|
| + int bpp = SkColorTypeBytesPerPixel(this->dstInfo().colorType()) * fFrameDims.left();
|
| + dst = SkTAddOffset<void>(dst, bpp);
|
| }
|
|
|
| - int onGetY() const override {
|
| - if (fCodec->fGif->Image.Interlace) {
|
| - return get_output_row_interlaced(INHERITED::onGetY(), this->dstInfo().height());
|
| - } else {
|
| - return INHERITED::onGetY();
|
| + for (int i = 0; i < count; i++) {
|
| + if (kSuccess != this->readRow()) {
|
| + const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
|
| + SkSwizzler::Fill(dst, this->dstInfo(), rowBytes, count - i, fFillIndex, colorPtr,
|
| + this->options().fZeroInitialized);
|
| + return gif_error("Could not decode line\n", SkCodec::kIncompleteInput);
|
| }
|
| + fSwizzler->swizzle(dst, fSrcBuffer.get());
|
| + dst = SkTAddOffset<void>(dst, rowBytes);
|
| }
|
| + return SkCodec::kSuccess;
|
| +}
|
|
|
| -private:
|
| - SkAutoTDelete<SkGifCodec> fCodec;
|
| -
|
| - typedef SkScanlineDecoder INHERITED;
|
| -};
|
| -
|
| -SkScanlineDecoder* SkGifCodec::NewSDFromStream(SkStream* stream) {
|
| - SkAutoTDelete<SkGifCodec> codec (static_cast<SkGifCodec*>(SkGifCodec::NewFromStream(stream)));
|
| - if (!codec) {
|
| - return NULL;
|
| +SkCodec::SkScanlineOrder SkGifCodec::onGetScanlineOrder() const {
|
| + if (fGif->Image.Interlace) {
|
| + return kOutOfOrder_SkScanlineOrder;
|
| + } else {
|
| + return kTopDown_SkScanlineOrder;
|
| }
|
| +}
|
|
|
| - const SkImageInfo& srcInfo = codec->getInfo();
|
| -
|
| - return new SkGifScanlineDecoder(srcInfo, codec.detach());
|
| +int SkGifCodec::onNextScanline() const {
|
| + if (fGif->Image.Interlace) {
|
| + return get_output_row_interlaced(this->INHERITED::onNextScanline(), this->dstInfo().height());
|
| + } else {
|
| + return this->INHERITED::onNextScanline();
|
| + }
|
| }
|
| +
|
|
|