return SkColorSpace_Base::MakeRGB(k2Dot2Curve_SkGammaNamed, toXYZD50);
}
+ if (is_almost_linear(coeffs)) {
+ return SkColorSpace_Base::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));
}
if (coeffs.fD == 0.0f) {
- // Y = (aX + b)^g + c for always
+ // Y = (aX + b)^g + e for always
if (0.0f == coeffs.fA || 0.0f == coeffs.fG) {
SkColorSpacePrintf("A or G is zero, constant transfer function "
"is nonsense");
}
if (coeffs.fD >= 1.0f) {
- // Y = eX + f for always
- if (0.0f == coeffs.fE) {
- SkColorSpacePrintf("E is zero, constant transfer function is "
+ // Y = cX + f for always
+ if (0.0f == coeffs.fC) {
+ SkColorSpacePrintf("C is zero, constant transfer function is "
"nonsense");
return false;
}
}
if ((0.0f == coeffs.fA || 0.0f == coeffs.fG) && 0.0f == coeffs.fC) {
- SkColorSpacePrintf("A or G, and E are zero, constant transfer function "
+ SkColorSpacePrintf("A or G, and C are zero, constant transfer function "
"is nonsense");
return false;
}
static inline bool is_almost_2dot2(const SkColorSpaceTransferFn& coeffs) {
return color_space_almost_equal(1.0f, coeffs.fA) &&
color_space_almost_equal(0.0f, coeffs.fB) &&
- color_space_almost_equal(0.0f, coeffs.fC) &&
- color_space_almost_equal(0.0f, coeffs.fD) &&
color_space_almost_equal(0.0f, coeffs.fE) &&
+ color_space_almost_equal(2.2f, coeffs.fG) &&
+ coeffs.fD <= 0.0f;
+}
+
+static inline bool is_almost_linear(const SkColorSpaceTransferFn& coeffs) {
+ // OutputVal = InputVal ^ 1.0f
+ const bool linearExp =
+ color_space_almost_equal(1.0f, coeffs.fA) &&
+ color_space_almost_equal(0.0f, coeffs.fB) &&
+ color_space_almost_equal(0.0f, coeffs.fE) &&
+ color_space_almost_equal(1.0f, coeffs.fG) &&
+ coeffs.fD <= 0.0f;
+
+ // OutputVal = 1.0f * InputVal
+ const bool linearFn =
+ color_space_almost_equal(1.0f, coeffs.fC) &&
color_space_almost_equal(0.0f, coeffs.fF) &&
- color_space_almost_equal(2.2f, coeffs.fG);
+ coeffs.fD >= 1.0f;
+
+ return linearExp || linearFn;
}
static inline void value_to_parametric(SkColorSpaceTransferFn* coeffs, float exponent) {
#include "SkColorSpace.h"
#include "SkColorSpace_Base.h"
#include "SkColorSpace_XYZ.h"
+#include "SkColorSpacePriv.h"
#include "Test.h"
#include "png.h"
SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, srgbToxyzD50);
REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace);
+ SkColorSpaceTransferFn srgbFn;
+ srgbFn.fA = (1.0f / 1.055f);
+ srgbFn.fB = (0.055f / 1.055f);
+ srgbFn.fC = (1.0f / 12.92f);
+ srgbFn.fD = 0.04045f;
+ srgbFn.fE = 0.0f;
+ srgbFn.fF = 0.0f;
+ srgbFn.fG = 2.4f;
+ sk_sp<SkColorSpace> rgbColorSpace2 = SkColorSpace::MakeRGB(srgbFn, srgbToxyzD50);
+ REPORTER_ASSERT(r, rgbColorSpace2 == namedColorSpace);
+
// Change a single value from the sRGB matrix
srgbToxyzD50.set(2, 2, 0.5f);
sk_sp<SkColorSpace> strangeColorSpace =
SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, srgbToxyzD50);
REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace);
+ SkColorSpaceTransferFn linearExpFn;
+ linearExpFn.fA = 1.0f;
+ linearExpFn.fB = 0.0f;
+ linearExpFn.fC = 0.0f;
+ linearExpFn.fD = 0.0f;
+ linearExpFn.fE = 0.0f;
+ linearExpFn.fF = 0.0f;
+ linearExpFn.fG = 1.0f;
+ sk_sp<SkColorSpace> rgbColorSpace2 = SkColorSpace::MakeRGB(linearExpFn, srgbToxyzD50);
+ REPORTER_ASSERT(r, rgbColorSpace2 == namedColorSpace);
+
+ SkColorSpaceTransferFn linearFn;
+ linearFn.fA = 0.0f;
+ linearFn.fB = 0.0f;
+ linearFn.fC = 1.0f;
+ linearFn.fD = 1.0f;
+ linearFn.fE = 0.0f;
+ linearFn.fF = 0.0f;
+ linearFn.fG = 0.0f;
+ sk_sp<SkColorSpace> rgbColorSpace3 = SkColorSpace::MakeRGB(linearFn, srgbToxyzD50);
+ REPORTER_ASSERT(r, rgbColorSpace3 == namedColorSpace);
+
// Change a single value from the sRGB matrix
srgbToxyzD50.set(2, 2, 0.5f);
sk_sp<SkColorSpace> strangeColorSpace =
REPORTER_ASSERT(r, strangeColorSpace != namedColorSpace);
}
+DEF_TEST(ColorSpaceAdobeCompare, r) {
+ // Create an sRGB color space by name
+ sk_sp<SkColorSpace> namedColorSpace = SkColorSpace::MakeNamed(SkColorSpace::kAdobeRGB_Named);
+
+ // Create an sRGB color space by value
+ SkMatrix44 adobeToxyzD50(SkMatrix44::kUninitialized_Constructor);
+ adobeToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50);
+
+ SkColorSpaceTransferFn fn;
+ fn.fA = 1.0f;
+ fn.fB = 0.0f;
+ fn.fC = 0.0f;
+ fn.fD = 0.0f;
+ fn.fE = 0.0f;
+ fn.fF = 0.0f;
+ fn.fG = 2.2f;
+ sk_sp<SkColorSpace> rgbColorSpace = SkColorSpace::MakeRGB(fn, adobeToxyzD50);
+ REPORTER_ASSERT(r, rgbColorSpace == namedColorSpace);
+}
+
DEF_TEST(ColorSpace_Named, r) {
const struct {
SkColorSpace::Named fNamed;