Test SkCodec to kIndex8 in nanobench.

BUG=skia:3257
BUG=skia:3475

Review URL: https://codereview.chromium.org/1051973002
diff --git a/bench/CodecBench.cpp b/bench/CodecBench.cpp
index e68c5de..debda71 100644
--- a/bench/CodecBench.cpp
+++ b/bench/CodecBench.cpp
@@ -48,18 +48,32 @@
 
 void CodecBench::onPreDraw() {
     SkAutoTDelete<SkCodec> codec(SkCodec::NewFromData(fData));
-    fBitmap.allocPixels(codec->getInfo().makeColorType(fColorType));
+
+    fInfo = codec->getInfo().makeColorType(fColorType);
+    SkAlphaType alphaType;
+    // Caller should not have created this CodecBench if the alpha type was
+    // invalid.
+    SkAssertResult(SkColorTypeValidateAlphaType(fColorType, fInfo.alphaType(),
+                                                &alphaType));
+    if (alphaType != fInfo.alphaType()) {
+        fInfo = fInfo.makeAlphaType(alphaType);
+    }
+
+    fPixelStorage.reset(fInfo.getSafeSize(fInfo.minRowBytes()));
 }
 
 void CodecBench::onDraw(const int n, SkCanvas* canvas) {
     SkAutoTDelete<SkCodec> codec;
+    SkPMColor colorTable[256];
+    int colorCount;
     for (int i = 0; i < n; i++) {
+        colorCount = 256;
         codec.reset(SkCodec::NewFromData(fData));
 #ifdef SK_DEBUG
         const SkImageGenerator::Result result =
 #endif
-        // fBitmap.info() was set to use fColorType in onPreDraw.
-        codec->getPixels(fBitmap.info(), fBitmap.getPixels(), fBitmap.rowBytes());
+        codec->getPixels(fInfo, fPixelStorage.get(), fInfo.minRowBytes(),
+                         NULL, colorTable, &colorCount);
         SkASSERT(result == SkImageGenerator::kSuccess
                  || result == SkImageGenerator::kIncompleteInput);
     }
diff --git a/bench/CodecBench.h b/bench/CodecBench.h
index 2bc4ba9..0675cca 100644
--- a/bench/CodecBench.h
+++ b/bench/CodecBench.h
@@ -9,7 +9,6 @@
 #define CodecBench_DEFINED
 
 #include "Benchmark.h"
-#include "SkBitmap.h"
 #include "SkData.h"
 #include "SkImageInfo.h"
 #include "SkRefCnt.h"
@@ -33,7 +32,8 @@
     SkString                fName;
     const SkColorType       fColorType;
     SkAutoTUnref<SkData>    fData;
-    SkBitmap                fBitmap;
+    SkImageInfo             fInfo;          // Set in onPreDraw.
+    SkAutoMalloc            fPixelStorage;
     typedef Benchmark INHERITED;
 };
 #endif // CodecBench_DEFINED
diff --git a/bench/DecodingBench.cpp b/bench/DecodingBench.cpp
index 60535ce..6cf3c3a 100644
--- a/bench/DecodingBench.cpp
+++ b/bench/DecodingBench.cpp
@@ -6,11 +6,11 @@
  */
 
 #include "DecodingBench.h"
+#include "SkBitmap.h"
 #include "SkData.h"
 #include "SkImageDecoder.h"
 #include "SkMallocPixelRef.h"
 #include "SkOSFile.h"
