diff --git a/gn/core.gni b/gn/core.gni
index 6696887..254ca94 100644
--- a/gn/core.gni
+++ b/gn/core.gni
@@ -75,11 +75,8 @@
   "$_src/core/SkColorMatrixFilterRowMajor255.cpp",
   "$_src/core/SkColorMatrixFilterRowMajor255.h",
   "$_src/core/SkColorSpace.cpp",
-  "$_src/core/SkColorSpace_A2B.cpp",
-  "$_src/core/SkColorSpace_A2B.h",
   "$_src/core/SkColorSpace_XYZ.cpp",
   "$_src/core/SkColorSpace_XYZ.h",
-  "$_src/core/SkColorSpace_ICC.cpp",
   "$_src/core/SkColorSpaceXform.cpp",
   "$_src/core/SkColorSpaceXformCanvas.cpp",
   "$_src/core/SkColorSpaceXformSteps.cpp",
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h
index eaafc25..7ad2f10 100644
--- a/include/core/SkColorSpace.h
+++ b/include/core/SkColorSpace.h
@@ -127,11 +127,6 @@
     static sk_sp<SkColorSpace> MakeRGB(SkGammaNamed gammaNamed, const SkMatrix44& toXYZD50);
 
     /**
-     *  Create an SkColorSpace from an ICC profile.
-     */
-    static sk_sp<SkColorSpace> MakeICC(const void*, size_t);
-
-    /**
      *  Create an SkColorSpace from a parsed (skcms) ICC profile.
      */
     static sk_sp<SkColorSpace> Make(const skcms_ICCProfile&);
@@ -141,16 +136,6 @@
      */
     void toProfile(skcms_ICCProfile*) const;
 
-    /**
-     *  Types of colorspaces.
-     */
-    enum Type {
-        kRGB_Type,
-        kCMYK_Type,
-        kGray_Type,
-    };
-    Type type() const;
-
     SkGammaNamed gammaNamed() const;
 
     /**
@@ -265,9 +250,6 @@
     virtual bool onGammaCloseToSRGB() const = 0;
     virtual bool onGammaIsLinear() const = 0;
     virtual bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const = 0;
-    virtual bool onIsCMYK() const { return false; }
-
-    virtual const SkData* onProfileData() const { return nullptr; }
 
     using INHERITED = SkRefCnt;
 };
diff --git a/site/user/sample/color.md b/site/user/sample/color.md
index 5870b03..eb9df66 100644
--- a/site/user/sample/color.md
+++ b/site/user/sample/color.md
@@ -80,9 +80,6 @@
 	
 	// Choose a common gamut and a common transfer function
 	sk_sp<SkColorSpace> MakeRGB(RenderTargetGamma, Gamut);
-	
-	// Create a color space from an ICC profile
-	sk_sp<SkColorSpace> MakeICC();
 
 Starting with **sources** (the things that you draw), there are a number of ways to make sure
 that they are tagged with a color space.
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 239f98a..81747e9 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -9,6 +9,7 @@
 #include "SkColorSpace_XYZ.h"
 #include "SkColorSpacePriv.h"
 #include "SkPoint3.h"
+#include "SkTemplates.h"
 #include <new>
 
 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const {
@@ -127,7 +128,7 @@
             break;
     }
 
-    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed, toXYZD50));
+    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed, nullptr, toXYZD50));
 }
 
 sk_sp<SkColorSpace> SkColorSpace::MakeRGB(RenderTargetGamma gamma, const SkMatrix44& toXYZD50) {
@@ -159,18 +160,7 @@
         return SkColorSpace::MakeRGB(kLinear_SkGammaNamed, toXYZD50);
     }
 
-    void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpaceTransferFn));
-    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
-    SkColorSpaceTransferFn* fn = SkTAddOffset<SkColorSpaceTransferFn>(memory, sizeof(SkGammas));
-    *fn = coeffs;
-    SkGammas::Data data;
-    data.fParamOffset = 0;
-    for (int channel = 0; channel < 3; ++channel) {
-        gammas->fType[channel] = SkGammas::Type::kParam_Type;
-        gammas->fData[channel] = data;
-    }
-    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed,
-                                                    std::move(gammas), toXYZD50, nullptr));
+    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed, &coeffs, toXYZD50));
 }
 
 sk_sp<SkColorSpace> SkColorSpace::MakeRGB(RenderTargetGamma gamma, Gamut gamut) {
@@ -189,7 +179,7 @@
     SkMatrix44 m44(SkMatrix44::kUninitialized_Constructor);
     m44.set3x3RowMajorf(to_xyz);
     (void)m44.getType();  // Force typemask to be computed to avoid races.
-    return new SkColorSpace_XYZ(gamma, m44);
+    return new SkColorSpace_XYZ(gamma, nullptr, m44);
 }
 
 SkColorSpace* sk_srgb_singleton() {
@@ -211,14 +201,6 @@
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
-SkColorSpace::Type SkColorSpace::type() const {
-    const SkMatrix44* m = this->toXYZD50();
-    if (m) {
-        return m->isScale() ? kGray_Type : kRGB_Type;
-    }
-    return this->onIsCMYK() ? kCMYK_Type : kRGB_Type;
-}
-
 SkGammaNamed SkColorSpace::gammaNamed() const {
     return this->onGammaNamed();
 }
@@ -289,6 +271,7 @@
      *  If kICC_Flag is set, we will write an ICC profile after the header.
      *  The ICC profile will be written as a uint32 size, followed immediately
      *  by the data (padded to 4 bytes).
+     *  DEPRECATED / UNUSED
      */
     static constexpr uint8_t kICC_Flag        = 1 << 1;
 
