Implement Fill() for incomplete decodes to RGBA_F16

Before this patch, we would hit an SkASSERT(false).

BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2335203002

Review-Url: https://codereview.chromium.org/2335203002
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 6b33023..0c7de85 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -915,7 +915,7 @@
 
     size_t rowBytes = bitmap.rowBytes();
     SkCodec::Result r = codec->getPixels(decodeInfo, bitmap.getPixels(), rowBytes);
-    if (SkCodec::kSuccess != r) {
+    if (SkCodec::kSuccess != r && SkCodec::kIncompleteInput != r) {
         return SkStringPrintf("Couldn't getPixels %s. Error code %d", fPath.c_str(), r);
     }
 
diff --git a/gyp/codec_android.gyp b/gyp/codec_android.gyp
index 833d430..ce96d8d 100644
--- a/gyp/codec_android.gyp
+++ b/gyp/codec_android.gyp
@@ -25,6 +25,7 @@
         '../include/private',
         '../src/android',
         '../src/codec',
+        '../src/core',
       ],
       'sources': [
         '../src/android/SkBitmapRegionCodec.cpp',
diff --git a/include/codec/SkCodec.h b/include/codec/SkCodec.h
index bee4f3c..b0647ed 100644
--- a/include/codec/SkCodec.h
+++ b/include/codec/SkCodec.h
@@ -601,30 +601,30 @@
      * On an incomplete input, getPixels() and getScanlines() will fill any uninitialized
      * scanlines.  This allows the subclass to indicate what value to fill with.
      *
-     * @param colorType Destination color type.
+     * @param dstInfo   Describes the destination.
      * @return          The value with which to fill uninitialized pixels.
      *
-     * Note that we can interpret the return value as an SkPMColor, a 16-bit 565 color,
-     * an 8-bit gray color, or an 8-bit index into a color table, depending on the color
-     * type.
+     * Note that we can interpret the return value as a 64-bit Float16 color, a SkPMColor,
+     * a 16-bit 565 color, an 8-bit gray color, or an 8-bit index into a color table,
+     * depending on the color type.
      */
-    uint32_t getFillValue(SkColorType colorType) const {
-        return this->onGetFillValue(colorType);
+    uint64_t getFillValue(const SkImageInfo& dstInfo) const {
+        return this->onGetFillValue(dstInfo);
     }
 
     /**
      * Some subclasses will override this function, but this is a useful default for the color
-     * types that we support.  Note that for color types that do not use the full 32-bits,
+     * types that we support.  Note that for color types that do not use the full 64-bits,
      * we will simply take the low bits of the fill value.
      *
+     * The defaults are:
+     * kRGBA_F16_SkColorType: Transparent or Black, depending on the src alpha type
      * kN32_SkColorType: Transparent or Black, depending on the src alpha type
      * kRGB_565_SkColorType: Black
      * kGray_8_SkColorType: Black
      * kIndex_8_SkColorType: First color in color table
      */
-    virtual uint32_t onGetFillValue(SkColorType /*colorType*/) const {
-        return kOpaque_SkAlphaType == fSrcInfo.alphaType() ? SK_ColorBLACK : SK_ColorTRANSPARENT;
-    }
+    virtual uint64_t onGetFillValue(const SkImageInfo& dstInfo) const;
 
     /**
      * Get method for the input stream
diff --git a/infra/bots/assets/skimage/VERSION b/infra/bots/assets/skimage/VERSION
index 1e8b314..c793025 100644
--- a/infra/bots/assets/skimage/VERSION
+++ b/infra/bots/assets/skimage/VERSION
@@ -1 +1 @@
-6
+7
\ No newline at end of file
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 089e310..7d67d18 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -302,10 +302,11 @@
     }
 }
 
-uint32_t SkBmpStandardCodec::onGetFillValue(SkColorType colorType) const {
+uint64_t SkBmpStandardCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
     const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
     if (colorPtr) {
-        return get_color_table_fill_value(colorType, colorPtr, 0);
+        return get_color_table_fill_value(dstInfo.colorType(), dstInfo.alphaType(), colorPtr, 0,
+                                          nullptr);
     }
-    return INHERITED::onGetFillValue(colorType);
+    return INHERITED::onGetFillValue(dstInfo);
 }
diff --git a/src/codec/SkBmpStandardCodec.h b/src/codec/SkBmpStandardCodec.h
index 506742b..7039cf7 100644
--- a/src/codec/SkBmpStandardCodec.h
+++ b/src/codec/SkBmpStandardCodec.h
@@ -57,7 +57,7 @@
             int* inputColorCount) override;
 
 
-    uint32_t onGetFillValue(SkColorType) const override;
+    uint64_t onGetFillValue(const SkImageInfo&) const override;
 
     SkSampler* getSampler(bool createIfNecessary) override {
         SkASSERT(fSwizzler);
diff --git a/src/codec/SkCodec.cpp b/src/codec/SkCodec.cpp
index b076954..6f29870 100644
--- a/src/codec/SkCodec.cpp
+++ b/src/codec/SkCodec.cpp
@@ -11,6 +11,7 @@
 #include "SkColorSpace.h"
 #include "SkData.h"
 #include "SkGifCodec.h"
+#include "SkHalf.h"
 #include "SkIcoCodec.h"
 #include "SkJpegCodec.h"
 #ifdef SK_HAS_PNG_LIBRARY
@@ -353,8 +354,24 @@
     }
 }
 
+uint64_t SkCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
+    switch (dstInfo.colorType()) {
+        case kRGBA_F16_SkColorType: {
+            static constexpr uint64_t transparentColor = 0;
+            static constexpr uint64_t opaqueColor = ((uint64_t) SK_Half1) << 48;
+            return (kOpaque_SkAlphaType == fSrcInfo.alphaType()) ? opaqueColor : transparentColor;
+        }
+        default: {
+            // This not only handles the kN32 case, but also k565, kGray8, kIndex8, since
+            // the low bits are zeros.
+            return (kOpaque_SkAlphaType == fSrcInfo.alphaType()) ?
+                    SK_ColorBLACK : SK_ColorTRANSPARENT;
+        }
+    }
+}
+
 static void fill_proc(const SkImageInfo& info, void* dst, size_t rowBytes,
-        uint32_t colorOrIndex, SkCodec::ZeroInitialized zeroInit, SkSampler* sampler) {
+        uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit, SkSampler* sampler) {
     if (sampler) {
         sampler->fill(info, dst, rowBytes, colorOrIndex, zeroInit);
     } else {
@@ -366,7 +383,7 @@
         ZeroInitialized zeroInit, int linesRequested, int linesDecoded) {
 
     void* fillDst;
-    const uint32_t fillValue = this->getFillValue(info.colorType());
+    const uint64_t fillValue = this->getFillValue(info);
     const int linesRemaining = linesRequested - linesDecoded;
     SkSampler* sampler = this->getSampler(false);
 
diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h
index 5845256..8876b72 100644
--- a/src/codec/SkCodecPriv.h
+++ b/src/codec/SkCodecPriv.h
@@ -9,6 +9,7 @@
 #define SkCodecPriv_DEFINED
 
 #include "SkColorPriv.h"
+#include "SkColorSpaceXform.h"
 #include "SkColorTable.h"
 #include "SkImageInfo.h"
 #include "SkTypes.h"
@@ -146,8 +147,8 @@
 /*
  * Given that the encoded image uses a color table, return the fill value
  */
-static inline uint32_t get_color_table_fill_value(SkColorType colorType, const SkPMColor* colorPtr,
-        uint8_t fillIndex) {
+static inline uint64_t get_color_table_fill_value(SkColorType colorType, SkAlphaType alphaType,
+        const SkPMColor* colorPtr, uint8_t fillIndex, SkColorSpaceXform* colorXform) {
     SkASSERT(nullptr != colorPtr);
     switch (colorType) {
         case kRGBA_8888_SkColorType:
@@ -157,6 +158,13 @@
             return SkPixel32ToPixel16(colorPtr[fillIndex]);
         case kIndex_8_SkColorType:
             return fillIndex;
+        case kRGBA_F16_SkColorType: {
+            SkASSERT(colorXform);
+            uint64_t dstColor;
+            uint32_t srcColor = colorPtr[fillIndex];
+            colorXform->apply(&dstColor, &srcColor, 1, colorType, alphaType);
+            return dstColor;
+        }
         default:
             SkASSERT(false);
             return 0;
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index 1e6e300..c35cd24 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -494,7 +494,7 @@
     // Initialize the swizzler
     if (fFrameIsSubset) {
         // Fill the background
-        SkSampler::Fill(dstInfo, dst, dstRowBytes, this->getFillValue(dstInfo.colorType()),
+        SkSampler::Fill(dstInfo, dst, dstRowBytes, this->getFillValue(dstInfo),
                 opts.fZeroInitialized);
     }
 
@@ -512,9 +512,10 @@
 
 // FIXME: This is similar to the implementation for bmp and png.  Can we share more code or
 //        possibly make this non-virtual?
-uint32_t SkGifCodec::onGetFillValue(SkColorType colorType) const {
+uint64_t SkGifCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
     const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
-    return get_color_table_fill_value(colorType, colorPtr, fFillIndex);
+    return get_color_table_fill_value(dstInfo.colorType(), dstInfo.alphaType(), colorPtr,
+                                      fFillIndex, nullptr);
 }
 
 SkCodec::Result SkGifCodec::onStartScanlineDecode(const SkImageInfo& dstInfo,
@@ -555,7 +556,7 @@
     if (fFrameIsSubset) {
         // Fill the requested rows
         SkImageInfo fillInfo = this->dstInfo().makeWH(this->dstInfo().width(), count);
-        uint32_t fillValue = this->onGetFillValue(this->dstInfo().colorType());
+        uint64_t fillValue = this->onGetFillValue(this->dstInfo());
         fSwizzler->fill(fillInfo, dst, rowBytes, fillValue, this->options().fZeroInitialized);
 
         // Start to write pixels at the start of the image frame
diff --git a/src/codec/SkGifCodec.h b/src/codec/SkGifCodec.h
index 984bcea..c56d371 100644
--- a/src/codec/SkGifCodec.h
+++ b/src/codec/SkGifCodec.h
@@ -66,7 +66,7 @@
 
     bool onRewind() override;
 
-    uint32_t onGetFillValue(SkColorType) const override;
+    uint64_t onGetFillValue(const SkImageInfo&) const override;
 
     int onOutputScanline(int inputScanline) const override;
 
diff --git a/src/codec/SkMaskSwizzler.h b/src/codec/SkMaskSwizzler.h
index 1dc1918..3bf8d17 100644
--- a/src/codec/SkMaskSwizzler.h
+++ b/src/codec/SkMaskSwizzler.h
@@ -39,7 +39,7 @@
     /**
      * Implement fill using a custom width.
      */
-    void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint32_t colorOrIndex,
+    void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint64_t colorOrIndex,
             SkCodec::ZeroInitialized zeroInit) override {
         const SkImageInfo fillInfo = info.makeWH(fDstWidth, info.height());
         SkSampler::Fill(fillInfo, dst, rowBytes, colorOrIndex, zeroInit);
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 46da29e..0002bc5 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -899,12 +899,15 @@
     return kSuccess;
 }
 
-uint32_t SkPngCodec::onGetFillValue(SkColorType colorType) const {
+uint64_t SkPngCodec::onGetFillValue(const SkImageInfo& dstInfo) const {
     const SkPMColor* colorPtr = get_color_ptr(fColorTable.get());
     if (colorPtr) {
-        return get_color_table_fill_value(colorType, colorPtr, 0);
+        SkAlphaType alphaType = select_alpha_xform(dstInfo.alphaType(),
+                                                   this->getInfo().alphaType());
+        return get_color_table_fill_value(dstInfo.colorType(), alphaType, colorPtr, 0,
+                                          fColorXform.get());
     }
-    return INHERITED::onGetFillValue(colorType);
+    return INHERITED::onGetFillValue(dstInfo);
 }
 
 SkCodec* SkPngCodec::NewFromStream(SkStream* stream, SkPngChunkReader* chunkReader) {
diff --git a/src/codec/SkPngCodec.h b/src/codec/SkPngCodec.h
index fba29a9..a4c20c7 100644
--- a/src/codec/SkPngCodec.h
+++ b/src/codec/SkPngCodec.h
@@ -43,7 +43,7 @@
             override;
     SkEncodedFormat onGetEncodedFormat() const override { return kPNG_SkEncodedFormat; }
     bool onRewind() override;
-    uint32_t onGetFillValue(SkColorType) const override;
+    uint64_t onGetFillValue(const SkImageInfo&) const override;
 
     // Helper to set up swizzler, color xforms, and color table. Also calls png_read_update_info.
     bool initializeXforms(const SkImageInfo& dstInfo, const Options&, SkPMColor* colorPtr,
diff --git a/src/codec/SkSampledCodec.cpp b/src/codec/SkSampledCodec.cpp
index 49c939c..47f99f7 100644
--- a/src/codec/SkSampledCodec.cpp
+++ b/src/codec/SkSampledCodec.cpp
@@ -253,7 +253,7 @@
 
             // We handle filling uninitialized memory here instead of using this->codec().
             // this->codec() does not know that we are sampling.
-            const uint32_t fillValue = this->codec()->getFillValue(info.colorType());
+            const uint64_t fillValue = this->codec()->getFillValue(info);
             const SkImageInfo fillInfo = info.makeWH(info.width(), 1);
             for (; y < nativeSize.height(); y++) {
                 int srcY = this->codec()->outputScanline(y);
diff --git a/src/codec/SkSampler.cpp b/src/codec/SkSampler.cpp
index ccfe400..244aa3b 100644
--- a/src/codec/SkSampler.cpp
+++ b/src/codec/SkSampler.cpp
@@ -11,7 +11,7 @@
 #include "SkUtils.h"
 
 void SkSampler::Fill(const SkImageInfo& info, void* dst, size_t rowBytes,
-        uint32_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {
+        uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {
     SkASSERT(dst != nullptr);
 
     // Calculate bytes to fill.  We use getSafeSize since the last row may not be padded.
@@ -24,26 +24,15 @@
         case kRGBA_8888_SkColorType:
         case kBGRA_8888_SkColorType: {
             // If memory is zero initialized, we may not need to fill
-            uint32_t color = colorOrIndex;
+            uint32_t color = (uint32_t) colorOrIndex;
             if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
                 return;
             }
 
-            // We must fill row by row in the case of unaligned row bytes
-            if (SkIsAlign4((size_t) dst) && SkIsAlign4(rowBytes)) {
-                sk_memset32((uint32_t*) dst, color,
-                        (uint32_t) bytesToFill / sizeof(SkPMColor));
-            } else {
-                // We must fill row by row in the case of unaligned row bytes.  This is an
-                // unlikely, slow case.
-                SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
-                uint32_t* dstRow = (uint32_t*) dst;
-                for (int row = 0; row < numRows; row++) {
-                    for (int col = 0; col < width; col++) {
-                        dstRow[col] = color;
-                    }
-                    dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes);
-                }
+            uint32_t* dstRow = (uint32_t*) dst;
+            for (int row = 0; row < numRows; row++) {
+                sk_memset32((uint32_t*) dstRow, color, width);
+                dstRow = SkTAddOffset<uint32_t>(dstRow, rowBytes);
             }
             break;
         }
@@ -61,19 +50,10 @@
                 return;
             }
 
-            if (SkIsAlign2((size_t) dst) && SkIsAlign2(rowBytes)) {
-                sk_memset16((uint16_t*) dst, color, (uint32_t) bytesToFill / sizeof(uint16_t));
-            } else {
-                // We must fill row by row in the case of unaligned row bytes.  This is an
-                // unlikely, slow case.
-                SkCodecPrintf("Warning: Strange number of row bytes, fill will be slow.\n");
-                uint16_t* dstRow = (uint16_t*) dst;
-                for (int row = 0; row < numRows; row++) {
-                    for (int col = 0; col < width; col++) {
-                        dstRow[col] = color;
-                    }
-                    dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes);
-                }
+            uint16_t* dstRow = (uint16_t*) dst;
+            for (int row = 0; row < numRows; row++) {
+                sk_memset16((uint16_t*) dstRow, color, width);
+                dstRow = SkTAddOffset<uint16_t>(dstRow, rowBytes);
             }
             break;
         }
@@ -95,6 +75,19 @@
 
             memset(dst, (uint8_t) colorOrIndex, bytesToFill);
             break;
+        case kRGBA_F16_SkColorType: {
+            uint64_t color = colorOrIndex;
+            if (SkCodec::kYes_ZeroInitialized == zeroInit && 0 == color) {
+                return;
+            }
+
+            uint64_t* dstRow = (uint64_t*) dst;
+            for (int row = 0; row < numRows; row++) {
+                sk_memset64((uint64_t*) dstRow, color, width);
+                dstRow = SkTAddOffset<uint64_t>(dstRow, rowBytes);
+            }
+            break;
+        }
         default:
             SkCodecPrintf("Error: Unsupported dst color type for fill().  Doing nothing.\n");
             SkASSERT(false);
diff --git a/src/codec/SkSampler.h b/src/codec/SkSampler.h
index 73e11c9..b233c32 100644
--- a/src/codec/SkSampler.h
+++ b/src/codec/SkSampler.h
@@ -35,6 +35,7 @@
      * Stride in bytes of the destination.
      *
      * @param colorOrIndex
+     * If colorType is kF16, colorOrIndex is treated as a 64-bit color.
      * If colorType is kN32, colorOrIndex is treated as a 32-bit color.
      * If colorType is k565, colorOrIndex is treated as a 16-bit color.
      * If colorType is kGray, colorOrIndex is treated as an 8-bit color.
@@ -46,13 +47,13 @@
      *
      */
     static void Fill(const SkImageInfo& info, void* dst, size_t rowBytes,
-            uint32_t colorOrIndex, SkCodec::ZeroInitialized zeroInit);
+            uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit);
 
     /**
      * Allow subclasses to implement unique versions of fill().
      */
     virtual void fill(const SkImageInfo& info, void* dst, size_t rowBytes,
-            uint32_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {}
+            uint64_t colorOrIndex, SkCodec::ZeroInitialized zeroInit) {}
 
     virtual ~SkSampler() {}
 private:
diff --git a/src/codec/SkSwizzler.h b/src/codec/SkSwizzler.h
index 6172af5..a535298 100644
--- a/src/codec/SkSwizzler.h
+++ b/src/codec/SkSwizzler.h
@@ -56,7 +56,7 @@
     /**
      * Implement fill using a custom width.
      */
-    void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint32_t colorOrIndex,
+    void fill(const SkImageInfo& info, void* dst, size_t rowBytes, uint64_t colorOrIndex,
             SkCodec::ZeroInitialized zeroInit) override {
         const SkImageInfo fillInfo = info.makeWH(fAllocatedWidth, info.height());
         SkSampler::Fill(fillInfo, dst, rowBytes, colorOrIndex, zeroInit);