Option for SkCodec to treat dst as all zeroes.

This recreates SkImageDecoder's feature to skip writing zeroes for
SkCodec.

Review URL: https://codereview.chromium.org/980903002
diff --git a/src/codec/SkCodec_libbmp.cpp b/src/codec/SkCodec_libbmp.cpp
index 5b9691c..a96cd66 100644
--- a/src/codec/SkCodec_libbmp.cpp
+++ b/src/codec/SkCodec_libbmp.cpp
@@ -502,6 +502,7 @@
  */
 SkCodec::Result SkBmpCodec::onGetPixels(const SkImageInfo& dstInfo,
                                         void* dst, size_t dstRowBytes,
+                                        const Options&,
                                         SkPMColor*, int*) {
     if (!this->rewindIfNeeded()) {
         return kCouldNotRewind;
@@ -844,7 +845,7 @@
 
     // Create swizzler
     SkSwizzler* swizzler = SkSwizzler::CreateSwizzler(config, fColorTable.get(),
-            dstInfo, dst, dstRowBytes, false);
+            dstInfo, dst, dstRowBytes, SkImageGenerator::kNo_ZeroInitialized);
 
     // Allocate space for a row buffer and a source for the swizzler
     SkAutoTDeleteArray<uint8_t> srcBuffer(SkNEW_ARRAY(uint8_t, rowBytes));
diff --git a/src/codec/SkCodec_libbmp.h b/src/codec/SkCodec_libbmp.h
index f35b88d..21dab1a 100644
--- a/src/codec/SkCodec_libbmp.h
+++ b/src/codec/SkCodec_libbmp.h
@@ -56,7 +56,7 @@
      *
      */
     virtual Result onGetPixels(const SkImageInfo& dstInfo, void* dst,
-                               size_t dstRowBytes, SkPMColor*,
+                               size_t dstRowBytes, const Options&, SkPMColor*,
                                int*) SK_OVERRIDE;
 
 private:
diff --git a/src/codec/SkCodec_libpng.cpp b/src/codec/SkCodec_libpng.cpp
index f42af38..bf0647d 100644
--- a/src/codec/SkCodec_libpng.cpp
+++ b/src/codec/SkCodec_libpng.cpp
@@ -363,8 +363,8 @@
 }
 
 SkCodec::Result SkPngCodec::onGetPixels(const SkImageInfo& requestedInfo, void* dst,
-                                        size_t rowBytes, SkPMColor ctable[],
-                                        int* ctableCount) {
+                                        size_t rowBytes, const Options& options,
+                                        SkPMColor ctable[], int* ctableCount) {
     if (!this->rewindIfNeeded()) {
         return kCouldNotRewind;
     }
@@ -430,9 +430,9 @@
         sc = SkSwizzler::kRGBA;
     }
     const SkPMColor* colors = colorTable ? colorTable->readColors() : NULL;
-    // TODO: Support skipZeroes.
     swizzler.reset(SkSwizzler::CreateSwizzler(sc, colors, requestedInfo,
-                                              dst, rowBytes, false));
+                                              dst, rowBytes,
+                                              options.fZeroInitialized));
     if (!swizzler) {
         // FIXME: CreateSwizzler could fail for another reason.
         return kUnimplemented;
diff --git a/src/codec/SkCodec_libpng.h b/src/codec/SkCodec_libpng.h
index a5327dd..b255449 100644
--- a/src/codec/SkCodec_libpng.h
+++ b/src/codec/SkCodec_libpng.h
@@ -22,7 +22,8 @@
     static SkCodec* NewFromStream(SkStream*);
     static bool IsPng(SkStream*);
 protected:
-    Result onGetPixels(const SkImageInfo&, void*, size_t, SkPMColor*, int*) SK_OVERRIDE;
+    Result onGetPixels(const SkImageInfo&, void*, size_t, const Options&, SkPMColor*, int*)
+            SK_OVERRIDE;
 private:
     png_structp             fPng_ptr;
     png_infop               fInfo_ptr;
diff --git a/src/codec/SkSwizzler.cpp b/src/codec/SkSwizzler.cpp
index 0668db6..1aa3793 100644
--- a/src/codec/SkSwizzler.cpp
+++ b/src/codec/SkSwizzler.cpp
@@ -199,7 +199,8 @@
 SkSwizzler* SkSwizzler::CreateSwizzler(SkSwizzler::SrcConfig sc,
                                        const SkPMColor* ctable,
                                        const SkImageInfo& info, void* dst,
-                                       size_t dstRowBytes, bool skipZeroes) {
+                                       size_t dstRowBytes,
+                                       SkImageGenerator::ZeroInitialized zeroInit) {
     if (kUnknown_SkColorType == info.colorType()) {
         return NULL;
     }
@@ -226,7 +227,8 @@
         case kIndex:
             switch (info.colorType()) {
                 case kN32_SkColorType:
-                    if (skipZeroes) {
+                    // We assume the color premultiplied ctable (or not) as desired.
+                    if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
                         proc = &swizzle_index_to_n32_skipZ;
                     } else {
                         proc = &swizzle_index_to_n32;
@@ -269,10 +271,10 @@
             switch (info.colorType()) {
                 case kN32_SkColorType:
                     if (info.alphaType() == kUnpremul_SkAlphaType) {
-                        // Respect skipZeroes?
+                        // Respect zeroInit?
                         proc = &swizzle_rgba_to_n32_unpremul;
                     } else {
-                        if (skipZeroes) {
+                        if (SkImageGenerator::kYes_ZeroInitialized == zeroInit) {
                             proc = &swizzle_rgba_to_n32_premul_skipZ;
                         } else {
                             proc = &swizzle_rgba_to_n32_premul;
diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h
index e22c05b..be20d0e 100644
--- a/src/codec/SkSwizzler.h
+++ b/src/codec/SkSwizzler.h
@@ -8,7 +8,7 @@
 #ifndef SkSwizzler_DEFINED
 #define SkSwizzler_DEFINED
 
-#include "SkTypes.h"
+#include "SkCodec.h"
 #include "SkColor.h"
 #include "SkImageInfo.h"
 
@@ -113,19 +113,20 @@
 
     /**
      *  Create a new SkSwizzler.
-     *  @param sc SrcConfig
-     *  @param info dimensions() describe both the src and the dst.
+     *  @param SrcConfig Description of the format of the source.
+     *  @param SkImageInfo dimensions() describe both the src and the dst.
      *              Other fields describe the dst.
      *  @param dst Destination to write pixels. Must match info and dstRowBytes
      *  @param dstRowBytes rowBytes for dst.
-     *  @param skipZeroes Whether to skip writing zeroes. Useful if dst is
-     *              zero-initialized. The implementation may or may not respect this.
+     *  @param ZeroInitialized Whether dst is zero-initialized. The
+                               implementation may choose to skip writing zeroes
+     *                         if set to kYes_ZeroInitialized.
      *  @return A new SkSwizzler or NULL on failure.
      */
-    static SkSwizzler* CreateSwizzler(SrcConfig sc, const SkPMColor* ctable,
-                                      const SkImageInfo& info, void* dst,
-                                      size_t dstRowBytes, bool skipZeroes);
-
+    static SkSwizzler* CreateSwizzler(SrcConfig, const SkPMColor* ctable,
+                                      const SkImageInfo&, void* dst,
+                                      size_t dstRowBytes,
+                                      SkImageGenerator::ZeroInitialized);
     /**
      *  Swizzle the next line. Call height times, once for each row of source.
      *  @param src The next row of the source data.
diff --git a/src/core/SkImageGenerator.cpp b/src/core/SkImageGenerator.cpp
index aabe83e..4c69fd2 100644
--- a/src/core/SkImageGenerator.cpp
+++ b/src/core/SkImageGenerator.cpp
@@ -16,8 +16,8 @@
 }
 
 SkImageGenerator::Result SkImageGenerator::getPixels(const SkImageInfo& info, void* pixels,
-                                                     size_t rowBytes, SkPMColor ctable[],
-                                                     int* ctableCount) {
+                                                     size_t rowBytes, const Options* options,
+                                                     SkPMColor ctable[], int* ctableCount) {
     if (kUnknown_SkColorType == info.colorType()) {
         return kInvalidConversion;
     }
@@ -40,7 +40,12 @@
         ctable = NULL;
     }
 
-    const Result result = this->onGetPixels(info, pixels, rowBytes, ctable, ctableCount);
+    // Default options.
+    Options optsStorage;
+    if (NULL == options) {
+        options = &optsStorage;
+    }
+    const Result result = this->onGetPixels(info, pixels, rowBytes, *options, ctable, ctableCount);
 
     if ((kIncompleteInput == result || kSuccess == result) && ctableCount) {
         SkASSERT(*ctableCount >= 0 && *ctableCount <= 256);
@@ -54,7 +59,7 @@
     if (kIndex_8_SkColorType == info.colorType()) {
         return kInvalidConversion;
     }
-    return this->getPixels(info, pixels, rowBytes, NULL, NULL);
+    return this->getPixels(info, pixels, rowBytes, NULL, NULL, NULL);
 }
 
 bool SkImageGenerator::getYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
@@ -119,7 +124,19 @@
     return false;
 }
 
+#ifdef SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
 SkImageGenerator::Result SkImageGenerator::onGetPixels(const SkImageInfo&, void*, size_t,
                                                        SkPMColor*, int*) {
     return kUnimplemented;
 }
+#endif
+
+SkImageGenerator::Result SkImageGenerator::onGetPixels(const SkImageInfo& info, void* dst,
+                                                       size_t rb, const Options& options,
+                                                       SkPMColor* colors, int* colorCount) {
+#ifdef SK_SUPPORT_LEGACY_OPTIONLESS_GET_PIXELS
+    return this->onGetPixels(info, dst, rb, colors, colorCount);
+#else
+    return kUnimplemented;
+#endif
+}
diff --git a/src/images/SkDecodingImageGenerator.cpp b/src/images/SkDecodingImageGenerator.cpp
index f9b9393..170397d 100644
--- a/src/images/SkDecodingImageGenerator.cpp
+++ b/src/images/SkDecodingImageGenerator.cpp
@@ -43,7 +43,7 @@
         return true;
     }
     virtual Result onGetPixels(const SkImageInfo& info,
-                               void* pixels, size_t rowBytes,
+                               void* pixels, size_t rowBytes, const Options&,
                                SkPMColor ctable[], int* ctableCount) SK_OVERRIDE;
     virtual bool onGetYUV8Planes(SkISize sizes[3], void* planes[3], size_t rowBytes[3],
                                  SkYUVColorSpace* colorSpace) SK_OVERRIDE;
@@ -148,7 +148,8 @@
 }
 
 SkImageGenerator::Result DecodingImageGenerator::onGetPixels(const SkImageInfo& info,
-        void* pixels, size_t rowBytes, SkPMColor ctableEntries[], int* ctableCount) {
+        void* pixels, size_t rowBytes, const Options& options, SkPMColor ctableEntries[],
+        int* ctableCount) {
     if (fInfo != info) {
         // The caller has specified a different info.  This is an
         // error for this kind of SkImageGenerator.  Use the Options
diff --git a/src/lazy/SkDiscardablePixelRef.cpp b/src/lazy/SkDiscardablePixelRef.cpp
index b6dec1b..b810c2b 100644
--- a/src/lazy/SkDiscardablePixelRef.cpp
+++ b/src/lazy/SkDiscardablePixelRef.cpp
@@ -71,7 +71,7 @@
     SkPMColor colors[256];
     int colorCount = 0;
 
-    const SkImageGenerator::Result result = fGenerator->getPixels(info, pixels, fRowBytes,
+    const SkImageGenerator::Result result = fGenerator->getPixels(info, pixels, fRowBytes, NULL,
                                                                   colors, &colorCount);
     switch (result) {
         case SkImageGenerator::kSuccess:
diff --git a/src/ports/SkImageGenerator_skia.cpp b/src/ports/SkImageGenerator_skia.cpp
index 6c27f45..1448d57 100644
--- a/src/ports/SkImageGenerator_skia.cpp
+++ b/src/ports/SkImageGenerator_skia.cpp
@@ -53,6 +53,7 @@
     }
 
     virtual Result onGetPixels(const SkImageInfo& info, void* pixels, size_t rowBytes,
+                               const Options&,
                                SkPMColor ctableEntries[], int* ctableCount) SK_OVERRIDE {
         SkMemoryStream stream(fData->data(), fData->size(), false);
         SkAutoTUnref<BareMemoryAllocator> allocator(SkNEW_ARGS(BareMemoryAllocator,