Add SkColorSpaceXform to the public API
BUG=skia:
GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2390263002
Review-Url: https://codereview.chromium.org/2390263002
diff --git a/bench/ColorCodecBench.cpp b/bench/ColorCodecBench.cpp
index b2bb658..3b0ff67 100644
--- a/bench/ColorCodecBench.cpp
+++ b/bench/ColorCodecBench.cpp
@@ -101,9 +101,9 @@
void* dst = fDst.get();
void* src = fSrc.get();
for (int y = 0; y < fSrcInfo.height(); y++) {
- xform->apply(dst, (uint32_t*) src, fSrcInfo.width(),
- select_xform_format(fDstInfo.colorType()),
- SkColorSpaceXform::kRGBA_8888_ColorFormat, fDstInfo.alphaType());
+ SkAssertResult(xform->apply(select_xform_format(fDstInfo.colorType()), dst,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, src,
+ fSrcInfo.width(), fDstInfo.alphaType()));
dst = SkTAddOffset<void>(dst, fDstInfo.minRowBytes());
src = SkTAddOffset<void>(src, fSrcInfo.minRowBytes());
}
diff --git a/gm/colorspacexform.cpp b/gm/colorspacexform.cpp
index 34abdc4b..33320ba 100644
--- a/gm/colorspacexform.cpp
+++ b/gm/colorspacexform.cpp
@@ -41,9 +41,9 @@
std::unique_ptr<SkColorSpaceXform> xform = SkColorSpaceXform::New(srcSpace.get(),
dstSpace.get());
- xform->apply(fWideGamutColors, colors, kNumColors,
- SkColorSpaceXform::kRGBA_F32_ColorFormat,
- SkColorSpaceXform::kBGRA_8888_ColorFormat, kOpaque_SkAlphaType);
+ xform->apply(SkColorSpaceXform::kRGBA_F32_ColorFormat, fWideGamutColors,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, colors, kNumColors,
+ kOpaque_SkAlphaType);
}
SkString onShortName() override {
diff --git a/include/core/SkColorSpaceXform.h b/include/core/SkColorSpaceXform.h
new file mode 100644
index 0000000..15b3d49
--- /dev/null
+++ b/include/core/SkColorSpaceXform.h
@@ -0,0 +1,67 @@
+/*
+ * 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 SkColorSpaceXform_DEFINED
+#define SkColorSpaceXform_DEFINED
+
+#include "SkImageInfo.h"
+
+class SkColorSpace;
+
+class SkColorSpaceXform : SkNoncopyable {
+public:
+
+ /**
+ * Create an object to handle color space conversions.
+ *
+ * @param srcSpace The encoded color space.
+ * @param dstSpace The destination color space.
+ *
+ */
+ static std::unique_ptr<SkColorSpaceXform> New(SkColorSpace* srcSpace, SkColorSpace* dstSpace);
+
+ enum ColorFormat {
+ kRGBA_8888_ColorFormat,
+ kBGRA_8888_ColorFormat,
+ kRGBA_F16_ColorFormat,
+ kRGBA_F32_ColorFormat,
+ };
+
+ /**
+ * Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer.
+ *
+ * F16 and F32 are only supported as dst color formats, and only when the dst color space
+ * is linear. This function will return false in unsupported cases.
+ *
+ * @param dst Stored in the format described by |dstColorFormat|
+ * @param src Stored in the format described by |srcColorFormat|
+ * @param len Number of pixels in the buffers
+ * @param dstColorFormat Describes color format of |dst|
+ * @param srcColorFormat Describes color format of |src|
+ * Must be kRGBA_8888 or kBGRA_8888
+ * @param alphaType Describes alpha properties of the |dst| (and |src|)
+ * kUnpremul preserves input alpha values
+ * kPremul performs a premultiplication and also preserves alpha values
+ * kOpaque optimization hint, |dst| alphas set to 1
+ *
+ */
+ bool apply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src, int count,
+ SkAlphaType alphaType) const {
+ return this->onApply(dstFormat, dst, srcFormat, src, count, alphaType);
+ }
+
+
+ virtual ~SkColorSpaceXform() {}
+
+protected:
+ virtual bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
+ int count, SkAlphaType alphaType) const = 0;
+
+ SkColorSpaceXform() {}
+};
+
+#endif
diff --git a/src/codec/SkCodecPriv.h b/src/codec/SkCodecPriv.h
index b93def8..f210303 100644
--- a/src/codec/SkCodecPriv.h
+++ b/src/codec/SkCodecPriv.h
@@ -176,8 +176,8 @@
SkASSERT(colorXform);
uint64_t dstColor;
uint32_t srcColor = colorPtr[fillIndex];
- colorXform->apply(&dstColor, &srcColor, 1, select_xform_format(dstColorType),
- SkColorSpaceXform::kRGBA_8888_ColorFormat, alphaType);
+ SkAssertResult(colorXform->apply(select_xform_format(dstColorType), &dstColor,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, &srcColor, 1, alphaType));
return dstColor;
}
default:
diff --git a/src/codec/SkJpegCodec.cpp b/src/codec/SkJpegCodec.cpp
index f6c856e..92ab2bc 100644
--- a/src/codec/SkJpegCodec.cpp
+++ b/src/codec/SkJpegCodec.cpp
@@ -517,8 +517,9 @@
}
if (fColorXform) {
- fColorXform->apply(dst, swizzleDst, dstWidth, select_xform_format(dstInfo.colorType()),
- SkColorSpaceXform::kRGBA_8888_ColorFormat, kOpaque_SkAlphaType);
+ SkAssertResult(fColorXform->apply(select_xform_format(dstInfo.colorType()), dst,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, swizzleDst,
+ dstWidth, kOpaque_SkAlphaType));
dst = SkTAddOffset<void>(dst, rowBytes);
}
diff --git a/src/codec/SkPngCodec.cpp b/src/codec/SkPngCodec.cpp
index 55a2960..83032e6 100644
--- a/src/codec/SkPngCodec.cpp
+++ b/src/codec/SkPngCodec.cpp
@@ -272,8 +272,9 @@
SkColorSpaceXform::kBGRA_8888_ColorFormat;
SkAlphaType xformAlphaType = select_xform_alpha(dstInfo.alphaType(),
this->getInfo().alphaType());
- fColorXform->apply(colorTable, colorTable, numColors, xformColorFormat,
- SkColorSpaceXform::kRGBA_8888_ColorFormat, xformAlphaType);
+ SkAssertResult(fColorXform->apply(xformColorFormat, colorTable,
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, colorTable,
+ numColors, xformAlphaType));
}
// Pad the color table with the last color in the table (or black) in the case that
@@ -441,13 +442,13 @@
fSwizzler->swizzle(dst, (const uint8_t*) src);
break;
case kColorOnly_XformMode:
- fColorXform->apply(dst, (const uint32_t*) src, fXformWidth, fXformColorFormat,
- srcColorFormat, fXformAlphaType);
+ SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, src,
+ fXformWidth, fXformAlphaType));
break;
case kSwizzleColor_XformMode:
fSwizzler->swizzle(fColorXformSrcRow, (const uint8_t*) src);
- fColorXform->apply(dst, fColorXformSrcRow, fXformWidth, fXformColorFormat,
- srcColorFormat, fXformAlphaType);
+ SkAssertResult(fColorXform->apply(fXformColorFormat, dst, srcColorFormat, fColorXformSrcRow,
+ fXformWidth, fXformAlphaType));
break;
}
}
diff --git a/src/codec/SkWebpCodec.cpp b/src/codec/SkWebpCodec.cpp
index 3e5ef2a..443a4a0 100644
--- a/src/codec/SkWebpCodec.cpp
+++ b/src/codec/SkWebpCodec.cpp
@@ -315,8 +315,9 @@
uint32_t* src = (uint32_t*) config.output.u.RGBA.rgba;
size_t srcRowBytes = config.output.u.RGBA.stride;
for (int y = 0; y < rowsDecoded; y++) {
- colorXform->apply(dst, src, dstInfo.width(), dstColorFormat,
- SkColorSpaceXform::kBGRA_8888_ColorFormat, xformAlphaType);
+ SkAssertResult(colorXform->apply(dstColorFormat, dst,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, src,
+ dstInfo.width(), xformAlphaType));
dst = SkTAddOffset<void>(dst, rowBytes);
src = SkTAddOffset<uint32_t>(src, srcRowBytes);
}
diff --git a/src/core/SkColorSpaceXform.cpp b/src/core/SkColorSpaceXform.cpp
index 6a67875..5abc476 100644
--- a/src/core/SkColorSpaceXform.cpp
+++ b/src/core/SkColorSpaceXform.cpp
@@ -8,7 +8,7 @@
#include "SkColorPriv.h"
#include "SkColorSpace_Base.h"
#include "SkColorSpacePriv.h"
-#include "SkColorSpaceXform.h"
+#include "SkColorSpaceXform_Base.h"
#include "SkHalf.h"
#include "SkOpts.h"
#include "SkSRGB.h"
@@ -584,8 +584,9 @@
}
}
-static void handle_color_lut(uint32_t* dst, const uint32_t* src, int len,
+static void handle_color_lut(uint32_t* dst, const void* vsrc, int len,
SkColorLookUpTable* colorLUT) {
+ const uint32_t* src = (const uint32_t*) vsrc;
while (len-- > 0) {
uint8_t r = (*src >> 0) & 0xFF,
g = (*src >> 8) & 0xFF,
@@ -1012,10 +1013,11 @@
template <SkAlphaType kAlphaType,
ColorSpaceMatch kCSM>
-static inline void do_color_xform(void* dst, const uint32_t* src, int len,
+static inline void do_color_xform(void* dst, const void* vsrc, int len,
const float* const srcTables[3], const float matrix[16],
const uint8_t* const dstTables[3], LoadFn load, Load1Fn load_1,
StoreFn store, Store1Fn store_1, size_t sizeOfDstPixel) {
+ const uint32_t* src = (const uint32_t*) vsrc;
Sk4f rXgXbX, rYgYbY, rZgZbZ, rTgTbT;
load_matrix(matrix, rXgXbX, rYgYbY, rZgZbZ, rTgTbT);
@@ -1117,7 +1119,7 @@
DstFormat kDst,
SkAlphaType kAlphaType,
ColorSpaceMatch kCSM>
-static void color_xform_RGBA(void* dst, const uint32_t* src, int len,
+static void color_xform_RGBA(void* dst, const void* src, int len,
const float* const srcTables[3], const float matrix[16],
const uint8_t* const dstTables[3]) {
LoadFn load;
@@ -1276,27 +1278,29 @@
///////////////////////////////////////////////////////////////////////////////////////////////////
template <SrcFormat kSrc, DstFormat kDst, ColorSpaceMatch kCSM>
-static inline void apply_set_alpha(void* dst, const uint32_t* src, int len, SkAlphaType alphaType,
+static inline bool apply_set_alpha(void* dst, const void* src, int len, SkAlphaType alphaType,
const float* const srcTables[3], const float matrix[16],
const uint8_t* const dstTables[3]) {
switch (alphaType) {
case kOpaque_SkAlphaType:
- return color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM>
+ color_xform_RGBA<kSrc, kDst, kOpaque_SkAlphaType, kCSM>
(dst, src, len, srcTables, matrix, dstTables);
+ return true;
case kPremul_SkAlphaType:
- return color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM>
+ color_xform_RGBA<kSrc, kDst, kPremul_SkAlphaType, kCSM>
(dst, src, len, srcTables, matrix, dstTables);
+ return true;
case kUnpremul_SkAlphaType:
- return color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM>
+ color_xform_RGBA<kSrc, kDst, kUnpremul_SkAlphaType, kCSM>
(dst, src, len, srcTables, matrix, dstTables);
+ return true;
default:
- SkASSERT(false);
- return;
+ return false;
}
}
template <SrcGamma kSrc, DstFormat kDst, ColorSpaceMatch kCSM>
-static inline void apply_set_src(void* dst, const uint32_t* src, int len, SkAlphaType alphaType,
+static inline bool apply_set_src(void* dst, const void* src, int len, SkAlphaType alphaType,
const float* const srcTables[3], const float matrix[16],
const uint8_t* const dstTables[3],
SkColorSpaceXform::ColorFormat srcColorFormat) {
@@ -1320,15 +1324,14 @@
(dst, src, len, alphaType, srcTables, matrix, dstTables);
}
default:
- SkASSERT(false);
+ return false;
}
}
template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-void SkColorSpaceXform_Base<kSrc, kDst, kCSM>
-::apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat,
- ColorFormat srcColorFormat, SkAlphaType alphaType)
-const
+bool SkColorSpaceXform_Base<kSrc, kDst, kCSM>
+::onApply(ColorFormat dstColorFormat, void* dst, ColorFormat srcColorFormat, const void* src,
+ int len, SkAlphaType alphaType) const
{
if (kFull_ColorSpaceMatch == kCSM) {
switch (alphaType) {
@@ -1339,16 +1342,17 @@
default:
switch (dstColorFormat) {
case kRGBA_8888_ColorFormat:
- return (void) memcpy(dst, src, len * sizeof(uint32_t));
+ memcpy(dst, src, len * sizeof(uint32_t));
+ return true;
case kBGRA_8888_ColorFormat:
- return SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len);
+ SkOpts::RGBA_to_BGRA((uint32_t*) dst, src, len);
+ return true;
case kRGBA_F16_ColorFormat:
case kRGBA_F32_ColorFormat:
// There's still work to do to xform to linear floats.
break;
default:
- SkASSERT(false);
- return;
+ return false;
}
}
}
@@ -1412,8 +1416,7 @@
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat);
default:
- SkASSERT(false);
- return;
+ return false;
}
case kRGBA_F32_ColorFormat:
switch (kDst) {
@@ -1422,12 +1425,10 @@
(dst, src, len, alphaType, fSrcGammaTables, fSrcToDst, nullptr,
srcColorFormat);
default:
- SkASSERT(false);
- return;
+ return false;
}
default:
- SkASSERT(false);
- return;
+ return false;
}
}
diff --git a/src/core/SkColorSpaceXform.h b/src/core/SkColorSpaceXform.h
deleted file mode 100644
index bb99071..0000000
--- a/src/core/SkColorSpaceXform.h
+++ /dev/null
@@ -1,102 +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 SkColorSpaceXform_DEFINED
-#define SkColorSpaceXform_DEFINED
-
-#include "SkColorSpace.h"
-#include "SkColorSpace_Base.h"
-#include "SkImageInfo.h"
-
-class SkColorSpaceXform : SkNoncopyable {
-public:
-
- /**
- * Create an object to handle color space conversions.
- *
- * @param srcSpace The encoded color space.
- * @param dstSpace The destination color space.
- *
- */
- static std::unique_ptr<SkColorSpaceXform> New(SkColorSpace* srcSpace, SkColorSpace* dstSpace);
-
- enum ColorFormat : uint8_t {
- kRGBA_8888_ColorFormat,
- kBGRA_8888_ColorFormat,
- kRGBA_F16_ColorFormat,
- kRGBA_F32_ColorFormat,
- };
-
- /**
- * Apply the color conversion to a |src| buffer, storing the output in the |dst| buffer.
- *
- * @param dst Stored in the format described by |dstColorFormat|
- * @param src Stored in the format described by |srcColorFormat|
- * @param len Number of pixels in the buffers
- * @param dstColorFormat Describes color format of |dst|
- * @param srcColorFormat Describes color format of |src|
- * Must be kRGBA_8888 or kBGRA_8888
- * @param alphaType Describes alpha properties of the |dst| (and |src|)
- * kUnpremul preserves input alpha values
- * kPremul performs a premultiplication and also preserves alpha values
- * kOpaque optimization hint, |dst| alphas set to 1
- *
- */
- virtual void apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat,
- ColorFormat srcColorFormat, SkAlphaType alphaType) const = 0;
-
- virtual ~SkColorSpaceXform() {}
-};
-
-enum SrcGamma {
- kLinear_SrcGamma,
- kTable_SrcGamma,
-};
-
-enum DstGamma {
- kLinear_DstGamma,
- kSRGB_DstGamma,
- k2Dot2_DstGamma,
- kTable_DstGamma,
-};
-
-enum ColorSpaceMatch {
- kNone_ColorSpaceMatch,
- kGamut_ColorSpaceMatch,
- kFull_ColorSpaceMatch,
-};
-
-template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
-class SkColorSpaceXform_Base : public SkColorSpaceXform {
-public:
-
- void apply(void* dst, const uint32_t* src, int len, ColorFormat dstColorFormat,
- ColorFormat srcColorFormat, SkAlphaType alphaType) const override;
-
- static constexpr int kDstGammaTableSize = 1024;
-
-private:
- SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
- SkColorSpace* dstSpace);
-
- sk_sp<SkColorLookUpTable> fColorLUT;
-
- // Contain pointers into storage or pointers into precomputed tables.
- const float* fSrcGammaTables[3];
- const uint8_t* fDstGammaTables[3];
- SkAutoMalloc fStorage;
-
- float fSrcToDst[16];
-
- friend class SkColorSpaceXform;
- friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space);
-};
-
-// For testing. Bypasses opts for when src and dst color spaces are equal.
-std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space);
-
-#endif
diff --git a/src/core/SkColorSpaceXform_Base.h b/src/core/SkColorSpaceXform_Base.h
new file mode 100644
index 0000000..02714ad
--- /dev/null
+++ b/src/core/SkColorSpaceXform_Base.h
@@ -0,0 +1,62 @@
+/*
+ * 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 SkColorSpaceXform_Base_DEFINED
+#define SkColorSpaceXform_Base_DEFINED
+
+#include "SkColorSpace.h"
+#include "SkColorSpace_Base.h"
+#include "SkColorSpaceXform.h"
+
+enum SrcGamma {
+ kLinear_SrcGamma,
+ kTable_SrcGamma,
+};
+
+enum DstGamma {
+ kLinear_DstGamma,
+ kSRGB_DstGamma,
+ k2Dot2_DstGamma,
+ kTable_DstGamma,
+};
+
+enum ColorSpaceMatch {
+ kNone_ColorSpaceMatch,
+ kGamut_ColorSpaceMatch,
+ kFull_ColorSpaceMatch,
+};
+
+template <SrcGamma kSrc, DstGamma kDst, ColorSpaceMatch kCSM>
+class SkColorSpaceXform_Base : public SkColorSpaceXform {
+public:
+ static constexpr int kDstGammaTableSize = 1024;
+
+protected:
+ bool onApply(ColorFormat dstFormat, void* dst, ColorFormat srcFormat, const void* src,
+ int count, SkAlphaType alphaType) const override;
+
+private:
+ SkColorSpaceXform_Base(SkColorSpace* srcSpace, const SkMatrix44& srcToDst,
+ SkColorSpace* dstSpace);
+
+ sk_sp<SkColorLookUpTable> fColorLUT;
+
+ // Contain pointers into storage or pointers into precomputed tables.
+ const float* fSrcGammaTables[3];
+ const uint8_t* fDstGammaTables[3];
+ SkAutoMalloc fStorage;
+
+ float fSrcToDst[16];
+
+ friend class SkColorSpaceXform;
+ friend std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space);
+};
+
+// For testing. Bypasses opts for when src and dst color spaces are equal.
+std::unique_ptr<SkColorSpaceXform> SlowIdentityXform(SkColorSpace* space);
+
+#endif
diff --git a/tests/ColorSpaceXformTest.cpp b/tests/ColorSpaceXformTest.cpp
index ed990fc..f792c6a 100644
--- a/tests/ColorSpaceXformTest.cpp
+++ b/tests/ColorSpaceXformTest.cpp
@@ -11,7 +11,7 @@
#include "SkColorPriv.h"
#include "SkColorSpace.h"
#include "SkColorSpace_Base.h"
-#include "SkColorSpaceXform.h"
+#include "SkColorSpaceXform_Base.h"
#include "Test.h"
class ColorSpaceXformTest {
@@ -40,8 +40,10 @@
// Create and perform an identity xform.
std::unique_ptr<SkColorSpaceXform> xform = ColorSpaceXformTest::CreateIdentityXform(gammas);
- xform->apply(dstPixels, srcPixels, width, select_xform_format(kN32_SkColorType),
- SkColorSpaceXform::kBGRA_8888_ColorFormat, kOpaque_SkAlphaType);
+ bool result = xform->apply(select_xform_format(kN32_SkColorType), dstPixels,
+ SkColorSpaceXform::kBGRA_8888_ColorFormat, srcPixels, width,
+ kOpaque_SkAlphaType);
+ REPORTER_ASSERT(r, result);
// Since the src->dst matrix is the identity, and the gamma curves match,
// the pixels should be unchanged.
@@ -182,6 +184,8 @@
sk_sp<SkColorSpace> srcSpace = SkColorSpace::NewICC(iccData->bytes(), iccData->size());
sk_sp<SkColorSpace> dstSpace = SkColorSpace::NewNamed(SkColorSpace::kSRGB_Named);
auto xform = SkColorSpaceXform::New(srcSpace.get(), dstSpace.get());
- xform->apply(dst.get(), src.get(), len, SkColorSpaceXform::kRGBA_8888_ColorFormat,
- SkColorSpaceXform::kRGBA_8888_ColorFormat, kUnpremul_SkAlphaType);
+ bool result = xform->apply(SkColorSpaceXform::kRGBA_8888_ColorFormat, dst.get(),
+ SkColorSpaceXform::kRGBA_8888_ColorFormat, src.get(), len,
+ kUnpremul_SkAlphaType);
+ REPORTER_ASSERT(r, result);
}