diff options
Diffstat (limited to 'src/codec/SkCodec_libgif.cpp')
-rw-r--r-- | src/codec/SkCodec_libgif.cpp | 174 |
1 files changed, 72 insertions, 102 deletions
diff --git a/src/codec/SkCodec_libgif.cpp b/src/codec/SkCodec_libgif.cpp index d8889defaf..ad7fb5b578 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(); + } } + |