Stop using SkSwizzler in SkRawCodec

Bug: skia:8473

SkRawCodec doesn't implement scanline decoding or incremental decoding,
so it doesn't take advantage of SkSwizzler's sampling. It just uses it
to do conversion, and then it potentially uses skcms to transform
colors. Instead, always use skcms and avoid creating the SkSwizzler.

Change-Id: Ie0d4f83b0eac18150a6d52382c8283babb6cbfca
Reviewed-on: https://skia-review.googlesource.com/c/175592
Commit-Queue: Leon Scroggins <scroggo@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
Auto-Submit: Leon Scroggins <scroggo@google.com>
Reviewed-by: Mike Klein <mtklein@google.com>
diff --git a/src/codec/SkRawCodec.cpp b/src/codec/SkRawCodec.cpp
index c9a78db..c6f7e55 100644
--- a/src/codec/SkRawCodec.cpp
+++ b/src/codec/SkRawCodec.cpp
@@ -17,7 +17,6 @@
 #include "SkRefCnt.h"
 #include "SkStream.h"
 #include "SkStreamPriv.h"
-#include "SkSwizzler.h"
 #include "SkTArray.h"
 #include "SkTaskGroup.h"
 #include "SkTemplates.h"
@@ -697,17 +696,6 @@
 SkCodec::Result SkRawCodec::onGetPixels(const SkImageInfo& dstInfo, void* dst,
                                         size_t dstRowBytes, const Options& options,
                                         int* rowsDecoded) {
-    SkImageInfo swizzlerInfo = dstInfo;
-    std::unique_ptr<uint32_t[]> xformBuffer = nullptr;
-    if (this->colorXform()) {
-        swizzlerInfo = swizzlerInfo.makeColorType(kRGBA_8888_SkColorType);
-        xformBuffer.reset(new uint32_t[dstInfo.width()]);
-    }
-
-    std::unique_ptr<SkSwizzler> swizzler = SkSwizzler::Make(
-            this->getEncodedInfo(), nullptr, swizzlerInfo, options);
-    SkASSERT(swizzler);
-
     const int width = dstInfo.width();
     const int height = dstInfo.height();
     std::unique_ptr<dng_image> image(fDngImage->render(width, height));
@@ -737,6 +725,34 @@
     buffer.fPixelSize = sizeof(uint8_t);
     buffer.fRowStep = width * 3;
 
+    constexpr auto srcFormat = skcms_PixelFormat_RGB_888;
+    skcms_PixelFormat dstFormat;
+    switch (dstInfo.colorType()) {
+        case kRGBA_8888_SkColorType:
+            dstFormat = skcms_PixelFormat_RGBA_8888;
+            break;
+        case kBGRA_8888_SkColorType:
+            dstFormat = skcms_PixelFormat_BGRA_8888;
+            break;
+        case kRGBA_F16_SkColorType:
+            dstFormat = skcms_PixelFormat_RGBA_hhhh;
+            break;
+        case kRGB_565_SkColorType:
+            dstFormat = skcms_PixelFormat_RGB_565;
+            break;
+        default:
+            return kInvalidConversion;
+    }
+
+    const skcms_ICCProfile* const srcProfile = this->getEncodedInfo().profile();
+    skcms_ICCProfile dstProfileStorage;
+    const skcms_ICCProfile* dstProfile = nullptr;
+    if (auto cs = dstInfo.colorSpace()) {
+        cs->toProfile(&dstProfileStorage);
+        dstProfile = &dstProfileStorage;
+    }
+
+
     for (int i = 0; i < height; ++i) {
         buffer.fArea = dng_rect(i, 0, i + 1, width);
 
@@ -747,13 +763,14 @@
             return kIncompleteInput;
         }
 
-        if (this->colorXform()) {
-            swizzler->swizzle(xformBuffer.get(), &srcRow[0]);
-
-            this->applyColorXform(dstRow, xformBuffer.get(), dstInfo.width());
-        } else {
-            swizzler->swizzle(dstRow, &srcRow[0]);
+        if (!skcms_Transform(&srcRow[0], srcFormat, skcms_AlphaFormat_Unpremul, srcProfile,
+                             dstRow,     dstFormat, skcms_AlphaFormat_Unpremul, dstProfile,
+                             dstInfo.width())) {
+            SkDebugf("failed to transform\n");
+            *rowsDecoded = i;
+            return kInternalError;
         }
+
         dstRow = SkTAddOffset<void>(dstRow, dstRowBytes);
     }
     return kSuccess;
diff --git a/src/codec/SkRawCodec.h b/src/codec/SkRawCodec.h
index c258ac1..fb8e338 100644
--- a/src/codec/SkRawCodec.h
+++ b/src/codec/SkRawCodec.h
@@ -45,6 +45,10 @@
 
     bool onDimensionsSupported(const SkISize&) override;
 
+    // SkCodec only applies the colorXform if it's necessary for color space
+    // conversion. SkRawCodec will always convert, so tell SkCodec not to.
+    bool usesColorXform() const override { return false; }
+
 private:
 
     /*