Refactor RGBA/BGRA xform logic in SkCodecs

BUG=skia:

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

Change-Id: Ic9105a2806b915fc56b6810a80dd444561d0d959
Reviewed-on: https://skia-review.googlesource.com/4554
Reviewed-by: Leon Scroggins <scroggo@google.com>
Commit-Queue: Matt Sarett <msarett@google.com>
diff --git a/src/codec/SkBmpCodec.cpp b/src/codec/SkBmpCodec.cpp
index 7cd1dfe..78f6b20 100644
--- a/src/codec/SkBmpCodec.cpp
+++ b/src/codec/SkBmpCodec.cpp
@@ -636,10 +636,10 @@
 void SkBmpCodec::applyColorXform(const SkImageInfo& dstInfo, void* dst, void* src) const {
     SkColorSpaceXform* xform = this->colorXform();
     if (xform) {
-        SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
-        SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kBGRA_8888_ColorFormat;
-        SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
-                                                   this->getInfo().alphaType());
+        const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
+        const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
+        const SkAlphaType alphaType = select_xform_alpha(dstInfo.alphaType(),
+                                                         this->getInfo().alphaType());
         SkAssertResult(xform->apply(dstFormat, dst, srcFormat, src, dstInfo.width(),
                                     alphaType));
     }
diff --git a/src/codec/SkBmpCodec.h b/src/codec/SkBmpCodec.h
index a51bbce..0e38c84 100644
--- a/src/codec/SkBmpCodec.h
+++ b/src/codec/SkBmpCodec.h
@@ -110,6 +110,12 @@
     uint32_t* xformBuffer() const { return fXformBuffer.get(); }
     void resetXformBuffer(int count) { fXformBuffer.reset(new uint32_t[count]); }
 
