add SkColorTypeIsNormalized()

This centralizes the logic for whether a color type is normalized.

The change in SkRasterPipelineBlitter is minor, only now properly
treating kR16G16_float_SkColorType as unnormalized.

The change in SkColorSpaceXformSteps is more extreme given the way
it had been written, with all the newer color types now correct.

I think I'm making the right call on kA16_float_SkColorType?

Are there equivalent sites to update in Ganesh?

Change-Id: I32a40b31b86c5fde0dea2528122a4deda91c5545
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253668
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/include/private/SkImageInfoPriv.h b/include/private/SkImageInfoPriv.h
index b414d36..15f0224 100644
--- a/include/private/SkImageInfoPriv.h
+++ b/include/private/SkImageInfoPriv.h
@@ -98,6 +98,32 @@
     return y * rowBytes + (x << SkColorTypeShiftPerPixel(ct));
 }
 
+static inline bool SkColorTypeIsNormalized(SkColorType ct) {
+    switch (ct) {
+        case kUnknown_SkColorType:
+        case kAlpha_8_SkColorType:
+        case kRGB_565_SkColorType:
+        case kARGB_4444_SkColorType:
+        case kRGBA_8888_SkColorType:
+        case kRGB_888x_SkColorType:
+        case kBGRA_8888_SkColorType:
+        case kRGBA_1010102_SkColorType:
+        case kRGB_101010x_SkColorType:
+        case kGray_8_SkColorType:
+        case kRGBA_F16Norm_SkColorType:
+        case kR8G8_unorm_SkColorType:
+        case kA16_unorm_SkColorType:
+        case kA16_float_SkColorType:          /*subtle... alpha is always [0,1]*/
+        case kR16G16_unorm_SkColorType:
+        case kR16G16B16A16_unorm_SkColorType: return true;
+
+        case kRGBA_F16_SkColorType:
+        case kRGBA_F32_SkColorType:
+        case kR16G16_float_SkColorType:       return false;
+    }
+    SkUNREACHABLE;
+}
+
 /**
  *  Returns true if |info| contains a valid combination of width, height, colorType, and alphaType.
  */
diff --git a/src/core/SkColorSpaceXformSteps.h b/src/core/SkColorSpaceXformSteps.h
index 1a15643..0b7a4f9 100644
--- a/src/core/SkColorSpaceXformSteps.h
+++ b/src/core/SkColorSpaceXformSteps.h
@@ -10,6 +10,7 @@
 
 #include "include/core/SkColorSpace.h"
 #include "include/core/SkImageInfo.h"
+#include "include/private/SkImageInfoPriv.h"
 
 class SkRasterPipeline;
 
@@ -41,13 +42,7 @@
     void apply(SkRasterPipeline*, bool src_is_normalized) const;
 
     void apply(SkRasterPipeline* p, SkColorType srcCT) const {
-    #if 0
-        this->apply(p, srcCT < kRGBA_F16_SkColorType);
-    #else
-        // F16Norm is normalized, but to make diffing with F16 easier we
-        // intentionally take the slower, non-normalized path here.
-        this->apply(p, srcCT < kRGBA_F16Norm_SkColorType);
-    #endif
+        return this->apply(p, SkColorTypeIsNormalized(srcCT));
     }
 
     Flags flags;
diff --git a/src/core/SkRasterPipeline.cpp b/src/core/SkRasterPipeline.cpp
index 4f73643..78b943a 100644
--- a/src/core/SkRasterPipeline.cpp
+++ b/src/core/SkRasterPipeline.cpp
@@ -5,6 +5,7 @@
  * found in the LICENSE file.
  */
 
+#include "include/private/SkImageInfoPriv.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "src/core/SkOpts.h"
 #include "src/core/SkRasterPipeline.h"
@@ -291,12 +292,11 @@
     }
 }
 
-void SkRasterPipeline::append_gamut_clamp_if_normalized(const SkImageInfo& dstInfo) {
-    // N.B. we _do_ clamp for kRGBA_F16Norm_SkColorType... because it's normalized.
-    if (dstInfo.colorType() != kRGBA_F16_SkColorType &&
-        dstInfo.colorType() != kRGBA_F32_SkColorType &&
-        dstInfo.alphaType() == kPremul_SkAlphaType)
-    {
+// Clamp premul values to [0,alpha] (logical [0,1]) to avoid the confusing
+// scenario of being able to store a logical color channel > 1.0 when alpha < 1.0.
+// Most software that works with normalized premul values expect r,g,b channels all <= a.
+void SkRasterPipeline::append_gamut_clamp_if_normalized(const SkImageInfo& info) {
+    if (info.alphaType() == kPremul_SkAlphaType && SkColorTypeIsNormalized(info.colorType())) {
         this->unchecked_append(SkRasterPipeline::clamp_gamut, nullptr);
     }
 }