aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--resources/randPixelsOffset.gifbin0 -> 277 bytes
-rw-r--r--src/codec/SkAndroidCodec.cpp17
-rw-r--r--tests/GifTest.cpp38
3 files changed, 50 insertions, 5 deletions
diff --git a/resources/randPixelsOffset.gif b/resources/randPixelsOffset.gif
new file mode 100644
index 0000000000..df326b81f2
--- /dev/null
+++ b/resources/randPixelsOffset.gif
Binary files differ
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));
+}