+    /*
+     * BMPs are typically encoded as BGRA/BGR so this is a more efficient choice
+     * than RGBA.
+     */
+    static const SkColorType kXformSrcColorType = kBGRA_8888_SkColorType;
+
 private:
 
     /*
diff --git a/src/codec/SkBmpMaskCodec.cpp b/src/codec/SkBmpMaskCodec.cpp
index 3ee1bb7..9612a23 100644
--- a/src/codec/SkBmpMaskCodec.cpp
+++ b/src/codec/SkBmpMaskCodec.cpp
@@ -60,7 +60,7 @@
 
     SkImageInfo swizzlerInfo = dstInfo;
     if (this->colorXform()) {
-        swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
         if (kPremul_SkAlphaType == dstInfo.alphaType()) {
             swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
         }
diff --git a/src/codec/SkBmpRLECodec.cpp b/src/codec/SkBmpRLECodec.cpp
index 0bc6f60..c2574dd 100644
--- a/src/codec/SkBmpRLECodec.cpp
+++ b/src/codec/SkBmpRLECodec.cpp
@@ -341,7 +341,7 @@
     SkImageInfo decodeInfo = dstInfo;
     if (decodeDst) {
         if (this->colorXform()) {
-            decodeInfo = decodeInfo.makeColorType(kBGRA_8888_SkColorType);
+            decodeInfo = decodeInfo.makeColorType(kXformSrcColorType);
             if (kRGBA_F16_SkColorType == dstInfo.colorType()) {
                 int count = height * dstInfo.width();
                 this->resetXformBuffer(count);
diff --git a/src/codec/SkBmpStandardCodec.cpp b/src/codec/SkBmpStandardCodec.cpp
index 004c257..eeb3a1b 100644
--- a/src/codec/SkBmpStandardCodec.cpp
+++ b/src/codec/SkBmpStandardCodec.cpp
@@ -183,7 +183,7 @@
     SkImageInfo swizzlerInfo = dstInfo;
     SkCodec::Options swizzlerOptions = opts;
     if (this->colorXform()) {
-        swizzlerInfo = swizzlerInfo.makeColorType(kBGRA_8888_SkColorType);
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
         if (kPremul_SkAlphaType == dstInfo.alphaType()) {
             swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
         }
diff --git a/src/codec/SkGifCodec.cpp b/src/codec/SkGifCodec.cpp
index e773ed7..7fc3c98 100644
--- a/src/codec/SkGifCodec.cpp
+++ b/src/codec/SkGifCodec.cpp
@@ -144,10 +144,12 @@
     return fReader->loopCount();
 }
 
+static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
+
 void SkGifCodec::initializeColorTable(const SkImageInfo& dstInfo, size_t frameIndex) {
     SkColorType colorTableColorType = dstInfo.colorType();
     if (this->colorXform()) {
-        colorTableColorType = kRGBA_8888_SkColorType;
+        colorTableColorType = kXformSrcColorType;
     }
 
     sk_sp<SkColorTable> currColorTable = fReader->getColorTable(colorTableColorType, frameIndex);
@@ -158,10 +160,10 @@
         fCurrColorTable.reset(new SkColorTable(&color, 1));
     } else if (this->colorXform() && !fXformOnDecode) {
         SkPMColor dstColors[256];
-        SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
-        SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
-        SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
-                                                        this->getInfo().alphaType());
+        const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
+        const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
+        const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
+                                                              this->getInfo().alphaType());
         SkAssertResult(this->colorXform()->apply(dstFormat, dstColors, srcFormat,
                                                  currColorTable->readColors(),
                                                  currColorTable->count(), xformAlphaType));
@@ -261,7 +263,7 @@
 
     SkImageInfo swizzlerInfo = dstInfo;
     if (this->colorXform()) {
-        swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
         if (kPremul_SkAlphaType == dstInfo.alphaType()) {
             swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
         }
@@ -470,7 +472,7 @@
         fSwizzler->swizzle(fXformBuffer.get(), src);
 
         const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
-        const SkColorSpaceXform::ColorFormat srcFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
+        const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
         const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
                                                               this->getInfo().alphaType());
         const int xformWidth = get_scaled_dimension(dstInfo.width(), fSwizzler->sampleX());
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index 614cde9..69b8027 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -385,8 +385,8 @@
             if (isCMYK) {
                 fDecoderMgr->dinfo()->out_color_space = JCS_CMYK;
             } else if (this->colorXform()) {
-                // Our color transformation code requires RGBA order inputs, but it'll swizzle
-                // to BGRA for us.
+                // Always using RGBA as the input format for color xforms makes the
+                // implementation a little simpler.
                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_RGBA;
             } else {
                 fDecoderMgr->dinfo()->out_color_space = JCS_EXT_BGRA;
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 3cf972d..758ffa5 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -212,6 +212,8 @@
     }
 }
 
+static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
+
 // Note: SkColorTable claims to store SkPMColors, which is not necessarily the case here.
 bool SkPngCodec::createColorTable(const SkImageInfo& dstInfo, int* ctableCount) {
 
@@ -224,7 +226,7 @@
     // Contents depend on tableColorType and our choice of if/when to premultiply:
     // { kPremul, kUnpremul, kOpaque } x { RGBA, BGRA }
     SkPMColor colorTable[256];
-    SkColorType tableColorType = this->colorXform() ? kRGBA_8888_SkColorType : dstInfo.colorType();
+    SkColorType tableColorType = this->colorXform() ? kXformSrcColorType : dstInfo.colorType();
 
     png_bytep alphas;
     int numColorsWithAlpha = 0;
@@ -267,11 +269,12 @@
     // If we are not decoding to F16, we can color xform now and store the results
     // in the color table.
     if (this->colorXform() && kRGBA_F16_SkColorType != dstInfo.colorType()) {
-        SkColorSpaceXform::ColorFormat xformColorFormat = select_xform_format(dstInfo.colorType());
-        SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
-                                                        this->getInfo().alphaType());
-        SkAssertResult(this->colorXform()->apply(xformColorFormat, colorTable,
-                SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable, numColors, xformAlphaType));
+        const SkColorSpaceXform::ColorFormat dstFormat = select_xform_format(dstInfo.colorType());
+        const SkColorSpaceXform::ColorFormat srcFormat = select_xform_format(kXformSrcColorType);
+        const SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
+                                                              this->getInfo().alphaType());
+        SkAssertResult(this->colorXform()->apply(dstFormat, colorTable, srcFormat, colorTable,
+                       numColors, xformAlphaType));
     }
 
     // Pad the color table with the last color in the table (or black) in the case that
@@ -430,7 +433,7 @@
 }
 
 void SkPngCodec::applyXformRow(void* dst, const void* src) {
-    const SkColorSpaceXform::ColorFormat srcColorFormat = SkColorSpaceXform::kRGBA_8888_ColorFormat;
+    const SkColorSpaceXform::ColorFormat srcColorFormat = select_xform_format(kXformSrcColorType);
     switch (fXformMode) {
         case kSwizzleOnly_XformMode:
             fSwizzler->swizzle(dst, (const uint8_t*) src);
@@ -1068,8 +1071,6 @@
     }
 
     // If the image is RGBA and we have a color xform, we can skip the swizzler.
-    // FIXME (msarett):
-    // Support more input types to this->colorXform() (ex: RGB, Gray) and skip the swizzler more often.
     if (this->colorXform() && SkEncodedInfo::kRGBA_Color == this->getEncodedInfo().color() &&
         !options.fSubset)
     {
@@ -1116,7 +1117,7 @@
     if (this->colorXform() &&
         apply_xform_on_decode(dstInfo.colorType(), this->getEncodedInfo().color()))
     {
-        swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
         if (kPremul_SkAlphaType == dstInfo.alphaType()) {
             swizzlerInfo = swizzlerInfo.makeAlphaType(kUnpremul_SkAlphaType);
         }
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index 1513632..93995c4 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -688,10 +688,11 @@
         return kInvalidConversion;
     }
 
+    static const SkColorType kXformSrcColorType = kRGBA_8888_SkColorType;
     SkImageInfo swizzlerInfo = dstInfo;
     std::unique_ptr<uint32_t[]> xformBuffer = nullptr;
     if (this->colorXform()) {
-        swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
+        swizzlerInfo = swizzlerInfo.makeColorType(kXformSrcColorType);
         xformBuffer.reset(new uint32_t[dstInfo.width()]);
     }
 
@@ -742,7 +743,7 @@
             swizzler->swizzle(xformBuffer.get(), &srcRow[0]);
 
             const SkColorSpaceXform::ColorFormat srcFormat =
-                    SkColorSpaceXform::kRGBA_8888_ColorFormat;
+                    select_xform_format(kXformSrcColorType);
             const SkColorSpaceXform::ColorFormat dstFormat =
                     select_xform_format(dstInfo.colorType());
             this->colorXform()->apply(dstFormat, dstRow, srcFormat, xformBuffer.get(),