@@ -324,87 +307,61 @@
 };
 
 size_t SkColorSpace::writeToMemory(void* memory) const {
-    // Start by trying the serialization fast path.  If we haven't saved ICC profile data,
-    // we must have a profile that we can serialize easily.
-    if (!this->onProfileData()) {
-        // Profile data is mandatory for A2B0 color spaces, so we must be XYZ.
-        SkASSERT(this->toXYZD50());
-        // If we have a named profile, only write the enum.
-        const SkGammaNamed gammaNamed = this->gammaNamed();
-        if (this == sk_srgb_singleton()) {
-            if (memory) {
-                *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(
-                        k0_Version, kSRGB_NamedColorSpace, gammaNamed, 0);
-            }
-            return sizeof(ColorSpaceHeader);
-        } else if (this == sk_srgb_linear_singleton()) {
-            if (memory) {
-                *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(
-                        k0_Version, kSRGBLinear_NamedColorSpace, gammaNamed, 0);
-            }
-            return sizeof(ColorSpaceHeader);
+    // If we have a named profile, only write the enum.
+    const SkGammaNamed gammaNamed = this->gammaNamed();
+    if (this == sk_srgb_singleton()) {
+        if (memory) {
+            *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(
+                    k0_Version, kSRGB_NamedColorSpace, gammaNamed, 0);
         }
+        return sizeof(ColorSpaceHeader);
+    } else if (this == sk_srgb_linear_singleton()) {
+        if (memory) {
+            *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(
+                    k0_Version, kSRGBLinear_NamedColorSpace, gammaNamed, 0);
+        }
+        return sizeof(ColorSpaceHeader);
+    }
 
-        // If we have a named gamma, write the enum and the matrix.
-        switch (gammaNamed) {
-            case kSRGB_SkGammaNamed:
-            case k2Dot2Curve_SkGammaNamed:
-            case kLinear_SkGammaNamed: {
-                if (memory) {
-                    *((ColorSpaceHeader*) memory) =
-                            ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
-                                                   ColorSpaceHeader::kMatrix_Flag);
-                    memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
-                    this->toXYZD50()->as3x4RowMajorf((float*) memory);
-                }
-                return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
+    // If we have a named gamma, write the enum and the matrix.
+    switch (gammaNamed) {
+        case kSRGB_SkGammaNamed:
+        case k2Dot2Curve_SkGammaNamed:
+        case kLinear_SkGammaNamed: {
+            if (memory) {
+                *((ColorSpaceHeader*) memory) =
+                        ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
+                                                ColorSpaceHeader::kMatrix_Flag);
+                memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
+                this->toXYZD50()->as3x4RowMajorf((float*) memory);
             }
-            default: {
-                SkColorSpaceTransferFn transferFn;
-                SkAssertResult(this->isNumericalTransferFn(&transferFn));
+            return sizeof(ColorSpaceHeader) + 12 * sizeof(float);
+        }
+        default: {
+            SkColorSpaceTransferFn transferFn;
+            SkAssertResult(this->isNumericalTransferFn(&transferFn));
 
-                if (memory) {
-                    *((ColorSpaceHeader*) memory) =
-                            ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
-                                                   ColorSpaceHeader::kTransferFn_Flag);
-                    memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
+            if (memory) {
+                *((ColorSpaceHeader*) memory) =
+                        ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed,
+                                                ColorSpaceHeader::kTransferFn_Flag);
+                memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
 
-                    *(((float*) memory) + 0) = transferFn.fA;
-                    *(((float*) memory) + 1) = transferFn.fB;
-                    *(((float*) memory) + 2) = transferFn.fC;
-                    *(((float*) memory) + 3) = transferFn.fD;
-                    *(((float*) memory) + 4) = transferFn.fE;
-                    *(((float*) memory) + 5) = transferFn.fF;
-                    *(((float*) memory) + 6) = transferFn.fG;
-                    memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
+                *(((float*) memory) + 0) = transferFn.fA;
+                *(((float*) memory) + 1) = transferFn.fB;
+                *(((float*) memory) + 2) = transferFn.fC;
+                *(((float*) memory) + 3) = transferFn.fD;
+                *(((float*) memory) + 4) = transferFn.fE;
+                *(((float*) memory) + 5) = transferFn.fF;
+                *(((float*) memory) + 6) = transferFn.fG;
+                memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
 
-                    this->toXYZD50()->as3x4RowMajorf((float*) memory);
-                }
-
-                return sizeof(ColorSpaceHeader) + 19 * sizeof(float);
+                this->toXYZD50()->as3x4RowMajorf((float*) memory);
             }
+
+            return sizeof(ColorSpaceHeader) + 19 * sizeof(float);
         }
     }
-
-    // Otherwise, serialize the ICC data.
-    size_t profileSize = this->onProfileData()->size();
-    if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) {
-        return 0;
-    }
-
-    if (memory) {
-        *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(k0_Version, 0,
-                                                               kNonStandard_SkGammaNamed,
-                                                               ColorSpaceHeader::kICC_Flag);
-        memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
-
-        *((uint32_t*) memory) = (uint32_t) SkAlign4(profileSize);
-        memory = SkTAddOffset<void>(memory, sizeof(uint32_t));
-
-        memcpy(memory, this->onProfileData()->data(), profileSize);
-        memset(SkTAddOffset<void>(memory, profileSize), 0, SkAlign4(profileSize) - profileSize);
-    }
-    return sizeof(ColorSpaceHeader) + sizeof(uint32_t) + SkAlign4(profileSize);
 }
 
 sk_sp<SkData> SkColorSpace::serialize() const {
@@ -455,18 +412,8 @@
 
     switch (header.fFlags) {
         case ColorSpaceHeader::kICC_Flag: {
-            if (length < sizeof(uint32_t)) {
-                return nullptr;
-            }
-
-            uint32_t profileSize = *((uint32_t*) data);
-            data = SkTAddOffset<const void>(data, sizeof(uint32_t));
-            length -= sizeof(uint32_t);
-            if (length < profileSize) {
-                return nullptr;
-            }
-
-            return MakeICC(data, profileSize);
+            // Deprecated and unsupported code path
+            return nullptr;
         }
         case ColorSpaceHeader::kTransferFn_Flag: {
             if (length < 19 * sizeof(float)) {
@@ -501,18 +448,6 @@
         return false;
     }
 
-    const SkData* srcData = src->onProfileData();
-    const SkData* dstData = dst->onProfileData();
-    if (srcData || dstData) {
-        if (srcData && dstData) {
-            return srcData->size() == dstData->size() &&
-                   0 == memcmp(srcData->data(), dstData->data(), srcData->size());
-        }
-
-        return false;
-    }
-
-    // Profiles are mandatory for A2B0 color spaces, so these must be XYZ
     if (src->gammaNamed() != dst->gammaNamed()) {
         return false;
     }
@@ -528,6 +463,7 @@
             return false;
         default:
             // It is unlikely that we will reach this case.
+            // TODO: Simplify this case now that color spaces have one representation.
             sk_sp<SkData> serializedSrcData = src->serialize();
             sk_sp<SkData> serializedDstData = dst->serialize();
             return serializedSrcData->size() == serializedDstData->size() &&
diff --git a/src/core/SkColorSpacePriv.h b/src/core/SkColorSpacePriv.h
index 7df6c97..898a61e 100644
--- a/src/core/SkColorSpacePriv.h
+++ b/src/core/SkColorSpacePriv.h
@@ -188,43 +188,6 @@
     return linearExp || linearFn;
 }
 
-static inline bool is_just_gamma(const SkColorSpaceTransferFn& coeffs) {
-    return transfer_fn_almost_equal(coeffs.fA, 1.0f)
-        && transfer_fn_almost_equal(coeffs.fB, 0.0f)
-        && transfer_fn_almost_equal(coeffs.fC, 0.0f)
-        && transfer_fn_almost_equal(coeffs.fD, 0.0f)
-        && transfer_fn_almost_equal(coeffs.fE, 0.0f)
-        && transfer_fn_almost_equal(coeffs.fF, 0.0f);
-}
-
-
-static inline void value_to_parametric(SkColorSpaceTransferFn* coeffs, float exponent) {
-    coeffs->fA = 1.0f;
-    coeffs->fB = 0.0f;
-    coeffs->fC = 0.0f;
-    coeffs->fD = 0.0f;
-    coeffs->fE = 0.0f;
-    coeffs->fF = 0.0f;
-    coeffs->fG = exponent;
-}
-
-static inline bool named_to_parametric(SkColorSpaceTransferFn* coeffs,
-                                       SkGammaNamed gammaNamed) {
-    switch (gammaNamed) {
-        case kSRGB_SkGammaNamed:
-            *coeffs = gSRGB_TransferFn;
-            return true;
-        case k2Dot2Curve_SkGammaNamed:
-            *coeffs = g2Dot2_TransferFn;
-            return true;
-        case kLinear_SkGammaNamed:
-            *coeffs = gLinear_TransferFn;
-            return true;
-        default:
-            return false;
-    }
-}
-
 // Return raw pointers to commonly used SkColorSpaces.
 // No need to ref/unref these, but if you do, do it in pairs.
 SkColorSpace* sk_srgb_singleton();
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 61a37ad..8596abf 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -77,23 +77,19 @@
 }
 
 void SkColorSpace::toProfile(skcms_ICCProfile* profile) const {
-    if (auto blob = this->onProfileData()) {
-        SkAssertResult(skcms_Parse(blob->data(), blob->size(), profile));
-    } else {
-        SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
-        SkColorSpaceTransferFn tf;
-        SkAssertResult(this->toXYZD50(&toXYZ) && this->isNumericalTransferFn(&tf));
+    SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor);
+    SkColorSpaceTransferFn tf;
+    SkAssertResult(this->toXYZD50(&toXYZ) && this->isNumericalTransferFn(&tf));
 
-        skcms_Matrix3x3 m = { {
-            { toXYZ.get(0, 0), toXYZ.get(0, 1), toXYZ.get(0, 2) },
-            { toXYZ.get(1, 0), toXYZ.get(1, 1), toXYZ.get(1, 2) },
-            { toXYZ.get(2, 0), toXYZ.get(2, 1), toXYZ.get(2, 2) },
-        } };
+    skcms_Matrix3x3 m = { {
+        { toXYZ.get(0, 0), toXYZ.get(0, 1), toXYZ.get(0, 2) },
+        { toXYZ.get(1, 0), toXYZ.get(1, 1), toXYZ.get(1, 2) },
+        { toXYZ.get(2, 0), toXYZ.get(2, 1), toXYZ.get(2, 2) },
+    } };
 
-        skcms_Init(profile);
-        skcms_SetTransferFunction(profile, (const skcms_TransferFunction*)&tf);
-        skcms_SetXYZD50(profile, &m);
-    }
+    skcms_Init(profile);
+    skcms_SetTransferFunction(profile, (const skcms_TransferFunction*)&tf);
+    skcms_SetXYZD50(profile, &m);
 }
 
 std::unique_ptr<SkColorSpaceXform> SkMakeColorSpaceXform(SkColorSpace* src, SkColorSpace* dst) {
diff --git a/src/core/SkColorSpace_A2B.cpp b/src/core/SkColorSpace_A2B.cpp
deleted file mode 100644
index 295f28f..0000000
--- a/src/core/SkColorSpace_A2B.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkColorSpace_A2B.h"
-
-SkColorSpace_A2B::SkColorSpace_A2B(SkColorSpace::Type iccType, std::vector<Element> elements,
-                                   PCS pcs, sk_sp<SkData> profileData)
-    : fProfileData(std::move(profileData))
-    , fICCType(iccType)
-    , fElements(std::move(elements))
-    , fPCS(pcs)
-{
-    SkASSERT(SkColorSpace::kRGB_Type == iccType || SkColorSpace::kCMYK_Type == iccType);
-}
diff --git a/src/core/SkColorSpace_A2B.h b/src/core/SkColorSpace_A2B.h
deleted file mode 100644
index 48e8a70..0000000
--- a/src/core/SkColorSpace_A2B.h
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkColorSpace_A2B_DEFINED
-#define SkColorSpace_A2B_DEFINED
-
-#include "SkColorLookUpTable.h"
-#include "SkColorSpace.h"
-#include "SkGammas.h"
-#include <vector>
-
-// An alternative SkColorSpace that represents all the color space data that
-// is stored in an A2B0 ICC tag. This allows us to use alternative profile
-// connection spaces (CIELAB instead of just CIEXYZ), use color-lookup-tables
-// to do color space transformations not representable as TRC functions or
-// matrix operations, as well as have multiple TRC functions. The CLUT also
-// allows conversion between non-3-channel input color spaces ie CMYK(4) to
-// a workable PCS (ie XYZ).
-//
-// AtoBType, lut8Type and lut16Type A2B0 tag types are supported. There are
-// also MPET (multi-processing-elements) A2B0 tags in the standard which allow
-// you to combine these 3 primitives (TRC, CLUT, matrix) in any order/quantity.
-// MPET tags are currently unsupported by the MakeICC parser, could be supported
-// here by the nature of the design.
-class SkColorSpace_A2B : public SkColorSpace {
-public:
-    const SkMatrix44* onToXYZD50() const override {
-        // the matrix specified in A2B0 profiles is not necessarily
-        // a to-XYZ matrix, as to-Lab is supported as well so returning
-        // that could be misleading. Additionally, B-curves are applied
-        // after the matrix is, but a toXYZD50 matrix is the last thing
-        // applied in order to get into the (XYZ) profile connection space.
-        return nullptr;
-    }
-
-    uint32_t onToXYZD50Hash() const override {
-        // See onToXYZD50()'s comment.
-        return 0;
-    }
-
-    const SkMatrix44* onFromXYZD50() const override {
-        // See onToXYZD50()'s comment. Also, A2B0 profiles are not supported
-        // as destination color spaces, so an inverse matrix is never wanted.
-        return nullptr;
-    }
-
-    // There is no single gamma curve in an A2B0 profile
-    SkGammaNamed onGammaNamed() const override { return kNonStandard_SkGammaNamed; }
-    bool onGammaCloseToSRGB() const override { return false; }
-    bool onGammaIsLinear() const override { return false; }
-    bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override { return false; }
-
-    bool onIsCMYK() const override { return SkColorSpace::kCMYK_Type == fICCType; }
-
-    const SkData* onProfileData() const override { return fProfileData.get(); }
-
-    sk_sp<SkColorSpace> makeLinearGamma() const override {
-        // TODO: Analyze the extrema of our projection into XYZ and use suitable primaries?
-        // For now, just fall back to a default, because we don't have a good answer.
-        return SkColorSpace::MakeSRGBLinear();
-    }
-
-    sk_sp<SkColorSpace> makeSRGBGamma() const override {
-        // See comment in makeLinearGamma
-        return SkColorSpace::MakeSRGB();
-    }
-
-    class Element {
-    public:
-        Element(SkGammaNamed gammaNamed, int channelCount)
-            : fType(Type::kGammaNamed)
-            , fGammaNamed(gammaNamed)
-            , fMatrix(SkMatrix44::kUninitialized_Constructor)
-            , fInputChannels(channelCount)
-            , fOutputChannels(channelCount) {
-            SkASSERT(gammaNamed != kNonStandard_SkGammaNamed);
-        }
-
-        explicit Element(sk_sp<SkGammas> gammas)
-            : fType(Type::kGammas)
-            , fGammas(std::move(gammas))
-            , fMatrix(SkMatrix44::kUninitialized_Constructor)
-            , fInputChannels(fGammas->channels())
-            , fOutputChannels(fGammas->channels()) {
-            for (int i = 0; i < fGammas->channels(); ++i) {
-                if (SkGammas::Type::kTable_Type == fGammas->type(i)) {
-                    SkASSERT(fGammas->data(i).fTable.fSize >= 2);
-                }
-            }
-        }
-
-        explicit Element(sk_sp<SkColorLookUpTable> colorLUT)
-            : fType(Type::kCLUT)
-            , fCLUT(std::move(colorLUT))
-            , fMatrix(SkMatrix44::kUninitialized_Constructor)
-            , fInputChannels(fCLUT->inputChannels())
-            , fOutputChannels(fCLUT->outputChannels())
-        {}
-
-        explicit Element(const SkMatrix44& matrix)
-            : fType(Type::kMatrix)
-            , fMatrix(matrix)
-            , fInputChannels(3)
-            , fOutputChannels(3)
-        {}
-
-        enum class Type {
-            kGammaNamed,
-            kGammas,
-            kCLUT,
-            kMatrix
-        };
-
-        Type type() const { return fType; }
-
-        SkGammaNamed gammaNamed() const {
-            SkASSERT(Type::kGammaNamed == fType);
-            return fGammaNamed;
-        }
-
-        const SkGammas& gammas() const {
-            SkASSERT(Type::kGammas == fType);
-            return *fGammas;
-        }
-
-        const SkColorLookUpTable& colorLUT() const {
-            SkASSERT(Type::kCLUT == fType);
-            return *fCLUT;
-        }
-
-        const SkMatrix44& matrix() const {
-            SkASSERT(Type::kMatrix == fType);
-            return fMatrix;
-        }
-
-        int inputChannels() const { return fInputChannels; }
-
-        int outputChannels() const { return fOutputChannels; }
-
-    private:
-        Type                      fType;
-        SkGammaNamed              fGammaNamed;
-        sk_sp<SkGammas>           fGammas;
-        sk_sp<SkColorLookUpTable> fCLUT;
-        SkMatrix44                fMatrix;
-        int                       fInputChannels;
-        int                       fOutputChannels;
-    };
-    const Element& element(int i) const { return fElements[i]; }
-
-    int count() const { return (int)fElements.size(); }
-
-    // the intermediate profile connection space that this color space
-    // represents the transformation to
-    enum class PCS : uint8_t {
-        kLAB, // CIELAB
-        kXYZ  // CIEXYZ
-    };
-
-    PCS pcs() const { return fPCS; }
-
-    SkColorSpace::Type iccType() const { return fICCType; }
-
-    SkColorSpace_A2B(SkColorSpace::Type iccType, std::vector<Element> elements, PCS pcs,
-                     sk_sp<SkData> profileData);
-
-private:
-    sk_sp<SkData>        fProfileData;
-
-    SkColorSpace::Type   fICCType;
-    std::vector<Element> fElements;
-    PCS                  fPCS;
-
-    friend class ColorSpaceXformTest;
-};
-
-#endif
diff --git a/src/core/SkColorSpace_ICC.cpp b/src/core/SkColorSpace_ICC.cpp
deleted file mode 100644
index 3cc82ed..0000000
--- a/src/core/SkColorSpace_ICC.cpp
+++ /dev/null
@@ -1,1556 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#include "SkAutoMalloc.h"
-#include "SkColorSpace.h"
-#include "SkColorSpacePriv.h"
-#include "SkColorSpace_A2B.h"
-#include "SkColorSpace_XYZ.h"
-#include "SkEndian.h"
-#include "SkFixed.h"
-#include "SkICCPriv.h"
-#include "SkTemplates.h"
-#include "../../third_party/skcms/skcms.h"
-
-#define return_if_false(pred, msg)                                   \
-    do {                                                             \
-        if (!(pred)) {                                               \
-            SkColorSpacePrintf("Invalid ICC Profile: %s.\n", (msg)); \
-            return false;                                            \
-        }                                                            \
-    } while (0)
-
-#define return_null(msg)                                             \
-    do {                                                             \
-        SkColorSpacePrintf("Invalid ICC Profile: %s.\n", (msg));     \
-        return nullptr;                                              \
-    } while (0)
-
-static uint16_t read_big_endian_u16(const uint8_t* ptr) {
-    return ptr[0] << 8 | ptr[1];
-}
-
-static uint32_t read_big_endian_u32(const uint8_t* ptr) {
-    return ptr[0] << 24 | ptr[1] << 16 | ptr[2] << 8 | ptr[3];
-}
-
-static int32_t read_big_endian_i32(const uint8_t* ptr) {
-    return (int32_t) read_big_endian_u32(ptr);
-}
-
-static constexpr float kWhitePointD50[] = { 0.96420f, 1.00000f, 0.82491f, };
-
-struct ICCProfileHeader {
-    uint32_t fSize;
-
-    // No reason to care about the preferred color management module (ex: Adobe, Apple, etc.).
-    // We're always going to use this one.
-    uint32_t fCMMType_ignored;
-
-    uint32_t fVersion;
-    uint32_t fProfileClass;
-    uint32_t fInputColorSpace;
-    uint32_t fPCS;
-    uint32_t fDateTime_ignored[3];
-    uint32_t fSignature;
-
-    // Indicates the platform that this profile was created for (ex: Apple, Microsoft).  This
-    // doesn't really matter to us.
-    uint32_t fPlatformTarget_ignored;
-
-    // Flags can indicate:
-    // (1) Whether this profile was embedded in a file.  This flag is consistently wrong.
-    //     Ex: The profile came from a file but indicates that it did not.
-    // (2) Whether we are allowed to use the profile independently of the color data.  If set,
-    //     this may allow us to use the embedded profile for testing separate from the original
-    //     image.
-    uint32_t fFlags_ignored;
-
-    // We support many output devices.  It doesn't make sense to think about the attributes of
-    // the device in the context of the image profile.
-    uint32_t fDeviceManufacturer_ignored;
-    uint32_t fDeviceModel_ignored;
-    uint32_t fDeviceAttributes_ignored[2];
-
-    uint32_t fRenderingIntent;
-    int32_t  fIlluminantXYZ[3];
-
-    // We don't care who created the profile.
-    uint32_t fCreator_ignored;
-
-    // This is an MD5 checksum.  Could be useful for checking if profiles are equal.
-    uint32_t fProfileId_ignored[4];
-
-    // Reserved for future use.
-    uint32_t fReserved_ignored[7];
-
-    uint32_t fTagCount;
-
-    void init(const uint8_t* src, size_t len) {
-        SkASSERT(kICCHeaderSize == sizeof(*this));
-
-        uint32_t* dst = (uint32_t*) this;
-        for (uint32_t i = 0; i < kICCHeaderSize / 4; i++, src+=4) {
-            dst[i] = read_big_endian_u32(src);
-        }
-    }
-
-    bool valid() const {
-        return_if_false(fSize >= kICCHeaderSize, "Size is too small");
-
-        uint8_t majorVersion = fVersion >> 24;
-        return_if_false(majorVersion <= 4, "Unsupported version");
-
-        // These are the four basic classes of profiles that we might expect to see embedded
-        // in images.  Additional classes exist, but they generally are used as a convenient
-        // way for CMMs to store calculated transforms.
-        return_if_false(fProfileClass == kDisplay_Profile ||
-                        fProfileClass == kInput_Profile ||
-                        fProfileClass == kOutput_Profile ||
-                        fProfileClass == kColorSpace_Profile,
-                        "Unsupported profile");
-
-        switch (fInputColorSpace) {
-            case kRGB_ColorSpace:
-                SkColorSpacePrintf("RGB Input Color Space");
-                break;
-            case kCMYK_ColorSpace:
-                SkColorSpacePrintf("CMYK Input Color Space\n");
-                break;
-            case kGray_ColorSpace:
-                SkColorSpacePrintf("Gray Input Color Space\n");
-                break;
-            default:
-                SkColorSpacePrintf("Unsupported Input Color Space: %c%c%c%c\n",
-                                   (fInputColorSpace>>24)&0xFF, (fInputColorSpace>>16)&0xFF,
-                                   (fInputColorSpace>> 8)&0xFF, (fInputColorSpace>> 0)&0xFF);
-                return false;
-        }
-
-        switch (fPCS) {
-            case kXYZ_PCSSpace:
-                SkColorSpacePrintf("XYZ PCS\n");
-                break;
-            case kLAB_PCSSpace:
-                SkColorSpacePrintf("Lab PCS\n");
-                break;
-            default:
-                // ICC currently (V4.3) only specifices XYZ and Lab PCS spaces
-                SkColorSpacePrintf("Unsupported PCS space: %c%c%c%c\n",
-                                   (fPCS>>24)&0xFF, (fPCS>>16)&0xFF,
-                                   (fPCS>> 8)&0xFF, (fPCS>> 0)&0xFF);
-                return false;
-        }
-
-        return_if_false(fSignature == kACSP_Signature, "Bad signature");
-
-        // TODO (msarett):
-        // Should we treat different rendering intents differently?
-        // Valid rendering intents include kPerceptual (0), kRelative (1),
-        // kSaturation (2), and kAbsolute (3).
-        if (fRenderingIntent > 3) {
-            // Warn rather than fail here.  Occasionally, we see perfectly
-            // normal profiles with wacky rendering intents.
-            SkColorSpacePrintf("Warning, bad rendering intent.\n");
-        }
-
-        return_if_false(
-                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[0]), kWhitePointD50[0]) &&
-                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[1]), kWhitePointD50[1]) &&
-                color_space_almost_equal(SkFixedToFloat(fIlluminantXYZ[2]), kWhitePointD50[2]),
-                "Illuminant must be D50");
-
-        return_if_false(fTagCount <= 100, "Too many tags");
-
-        return true;
-    }
-};
-
-template <class T>
-static bool safe_add(T arg1, T arg2, size_t* result) {
-    SkASSERT(arg1 >= 0);
-    SkASSERT(arg2 >= 0);
-    if (arg1 >= 0 && arg2 <= std::numeric_limits<T>::max() - arg1) {
-        T sum = arg1 + arg2;
-        if (sum <= std::numeric_limits<size_t>::max()) {
-            *result = static_cast<size_t>(sum);
-            return true;
-        }
-    }
-    return false;
-}
-
-static bool safe_mul(uint32_t arg1, uint32_t arg2, uint32_t* result) {
-    uint64_t product64 = (uint64_t) arg1 * (uint64_t) arg2;
-    uint32_t product32 = (uint32_t) product64;
-    if (product32 != product64) {
-        return false;
-    }
-
-    *result = product32;
-    return true;
-}
-
-struct ICCTag {
-    uint32_t fSignature;
-    uint32_t fOffset;
-    uint32_t fLength;
-
-    const uint8_t* init(const uint8_t* src) {
-        fSignature = read_big_endian_u32(src);
-        fOffset = read_big_endian_u32(src + 4);
-        fLength = read_big_endian_u32(src + 8);
-        return src + 12;
-    }
-
-    bool valid(size_t len) {
-        size_t tagEnd;
-        return_if_false(safe_add(fOffset, fLength, &tagEnd),
-                        "Tag too large, overflows integer addition");
-        return_if_false(tagEnd <= len, "Tag too large for ICC profile");
-        return true;
-    }
-
-    const uint8_t* addr(const uint8_t* src) const {
-        return src + fOffset;
-    }
-
-    static const ICCTag* Find(const ICCTag tags[], int count, uint32_t signature) {
-        for (int i = 0; i < count; ++i) {
-            if (tags[i].fSignature == signature) {
-                return &tags[i];
-            }
-        }
-        return nullptr;
-    }
-};
-
-static bool load_xyz(float dst[3], const uint8_t* src, size_t len) {
-    if (len < 20) {
-        SkColorSpacePrintf("XYZ tag is too small (%d bytes)", len);
-        return false;
-    }
-
-    dst[0] = SkFixedToFloat(read_big_endian_i32(src + 8));
-    dst[1] = SkFixedToFloat(read_big_endian_i32(src + 12));
-    dst[2] = SkFixedToFloat(read_big_endian_i32(src + 16));
-    SkColorSpacePrintf("XYZ %g %g %g\n", dst[0], dst[1], dst[2]);
-    return true;
-}
-
-static SkGammas::Type set_gamma_value(SkGammas::Data* data, float value) {
-    if (color_space_almost_equal(2.2f, value)) {
-        data->fNamed = k2Dot2Curve_SkGammaNamed;
-        return SkGammas::Type::kNamed_Type;
-    }
-
-    if (color_space_almost_equal(1.0f, value)) {
-        data->fNamed = kLinear_SkGammaNamed;
-        return SkGammas::Type::kNamed_Type;
-    }
-
-    if (color_space_almost_equal(0.0f, value)) {
-        return SkGammas::Type::kNone_Type;
-    }
-
-    data->fValue = value;
-    return SkGammas::Type::kValue_Type;
-}
-
-static float read_big_endian_16_dot_16(const uint8_t buf[4]) {
-    // It just so happens that SkFixed is also 16.16!
-    return SkFixedToFloat(read_big_endian_i32(buf));
-}
-
-/**
- *  @param outData     Set to the appropriate value on success.  If we have table or
- *                     parametric gamma, it is the responsibility of the caller to set
- *                     fOffset.
- *  @param outParams   If this is a parametric gamma, this is set to the appropriate
- *                     parameters on success.
- *  @param outTagBytes Will be set to the length of the tag on success.
- *  @src               Pointer to tag data.
- *  @len               Length of tag data in bytes.
- *
- *  @return            kNone_Type on failure, otherwise the type of the gamma tag.
- */
-static SkGammas::Type parse_gamma(SkGammas::Data* outData, SkColorSpaceTransferFn* outParams,
-                                  size_t* outTagBytes, const uint8_t* src, size_t len) {
-    if (len < 12) {
-        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-        return SkGammas::Type::kNone_Type;
-    }
-
-    // In the case of consecutive gamma tags, we need to count the number of bytes in the
-    // tag, so that we can move on to the next tag.
-    size_t tagBytes;
-
-    uint32_t type = read_big_endian_u32(src);
-    // Bytes 4-7 are reserved and should be set to zero.
-    switch (type) {
-        case kTAG_CurveType: {
-            uint32_t count = read_big_endian_u32(src + 8);
-
-            // tagBytes = 12 + 2 * count
-            // We need to do safe addition here to avoid integer overflow.
-            if (!safe_add(count, count, &tagBytes) ||
-                !safe_add((size_t) 12, tagBytes, &tagBytes))
-            {
-                SkColorSpacePrintf("Invalid gamma count");
-                return SkGammas::Type::kNone_Type;
-            }
-
-            if (len < tagBytes) {
-                SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                return SkGammas::Type::kNone_Type;
-            }
-            *outTagBytes = tagBytes;
-
-            if (0 == count) {
-                // Some tags require a gamma curve, but the author doesn't actually want
-                // to transform the data.  In this case, it is common to see a curve with
-                // a count of 0.
-                outData->fNamed = kLinear_SkGammaNamed;
-                return SkGammas::Type::kNamed_Type;
-            }
-
-            const uint16_t* table = (const uint16_t*) (src + 12);
-            if (1 == count) {
-                // The table entry is the gamma (with a bias of 256).
-                float value = (read_big_endian_u16((const uint8_t*) table)) / 256.0f;
-                SkColorSpacePrintf("gamma %g\n", value);
-
-                return set_gamma_value(outData, value);
-            }
-
-            // This optimization is especially important for A2B profiles, where we do
-            // not resize tables or interpolate lookups.
-            if (2 == count) {
-                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
-                        65535 == read_big_endian_u16((const uint8_t*) &table[1])) {
-                    outData->fNamed = kLinear_SkGammaNamed;
-                    return SkGammas::Type::kNamed_Type;
-                }
-            }
-
-            // Check for frequently occurring sRGB curves.
-            // We do this by sampling a few values and see if they match our expectation.
-            // A more robust solution would be to compare each value in this curve against
-            // an sRGB curve to see if we remain below an error threshold.  At this time,
-            // we haven't seen any images in the wild that make this kind of
-            // calculation necessary.  We encounter identical gamma curves over and
-            // over again, but relatively few variations.
-            if (1024 == count) {
-                // The magic values were chosen because they match both the very common
-                // HP sRGB gamma table and the less common Canon sRGB gamma table (which use
-                // different rounding rules).
-                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
-                        3366 == read_big_endian_u16((const uint8_t*) &table[257]) &&
-                        14116 == read_big_endian_u16((const uint8_t*) &table[513]) &&
-                        34318 == read_big_endian_u16((const uint8_t*) &table[768]) &&
-                        65535 == read_big_endian_u16((const uint8_t*) &table[1023])) {
-                    outData->fNamed = kSRGB_SkGammaNamed;
-                    return SkGammas::Type::kNamed_Type;
-                }
-            }
-
-            if (26 == count) {
-                // The magic values match a clever "minimum size" approach to representing sRGB.
-                // code.facebook.com/posts/411525055626587/under-the-hood-improving-facebook-photos
-                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
-                        3062 == read_big_endian_u16((const uint8_t*) &table[6]) &&
-                        12824 == read_big_endian_u16((const uint8_t*) &table[12]) &&
-                        31237 == read_big_endian_u16((const uint8_t*) &table[18]) &&
-                        65535 == read_big_endian_u16((const uint8_t*) &table[25])) {
-                    outData->fNamed = kSRGB_SkGammaNamed;
-                    return SkGammas::Type::kNamed_Type;
-                }
-            }
-
-            if (4096 == count) {
-                // The magic values were chosen because they match Nikon, Epson, and
-                // lcms2 sRGB gamma tables (all of which use different rounding rules).
-                if (0 == read_big_endian_u16((const uint8_t*) &table[0]) &&
-                        950 == read_big_endian_u16((const uint8_t*) &table[515]) &&
-                        3342 == read_big_endian_u16((const uint8_t*) &table[1025]) &&
-                        14079 == read_big_endian_u16((const uint8_t*) &table[2051]) &&
-                        65535 == read_big_endian_u16((const uint8_t*) &table[4095])) {
-                    outData->fNamed = kSRGB_SkGammaNamed;
-                    return SkGammas::Type::kNamed_Type;
-                }
-            }
-
-            // Otherwise, we will represent gamma with a table.
-            outData->fTable.fSize = count;
-            return SkGammas::Type::kTable_Type;
-        }
-        case kTAG_ParaCurveType: {
-            // Determine the format of the parametric curve tag.
-            uint16_t format = read_big_endian_u16(src + 8);
-            if (format > kGABCDEF_ParaCurveType) {
-                SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
-                return SkGammas::Type::kNone_Type;
-            }
-
-            if (kExponential_ParaCurveType == format) {
-                tagBytes = 12 + 4;
-                if (len < tagBytes) {
-                    SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                    return SkGammas::Type::kNone_Type;
-                }
-
-                // Y = X^g
-                float g = read_big_endian_16_dot_16(src + 12);
-
-                *outTagBytes = tagBytes;
-                return set_gamma_value(outData, g);
-            }
-
-            // Here's where the real parametric gammas start.  There are many
-            // permutations of the same equations.
-            //
-            // Y = (aX + b)^g + e  for X >= d
-            // Y = cX + f          otherwise
-            //
-            // We will fill in with zeros as necessary to always match the above form.
-            if (len < 24) {
-                SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                return SkGammas::Type::kNone_Type;
-            }
-            float g = read_big_endian_16_dot_16(src + 12);
-            float a = read_big_endian_16_dot_16(src + 16);
-            float b = read_big_endian_16_dot_16(src + 20);
-            float c = 0.0f, d = 0.0f, e = 0.0f, f = 0.0f;
-            switch(format) {
-                case kGAB_ParaCurveType:
-                    tagBytes = 12 + 12;
-
-                    // Y = (aX + b)^g  for X >= -b/a
-                    // Y = 0           otherwise
-                    d = -b / a;
-                    break;
-                case kGABC_ParaCurveType:
-                    tagBytes = 12 + 16;
-                    if (len < tagBytes) {
-                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                        return SkGammas::Type::kNone_Type;
-                    }
-
-                    // Y = (aX + b)^g + e  for X >= -b/a
-                    // Y = e               otherwise
-                    e = read_big_endian_16_dot_16(src + 24);
-                    d = -b / a;
-                    f = e;
-                    break;
-                case kGABDE_ParaCurveType:
-                    tagBytes = 12 + 20;
-                    if (len < tagBytes) {
-                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                        return SkGammas::Type::kNone_Type;
-                    }
-
-                    // Y = (aX + b)^g  for X >= d
-                    // Y = cX          otherwise
-                    c = read_big_endian_16_dot_16(src + 24);
-                    d = read_big_endian_16_dot_16(src + 28);
-                    break;
-                case kGABCDEF_ParaCurveType:
-                    tagBytes = 12 + 28;
-                    if (len < tagBytes) {
-                        SkColorSpacePrintf("gamma tag is too small (%d bytes)", len);
-                        return SkGammas::Type::kNone_Type;
-                    }
-
-                    // Y = (aX + b)^g + e  for X >= d
-                    // Y = cX + f          otherwise
-                    c = read_big_endian_16_dot_16(src + 24);
-                    d = read_big_endian_16_dot_16(src + 28);
-                    e = read_big_endian_16_dot_16(src + 32);
-                    f = read_big_endian_16_dot_16(src + 36);
-                    break;
-                default:
-                    SkASSERT(false);
-                    return SkGammas::Type::kNone_Type;
-            }
-
-            outParams->fG = g;
-            outParams->fA = a;
-            outParams->fB = b;
-            outParams->fC = c;
-            outParams->fD = d;
-            outParams->fE = e;
-            outParams->fF = f;
-
-            if (!is_valid_transfer_fn(*outParams)) {
-                return SkGammas::Type::kNone_Type;
-            }
-
-            if (is_almost_srgb(*outParams)) {
-                outData->fNamed = kSRGB_SkGammaNamed;
-                return SkGammas::Type::kNamed_Type;
-            }
-
-            if (is_almost_2dot2(*outParams)) {
-                outData->fNamed = k2Dot2Curve_SkGammaNamed;
-                return SkGammas::Type::kNamed_Type;
-            }
-
-            *outTagBytes = tagBytes;
-            return SkGammas::Type::kParam_Type;
-        }
-        default:
-            SkColorSpacePrintf("Unsupported gamma tag type %d\n", type);
-            return SkGammas::Type::kNone_Type;
-    }
-}
-
-/**
- *  Returns the additional size in bytes needed to store the gamma tag.
- */
-static size_t gamma_alloc_size(SkGammas::Type type, const SkGammas::Data& data) {
-    switch (type) {
-        case SkGammas::Type::kNamed_Type:
-        case SkGammas::Type::kValue_Type:
-            return 0;
-        case SkGammas::Type::kTable_Type:
-            return sizeof(float) * data.fTable.fSize;
-        case SkGammas::Type::kParam_Type:
-            return sizeof(SkColorSpaceTransferFn);
-        default:
-            SkASSERT(false);
-            return 0;
-    }
-}
-
-/**
- *  Sets invalid gamma to the default value.
- */
-static void handle_invalid_gamma(SkGammas::Type* type, SkGammas::Data* data) {
-    if (SkGammas::Type::kNone_Type == *type) {
-        *type = SkGammas::Type::kNamed_Type;
-
-        // Guess sRGB in the case of a malformed transfer function.
-        data->fNamed = kSRGB_SkGammaNamed;
-    }
-}
-
-/**
- *  Finish loading the gammas, now that we have allocated memory for the SkGammas struct.
- *
- *  There's nothing to do for the simple cases, but for table gammas we need to actually
- *  read the table into heap memory.  And for parametric gammas, we need to copy over the
- *  parameter values.
- *
- *  @param memory Pointer to start of the SkGammas memory block
- *  @param offset Bytes of memory (after the SkGammas struct) that are already in use.
- *  @param data   In-out variable.  Will fill in the offset to the table or parameters
- *                if necessary.
- *  @param params Parameters for gamma curve.  Only initialized/used when we have a
- *                parametric gamma.
- *  @param src    Pointer to start of the gamma tag.
- *
- *  @return       Additional bytes of memory that are being used by this gamma curve.
- */
-static size_t load_gammas(void* memory, size_t offset, SkGammas::Type type,
-                        SkGammas::Data* data, const SkColorSpaceTransferFn& params,
-                        const uint8_t* src) {
-    void* storage = SkTAddOffset<void>(memory, offset + sizeof(SkGammas));
-
-    switch (type) {
-        case SkGammas::Type::kNamed_Type:
-        case SkGammas::Type::kValue_Type:
-            // Nothing to do here.
-            return 0;
-        case SkGammas::Type::kTable_Type: {
-            data->fTable.fOffset = offset;
-
-            float* outTable = (float*) storage;
-            const uint16_t* inTable = (const uint16_t*) (src + 12);
-            for (int i = 0; i < data->fTable.fSize; i++) {
-                outTable[i] = (read_big_endian_u16((const uint8_t*) &inTable[i])) / 65535.0f;
-            }
-
-            return sizeof(float) * data->fTable.fSize;
-        }
-        case SkGammas::Type::kParam_Type:
-            data->fTable.fOffset = offset;
-            memcpy(storage, &params, sizeof(SkColorSpaceTransferFn));
-            return sizeof(SkColorSpaceTransferFn);
-        default:
-            SkASSERT(false);
-            return 0;
-    }
-}
-
-static constexpr uint32_t kTAG_AtoBType  = SkSetFourByteTag('m', 'A', 'B', ' ');
-static constexpr uint32_t kTAG_lut8Type  = SkSetFourByteTag('m', 'f', 't', '1');
-static constexpr uint32_t kTAG_lut16Type = SkSetFourByteTag('m', 'f', 't', '2');
-
-static bool load_color_lut(sk_sp<SkColorLookUpTable>* colorLUT, uint32_t inputChannels,
-                           size_t precision, const uint8_t gridPoints[3], const uint8_t* src,
-                           size_t len) {
-    switch (precision) {
-        case 1: //  8-bit data
-        case 2: // 16-bit data
-            break;
-        default:
-            SkColorSpacePrintf("Color LUT precision must be 8-bit or 16-bit. Found: %d-bit\n",
-                               8*precision);
-            return false;
-    }
-
-    uint32_t numEntries = SkColorLookUpTable::kOutputChannels;
-    for (uint32_t i = 0; i < inputChannels; i++) {
-        if (1 >= gridPoints[i]) {
-            SkColorSpacePrintf("Each input channel must have at least two grid points.");
-            return false;
-        }
-
-        if (!safe_mul(numEntries, gridPoints[i], &numEntries)) {
-            SkColorSpacePrintf("Too many entries in Color LUT.");
-            return false;
-        }
-    }
-
-    uint32_t clutBytes;
-    if (!safe_mul(numEntries, precision, &clutBytes)) {
-        SkColorSpacePrintf("Too many entries in Color LUT.\n");
-        return false;
-    }
-
-    if (len < clutBytes) {
-        SkColorSpacePrintf("Color LUT tag is too small (%d / %d bytes).\n", len, clutBytes);
-        return false;
-    }
-
-    // Movable struct colorLUT has ownership of fTable.
-    void* memory = sk_malloc_throw(sizeof(SkColorLookUpTable) + sizeof(float) * numEntries);
-    *colorLUT = sk_sp<SkColorLookUpTable>(new (memory) SkColorLookUpTable(inputChannels,
-                                                                          gridPoints));
-
-    float* table = SkTAddOffset<float>(memory, sizeof(SkColorLookUpTable));
-    const uint8_t* ptr = src;
-    for (uint32_t i = 0; i < numEntries; i++, ptr += precision) {
-        if (1 == precision) {
-            table[i] = ((float) *ptr) / 255.0f;
-        } else {
-            table[i] = ((float) read_big_endian_u16(ptr)) / 65535.0f;
-        }
-    }
-
-    return true;
-}
-
-/**
- *  Reads a matrix out of an A2B tag of an ICC profile.
- *  If |translate| is true, it will load a 3x4 matrix out that corresponds to a XYZ
- *  transform as well as a translation, and if |translate| is false it only loads a
- *  3x3 matrix with no translation
- *
- *  @param matrix    The matrix to store the result in
- *  @param src       Data to load the matrix out of.
- *  @param len       The length of |src|.
- *                   Must have 48 bytes if |translate| is set and 36 bytes otherwise.
- *  @param translate Whether to read the translation column or not
- *  @param pcs       The profile connection space of the profile this matrix is for
- *
- *  @return          false on failure, true on success
- */
-static bool load_matrix(SkMatrix44* matrix, const uint8_t* src, size_t len, bool translate,
-                        SkColorSpace_A2B::PCS pcs) {
-    const size_t minLen = translate ? 48 : 36;
-    if (len < minLen) {
-        SkColorSpacePrintf("Matrix tag is too small (%d bytes).", len);
-        return false;
-    }
-
-    float encodingFactor;
-    switch (pcs) {
-        case SkColorSpace_A2B::PCS::kLAB:
-            encodingFactor = 1.f;
-            break;
-        case SkColorSpace_A2B::PCS::kXYZ:
-            encodingFactor = 65535 / 32768.f;
-            break;
-        default:
-            encodingFactor = 1.f;
-            SkASSERT(false);
-            break;
-    }
-    float array[16];
-    array[ 0] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src));
-    array[ 1] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 4));
-    array[ 2] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 8));
-
-    array[ 4] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 12));
-    array[ 5] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 16));
-    array[ 6] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 20));
-
-    array[ 8] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 24));
-    array[ 9] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 28));
-    array[10] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 32));
-
-    if (translate) {
-        array[ 3] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 36)); // translate R
-        array[ 7] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 40)); // translate G
-        array[11] = encodingFactor * SkFixedToFloat(read_big_endian_i32(src + 44)); // translate B
-    } else {
-        array[ 3] = 0.0f;
-        array[ 7] = 0.0f;
-        array[11] = 0.0f;
-    }
-
-    array[12] = 0.0f;
-    array[13] = 0.0f;
-    array[14] = 0.0f;
-    array[15] = 1.0f;
-    matrix->setRowMajorf(array);
-    SkColorSpacePrintf("A2B0 matrix loaded:\n");
-    for (int r = 0; r < 4; ++r) {
-        SkColorSpacePrintf("|");
-        for (int c = 0; c < 4; ++c) {
-            SkColorSpacePrintf(" %f ", matrix->get(r, c));
-        }
-        SkColorSpacePrintf("|\n");
-    }
-    return true;
-}
-
-static inline SkGammaNamed is_named(const sk_sp<SkGammas>& gammas) {
-    for (uint8_t i = 0; i < gammas->channels(); ++i) {
-        if (!gammas->isNamed(i) || gammas->data(i).fNamed != gammas->data(0).fNamed) {
-            return kNonStandard_SkGammaNamed;
-        }
-    }
-    return gammas->data(0).fNamed;
-}
-
-/**
- *  Parse and load an entire stored curve. Handles invalid gammas as well.
- *
- *  There's nothing to do for the simple cases, but for table gammas we need to actually
- *  read the table into heap memory.  And for parametric gammas, we need to copy over the
- *  parameter values.
- *
- *  @param gammaNamed    Out-variable. The named gamma curve.
- *  @param gammas        Out-variable. The stored gamma curve information. Can be null if
- *                       gammaNamed is a named curve
- *  @param inputChannels The number of gamma input channels
- *  @param rTagPtr       Pointer to start of the gamma tag.
- *  @param taglen        The size in bytes of the tag
- *
- *  @return              false on failure, true on success
- */
-static bool parse_and_load_gamma(SkGammaNamed* gammaNamed, sk_sp<SkGammas>* gammas,
-                                 uint8_t inputChannels, const uint8_t* tagSrc, size_t tagLen) {
-    SkGammas::Data data[kMaxColorChannels];
-    SkColorSpaceTransferFn params[kMaxColorChannels];
-    SkGammas::Type type[kMaxColorChannels];
-    const uint8_t* tagPtr[kMaxColorChannels];
-
-    tagPtr[0] = tagSrc;
-
-    *gammaNamed = kNonStandard_SkGammaNamed;
-
-    // On an invalid first gamma, tagBytes remains set as zero.  This causes the two
-    // subsequent to be treated as identical (which is what we want).
-    size_t tagBytes = 0;
-    type[0] = parse_gamma(&data[0], &params[0], &tagBytes, tagPtr[0], tagLen);
-    handle_invalid_gamma(&type[0], &data[0]);
-    size_t alignedTagBytes = SkAlign4(tagBytes);
-
-    bool allChannelsSame = false;
-    if (inputChannels * alignedTagBytes <= tagLen) {
-        allChannelsSame = true;
-        for (uint8_t i = 1; i < inputChannels; ++i) {
-            if (0 != memcmp(tagSrc, tagSrc + i * alignedTagBytes, tagBytes)) {
-                allChannelsSame = false;
-                break;
-            }
-        }
-    }
-    if (allChannelsSame) {
-        if (SkGammas::Type::kNamed_Type == type[0]) {
-            *gammaNamed = data[0].fNamed;
-        } else {
-            size_t allocSize = sizeof(SkGammas);
-            return_if_false(safe_add(allocSize, gamma_alloc_size(type[0], data[0]), &allocSize),
-                            "SkGammas struct is too large to allocate");
-            void* memory = sk_malloc_throw(allocSize);
-            *gammas = sk_sp<SkGammas>(new (memory) SkGammas(inputChannels));
-            load_gammas(memory, 0, type[0], &data[0], params[0], tagPtr[0]);
-
-            for (uint8_t channel = 0; channel < inputChannels; ++channel) {
-                (*gammas)->fType[channel] = type[0];
-                (*gammas)->fData[channel] = data[0];
-            }
-        }
-    } else {
-        for (uint8_t channel = 1; channel < inputChannels; ++channel) {
-            tagPtr[channel] = tagPtr[channel - 1] + alignedTagBytes;
-            tagLen = tagLen > alignedTagBytes ? tagLen - alignedTagBytes : 0;
-            tagBytes = 0;
-            type[channel] = parse_gamma(&data[channel], &params[channel], &tagBytes,
-                                        tagPtr[channel], tagLen);
-            handle_invalid_gamma(&type[channel], &data[channel]);
-            alignedTagBytes = SkAlign4(tagBytes);
-        }
-
-        size_t allocSize = sizeof(SkGammas);
-        for (uint8_t channel = 0; channel < inputChannels; ++channel) {
-            return_if_false(safe_add(allocSize, gamma_alloc_size(type[channel], data[channel]),
-                                     &allocSize),
-                            "SkGammas struct is too large to allocate");
-        }
-        void* memory = sk_malloc_throw(allocSize);
-        *gammas = sk_sp<SkGammas>(new (memory) SkGammas(inputChannels));
-
-        uint32_t offset = 0;
-        for (uint8_t channel = 0; channel < inputChannels; ++channel) {
-            (*gammas)->fType[channel] = type[channel];
-            offset += load_gammas(memory,offset, type[channel], &data[channel], params[channel],
-                                  tagPtr[channel]);
-            (*gammas)->fData[channel] = data[channel];
-
-        }
-    }
-
-    if (kNonStandard_SkGammaNamed == *gammaNamed) {
-        *gammaNamed = is_named(*gammas);
-        if (kNonStandard_SkGammaNamed != *gammaNamed) {
-            // No need to keep the gammas struct, the enum is enough.
-            *gammas = nullptr;
-        }
-    }
-    return true;
-}
-
-static bool is_lut_gamma_linear(const uint8_t* src, size_t count, size_t precision) {
-    // check for linear gamma (this is very common in lut gammas, as they aren't optional)
-    const float normalizeX = 1.f / (count - 1);
-    for (uint32_t x = 0; x < count; ++x) {
-        const float y = precision == 1 ? (src[x] / 255.f)
-                                       : (read_big_endian_u16(src + 2*x) / 65535.f);
-        if (!color_space_almost_equal(x * normalizeX, y)) {
-            return false;
-        }
-    }
-    return true;
-}
-
-static bool load_lut_gammas(sk_sp<SkGammas>* gammas, SkGammaNamed* gammaNamed, size_t numTables,
-                            size_t entriesPerTable, size_t precision, const uint8_t* src,
-                            size_t len) {
-    if (precision != 1 && precision != 2) {
-        SkColorSpacePrintf("Invalid gamma table precision %d\n", precision);
-        return false;
-    }
-    uint32_t totalEntries;
-    return_if_false(safe_mul(entriesPerTable, numTables, &totalEntries),
-                    "Too many entries in gamma table.");
-    uint32_t readBytes;
-    return_if_false(safe_mul(precision, totalEntries, &readBytes),
-                    "SkGammas struct is too large to read");
-    if (len < readBytes) {
-        SkColorSpacePrintf("Gamma table is too small. Provided: %d. Required: %d\n",
-                           len, readBytes);
-        return false;
-    }
-
-    uint32_t writeBytesPerChannel;
-    return_if_false(safe_mul(sizeof(float), entriesPerTable, &writeBytesPerChannel),
-                    "SkGammas struct is too large to allocate");
-    const size_t readBytesPerChannel = precision * entriesPerTable;
-    size_t numTablesToUse = 1;
-    for (size_t tableIndex = 1; tableIndex < numTables; ++tableIndex) {
-        if (0 != memcmp(src, src + readBytesPerChannel * tableIndex, readBytesPerChannel)) {
-            numTablesToUse = numTables;
-            break;
-        }
-    }
-
-    if (1 == numTablesToUse) {
-        if (is_lut_gamma_linear(src, entriesPerTable, precision)) {
-            *gammaNamed = kLinear_SkGammaNamed;
-            return true;
-        }
-    }
-    *gammaNamed = kNonStandard_SkGammaNamed;
-
-    uint32_t writetableBytes;
-    return_if_false(safe_mul(numTablesToUse, writeBytesPerChannel, &writetableBytes),
-                    "SkGammas struct is too large to allocate");
-    size_t allocSize = sizeof(SkGammas);
-    return_if_false(safe_add(allocSize, (size_t)writetableBytes, &allocSize),
-                    "SkGammas struct is too large to allocate");
-
-    void* memory = sk_malloc_throw(allocSize);
-    *gammas = sk_sp<SkGammas>(new (memory) SkGammas(numTables));
-
-    for (size_t tableIndex = 0; tableIndex < numTablesToUse; ++tableIndex) {
-        const uint8_t* ptr = src + readBytesPerChannel * tableIndex;
-        const size_t offset = sizeof(SkGammas) + tableIndex * writeBytesPerChannel;
-        float* table = SkTAddOffset<float>(memory, offset);
-        if (1 == precision) {
-            for (uint32_t i = 0; i < entriesPerTable; ++i, ptr += 1) {
-                table[i] = ((float) *ptr) / 255.0f;
-            }
-        } else if (2 == precision) {
-            for (uint32_t i = 0; i < entriesPerTable; ++i, ptr += 2) {
-                table[i] = ((float) read_big_endian_u16(ptr)) / 65535.0f;
-            }
-        }
-    }
-
-    SkASSERT(1 == numTablesToUse|| numTables == numTablesToUse);
-
-    size_t tableOffset = 0;
-    for (size_t tableIndex = 0; tableIndex < numTables; ++tableIndex) {
-        (*gammas)->fType[tableIndex]                = SkGammas::Type::kTable_Type;
-        (*gammas)->fData[tableIndex].fTable.fOffset = tableOffset;
-        (*gammas)->fData[tableIndex].fTable.fSize   = entriesPerTable;
-        if (numTablesToUse > 1) {
-            tableOffset += writeBytesPerChannel;
-        }
-    }
-
-    return true;
-}
-
-bool load_a2b0_a_to_b_type(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
-                           size_t len, SkColorSpace_A2B::PCS pcs) {
-    SkASSERT(len >= 32);
-    // Read the number of channels.  The four bytes (4-7) that we skipped are reserved and
-    // must be zero.
-    const uint8_t inputChannels = src[8];
-    const uint8_t outputChannels = src[9];
-    if (SkColorLookUpTable::kOutputChannels != outputChannels) {
-        // We only handle RGB outputs. The number of output channels must be 3.
-        SkColorSpacePrintf("Output channels (%d) must equal 3 in A to B tag.\n", outputChannels);
-        return false;
-    }
-    if (inputChannels == 0 || inputChannels > 4) {
-        // And we only support 4 input channels.
-        // ICC says up to 16 but our decode can only handle 4.
-        // It could easily be extended to support up to 8, but we only allow CMYK/RGB
-        // input color spaces which are 3 and 4 so let's restrict it to 4 instead of 8.
-        // We can always change this check when we support bigger input spaces.
-        SkColorSpacePrintf("Input channels (%d) must be between 1 and 4 in A to B tag.\n",
-                           inputChannels);
-        return false;
-    }
-
-
-    // It is important that these are loaded in the order of application, as the
-    // order you construct an A2B color space's elements is the order it is applied
-
-    // If the offset is non-zero it indicates that the element is present.
-    const uint32_t offsetToACurves = read_big_endian_i32(src + 28);
-    if (0 != offsetToACurves && offsetToACurves < len) {
-        const size_t tagLen = len - offsetToACurves;
-        SkGammaNamed gammaNamed;
-        sk_sp<SkGammas> gammas;
-        if (!parse_and_load_gamma(&gammaNamed, &gammas, inputChannels, src + offsetToACurves,
-                                  tagLen)) {
-            return false;
-        }
-        if (gammas) {
-            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
-        } else if (kLinear_SkGammaNamed != gammaNamed) {
-            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, inputChannels));
-        }
-    }
-
-    const uint32_t offsetToColorLUT = read_big_endian_i32(src + 24);
-    if (0 != offsetToColorLUT && offsetToColorLUT < len) {
-        sk_sp<SkColorLookUpTable> colorLUT;
-        const uint8_t* clutSrc = src + offsetToColorLUT;
-        const size_t clutLen = len - offsetToColorLUT;
-        // 16 bytes reserved for grid points, 1 for precision, 3 for padding.
-        // The color LUT data follows after this header.
-        static constexpr uint32_t kColorLUTHeaderSize = 20;
-        if (clutLen < kColorLUTHeaderSize) {
-            SkColorSpacePrintf("Color LUT tag is too small (%d bytes).", clutLen);
-            return false;
-        }
-
-        SkASSERT(inputChannels <= kMaxColorChannels);
-        uint8_t gridPoints[kMaxColorChannels];
-        for (uint32_t i = 0; i < inputChannels; ++i) {
-            gridPoints[i] = clutSrc[i];
-        }
-        // Space is provided for a maximum of 16 input channels.
-        // Now we determine the precision of the table values.
-        const uint8_t precision = clutSrc[16];
-        if (!load_color_lut(&colorLUT, inputChannels, precision, gridPoints,
-                            clutSrc + kColorLUTHeaderSize, clutLen - kColorLUTHeaderSize)) {
-            SkColorSpacePrintf("Failed to read color LUT from A to B tag.\n");
-            return false;
-        }
-        elements->push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));
-    }
-
-    const uint32_t offsetToMCurves = read_big_endian_i32(src + 20);
-    if (0 != offsetToMCurves && offsetToMCurves < len) {
-        const size_t tagLen = len - offsetToMCurves;
-        SkGammaNamed gammaNamed;
-        sk_sp<SkGammas> gammas;
-        if (!parse_and_load_gamma(&gammaNamed, &gammas, outputChannels, src + offsetToMCurves,
-                                  tagLen)) {
-            return false;
-        }
-        if (gammas) {
-            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
-        } else if (kLinear_SkGammaNamed != gammaNamed) {
-            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, outputChannels));
-        }
-    }
-
-    const uint32_t offsetToMatrix = read_big_endian_i32(src + 16);
-    if (0 != offsetToMatrix && offsetToMatrix < len) {
-        SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
-        if (!load_matrix(&matrix, src + offsetToMatrix, len - offsetToMatrix, true, pcs)) {
-            SkColorSpacePrintf("Failed to read matrix from A to B tag.\n");
-        } else if (!matrix.isIdentity()) {
-            elements->push_back(SkColorSpace_A2B::Element(matrix));
-        }
-    }
-
-    const uint32_t offsetToBCurves = read_big_endian_i32(src + 12);
-    if (0 != offsetToBCurves && offsetToBCurves < len) {
-        const size_t tagLen = len - offsetToBCurves;
-        SkGammaNamed gammaNamed;
-        sk_sp<SkGammas> gammas;
-        if (!parse_and_load_gamma(&gammaNamed, &gammas, outputChannels, src + offsetToBCurves,
-                                  tagLen)) {
-            return false;
-        }
-        if (gammas) {
-            elements->push_back(SkColorSpace_A2B::Element(std::move(gammas)));
-        } else if (kLinear_SkGammaNamed != gammaNamed) {
-            elements->push_back(SkColorSpace_A2B::Element(gammaNamed, outputChannels));
-        }
-    }
-
-    return true;
-}
-
-bool load_a2b0_lutn_type(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
-                         size_t len, SkColorSpace_A2B::PCS pcs) {
-    const uint32_t type = read_big_endian_u32(src);
-    switch (type) {
-        case kTAG_lut8Type:
-            SkASSERT(len >= 48);
-            break;
-        case kTAG_lut16Type:
-            SkASSERT(len >= 52);
-            break;
-        default:
-            SkASSERT(false);
-            return false;
-    }
-    // Read the number of channels.
-    // The four bytes (4-7) that we skipped are reserved and must be zero.
-    const uint8_t inputChannels = src[8];
-    const uint8_t outputChannels = src[9];
-    if (SkColorLookUpTable::kOutputChannels != outputChannels) {
-        // We only handle RGB outputs. The number of output channels must be 3.
-        SkColorSpacePrintf("Output channels (%d) must equal 3 in A to B tag.\n", outputChannels);
-        return false;
-    }
-    if (inputChannels == 0 || inputChannels > 4) {
-        // And we only support 4 input channels.
-        // ICC says up to 16 but our decode can only handle 4.
-        // It could easily be extended to support up to 8, but we only allow CMYK/RGB
-        // input color spaces which are 3 and 4 so let's restrict it to 4 instead of 8.
-        // We can always change this check when we support bigger input spaces.
-        SkColorSpacePrintf("Input channels (%d) must be between 1 and 4 in A to B tag.\n",
-                           inputChannels);
-        return false;
-    }
-
-    const uint8_t clutGridPoints = src[10];
-    // 11th byte reserved for padding (required to be zero)
-
-    SkMatrix44 matrix(SkMatrix44::kUninitialized_Constructor);
-    load_matrix(&matrix, &src[12], len - 12, false, pcs);
-    if (!matrix.isIdentity()) {
-        // ICC specs (10.8/10.9) say lut8/16Type profiles must have identity matrices
-        // if the input color space is not PCSXYZ, and we do not support PCSXYZ input color spaces
-        // so we should never encounter a non-identity matrix here.
-        // However, 2 test images from the ICC website have RGB input spaces and non-identity
-        // matrices so we're not going to fail here, despite being against the spec.
-        SkColorSpacePrintf("Warning: non-Identity matrix found in non-XYZ input color space"
-                           "lut profile");
-        elements->push_back(SkColorSpace_A2B::Element(matrix));
-    }
-
-    size_t dataOffset      = 48;
-    // # of input table entries
-    size_t inTableEntries  = 256;
-    // # of output table entries
-    size_t outTableEntries = 256;
-    size_t precision       = 1;
-    if (kTAG_lut16Type == type) {
-        dataOffset      = 52;
-        inTableEntries  = read_big_endian_u16(src + 48);
-        outTableEntries = read_big_endian_u16(src + 50);
-        precision       = 2;
-
-        constexpr size_t kMaxLut16GammaEntries = 4096;
-        if (inTableEntries < 2) {
-            SkColorSpacePrintf("Too few (%d) input gamma table entries. Must have at least 2.\n",
-                               inTableEntries);
-            return false;
-        } else if (inTableEntries > kMaxLut16GammaEntries) {
-            SkColorSpacePrintf("Too many (%d) input gamma table entries. Must have at most %d.\n",
-                               inTableEntries, kMaxLut16GammaEntries);
-            return false;
-        }
-
-        if (outTableEntries < 2) {
-            SkColorSpacePrintf("Too few (%d) output gamma table entries. Must have at least 2.\n",
-                               outTableEntries);
-            return false;
-        } else if (outTableEntries > kMaxLut16GammaEntries) {
-            SkColorSpacePrintf("Too many (%d) output gamma table entries. Must have at most %d.\n",
-                               outTableEntries, kMaxLut16GammaEntries);
-            return false;
-        }
-    }
-
-    const size_t inputOffset = dataOffset;
-    return_if_false(len >= inputOffset, "A2B0 lutnType tag too small for input gamma table");
-    sk_sp<SkGammas> inputGammas;
-    SkGammaNamed inputGammaNamed;
-    if (!load_lut_gammas(&inputGammas, &inputGammaNamed, inputChannels, inTableEntries, precision,
-                         src + inputOffset, len - inputOffset)) {
-        SkColorSpacePrintf("Failed to read input gammas from lutnType tag.\n");
-        return false;
-    }
-    SkASSERT(inputGammas || inputGammaNamed != kNonStandard_SkGammaNamed);
-    if (kLinear_SkGammaNamed != inputGammaNamed) {
-        if (kNonStandard_SkGammaNamed != inputGammaNamed) {
-            elements->push_back(SkColorSpace_A2B::Element(inputGammaNamed, inputChannels));
-        } else {
-            elements->push_back(SkColorSpace_A2B::Element(std::move(inputGammas)));
-        }
-    }
-
-    const size_t clutOffset = inputOffset + precision*inTableEntries*inputChannels;
-    return_if_false(len >= clutOffset, "A2B0 lutnType tag too small for CLUT");
-    sk_sp<SkColorLookUpTable> colorLUT;
-    const uint8_t gridPoints[kMaxColorChannels] = {
-        clutGridPoints, clutGridPoints, clutGridPoints, clutGridPoints
-    };
-    if (!load_color_lut(&colorLUT, inputChannels, precision, gridPoints, src + clutOffset,
-                        len - clutOffset)) {
-        SkColorSpacePrintf("Failed to read color LUT from lutnType tag.\n");
-        return false;
-    }
-    SkASSERT(colorLUT);
-    elements->push_back(SkColorSpace_A2B::Element(std::move(colorLUT)));
-
-    size_t clutSize = precision * outputChannels;
-    for (int i = 0; i < inputChannels; ++i) {
-        clutSize *= clutGridPoints;
-    }
-    const size_t outputOffset = clutOffset + clutSize;
-    return_if_false(len >= outputOffset, "A2B0 lutnType tag too small for output gamma table");
-    sk_sp<SkGammas> outputGammas;
-    SkGammaNamed outputGammaNamed;
-    if (!load_lut_gammas(&outputGammas, &outputGammaNamed, outputChannels, outTableEntries,
-                         precision, src + outputOffset, len - outputOffset)) {
-        SkColorSpacePrintf("Failed to read output gammas from lutnType tag.\n");
-        return false;
-    }
-    SkASSERT(outputGammas || outputGammaNamed != kNonStandard_SkGammaNamed);
-    if (kLinear_SkGammaNamed != outputGammaNamed) {
-        if (kNonStandard_SkGammaNamed != outputGammaNamed) {
-            elements->push_back(SkColorSpace_A2B::Element(outputGammaNamed, outputChannels));
-        } else {
-            elements->push_back(SkColorSpace_A2B::Element(std::move(outputGammas)));
-        }
-    }
-
-    return true;
-}
-
-static inline int icf_channels(SkColorSpace::Type iccType) {
-    switch (iccType) {
-        case SkColorSpace::kRGB_Type:
-            return 3;
-        case SkColorSpace::kCMYK_Type:
-            return 4;
-        default:
-            SkASSERT(false);
-            return 0;
-    }
-}
-
-static bool load_a2b0(std::vector<SkColorSpace_A2B::Element>* elements, const uint8_t* src,
-                      size_t len, SkColorSpace_A2B::PCS pcs,
-                      SkColorSpace::Type iccType) {
-    if (len < 4) {
-        return false;
-    }
-    const uint32_t type = read_big_endian_u32(src);
-
-    switch (type) {
-        case kTAG_AtoBType:
-            if (len < 32) {
-                SkColorSpacePrintf("A to B tag is too small (%d bytes).", len);
-                return false;
-            }
-            SkColorSpacePrintf("A2B0 tag is of type lutAtoBType\n");
-            if (!load_a2b0_a_to_b_type(elements, src, len, pcs)) {
-                return false;
-            }
-            break;
-        case kTAG_lut8Type:
-            if (len < 48) {
-                SkColorSpacePrintf("lut8 tag is too small (%d bytes).", len);
-                return false;
-            }
-            SkColorSpacePrintf("A2B0 tag of type lut8Type\n");
-            if (!load_a2b0_lutn_type(elements, src, len, pcs)) {
-                return false;
-            }
-            break;
-        case kTAG_lut16Type:
-            if (len < 52) {
-                SkColorSpacePrintf("lut16 tag is too small (%d bytes).", len);
-                return false;
-            }
-            SkColorSpacePrintf("A2B0 tag of type lut16Type\n");
-            if (!load_a2b0_lutn_type(elements, src, len, pcs)) {
-                return false;
-            }
-            break;
-        default:
-            SkColorSpacePrintf("Unsupported A to B tag type: %c%c%c%c\n", (type>>24)&0xFF,
-                               (type>>16)&0xFF, (type>>8)&0xFF, type&0xFF);
-            return false;
-    }
-    SkASSERT(SkColorSpace_A2B::PCS::kLAB == pcs || SkColorSpace_A2B::PCS::kXYZ == pcs);
-    static constexpr int kPCSChannels = 3; // must be PCSLAB or PCSXYZ
-    if (elements->empty()) {
-        return kPCSChannels == icf_channels(iccType);
-    }
-    // now let's verify that the input/output channels of each A2B element actually match up
-    if (icf_channels(iccType) != elements->front().inputChannels()) {
-        SkColorSpacePrintf("Input channel count does not match first A2B element's input count");
-        return false;
-    }
-    for (size_t i = 1; i < elements->size(); ++i) {
-        if ((*elements)[i - 1].outputChannels() != (*elements)[i].inputChannels()) {
-            SkColorSpacePrintf("A2B elements don't agree in input/output channel counts");
-            return false;
-        }
-    }
-    if (kPCSChannels != elements->back().outputChannels()) {
-        SkColorSpacePrintf("PCS channel count doesn't match last A2B element's output count");
-        return false;
-    }
-    return true;
-}
-
-static bool tag_equals(const ICCTag* a, const ICCTag* b, const uint8_t* base) {
-    if (!a || !b) {
-        return a == b;
-    }
-
-    if (a->fLength != b->fLength) {
-        return false;
-    }
-
-    if (a->fOffset == b->fOffset) {
-        return true;
-    }
-
-    return !memcmp(a->addr(base), b->addr(base), a->fLength);
-}
-
-static inline bool is_close_to_d50(const SkMatrix44& matrix) {
-    // rX + gX + bX
-    float X = matrix.getFloat(0, 0) + matrix.getFloat(0, 1) + matrix.getFloat(0, 2);
-
-    // rY + gY + bY
-    float Y = matrix.getFloat(1, 0) + matrix.getFloat(1, 1) + matrix.getFloat(1, 2);
-
-    // rZ + gZ + bZ
-    float Z = matrix.getFloat(2, 0) + matrix.getFloat(2, 1) + matrix.getFloat(2, 2);
-
-    static const float kD50_WhitePoint[3] = { 0.96420f, 1.00000f, 0.82491f };
-
-    // This is a bit more lenient than QCMS and Adobe.  Is there a reason to be stricter here?
-    return (SkTAbs(X - kD50_WhitePoint[0]) <= 0.04f) &&
-           (SkTAbs(Y - kD50_WhitePoint[1]) <= 0.04f) &&
-           (SkTAbs(Z - kD50_WhitePoint[2]) <= 0.04f);
-}
-
-static sk_sp<SkColorSpace> make_xyz(const ICCProfileHeader& header, ICCTag* tags, int tagCount,
-                                    const uint8_t* base, sk_sp<SkData> profileData) {
-    if (kLAB_PCSSpace == header.fPCS) {
-        return nullptr;
-    }
-
-    // Recognize the rXYZ, gXYZ, and bXYZ tags.
-    const ICCTag* r = ICCTag::Find(tags, tagCount, kTAG_rXYZ);
-    const ICCTag* g = ICCTag::Find(tags, tagCount, kTAG_gXYZ);
-    const ICCTag* b = ICCTag::Find(tags, tagCount, kTAG_bXYZ);
-    if (!r || !g || !b) {
-        return nullptr;
-    }
-
-    float toXYZ[9];
-    if (!load_xyz(&toXYZ[0], r->addr(base), r->fLength) ||
-        !load_xyz(&toXYZ[3], g->addr(base), g->fLength) ||
-        !load_xyz(&toXYZ[6], b->addr(base), b->fLength))
-    {
-        return_null("Need valid rgb tags for XYZ space");
-    }
-    SkMatrix44 mat(SkMatrix44::kUninitialized_Constructor);
-    mat.set3x3(toXYZ[0], toXYZ[1], toXYZ[2],
-               toXYZ[3], toXYZ[4], toXYZ[5],
-               toXYZ[6], toXYZ[7], toXYZ[8]);
-    if (!is_close_to_d50(mat)) {
-        return_null("XYZ matrix is not D50");
-    }
-
-    // If some, but not all, of the gamma tags are missing, assume that all
-    // gammas are meant to be the same.
-    r = ICCTag::Find(tags, tagCount, kTAG_rTRC);
-    g = ICCTag::Find(tags, tagCount, kTAG_gTRC);
-    b = ICCTag::Find(tags, tagCount, kTAG_bTRC);
-    if (!r || !g || !b) {
-        return_null("Need valid TRC tags for XYZ space");
-    }
-
-    SkGammaNamed gammaNamed = kNonStandard_SkGammaNamed;
-    sk_sp<SkGammas> gammas = nullptr;
-    size_t tagBytes;
-    if (tag_equals(r, g, base) && tag_equals(g, b, base)) {
-        SkGammas::Data data;
-        SkColorSpaceTransferFn params;
-        SkGammas::Type type =
-                parse_gamma(&data, &params, &tagBytes, r->addr(base), r->fLength);
-        handle_invalid_gamma(&type, &data);
-
-        if (SkGammas::Type::kNamed_Type == type) {
-            gammaNamed = data.fNamed;
-        } else {
-            size_t allocSize = sizeof(SkGammas);
-            if (!safe_add(allocSize, gamma_alloc_size(type, data), &allocSize)) {
-                return_null("SkGammas struct is too large to allocate");
-            }
-            void* memory = sk_malloc_throw(allocSize);
-            gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
-            load_gammas(memory, 0, type, &data, params, r->addr(base));
-
-            for (int i = 0; i < 3; ++i) {
-                gammas->fType[i] = type;
-                gammas->fData[i] = data;
-            }
-        }
-    } else {
-        SkGammas::Data rData;
-        SkColorSpaceTransferFn rParams;
-        SkGammas::Type rType =
-                parse_gamma(&rData, &rParams, &tagBytes, r->addr(base), r->fLength);
-        handle_invalid_gamma(&rType, &rData);
-
-        SkGammas::Data gData;
-        SkColorSpaceTransferFn gParams;
-        SkGammas::Type gType =
-                parse_gamma(&gData, &gParams, &tagBytes, g->addr(base), g->fLength);
-        handle_invalid_gamma(&gType, &gData);
-
-        SkGammas::Data bData;
-        SkColorSpaceTransferFn bParams;
-        SkGammas::Type bType =
-                parse_gamma(&bData, &bParams, &tagBytes, b->addr(base), b->fLength);
-        handle_invalid_gamma(&bType, &bData);
-
-        size_t allocSize = sizeof(SkGammas);
-        if (!safe_add(allocSize, gamma_alloc_size(rType, rData), &allocSize) ||
-            !safe_add(allocSize, gamma_alloc_size(gType, gData), &allocSize) ||
-            !safe_add(allocSize, gamma_alloc_size(bType, bData), &allocSize)) {
-            return_null("SkGammas struct is too large to allocate");
-        }
-        void* memory = sk_malloc_throw(allocSize);
-        gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
-
-        uint32_t offset = 0;
-        gammas->fType[0] = rType;
-        offset += load_gammas(memory, offset, rType, &rData, rParams,
-                                r->addr(base));
-
-        gammas->fType[1] = gType;
-        offset += load_gammas(memory, offset, gType, &gData, gParams,
-                                g->addr(base));
-
-        gammas->fType[2] = bType;
-        load_gammas(memory, offset, bType, &bData, bParams, b->addr(base));
-
-        gammas->fData[0] = rData;
-        gammas->fData[1] = gData;
-        gammas->fData[2] = bData;
-    }
-
-
-    if (kNonStandard_SkGammaNamed == gammaNamed) {
-        // It's possible that we'll initially detect non-matching gammas, only for
-        // them to evaluate to the same named gamma curve.
-        gammaNamed = is_named(gammas);
-    }
-
-    if (kNonStandard_SkGammaNamed == gammaNamed) {
-        return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed,
-                                                        std::move(gammas),
-                                                        mat, std::move(profileData)));
-    }
-
-    return SkColorSpace::MakeRGB(gammaNamed, mat);
-}
-
-static sk_sp<SkColorSpace> make_gray(const ICCProfileHeader& header, ICCTag* tags, int tagCount,
-                                     const uint8_t* base, sk_sp<SkData> profileData) {
-    if (kLAB_PCSSpace == header.fPCS) {
-        return nullptr;
-    }
-
-    const ICCTag* grayTRC = ICCTag::Find(tags, tagCount, kTAG_kTRC);
-    if (!grayTRC) {
-        return_null("grayTRC tag required for monochrome profiles.");
-    }
-    SkGammas::Data data;
-    SkColorSpaceTransferFn params;
-    size_t tagBytes;
-    SkGammas::Type type =
-            parse_gamma(&data, &params, &tagBytes, grayTRC->addr(base), grayTRC->fLength);
-    handle_invalid_gamma(&type, &data);
-
-    SkMatrix44 toXYZD50(SkMatrix44::kIdentity_Constructor);
-    toXYZD50.setFloat(0, 0, kWhitePointD50[0]);
-    toXYZD50.setFloat(1, 1, kWhitePointD50[1]);
-    toXYZD50.setFloat(2, 2, kWhitePointD50[2]);
-    if (SkGammas::Type::kNamed_Type == type) {
-        return SkColorSpace::MakeRGB(data.fNamed, toXYZD50);
-    }
-
-    size_t allocSize = sizeof(SkGammas);
-    if (!safe_add(allocSize, gamma_alloc_size(type, data), &allocSize)) {
-        return_null("SkGammas struct is too large to allocate");
-    }
-    void* memory = sk_malloc_throw(allocSize);
-    sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas(3));
-    load_gammas(memory, 0, type, &data, params, grayTRC->addr(base));
-    for (int i = 0; i < 3; ++i) {
-        gammas->fType[i] = type;
-        gammas->fData[i] = data;
-    }
-
-    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed,
-                                                    std::move(gammas),
-                                                    toXYZD50, std::move(profileData)));
-}
-
-static sk_sp<SkColorSpace> make_a2b(SkColorSpace::Type iccType,
-                                    const ICCProfileHeader& header, ICCTag* tags, int tagCount,
-                                    const uint8_t* base, sk_sp<SkData> profileData) {
-    const ICCTag* a2b0 = ICCTag::Find(tags, tagCount, kTAG_A2B0);
-    if (a2b0) {
-        const SkColorSpace_A2B::PCS pcs = kXYZ_PCSSpace == header.fPCS
-                                        ? SkColorSpace_A2B::PCS::kXYZ
-                                        : SkColorSpace_A2B::PCS::kLAB;
-        std::vector<SkColorSpace_A2B::Element> elements;
-        if (load_a2b0(&elements, a2b0->addr(base), a2b0->fLength, pcs, iccType)) {
-            return sk_sp<SkColorSpace>(new SkColorSpace_A2B(iccType, std::move(elements),
-                                                            pcs, std::move(profileData)));
-        }
-    }
-
-    return nullptr;
-}
-
-sk_sp<SkColorSpace> SkColorSpace::MakeICC(const void* input, size_t len) {
-    if (!input || len < kICCHeaderSize) {
-        return_null("Data is null or not large enough to contain an ICC profile");
-    }
-
-    // Make sure we're at least as strict as skcms_Parse().
-    skcms_ICCProfile p;
-    if (!skcms_Parse(input, len, &p)) {
-        return nullptr;
-    }
-
-    // Create our own copy of the input.
-    void* memory = sk_malloc_throw(len);
-    memcpy(memory, input, len);
-    sk_sp<SkData> profileData = SkData::MakeFromMalloc(memory, len);
-    const uint8_t* base = profileData->bytes();
-    const uint8_t* ptr = base;
-
-    // Read the ICC profile header and check to make sure that it is valid.
-    ICCProfileHeader header;
-    header.init(ptr, len);
-    if (!header.valid()) {
-        return nullptr;
-    }
-
-    // Adjust ptr and len before reading the tags.
-    if (len < header.fSize) {
-        SkColorSpacePrintf("ICC profile might be truncated.\n");
-    } else if (len > header.fSize) {
-        SkColorSpacePrintf("Caller provided extra data beyond the end of the ICC profile.\n");
-        len = header.fSize;
-    }
-    ptr += kICCHeaderSize;
-    len -= kICCHeaderSize;
-
-    // Parse tag headers.
-    uint32_t tagCount = header.fTagCount;
-    SkColorSpacePrintf("ICC profile contains %d tags.\n", tagCount);
-    if (len < kICCTagTableEntrySize * tagCount) {
-        return_null("Not enough input data to read tag table entries");
-    }
-
-    SkAutoTArray<ICCTag> tags(tagCount);
-    for (uint32_t i = 0; i < tagCount; i++) {
-        ptr = tags[i].init(ptr);
-        SkColorSpacePrintf("[%d] %c%c%c%c %d %d\n", i, (tags[i].fSignature >> 24) & 0xFF,
-                (tags[i].fSignature >> 16) & 0xFF, (tags[i].fSignature >>  8) & 0xFF,
-                (tags[i].fSignature >>  0) & 0xFF, tags[i].fOffset, tags[i].fLength);
-
-        if (!tags[i].valid(kICCHeaderSize + len)) {
-            return_null("Tag is too large to fit in ICC profile");
-        }
-    }
-
-    Type a2b_type = kRGB_Type;
-    switch (header.fInputColorSpace) {
-        case kRGB_ColorSpace: {
-            sk_sp<SkColorSpace> colorSpace =
-                    make_xyz(header, tags.get(), tagCount, base, profileData);
-            if (colorSpace) {
-                return colorSpace;
-            }
-            break;
-        }
-        case kGray_ColorSpace: {
-            return make_gray(header, tags.get(), tagCount, base, profileData);
-        }
-        case kCMYK_ColorSpace:
-            a2b_type = kCMYK_Type;
-            break;
-        default:
-            return_null("ICC profile contains unsupported colorspace");
-    }
-
-    return make_a2b(a2b_type, header, tags.get(), tagCount, base, profileData);
-}
diff --git a/src/core/SkColorSpace_XYZ.cpp b/src/core/SkColorSpace_XYZ.cpp
index 8a38f52..cbb55cc 100644
--- a/src/core/SkColorSpace_XYZ.cpp
+++ b/src/core/SkColorSpace_XYZ.cpp
@@ -10,30 +10,16 @@
 #include "SkColorSpaceXformPriv.h"
 #include "SkOpts.h"
 
