diff options
author | Leon Scroggins III <scroggo@google.com> | 2016-12-16 14:17:03 -0500 |
---|---|---|
committer | Skia Commit-Bot <skia-commit-bot@chromium.org> | 2016-12-16 19:51:52 +0000 |
commit | 4cd68653e32928536854769ba132db5b43b5d337 (patch) | |
tree | 80302bfde52d791a27d445c9a58a71365c3f20ea | |
parent | f856fd1ccdd839646159767f6aa9a2f2a1b97f04 (diff) |
Only attempt index8 if underlying GIF is index8
Recent changes (crrev.com/2045293002) made it so that a GIF may not
support index 8. In that case, make SkAndroidCodec not suggest index 8.
Add a test and a new test file. randPixelsOffset.gif is the same as
randPixels.gif, except its frame is offset. Since it does not have a
transparent index, we have to decode to kN32.
Change-Id: I1c09ab9094083de3dfc436632b3c26dbde1dccbd
Reviewed-on: https://skia-review.googlesource.com/6196
Commit-Queue: Leon Scroggins <scroggo@google.com>
Reviewed-by: Matt Sarett <msarett@google.com>
-rw-r--r-- | resources/randPixelsOffset.gif | bin | 0 -> 277 bytes | |||
-rw-r--r-- | src/codec/SkAndroidCodec.cpp | 17 | ||||
-rw-r--r-- | tests/GifTest.cpp | 38 |
3 files changed, 50 insertions, 5 deletions
diff --git a/resources/randPixelsOffset.gif b/resources/randPixelsOffset.gif Binary files differnew file mode 100644 index 0000000000..df326b81f2 --- /dev/null +++ b/resources/randPixelsOffset.gif diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp index a3daeae72b..26b9638c96 100644 --- a/src/codec/SkAndroidCodec.cpp +++ b/src/codec/SkAndroidCodec.cpp @@ -63,13 +63,20 @@ SkAndroidCodec* SkAndroidCodec::NewFromData(sk_sp<SkData> data, SkPngChunkReader SkColorType SkAndroidCodec::computeOutputColorType(SkColorType requestedColorType) { // The legacy GIF and WBMP decoders always decode to kIndex_8_SkColorType. - // We will maintain this behavior. - SkEncodedImageFormat format = (SkEncodedImageFormat)this->getEncodedFormat(); - if (SkEncodedImageFormat::kGIF == format || SkEncodedImageFormat::kWBMP == format) { - return kIndex_8_SkColorType; + // We will maintain this behavior when we can. + const SkColorType suggestedColorType = this->getInfo().colorType(); + switch ((SkEncodedImageFormat) this->getEncodedFormat()) { + case SkEncodedImageFormat::kGIF: + if (suggestedColorType == kIndex_8_SkColorType) { + return kIndex_8_SkColorType; + } + break; + case SkEncodedImageFormat::kWBMP: + return kIndex_8_SkColorType; + default: + break; } - SkColorType suggestedColorType = this->getInfo().colorType(); bool highPrecision = fCodec->getEncodedInfo().bitsPerComponent() > 8; switch (requestedColorType) { case kARGB_4444_SkColorType: diff --git a/tests/GifTest.cpp b/tests/GifTest.cpp index 12bfb5348f..dae2bc9329 100644 --- a/tests/GifTest.cpp +++ b/tests/GifTest.cpp @@ -273,3 +273,41 @@ DEF_TEST(Codec_GifTruncated, r) { std::unique_ptr<SkCodec> codec(SkCodec::NewFromData(data)); REPORTER_ASSERT(r, !codec); } + +// There was a bug where SkAndroidCodec::computeOutputColorType returned kIndex_8 for +// GIFs that did not support kIndex_8. Verify that for such an image, the method computes +// something that it can actually decode to. +DEF_TEST(Codec_GifIndex8, r) { + std::unique_ptr<SkStream> stream(GetResourceAsStream("randPixelsOffset.gif")); + if (!stream) { + return; + } + + std::unique_ptr<SkAndroidCodec> codec(SkAndroidCodec::NewFromStream(stream.release())); + REPORTER_ASSERT(r, codec); + if (!codec) { + return; + } + + REPORTER_ASSERT(r, codec->getInfo().colorType() == kN32_SkColorType); + const SkColorType outputColorType = codec->computeOutputColorType(kN32_SkColorType); + REPORTER_ASSERT(r, outputColorType == kN32_SkColorType); + + SkAndroidCodec::AndroidOptions options; + sk_sp<SkColorTable> colorTable(nullptr); + int maxColors = 256; + if (kIndex_8_SkColorType == outputColorType) { + SkPMColor colors[256]; + colorTable.reset(new SkColorTable(colors, maxColors)); + options.fColorPtr = const_cast<SkPMColor*>(colorTable->readColors()); + options.fColorCount = &maxColors; + } + + auto info = codec->getInfo().makeColorType(outputColorType); + SkBitmap bm; + bm.setInfo(info); + bm.allocPixels(colorTable.get()); + + REPORTER_ASSERT(r, SkCodec::kSuccess == codec->getAndroidPixels(info, bm.getPixels(), + bm.rowBytes(), &options)); +} |