| Index: src/codec/SkGifCodec.cpp
|
| diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
|
| index 876d71f553a1a45ed3b1f04a08468aacd02a37a5..cb36cbf4649c6158dd7f51415f67849faad4d7ac 100644
|
| --- a/src/codec/SkGifCodec.cpp
|
| +++ b/src/codec/SkGifCodec.cpp
|
| @@ -175,15 +175,37 @@ SkCodec::Result SkGifCodec::prepareToDecode(const SkImageInfo& dstInfo, SkPMColo
|
| }
|
|
|
| const size_t frameIndex = opts.fFrameIndex;
|
| - if (frameIndex > 0 && dstInfo.colorType() == kIndex_8_SkColorType) {
|
| - // FIXME: It is possible that a later frame can be decoded to index8, if it does one of the
|
| - // following:
|
| - // - Covers the entire previous frame
|
| - // - Shares a color table (and transparent index) with any prior frames that are showing.
|
| - // We must support index8 for the first frame to be backwards compatible on Android, but
|
| - // we do not (currently) need to support later frames as index8.
|
| - return gif_error("Cannot decode multiframe gif (except frame 0) as index 8.\n",
|
| - kInvalidConversion);
|
| + if (frameIndex > 0) {
|
| + switch (dstInfo.colorType()) {
|
| + case kIndex_8_SkColorType:
|
| + // FIXME: It is possible that a later frame can be decoded to index8, if it does one
|
| + // of the following:
|
| + // - Covers the entire previous frame
|
| + // - Shares a color table (and transparent index) with any prior frames that are
|
| + // showing.
|
| + // We must support index8 for the first frame to be backwards compatible on Android,
|
| + // but we do not (currently) need to support later frames as index8.
|
| + return gif_error("Cannot decode multiframe gif (except frame 0) as index 8.\n",
|
| + kInvalidConversion);
|
| + case kRGB_565_SkColorType:
|
| + // FIXME: In theory, we might be able to support this, but it's not clear that it
|
| + // is necessary (Chromium does not decode to 565, and Android does not decode
|
| + // frames beyond the first). Disabling it because it is somewhat difficult:
|
| + // - If there is a transparent pixel, and this frame draws on top of another frame
|
| + // (if the frame is independent with a transparent pixel, we should not decode to
|
| + // 565 anyway, since it is not opaque), we need to skip drawing the transparent
|
| + // pixels (see writeTransparentPixels in haveDecodedRow). We currently do this by
|
| + // first swizzling into temporary memory, then copying into the destination. (We
|
| + // let the swizzler handle it first because it may need to sample.) After
|
| + // swizzling to 565, we do not know which pixels in our temporary memory
|
| + // correspond to the transparent pixel, so we do not know what to skip. We could
|
| + // special case the non-sampled case (no need to swizzle), but as this is
|
| + // currently unused we can just not support it.
|
| + return gif_error("Cannot decode multiframe gif (except frame 0) as 565.\n",
|
| + kInvalidConversion);
|
| + default:
|
| + break;
|
| + }
|
| }
|
|
|
| fReader->parse((SkGifImageReader::SkGIFParseQuery) frameIndex);
|
| @@ -489,7 +511,7 @@ bool SkGifCodec::haveDecodedRow(size_t frameIndex, const unsigned char* rowBegin
|
| // we must write these for passes beyond the first, or the initial passes
|
| // will "show through" the later ones.
|
| const auto dstInfo = this->dstInfo();
|
| - if (writeTransparentPixels || dstInfo.colorType() == kRGB_565_SkColorType) {
|
| + if (writeTransparentPixels) {
|
| fSwizzler->swizzle(dstLine, rowBegin);
|
| } else {
|
| // We cannot swizzle directly into the dst, since that will write the transparent pixels.
|
|
|