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>
diff --git a/resources/randPixelsOffset.gif b/resources/randPixelsOffset.gif
new file mode 100644
index 0000000..df326b8
--- /dev/null
+++ b/resources/randPixelsOffset.gif
Binary files differ
diff --git a/src/codec/SkAndroidCodec.cpp b/src/codec/SkAndroidCodec.cpp
index a3daeae..26b9638 100644
--- a/src/codec/SkAndroidCodec.cpp
+++ b/src/codec/SkAndroidCodec.cpp
@@ -63,13 +63,20 @@
 
 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 12bfb53..dae2bc9 100644
--- a/tests/GifTest.cpp
+++ b/tests/GifTest.cpp
@@ -273,3 +273,41 @@
     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));
+}