-SkColorSpace_XYZ::SkColorSpace_XYZ(SkGammaNamed gammaNamed, const SkMatrix44& toXYZD50)
-    : fProfileData(nullptr)
-    , fGammaNamed(gammaNamed)
-    , fGammas(nullptr)
-    , fToXYZD50(toXYZD50)
-    , fToXYZD50Hash(SkOpts::hash_fn(toXYZD50.values(), 16 * sizeof(SkMScalar), 0))
-    , fFromXYZD50(SkMatrix44::kUninitialized_Constructor)
-{}
-
-SkColorSpace_XYZ::SkColorSpace_XYZ(SkGammaNamed gammaNamed, sk_sp<SkGammas> gammas,
-                                   const SkMatrix44& toXYZD50, sk_sp<SkData> profileData)
-    : fProfileData(std::move(profileData))
-    , fGammaNamed(gammaNamed)
-    , fGammas(std::move(gammas))
-    , fToXYZD50(toXYZD50)
-    , fToXYZD50Hash(SkOpts::hash_fn(toXYZD50.values(), 16 * sizeof(SkMScalar), 0))
-    , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) {
-    SkASSERT(!fGammas || 3 == fGammas->channels());
-    if (fGammas) {
-        for (int i = 0; i < fGammas->channels(); ++i) {
-            if (SkGammas::Type::kTable_Type == fGammas->type(i)) {
-                SkASSERT(fGammas->data(i).fTable.fSize >= 2);
-            }
-        }
+SkColorSpace_XYZ::SkColorSpace_XYZ(SkGammaNamed gammaNamed,
+                                   const SkColorSpaceTransferFn* transferFn,
+                                   const SkMatrix44& toXYZD50)
+        : fGammaNamed(gammaNamed)
+        , fToXYZD50(toXYZD50)
+        , fToXYZD50Hash(SkOpts::hash_fn(toXYZD50.values(), 16 * sizeof(SkMScalar), 0))
+        , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) {
+    SkASSERT(fGammaNamed != kNonStandard_SkGammaNamed || transferFn);
+    if (transferFn) {
+        fTransferFn = *transferFn;
     }
 }
 
@@ -59,26 +45,25 @@
 }
 
 bool SkColorSpace_XYZ::onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const {
-    if (named_to_parametric(coeffs, fGammaNamed)) {
-        return true;
+    switch (fGammaNamed) {
+        case kSRGB_SkGammaNamed:
+            *coeffs = gSRGB_TransferFn;
+            break;
+        case k2Dot2Curve_SkGammaNamed:
+            *coeffs = g2Dot2_TransferFn;
+            break;
+        case kLinear_SkGammaNamed:
+            *coeffs = gLinear_TransferFn;
+            break;
+        case kNonStandard_SkGammaNamed:
+            *coeffs = fTransferFn;
+            break;
+        default:
+            SkDEBUGFAIL("Unknown named gamma");
+            return false;
     }
 
-    SkASSERT(fGammas);
-    if (!fGammas->allChannelsSame()) {
-        return false;
-    }
-
-    if (fGammas->isValue(0)) {
-        value_to_parametric(coeffs, fGammas->data(0).fValue);
-        return true;
-    }
-
-    if (fGammas->isParametric(0)) {
-        *coeffs = fGammas->params(0);
-        return true;
-    }
-
-    return false;
+    return true;
 }
 
 sk_sp<SkColorSpace> SkColorSpace_XYZ::makeLinearGamma() const {
@@ -100,5 +85,5 @@
     spin.set3x3(0, 1, 0, 0, 0, 1, 1, 0, 0);
     spin.postConcat(fToXYZD50);
     (void)spin.getType();  // Pre-cache spin matrix type to avoid races in future getType() calls.
-    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(fGammaNamed, fGammas, spin, fProfileData));
+    return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(fGammaNamed, &fTransferFn, spin));
 }
diff --git a/src/core/SkColorSpace_XYZ.h b/src/core/SkColorSpace_XYZ.h
index 72a1d62..97e3dbc 100644
--- a/src/core/SkColorSpace_XYZ.h
+++ b/src/core/SkColorSpace_XYZ.h
@@ -10,7 +10,6 @@
 
 #include "SkColorSpace.h"
 #include "SkData.h"
-#include "SkGammas.h"
 #include "SkOnce.h"
 
 class SkColorSpace_XYZ : public SkColorSpace {
@@ -24,29 +23,19 @@
     bool onGammaIsLinear() const override;
     bool onIsNumericalTransferFn(SkColorSpaceTransferFn* coeffs) const override;
 
-    const SkData* onProfileData() const override { return fProfileData.get(); }
-
     sk_sp<SkColorSpace> makeLinearGamma() const override;
     sk_sp<SkColorSpace> makeSRGBGamma() const override;
     sk_sp<SkColorSpace> makeColorSpin() const override;
 
     SkGammaNamed onGammaNamed() const override { return fGammaNamed; }
 
-    const SkGammas* gammas() const { return fGammas.get(); }
-
-    void toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>* storage, int numTables) const;
-
-    SkColorSpace_XYZ(SkGammaNamed gammaNamed, const SkMatrix44& toXYZ);
-
-    SkColorSpace_XYZ(SkGammaNamed gammaNamed, sk_sp<SkGammas> gammas,
-                     const SkMatrix44& toXYZ, sk_sp<SkData> profileData);
+    SkColorSpace_XYZ(SkGammaNamed gammaNamed, const SkColorSpaceTransferFn* transferFn,
+                     const SkMatrix44& toXYZ);
 
 private:
-    sk_sp<SkData>          fProfileData;
-
-    const SkGammaNamed     fGammaNamed;
-    sk_sp<SkGammas>        fGammas;
-    const SkMatrix44       fToXYZD50;
+    SkGammaNamed           fGammaNamed;
+    SkColorSpaceTransferFn fTransferFn;
+    SkMatrix44             fToXYZD50;
     uint32_t               fToXYZD50Hash;
 
     mutable SkMatrix44     fFromXYZD50;
diff --git a/src/core/SkGammas.h b/src/core/SkGammas.h
deleted file mode 100644
index 6cb504c..0000000
--- a/src/core/SkGammas.h
+++ /dev/null
@@ -1,139 +0,0 @@
-/*
- * Copyright 2016 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkGammas_DEFINED
-#define SkGammas_DEFINED
-
-#include "SkColorSpace.h"
-#include "SkData.h"
-#include "SkTemplates.h"
-
-struct SkGammas : SkRefCnt {
-
-    // There are four possible representations for gamma curves.  kNone_Type is used
-    // as a placeholder until the struct is initialized.  It is not a valid value.
-    enum class Type {
-        kNone_Type,
-        kNamed_Type,
-        kValue_Type,
-        kTable_Type,
-        kParam_Type,
-    };
-
-    // Contains information for a gamma table.
-    struct Table {
-        size_t fOffset;
-        int    fSize;
-
-        const float* table(const SkGammas* base) const {
-            return SkTAddOffset<const float>(base, sizeof(SkGammas) + fOffset);
-        }
-    };
-
-    // Contains the actual gamma curve information.  Should be interpreted
-    // based on the type of the gamma curve.
-    union Data {
-        Data() : fTable{0, 0} {}
-
-        SkGammaNamed fNamed;
-        float        fValue;
-        Table        fTable;
-        size_t       fParamOffset;
-
-        const SkColorSpaceTransferFn& params(const SkGammas* base) const {
-            return *SkTAddOffset<const SkColorSpaceTransferFn>(base,
-                                                               sizeof(SkGammas) + fParamOffset);
-        }
-    };
-
-    bool allChannelsSame() const {
-        // All channels are the same type?
-        Type type = this->type(0);
-        for (int i = 1; i < this->channels(); i++) {
-            if (type != this->type(i)) {
-                return false;
-            }
-        }
-
-        // All data the same?
-        auto& first = this->data(0);
-        for (int i = 1; i < this->channels(); i++) {
-            auto& data = this->data(i);
-            switch (type) {
-                case Type:: kNone_Type:                                                    break;
-                case Type::kNamed_Type: if (first.fNamed != data.fNamed) { return false; } break;
-                case Type::kValue_Type: if (first.fValue != data.fValue) { return false; } break;
-                case Type::kTable_Type:
-                    if (first.fTable.fOffset != data.fTable.fOffset) { return false; }
-                    if (first.fTable.fSize   != data.fTable.fSize  ) { return false; }
-                    break;
-                case Type::kParam_Type:
-                    if (0 != memcmp(&first.params(this), &data.params(this),
-                                    sizeof(SkColorSpaceTransferFn))) {
-                        return false;
-                    }
-                    break;
-            }
-        }
-        return true;
-    }
-
-    bool isNamed     (int i) const { return Type::kNamed_Type == this->type(i); }
-    bool isValue     (int i) const { return Type::kValue_Type == this->type(i); }
-    bool isTable     (int i) const { return Type::kTable_Type == this->type(i); }
-    bool isParametric(int i) const { return Type::kParam_Type == this->type(i); }
-
-    const Data& data(int i) const {
-        SkASSERT(i >= 0 && i < fChannels);
-        return fData[i];
-    }
-
-    const float* table(int i) const {
-        SkASSERT(this->isTable(i));
-        return this->data(i).fTable.table(this);
-    }
-
-    int tableSize(int i) const {
-        SkASSERT(this->isTable(i));
-        return this->data(i).fTable.fSize;
-    }
-
-    const SkColorSpaceTransferFn& params(int i) const {
-        SkASSERT(this->isParametric(i));
-        return this->data(i).params(this);
-    }
-
-    Type type(int i) const {
-        SkASSERT(i >= 0 && i < fChannels);
-        return fType[i];
-    }
-
-    int channels() const { return fChannels; }
-
-    SkGammas(int channels) : fChannels(channels) {
-        SkASSERT(channels <= (int)SK_ARRAY_COUNT(fType));
-        for (Type& t : fType) {
-            t = Type::kNone_Type;
-        }
-    }
-
-    // These fields should only be modified when initializing the struct.
-    int  fChannels;
-    Data fData[4];
-    Type fType[4];
-
-    // Objects of this type are sometimes created in a custom fashion using
-    // sk_malloc_throw and therefore must be sk_freed.  We overload new to
-    // also call sk_malloc_throw so that memory can be unconditionally released
-    // using sk_free in an overloaded delete. Overloading regular new means we
-    // must also overload placement new.
-    void* operator new(size_t size) { return sk_malloc_throw(size); }
-    void* operator new(size_t, void* p) { return p; }
-    void operator delete(void* p) { sk_free(p); }
-};
-
-#endif