-#include "SkPixelRef.h"
 #include "SkStream.h"
 
 /*
@@ -61,40 +61,41 @@
     // Allocate the pixels now, to remove it from the loop.
     SkAutoTDelete<SkStreamRewindable> stream(new SkMemoryStream(fData));
     SkAutoTDelete<SkImageDecoder> decoder(SkImageDecoder::Factory(stream));
+    SkBitmap bm;
 #ifdef SK_DEBUG
     SkImageDecoder::Result result =
 #endif
-    decoder->decode(stream, &fBitmap, fColorType,
-                    SkImageDecoder::kDecodeBounds_Mode);
+    decoder->decode(stream, &bm, fColorType, SkImageDecoder::kDecodeBounds_Mode);
     SkASSERT(SkImageDecoder::kFailure != result);
-    fBitmap.allocPixels(fBitmap.info());
+
+    const size_t rowBytes = bm.info().minRowBytes();
+    fPixelStorage.reset(bm.info().getSafeSize(rowBytes));
 }
 
-// Allocator which just reuses the pixels from an existing SkPixelRef.
-class UseExistingAllocator : public SkBitmap::Allocator {
+// Allocator which just uses an existing block of memory.
+class TargetAllocator : public SkBitmap::Allocator {
 public:
-    explicit UseExistingAllocator(SkPixelRef* pr)
-        : fPixelRef(SkRef(pr)) {}
+    explicit TargetAllocator(void* storage)
+        : fPixelStorage(storage) {}
 
     bool allocPixelRef(SkBitmap* bm, SkColorTable* ct) override {
-        // We depend on the fact that fPixelRef is an SkMallocPixelRef, which
-        // is always locked, and the fact that this will only ever be used to
-        // decode to a bitmap with the same settings used to create the
-        // original pixel ref.
+        // We depend on the fact that this will only ever be used to
+        // decode to a bitmap with the same settings used to create
+        // fPixelStorage.
         bm->setPixelRef(SkMallocPixelRef::NewDirect(bm->info(),
-                fPixelRef->pixels(), bm->rowBytes(), ct))->unref();
+                fPixelStorage, bm->rowBytes(), ct))->unref();
         return true;
     }
 
 private:
-    SkAutoTUnref<SkPixelRef> fPixelRef;
+    void* fPixelStorage; // Unowned. DecodingBench owns this.
 };
 
 void DecodingBench::onDraw(const int n, SkCanvas* canvas) {
     SkBitmap bitmap;
     // Declare the allocator before the decoder, so it will outlive the
     // decoder, which will unref it.
-    UseExistingAllocator allocator(fBitmap.pixelRef());
+    TargetAllocator allocator(fPixelStorage.get());
     SkAutoTDelete<SkImageDecoder> decoder;
     SkAutoTDelete<SkStreamRewindable> stream;
     for (int i = 0; i < n; i++) {
diff --git a/bench/DecodingBench.h b/bench/DecodingBench.h
index 61b90a1..a32bfea 100644
--- a/bench/DecodingBench.h
+++ b/bench/DecodingBench.h
@@ -9,10 +9,8 @@
 #define DecodingBench_DEFINED
 
 #include "Benchmark.h"
-#include "SkBitmap.h"
 #include "SkData.h"
 #include "SkImageDecoder.h"
-#include "SkImageInfo.h"
 #include "SkRefCnt.h"
 #include "SkString.h"
 
@@ -36,7 +34,7 @@
     SkString                fName;
     SkColorType             fColorType;
     SkAutoTUnref<SkData>    fData;
-    SkBitmap                fBitmap;
+    SkAutoMalloc            fPixelStorage;
     typedef Benchmark INHERITED;
 };
 #endif // DecodingBench_DEFINED
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index 701128f..bf99a1e 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -540,7 +540,7 @@
 
         // Choose the candidate color types for image decoding
         const SkColorType colorTypes[] =
-            { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType };
+            { kN32_SkColorType, kRGB_565_SkColorType, kAlpha_8_SkColorType, kIndex_8_SkColorType };
         fColorTypes.push_back_n(SK_ARRAY_COUNT(colorTypes), colorTypes);
     }
 
@@ -644,15 +644,32 @@
                 // Nothing to time.
                 continue;
             }
+
             while (fCurrentColorType < fColorTypes.count()) {
-                SkColorType colorType = fColorTypes[fCurrentColorType];
+                const SkColorType colorType = fColorTypes[fCurrentColorType];
                 fCurrentColorType++;
+
                 // Make sure we can decode to this color type.
-                SkBitmap bitmap;
                 SkImageInfo info = codec->getInfo().makeColorType(colorType);
-                bitmap.allocPixels(info);
+                SkAlphaType alphaType;
+                if (!SkColorTypeValidateAlphaType(colorType, info.alphaType(),
+                                                  &alphaType)) {
+                    continue;
+                }
+                if (alphaType != info.alphaType()) {
+                    info = info.makeAlphaType(alphaType);
+                }
+
+                const size_t rowBytes = info.minRowBytes();
+                SkAutoMalloc storage(info.getSafeSize(rowBytes));
+
+                // Used if fCurrentColorType is kIndex_8_SkColorType
+                int colorCount = 256;
+                SkPMColor colors[256];
+
                 const SkImageGenerator::Result result = codec->getPixels(
-                        bitmap.info(), bitmap.getPixels(), bitmap.rowBytes());
+                        info, storage.get(), rowBytes, NULL, colors,
+                        &colorCount);
                 switch (result) {
                     case SkImageGenerator::kSuccess:
                     case SkImageGenerator::kIncompleteInput: