Move skcms.h to include/third_party/skcms

Add a shim to redirect until clients are updated

Change-Id: Ib43614e5620b1a24ca18187c1646a8ed1a9ee7a4
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/211003
Reviewed-by: Mike Klein <mtklein@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/BUILD.gn b/BUILD.gn
index 5339658..00fda34 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -762,8 +762,9 @@
   }
 
   public = [
-    "third_party/skcms/skcms.h",
+    "include/third_party/skcms/skcms.h",
   ]
+  include_dirs = [ "include/third_party/skcms" ]
   sources = rebase_path(skcms_sources, ".", "third_party/skcms")
 }
 
diff --git a/dm/DMSrcSink.cpp b/dm/DMSrcSink.cpp
index ad685ad..2f84e62 100644
--- a/dm/DMSrcSink.cpp
+++ b/dm/DMSrcSink.cpp
@@ -26,6 +26,7 @@
 #include "include/ports/SkImageGeneratorWIC.h"
 #include "include/private/SkImageInfoPriv.h"
 #include "include/private/SkTLogic.h"
+#include "include/third_party/skcms/skcms.h"
 #include "include/utils/SkNullCanvas.h"
 #include "include/utils/SkRandom.h"
 #include "src/codec/SkCodecImageGenerator.h"
@@ -74,8 +75,6 @@
 #include <cmath>
 #include <functional>
 
-#include "skcms.h"
-
 static DEFINE_bool(multiPage, false,
                    "For document-type backends, render the source into multiple pages");
 static DEFINE_bool(RAW_threading, true, "Allow RAW decodes to run on multiple threads?");
diff --git a/include/core/SkColorSpace.h b/include/core/SkColorSpace.h
index 205554a..cb55114 100644
--- a/include/core/SkColorSpace.h
+++ b/include/core/SkColorSpace.h
@@ -10,7 +10,7 @@
 
 #include "include/private/SkFixed.h"
 #include "include/private/SkOnce.h"
-#include "skcms.h"
+#include "include/third_party/skcms/skcms.h"
 #include "include/core/SkMatrix44.h"
 #include "include/core/SkRefCnt.h"
 #include <memory>
diff --git a/include/private/SkEncodedInfo.h b/include/private/SkEncodedInfo.h
index c036b60..887198c 100644
--- a/include/private/SkEncodedInfo.h
+++ b/include/private/SkEncodedInfo.h
@@ -10,7 +10,7 @@
 
 #include "include/core/SkData.h"
 #include "include/core/SkImageInfo.h"
-#include "skcms.h"
+#include "include/third_party/skcms/skcms.h"
 
 struct SkEncodedInfo {
 public:
diff --git a/include/third_party/skcms/skcms.h b/include/third_party/skcms/skcms.h
new file mode 100644
index 0000000..6ca8236
--- /dev/null
+++ b/include/third_party/skcms/skcms.h
@@ -0,0 +1,310 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#pragma once
+
+// skcms.h contains the entire public API for skcms.
+
+#ifndef SKCMS_API
+    #define SKCMS_API
+#endif
+
+#include <stdbool.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// A row-major 3x3 matrix (ie vals[row][col])
+typedef struct skcms_Matrix3x3 {
+    float vals[3][3];
+} skcms_Matrix3x3;
+
+// It is _not_ safe to alias the pointers to invert in-place.
+SKCMS_API bool            skcms_Matrix3x3_invert(const skcms_Matrix3x3*, skcms_Matrix3x3*);
+SKCMS_API skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3*, const skcms_Matrix3x3*);
+
+// A row-major 3x4 matrix (ie vals[row][col])
+typedef struct skcms_Matrix3x4 {
+    float vals[3][4];
+} skcms_Matrix3x4;
+
+// A transfer function mapping encoded values to linear values,
+// represented by this 7-parameter piecewise function:
+//
+//   linear = sign(encoded) *  (c*|encoded| + f)       , 0 <= |encoded| < d
+//          = sign(encoded) * ((a*|encoded| + b)^g + e), d <= |encoded|
+//
+// (A simple gamma transfer function sets g to gamma and a to 1.)
+typedef struct skcms_TransferFunction {
+    float g, a,b,c,d,e,f;
+} skcms_TransferFunction;
+
+SKCMS_API float skcms_TransferFunction_eval  (const skcms_TransferFunction*, float);
+SKCMS_API bool  skcms_TransferFunction_invert(const skcms_TransferFunction*,
+                                              skcms_TransferFunction*);
+
+// Unified representation of 'curv' or 'para' tag data, or a 1D table from 'mft1' or 'mft2'
+typedef union skcms_Curve {
+    struct {
+        uint32_t alias_of_table_entries;
+        skcms_TransferFunction parametric;
+    };
+    struct {
+        uint32_t table_entries;
+        const uint8_t* table_8;
+        const uint8_t* table_16;
+    };
+} skcms_Curve;
+
+typedef struct skcms_A2B {
+    // Optional: N 1D curves, followed by an N-dimensional CLUT.
+    // If input_channels == 0, these curves and CLUT are skipped,
+    // Otherwise, input_channels must be in [1, 4].
+    uint32_t        input_channels;
+    skcms_Curve     input_curves[4];
+    uint8_t         grid_points[4];
+    const uint8_t*  grid_8;
+    const uint8_t*  grid_16;
+
+    // Optional: 3 1D curves, followed by a color matrix.
+    // If matrix_channels == 0, these curves and matrix are skipped,
+    // Otherwise, matrix_channels must be 3.
+    uint32_t        matrix_channels;
+    skcms_Curve     matrix_curves[3];
+    skcms_Matrix3x4 matrix;
+
+    // Required: 3 1D curves. Always present, and output_channels must be 3.
+    uint32_t        output_channels;
+    skcms_Curve     output_curves[3];
+} skcms_A2B;
+
+typedef struct skcms_ICCProfile {
+    const uint8_t* buffer;
+
+    uint32_t size;
+    uint32_t data_color_space;
+    uint32_t pcs;
+    uint32_t tag_count;
+
+    // skcms_Parse() will set commonly-used fields for you when possible:
+
+    // If we can parse red, green and blue transfer curves from the profile,
+    // trc will be set to those three curves, and has_trc will be true.
+    bool                   has_trc;
+    skcms_Curve            trc[3];
+
+    // If this profile's gamut can be represented by a 3x3 transform to XYZD50,
+    // skcms_Parse() sets toXYZD50 to that transform and has_toXYZD50 to true.
+    bool                   has_toXYZD50;
+    skcms_Matrix3x3        toXYZD50;
+
+    // If the profile has a valid A2B0 tag, skcms_Parse() sets A2B to that data,
+    // and has_A2B to true.
+    bool                   has_A2B;
+    skcms_A2B              A2B;
+} skcms_ICCProfile;
+
+// The sRGB color profile is so commonly used that we offer a canonical skcms_ICCProfile for it.
+SKCMS_API const skcms_ICCProfile* skcms_sRGB_profile(void);
+// Ditto for XYZD50, the most common profile connection space.
+SKCMS_API const skcms_ICCProfile* skcms_XYZD50_profile(void);
+
+SKCMS_API const skcms_TransferFunction* skcms_sRGB_TransferFunction(void);
+SKCMS_API const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction(void);
+SKCMS_API const skcms_TransferFunction* skcms_Identity_TransferFunction(void);
+
+// Practical equality test for two skcms_ICCProfiles.
+// The implementation is subject to change, but it will always try to answer
+// "can I substitute A for B?" and "can I skip transforming from A to B?".
+SKCMS_API bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A,
+                                                const skcms_ICCProfile* B);
+
+// Practical test that answers: Is curve roughly the inverse of inv_tf? Typically used by passing
+// the inverse of a known parametric transfer function (like sRGB), to determine if a particular
+// curve is very close to sRGB.
+SKCMS_API bool skcms_AreApproximateInverses(const skcms_Curve* curve,
+                                            const skcms_TransferFunction* inv_tf);
+
+// Similar to above, answering the question for all three TRC curves of the given profile. Again,
+// passing skcms_sRGB_InverseTransferFunction as inv_tf will answer the question:
+// "Does this profile have a transfer function that is very close to sRGB?"
+SKCMS_API bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile* profile,
+                                                const skcms_TransferFunction* inv_tf);
+
+// Parse an ICC profile and return true if possible, otherwise return false.
+// The buffer is not copied, it must remain valid as long as the skcms_ICCProfile
+// will be used.
+SKCMS_API bool skcms_Parse(const void*, size_t, skcms_ICCProfile*);
+
+SKCMS_API bool skcms_ApproximateCurve(const skcms_Curve* curve,
+                                      skcms_TransferFunction* approx,
+                                      float* max_error);
+
+typedef struct skcms_ICCTag {
+    uint32_t       signature;
+    uint32_t       type;
+    uint32_t       size;
+    const uint8_t* buf;
+} skcms_ICCTag;
+
+SKCMS_API void skcms_GetTagByIndex    (const skcms_ICCProfile*, uint32_t idx, skcms_ICCTag*);
+SKCMS_API bool skcms_GetTagBySignature(const skcms_ICCProfile*, uint32_t sig, skcms_ICCTag*);
+
+// These are common ICC signature values
+enum {
+    // data_color_space
+    skcms_Signature_CMYK = 0x434D594B,
+    skcms_Signature_Gray = 0x47524159,
+    skcms_Signature_RGB  = 0x52474220,
+
+    // pcs
+    skcms_Signature_Lab  = 0x4C616220,
+    skcms_Signature_XYZ  = 0x58595A20,
+};
+
+typedef enum skcms_PixelFormat {
+    skcms_PixelFormat_A_8,
+    skcms_PixelFormat_A_8_,
+    skcms_PixelFormat_G_8,
+    skcms_PixelFormat_G_8_,
+    skcms_PixelFormat_RGBA_8888_Palette8,
+    skcms_PixelFormat_BGRA_8888_Palette8,
+
+    skcms_PixelFormat_RGB_565,
+    skcms_PixelFormat_BGR_565,
+
+    skcms_PixelFormat_ABGR_4444,
+    skcms_PixelFormat_ARGB_4444,
+
+    skcms_PixelFormat_RGB_888,
+    skcms_PixelFormat_BGR_888,
+    skcms_PixelFormat_RGBA_8888,
+    skcms_PixelFormat_BGRA_8888,
+
+    skcms_PixelFormat_RGBA_1010102,
+    skcms_PixelFormat_BGRA_1010102,
+
+    skcms_PixelFormat_RGB_161616LE,     // Little-endian.  Pointers must be 16-bit aligned.
+    skcms_PixelFormat_BGR_161616LE,
+    skcms_PixelFormat_RGBA_16161616LE,
+    skcms_PixelFormat_BGRA_16161616LE,
+
+    skcms_PixelFormat_RGB_161616BE,     // Big-endian.  Pointers must be 16-bit aligned.
+    skcms_PixelFormat_BGR_161616BE,
+    skcms_PixelFormat_RGBA_16161616BE,
+    skcms_PixelFormat_BGRA_16161616BE,
+
+    // TODO: clean up references to non-explicit endian 16161616
+    skcms_PixelFormat_RGB_161616    = skcms_PixelFormat_RGB_161616BE,
+    skcms_PixelFormat_BGR_161616    = skcms_PixelFormat_BGR_161616BE,
+    skcms_PixelFormat_RGBA_16161616 = skcms_PixelFormat_RGBA_16161616BE,
+    skcms_PixelFormat_BGRA_16161616 = skcms_PixelFormat_BGRA_16161616BE,
+
+    skcms_PixelFormat_RGB_hhh_Norm,   // 1-5-10 half-precision float in [0,1]
+    skcms_PixelFormat_BGR_hhh_Norm,   // Pointers must be 16-bit aligned.
+    skcms_PixelFormat_RGBA_hhhh_Norm,
+    skcms_PixelFormat_BGRA_hhhh_Norm,
+
+    skcms_PixelFormat_RGB_hhh,        // 1-5-10 half-precision float.
+    skcms_PixelFormat_BGR_hhh,        // Pointers must be 16-bit aligned.
+    skcms_PixelFormat_RGBA_hhhh,
+    skcms_PixelFormat_BGRA_hhhh,
+
+    skcms_PixelFormat_RGB_fff,        // 1-8-23 single-precision float (the normal kind).
+    skcms_PixelFormat_BGR_fff,        // Pointers must be 32-bit aligned.
+    skcms_PixelFormat_RGBA_ffff,
+    skcms_PixelFormat_BGRA_ffff,
+} skcms_PixelFormat;
+
+// We always store any alpha channel linearly.  In the chart below, tf-1() is the inverse
+// transfer function for the given color profile (applying the transfer function linearizes).
+
+// We treat opaque as a strong requirement, not just a performance hint: we will ignore
+// any source alpha and treat it as 1.0, and will make sure that any destination alpha
+// channel is filled with the equivalent of 1.0.
+
+// We used to offer multiple types of premultiplication, but now just one, PremulAsEncoded.
+// This is the premul you're probably used to working with.
+
+typedef enum skcms_AlphaFormat {
+    skcms_AlphaFormat_Opaque,          // alpha is always opaque
+                                       //   tf-1(r),   tf-1(g),   tf-1(b),   1.0
+    skcms_AlphaFormat_Unpremul,        // alpha and color are unassociated
+                                       //   tf-1(r),   tf-1(g),   tf-1(b),   a
+    skcms_AlphaFormat_PremulAsEncoded, // premultiplied while encoded
+                                       //   tf-1(r)*a, tf-1(g)*a, tf-1(b)*a, a
+} skcms_AlphaFormat;
+
+// Convert npixels pixels from src format and color profile to dst format and color profile
+// and return true, otherwise return false.  It is safe to alias dst == src if dstFmt == srcFmt.
+SKCMS_API bool skcms_Transform(const void*             src,
+                               skcms_PixelFormat       srcFmt,
+                               skcms_AlphaFormat       srcAlpha,
+                               const skcms_ICCProfile* srcProfile,
+                               void*                   dst,
+                               skcms_PixelFormat       dstFmt,
+                               skcms_AlphaFormat       dstAlpha,
+                               const skcms_ICCProfile* dstProfile,
+                               size_t                  npixels);
+
+// As skcms_Transform(), supporting srcFmts with a palette.
+SKCMS_API bool skcms_TransformWithPalette(const void*             src,
+                                          skcms_PixelFormat       srcFmt,
+                                          skcms_AlphaFormat       srcAlpha,
+                                          const skcms_ICCProfile* srcProfile,
+                                          void*                   dst,
+                                          skcms_PixelFormat       dstFmt,
+                                          skcms_AlphaFormat       dstAlpha,
+                                          const skcms_ICCProfile* dstProfile,
+                                          size_t                  npixels,
+                                          const void*             palette);
+
+// If profile can be used as a destination in skcms_Transform, return true. Otherwise, attempt to
+// rewrite it with approximations where reasonable. If successful, return true. If no reasonable
+// approximation exists, leave the profile unchanged and return false.
+SKCMS_API bool skcms_MakeUsableAsDestination(skcms_ICCProfile* profile);
+
+// If profile can be used as a destination with a single parametric transfer function (ie for
+// rasterization), return true. Otherwise, attempt to rewrite it with approximations where
+// reasonable. If successful, return true. If no reasonable approximation exists, leave the
+// profile unchanged and return false.
+SKCMS_API bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile);
+
+SKCMS_API bool skcms_PrimariesToXYZD50(float rx, float ry,
+                                       float gx, float gy,
+                                       float bx, float by,
+                                       float wx, float wy,
+                                       skcms_Matrix3x3* toXYZD50);
+
+// Utilities for programmatically constructing profiles
+static inline void skcms_Init(skcms_ICCProfile* p) {
+    memset(p, 0, sizeof(*p));
+    p->data_color_space = skcms_Signature_RGB;
+    p->pcs = skcms_Signature_XYZ;
+}
+
+static inline void skcms_SetTransferFunction(skcms_ICCProfile* p,
+                                             const skcms_TransferFunction* tf) {
+    p->has_trc = true;
+    for (int i = 0; i < 3; ++i) {
+        p->trc[i].table_entries = 0;
+        p->trc[i].parametric = *tf;
+    }
+}
+
+static inline void skcms_SetXYZD50(skcms_ICCProfile* p, const skcms_Matrix3x3* m) {
+    p->has_toXYZD50 = true;
+    p->toXYZD50 = *m;
+}
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/public.bzl b/public.bzl
index 73b18d6..010fdc1 100644
--- a/public.bzl
+++ b/public.bzl
@@ -419,6 +419,7 @@
     "include/pathops",
     "include/ports",
     "include/private",
+    "include/third_party/skcms",
     "include/utils",
     "include/utils/mac",
     "src/codec",
@@ -436,7 +437,6 @@
     "src/sksl",
     "src/utils",
     "third_party/gif",
-    "third_party/skcms",
 ]
 
 ################################################################################
diff --git a/src/core/SkColorSpace.cpp b/src/core/SkColorSpace.cpp
index 9fe521f..bac4b88 100644
--- a/src/core/SkColorSpace.cpp
+++ b/src/core/SkColorSpace.cpp
@@ -7,9 +7,9 @@
 
 #include "include/core/SkColorSpace.h"
 #include "include/core/SkData.h"
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "src/core/SkOpts.h"
-#include "skcms.h"
 
 bool SkColorSpacePrimaries::toXYZD50(skcms_Matrix3x3* toXYZ_D50) const {
     return skcms_PrimariesToXYZD50(fRX, fRY, fGX, fGY, fBX, fBY, fWX, fWY, toXYZ_D50);
diff --git a/src/core/SkColorSpaceXformSteps.cpp b/src/core/SkColorSpaceXformSteps.cpp
index 07b5ebb..9c45121 100644
--- a/src/core/SkColorSpaceXformSteps.cpp
+++ b/src/core/SkColorSpaceXformSteps.cpp
@@ -5,10 +5,10 @@
  * found in the LICENSE file.
  */
 
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "src/core/SkColorSpaceXformSteps.h"
 #include "src/core/SkRasterPipeline.h"
-#include "skcms.h"
 
 // TODO(mtklein): explain the logic of this file
 
diff --git a/src/images/SkImageEncoderFns.h b/src/images/SkImageEncoderFns.h
index 058430b..42b9dd7 100644
--- a/src/images/SkImageEncoderFns.h
+++ b/src/images/SkImageEncoderFns.h
@@ -8,11 +8,11 @@
 #ifndef SkImageEncoderFns_DEFINED
 #define SkImageEncoderFns_DEFINED
 
-#include "skcms.h"
 #include "include/core/SkColor.h"
 #include "include/core/SkICC.h"
 #include "include/core/SkTypes.h"
 #include "include/private/SkColorData.h"
+#include "include/third_party/skcms/skcms.h"
 
 typedef void (*transform_scanline_proc)(char* dst, const char* src, int width, int bpp);
 
diff --git a/tests/ColorSpaceTest.cpp b/tests/ColorSpaceTest.cpp
index e8864d4..07516f7 100644
--- a/tests/ColorSpaceTest.cpp
+++ b/tests/ColorSpaceTest.cpp
@@ -12,11 +12,11 @@
 #include "include/core/SkRefCnt.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkTypes.h"
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "tests/Test.h"
 #include "tools/Resources.h"
 
-#include "skcms.h"
 #include "png.h"
 
 #include <memory>
diff --git a/tests/ICCTest.cpp b/tests/ICCTest.cpp
index 5a52f65..f9e62ce 100644
--- a/tests/ICCTest.cpp
+++ b/tests/ICCTest.cpp
@@ -9,12 +9,11 @@
 
 #include "include/core/SkICC.h"
 #include "include/core/SkString.h"
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpacePriv.h"
 #include "tests/Test.h"
 #include "tools/Resources.h"
 
-#include "skcms.h"
-
 DEF_TEST(AdobeRGB, r) {
     if (sk_sp<SkData> profile = GetResourceAsData("icc_profiles/AdobeRGB1998.icc")) {
         skcms_ICCProfile parsed;
diff --git a/tests/NonlinearBlendingTest.cpp b/tests/NonlinearBlendingTest.cpp
index 9c1d286..a4e9892 100644
--- a/tests/NonlinearBlendingTest.cpp
+++ b/tests/NonlinearBlendingTest.cpp
@@ -5,8 +5,8 @@
  * found in the LICENSE file.
  */
 
-#include "skcms.h"
 #include "include/core/SkColorSpace.h"
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpaceXformSteps.h"
 #include "tests/Test.h"
 
diff --git a/third_party/skcms/skcms.gni b/third_party/skcms/skcms.gni
index a3def6e..759f27f 100644
--- a/third_party/skcms/skcms.gni
+++ b/third_party/skcms/skcms.gni
@@ -5,7 +5,6 @@
 
 skcms_sources = [
   "skcms.cc",
-  "skcms.h",
   "skcms_internal.h",
   "src/Transform_inl.h",
 ]
diff --git a/third_party/skcms/skcms.h b/third_party/skcms/skcms.h
index 6ca8236..b09df14 100644
--- a/third_party/skcms/skcms.h
+++ b/third_party/skcms/skcms.h
@@ -1,310 +1,5 @@
-/*
- * Copyright 2018 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
+// Copyright 2019 Google LLC.
+// Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
 
-#pragma once
-
-// skcms.h contains the entire public API for skcms.
-
-#ifndef SKCMS_API
-    #define SKCMS_API
-#endif
-
-#include <stdbool.h>
-#include <stddef.h>
-#include <stdint.h>
-#include <string.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-// A row-major 3x3 matrix (ie vals[row][col])
-typedef struct skcms_Matrix3x3 {
-    float vals[3][3];
-} skcms_Matrix3x3;
-
-// It is _not_ safe to alias the pointers to invert in-place.
-SKCMS_API bool            skcms_Matrix3x3_invert(const skcms_Matrix3x3*, skcms_Matrix3x3*);
-SKCMS_API skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3*, const skcms_Matrix3x3*);
-
-// A row-major 3x4 matrix (ie vals[row][col])
-typedef struct skcms_Matrix3x4 {
-    float vals[3][4];
-} skcms_Matrix3x4;
-
-// A transfer function mapping encoded values to linear values,
-// represented by this 7-parameter piecewise function:
-//
-//   linear = sign(encoded) *  (c*|encoded| + f)       , 0 <= |encoded| < d
-//          = sign(encoded) * ((a*|encoded| + b)^g + e), d <= |encoded|
-//
-// (A simple gamma transfer function sets g to gamma and a to 1.)
-typedef struct skcms_TransferFunction {
-    float g, a,b,c,d,e,f;
-} skcms_TransferFunction;
-
-SKCMS_API float skcms_TransferFunction_eval  (const skcms_TransferFunction*, float);
-SKCMS_API bool  skcms_TransferFunction_invert(const skcms_TransferFunction*,
-                                              skcms_TransferFunction*);
-
-// Unified representation of 'curv' or 'para' tag data, or a 1D table from 'mft1' or 'mft2'
-typedef union skcms_Curve {
-    struct {
-        uint32_t alias_of_table_entries;
-        skcms_TransferFunction parametric;
-    };
-    struct {
-        uint32_t table_entries;
-        const uint8_t* table_8;
-        const uint8_t* table_16;
-    };
-} skcms_Curve;
-
-typedef struct skcms_A2B {
-    // Optional: N 1D curves, followed by an N-dimensional CLUT.
-    // If input_channels == 0, these curves and CLUT are skipped,
-    // Otherwise, input_channels must be in [1, 4].
-    uint32_t        input_channels;
-    skcms_Curve     input_curves[4];
-    uint8_t         grid_points[4];
-    const uint8_t*  grid_8;
-    const uint8_t*  grid_16;
-
-    // Optional: 3 1D curves, followed by a color matrix.
-    // If matrix_channels == 0, these curves and matrix are skipped,
-    // Otherwise, matrix_channels must be 3.
-    uint32_t        matrix_channels;
-    skcms_Curve     matrix_curves[3];
-    skcms_Matrix3x4 matrix;
-
-    // Required: 3 1D curves. Always present, and output_channels must be 3.
-    uint32_t        output_channels;
-    skcms_Curve     output_curves[3];
-} skcms_A2B;
-
-typedef struct skcms_ICCProfile {
-    const uint8_t* buffer;
-
-    uint32_t size;
-    uint32_t data_color_space;
-    uint32_t pcs;
-    uint32_t tag_count;
-
-    // skcms_Parse() will set commonly-used fields for you when possible:
-
-    // If we can parse red, green and blue transfer curves from the profile,
-    // trc will be set to those three curves, and has_trc will be true.
-    bool                   has_trc;
-    skcms_Curve            trc[3];
-
-    // If this profile's gamut can be represented by a 3x3 transform to XYZD50,
-    // skcms_Parse() sets toXYZD50 to that transform and has_toXYZD50 to true.
-    bool                   has_toXYZD50;
-    skcms_Matrix3x3        toXYZD50;
-
-    // If the profile has a valid A2B0 tag, skcms_Parse() sets A2B to that data,
-    // and has_A2B to true.
-    bool                   has_A2B;
-    skcms_A2B              A2B;
-} skcms_ICCProfile;
-
-// The sRGB color profile is so commonly used that we offer a canonical skcms_ICCProfile for it.
-SKCMS_API const skcms_ICCProfile* skcms_sRGB_profile(void);
-// Ditto for XYZD50, the most common profile connection space.
-SKCMS_API const skcms_ICCProfile* skcms_XYZD50_profile(void);
-
-SKCMS_API const skcms_TransferFunction* skcms_sRGB_TransferFunction(void);
-SKCMS_API const skcms_TransferFunction* skcms_sRGB_Inverse_TransferFunction(void);
-SKCMS_API const skcms_TransferFunction* skcms_Identity_TransferFunction(void);
-
-// Practical equality test for two skcms_ICCProfiles.
-// The implementation is subject to change, but it will always try to answer
-// "can I substitute A for B?" and "can I skip transforming from A to B?".
-SKCMS_API bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile* A,
-                                                const skcms_ICCProfile* B);
-
-// Practical test that answers: Is curve roughly the inverse of inv_tf? Typically used by passing
-// the inverse of a known parametric transfer function (like sRGB), to determine if a particular
-// curve is very close to sRGB.
-SKCMS_API bool skcms_AreApproximateInverses(const skcms_Curve* curve,
-                                            const skcms_TransferFunction* inv_tf);
-
-// Similar to above, answering the question for all three TRC curves of the given profile. Again,
-// passing skcms_sRGB_InverseTransferFunction as inv_tf will answer the question:
-// "Does this profile have a transfer function that is very close to sRGB?"
-SKCMS_API bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile* profile,
-                                                const skcms_TransferFunction* inv_tf);
-
-// Parse an ICC profile and return true if possible, otherwise return false.
-// The buffer is not copied, it must remain valid as long as the skcms_ICCProfile
-// will be used.
-SKCMS_API bool skcms_Parse(const void*, size_t, skcms_ICCProfile*);
-
-SKCMS_API bool skcms_ApproximateCurve(const skcms_Curve* curve,
-                                      skcms_TransferFunction* approx,
-                                      float* max_error);
-
-typedef struct skcms_ICCTag {
-    uint32_t       signature;
-    uint32_t       type;
-    uint32_t       size;
-    const uint8_t* buf;
-} skcms_ICCTag;
-
-SKCMS_API void skcms_GetTagByIndex    (const skcms_ICCProfile*, uint32_t idx, skcms_ICCTag*);
-SKCMS_API bool skcms_GetTagBySignature(const skcms_ICCProfile*, uint32_t sig, skcms_ICCTag*);
-
-// These are common ICC signature values
-enum {
-    // data_color_space
-    skcms_Signature_CMYK = 0x434D594B,
-    skcms_Signature_Gray = 0x47524159,
-    skcms_Signature_RGB  = 0x52474220,
-
-    // pcs
-    skcms_Signature_Lab  = 0x4C616220,
-    skcms_Signature_XYZ  = 0x58595A20,
-};
-
-typedef enum skcms_PixelFormat {
-    skcms_PixelFormat_A_8,
-    skcms_PixelFormat_A_8_,
-    skcms_PixelFormat_G_8,
-    skcms_PixelFormat_G_8_,
-    skcms_PixelFormat_RGBA_8888_Palette8,
-    skcms_PixelFormat_BGRA_8888_Palette8,
-
-    skcms_PixelFormat_RGB_565,
-    skcms_PixelFormat_BGR_565,
-
-    skcms_PixelFormat_ABGR_4444,
-    skcms_PixelFormat_ARGB_4444,
-
-    skcms_PixelFormat_RGB_888,
-    skcms_PixelFormat_BGR_888,
-    skcms_PixelFormat_RGBA_8888,
-    skcms_PixelFormat_BGRA_8888,
-
-    skcms_PixelFormat_RGBA_1010102,
-    skcms_PixelFormat_BGRA_1010102,
-
-    skcms_PixelFormat_RGB_161616LE,     // Little-endian.  Pointers must be 16-bit aligned.
-    skcms_PixelFormat_BGR_161616LE,
-    skcms_PixelFormat_RGBA_16161616LE,
-    skcms_PixelFormat_BGRA_16161616LE,
-
-    skcms_PixelFormat_RGB_161616BE,     // Big-endian.  Pointers must be 16-bit aligned.
-    skcms_PixelFormat_BGR_161616BE,
-    skcms_PixelFormat_RGBA_16161616BE,
-    skcms_PixelFormat_BGRA_16161616BE,
-
-    // TODO: clean up references to non-explicit endian 16161616
-    skcms_PixelFormat_RGB_161616    = skcms_PixelFormat_RGB_161616BE,
-    skcms_PixelFormat_BGR_161616    = skcms_PixelFormat_BGR_161616BE,
-    skcms_PixelFormat_RGBA_16161616 = skcms_PixelFormat_RGBA_16161616BE,
-    skcms_PixelFormat_BGRA_16161616 = skcms_PixelFormat_BGRA_16161616BE,
-
-    skcms_PixelFormat_RGB_hhh_Norm,   // 1-5-10 half-precision float in [0,1]
-    skcms_PixelFormat_BGR_hhh_Norm,   // Pointers must be 16-bit aligned.
-    skcms_PixelFormat_RGBA_hhhh_Norm,
-    skcms_PixelFormat_BGRA_hhhh_Norm,
-
-    skcms_PixelFormat_RGB_hhh,        // 1-5-10 half-precision float.
-    skcms_PixelFormat_BGR_hhh,        // Pointers must be 16-bit aligned.
-    skcms_PixelFormat_RGBA_hhhh,
-    skcms_PixelFormat_BGRA_hhhh,
-
-    skcms_PixelFormat_RGB_fff,        // 1-8-23 single-precision float (the normal kind).
-    skcms_PixelFormat_BGR_fff,        // Pointers must be 32-bit aligned.
-    skcms_PixelFormat_RGBA_ffff,
-    skcms_PixelFormat_BGRA_ffff,
-} skcms_PixelFormat;
-
-// We always store any alpha channel linearly.  In the chart below, tf-1() is the inverse
-// transfer function for the given color profile (applying the transfer function linearizes).
-
-// We treat opaque as a strong requirement, not just a performance hint: we will ignore
-// any source alpha and treat it as 1.0, and will make sure that any destination alpha
-// channel is filled with the equivalent of 1.0.
-
-// We used to offer multiple types of premultiplication, but now just one, PremulAsEncoded.
-// This is the premul you're probably used to working with.
-
-typedef enum skcms_AlphaFormat {
-    skcms_AlphaFormat_Opaque,          // alpha is always opaque
-                                       //   tf-1(r),   tf-1(g),   tf-1(b),   1.0
-    skcms_AlphaFormat_Unpremul,        // alpha and color are unassociated
-                                       //   tf-1(r),   tf-1(g),   tf-1(b),   a
-    skcms_AlphaFormat_PremulAsEncoded, // premultiplied while encoded
-                                       //   tf-1(r)*a, tf-1(g)*a, tf-1(b)*a, a
-} skcms_AlphaFormat;
-
-// Convert npixels pixels from src format and color profile to dst format and color profile
-// and return true, otherwise return false.  It is safe to alias dst == src if dstFmt == srcFmt.
-SKCMS_API bool skcms_Transform(const void*             src,
-                               skcms_PixelFormat       srcFmt,
-                               skcms_AlphaFormat       srcAlpha,
-                               const skcms_ICCProfile* srcProfile,
-                               void*                   dst,
-                               skcms_PixelFormat       dstFmt,
-                               skcms_AlphaFormat       dstAlpha,
-                               const skcms_ICCProfile* dstProfile,
-                               size_t                  npixels);
-
-// As skcms_Transform(), supporting srcFmts with a palette.
-SKCMS_API bool skcms_TransformWithPalette(const void*             src,
-                                          skcms_PixelFormat       srcFmt,
-                                          skcms_AlphaFormat       srcAlpha,
-                                          const skcms_ICCProfile* srcProfile,
-                                          void*                   dst,
-                                          skcms_PixelFormat       dstFmt,
-                                          skcms_AlphaFormat       dstAlpha,
-                                          const skcms_ICCProfile* dstProfile,
-                                          size_t                  npixels,
-                                          const void*             palette);
-
-// If profile can be used as a destination in skcms_Transform, return true. Otherwise, attempt to
-// rewrite it with approximations where reasonable. If successful, return true. If no reasonable
-// approximation exists, leave the profile unchanged and return false.
-SKCMS_API bool skcms_MakeUsableAsDestination(skcms_ICCProfile* profile);
-
-// If profile can be used as a destination with a single parametric transfer function (ie for
-// rasterization), return true. Otherwise, attempt to rewrite it with approximations where
-// reasonable. If successful, return true. If no reasonable approximation exists, leave the
-// profile unchanged and return false.
-SKCMS_API bool skcms_MakeUsableAsDestinationWithSingleCurve(skcms_ICCProfile* profile);
-
-SKCMS_API bool skcms_PrimariesToXYZD50(float rx, float ry,
-                                       float gx, float gy,
-                                       float bx, float by,
-                                       float wx, float wy,
-                                       skcms_Matrix3x3* toXYZD50);
-
-// Utilities for programmatically constructing profiles
-static inline void skcms_Init(skcms_ICCProfile* p) {
-    memset(p, 0, sizeof(*p));
-    p->data_color_space = skcms_Signature_RGB;
-    p->pcs = skcms_Signature_XYZ;
-}
-
-static inline void skcms_SetTransferFunction(skcms_ICCProfile* p,
-                                             const skcms_TransferFunction* tf) {
-    p->has_trc = true;
-    for (int i = 0; i < 3; ++i) {
-        p->trc[i].table_entries = 0;
-        p->trc[i].parametric = *tf;
-    }
-}
-
-static inline void skcms_SetXYZD50(skcms_ICCProfile* p, const skcms_Matrix3x3* m) {
-    p->has_toXYZD50 = true;
-    p->toXYZD50 = *m;
-}
-
-#ifdef __cplusplus
-}
-#endif
+// This is a temporary redirection header until clients are updated to use the skcms.h in include
+#include "../../include/third_party/skcms/skcms.h"
diff --git a/tools/imgcvt.cpp b/tools/imgcvt.cpp
index 71b599c..5c024f0 100644
--- a/tools/imgcvt.cpp
+++ b/tools/imgcvt.cpp
@@ -5,12 +5,12 @@
 * found in the LICENSE file.
 */
 
-#include "skcms.h"
 #include "include/core/SkCanvas.h"
 #include "include/core/SkData.h"
 #include "include/core/SkImage.h"
 #include "include/core/SkStream.h"
 #include "include/core/SkSurface.h"
+#include "include/third_party/skcms/skcms.h"
 #include "src/core/SkColorSpacePriv.h"
 
 static void write_png(const char* path, sk_sp<SkImage> img) {