Add clamp before drawing F16->8888 in DMSrcSink ColorCodecSrc

Verified that this fixes the wrongness of a few of the colorImage
diffs in Gold.

Bug: skia:6738
Change-Id: Icf0b7573ccb87268b480d7cc0a6cfe6fa8ae73f7
Reviewed-on: https://skia-review.googlesource.com/19271
Reviewed-by: Mike Klein <mtklein@chromium.org>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index 4ac7e80..4029524 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -1043,6 +1043,30 @@
     return flags.type != SinkFlags::kRaster || flags.approach != SinkFlags::kDirect;
 }
 
+void clamp_if_necessary(const SkBitmap& bitmap, SkColorType dstCT) {
+    if (kRGBA_F16_SkColorType != bitmap.colorType() || kRGBA_F16_SkColorType == dstCT) {
+        // No need to clamp if the dst is F16.  We will clamp when we encode to PNG.
+        return;
+    }
+
+    void* ptr = bitmap.getAddr(0, 0);
+    SkRasterPipeline_<256> p;
+    p.append(SkRasterPipeline::load_f16, &ptr);
+    p.append(SkRasterPipeline::clamp_0);
+    if (kPremul_SkAlphaType == bitmap.alphaType()) {
+        p.append(SkRasterPipeline::clamp_a);
+    } else {
+        p.append(SkRasterPipeline::clamp_1);
+    }
+    p.append(SkRasterPipeline::store_f16, &ptr);
+
+    auto run = p.compile();
+    for (int y = 0; y < bitmap.height(); y++) {
+        run(0, y, bitmap.width());
+        ptr = SkTAddOffset<void>(ptr, bitmap.rowBytes());
+    }
+}
+
 Error ColorCodecSrc::draw(SkCanvas* canvas) const {
     if (kRGB_565_SkColorType == canvas->imageInfo().colorType()) {
         return Error::Nonfatal("No need to test color correction to 565 backend.");
@@ -1113,6 +1137,8 @@
         case kBaseline_Mode:
         case kDst_sRGB_Mode:
         case kDst_HPZR30w_Mode:
+            // We do not support drawing unclamped F16.
+            clamp_if_necessary(bitmap, canvas->imageInfo().colorType());
             canvas->drawBitmap(bitmap, 0, 0);
             break;
         default: