16constexpr double kSrgbGamma = 2.4;
17constexpr double kSrgbLinearThreshold = 0.04045;
18constexpr double kSrgbLinearSlope = 12.92;
19constexpr double kSrgbEncodedOffset = 0.055;
20constexpr double kSrgbEncodedDivisor = 1.055;
21constexpr double kSrgbLinearToEncodedThreshold = 0.0031308;
24double srgbEOTF(
double v) {
25 if (v <= kSrgbLinearThreshold) {
26 return v / kSrgbLinearSlope;
28 return std::pow((v + kSrgbEncodedOffset) / kSrgbEncodedDivisor, kSrgbGamma);
32double srgbOETF(
double v) {
33 if (v <= kSrgbLinearToEncodedThreshold) {
34 return v * kSrgbLinearSlope;
36 return kSrgbEncodedDivisor * std::pow(v, 1.0 / kSrgbGamma) -
41double srgbEOTFExtended(
double v) {
42 return v < 0.0 ? -srgbEOTF(-v) : srgbEOTF(v);
46double srgbOETFExtended(
double v) {
47 return v < 0.0 ? -srgbOETF(-v) : srgbOETF(v);
57static constexpr double kP3ToSrgbLinear[9] = {
58 1.2249401, -0.2249402, 0.0, -0.0420569, 1.0420571,
59 0.0, -0.0196376, -0.0786507, 1.0982884,
65DlColor p3ToExtendedSrgb(
const DlColor& color) {
67 double r_lin = srgbEOTFExtended(
static_cast<double>(color.getRedF()));
68 double g_lin = srgbEOTFExtended(
static_cast<double>(color.getGreenF()));
69 double b_lin = srgbEOTFExtended(
static_cast<double>(color.getBlueF()));
72 double r_srgb_lin = kP3ToSrgbLinear[0] * r_lin + kP3ToSrgbLinear[1] * g_lin +
73 kP3ToSrgbLinear[2] * b_lin;
74 double g_srgb_lin = kP3ToSrgbLinear[3] * r_lin + kP3ToSrgbLinear[4] * g_lin +
75 kP3ToSrgbLinear[5] * b_lin;
76 double b_srgb_lin = kP3ToSrgbLinear[6] * r_lin + kP3ToSrgbLinear[7] * g_lin +
77 kP3ToSrgbLinear[8] * b_lin;
80 double r_out = srgbOETFExtended(r_srgb_lin);
81 double g_out = srgbOETFExtended(g_srgb_lin);
82 double b_out = srgbOETFExtended(b_srgb_lin);
84 return DlColor(color.getAlphaF(),
static_cast<float>(r_out),
85 static_cast<float>(g_out),
static_cast<float>(b_out),
92 switch (color_space_) {
94 switch (color_space) {
98 return DlColor(alpha_, red_, green_, blue_,
105 switch (color_space) {
107 return DlColor(alpha_, std::clamp(red_, 0.0f, 1.0f),
108 std::clamp(green_, 0.0f, 1.0f),
117 switch (color_space) {
121 return p3ToExtendedSrgb(*
this);
#define FML_CHECK(condition)
DlColor withColorSpace(DlColorSpace color_space) const