Flutter Engine
The Flutter Engine
Public Member Functions | Static Public Member Functions | Friends | List of all members
SkColorSpace Class Reference

#include <SkColorSpace.h>

Inheritance diagram for SkColorSpace:
SkNVRefCnt< SkColorSpace >

Public Member Functions

void toProfile (skcms_ICCProfile *) const
 
bool gammaCloseToSRGB () const
 
bool gammaIsLinear () const
 
bool isNumericalTransferFn (skcms_TransferFunction *fn) const
 
bool toXYZD50 (skcms_Matrix3x3 *toXYZD50) const
 
uint32_t toXYZD50Hash () const
 
sk_sp< SkColorSpacemakeLinearGamma () const
 
sk_sp< SkColorSpacemakeSRGBGamma () const
 
sk_sp< SkColorSpacemakeColorSpin () const
 
bool isSRGB () const
 
sk_sp< SkDataserialize () const
 
size_t writeToMemory (void *memory) const
 
void transferFn (float gabcdef[7]) const
 
void transferFn (skcms_TransferFunction *fn) const
 
void invTransferFn (skcms_TransferFunction *fn) const
 
void gamutTransformTo (const SkColorSpace *dst, skcms_Matrix3x3 *src_to_dst) const
 
uint32_t transferFnHash () const
 
uint64_t hash () const
 
- Public Member Functions inherited from SkNVRefCnt< SkColorSpace >
 SkNVRefCnt ()
 
 ~SkNVRefCnt ()
 
bool unique () const
 
void ref () const
 
void unref () const
 
void deref () const
 
bool refCntGreaterThan (int32_t threadIsolatedTestCnt) const
 

Static Public Member Functions

static sk_sp< SkColorSpaceMakeSRGB ()
 
static sk_sp< SkColorSpaceMakeSRGBLinear ()
 
static sk_sp< SkColorSpaceMakeRGB (const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
 
static sk_sp< SkColorSpaceMake (const skcms_ICCProfile &)
 
static sk_sp< SkColorSpaceDeserialize (const void *data, size_t length)
 
static bool Equals (const SkColorSpace *, const SkColorSpace *)
 

Friends

class SkColorSpaceSingletonFactory
 

Detailed Description

Definition at line 107 of file SkColorSpace.h.

Member Function Documentation

◆ Deserialize()

sk_sp< SkColorSpace > SkColorSpace::Deserialize ( const void *  data,
size_t  length 
)
static

Definition at line 266 of file SkColorSpace.cpp.

266 {
267 if (length < sizeof(ColorSpaceHeader)) {
268 return nullptr;
269 }
270
272 data = SkTAddOffset<const void>(data, sizeof(ColorSpaceHeader));
273 length -= sizeof(ColorSpaceHeader);
274 if (header.fVersion != k1_Version) {
275 return nullptr;
276 }
277
278 if (length < 16 * sizeof(float)) {
279 return nullptr;
280 }
281
283 memcpy(&transferFn, data, 7 * sizeof(float));
284 data = SkTAddOffset<const void>(data, 7 * sizeof(float));
285
286 skcms_Matrix3x3 toXYZ;
287 memcpy(&toXYZ, data, 9 * sizeof(float));
288 return SkColorSpace::MakeRGB(transferFn, toXYZ);
289}
@ k1_Version
void transferFn(float gabcdef[7]) const
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
size_t length
static const char header[]
Definition: skpbench.cpp:88
std::shared_ptr< const fml::Mapping > data
Definition: texture_gles.cc:63

◆ Equals()

bool SkColorSpace::Equals ( const SkColorSpace x,
const SkColorSpace y 
)
static

If both are null, we return true. If one is null and the other is not, we return false. If both are non-null, we do a deeper compare.

Definition at line 291 of file SkColorSpace.cpp.

291 {
292 if (x == y) {
293 return true;
294 }
295
296 if (!x || !y) {
297 return false;
298 }
299
300 if (x->hash() == y->hash()) {
301 #if defined(SK_DEBUG)
302 // Do these floats function equivalently?
303 // This returns true more often than simple float comparison (NaN vs. NaN) and,
304 // also returns true more often than simple bitwise comparison (+0 vs. -0) and,
305 // even returns true more often than those two OR'd together (two different NaNs).
306 auto equiv = [](float X, float Y) {
307 return (X==Y)
308 || (std::isnan(X) && std::isnan(Y));
309 };
310
311 for (int i = 0; i < 7; i++) {
312 float X = (&x->fTransferFn.g)[i],
313 Y = (&y->fTransferFn.g)[i];
314 SkASSERTF(equiv(X,Y), "Hash collision at tf[%d], !equiv(%g,%g)\n", i, X,Y);
315 }
316 for (int r = 0; r < 3; r++)
317 for (int c = 0; c < 3; c++) {
318 float X = x->fToXYZD50.vals[r][c],
319 Y = y->fToXYZD50.vals[r][c];
320 SkASSERTF(equiv(X,Y), "Hash collision at toXYZD50[%d][%d], !equiv(%g,%g)\n", r,c, X,Y);
321 }
322 #endif
323 return true;
324 }
325 return false;
326}
#define SkASSERTF(cond, fmt,...)
Definition: SkAssert.h:117
static const SkScalar Y
Definition: StrokeBench.cpp:55
static const SkScalar X
Definition: StrokeBench.cpp:54
double y
double x

◆ gammaCloseToSRGB()

bool SkColorSpace::gammaCloseToSRGB ( ) const

Returns true if the color space gamma is near enough to be approximated as sRGB.

Definition at line 151 of file SkColorSpace.cpp.

151 {
152 // Nearly-equal transfer functions were snapped at construction time, so just do an exact test
153 return memcmp(&fTransferFn, &SkNamedTransferFn::kSRGB, 7*sizeof(float)) == 0;
154}
static constexpr skcms_TransferFunction kSRGB
Definition: SkColorSpace.h:45

◆ gammaIsLinear()

bool SkColorSpace::gammaIsLinear ( ) const

Returns true if the color space gamma is linear.

Definition at line 156 of file SkColorSpace.cpp.

156 {
157 // Nearly-equal transfer functions were snapped at construction time, so just do an exact test
158 return memcmp(&fTransferFn, &SkNamedTransferFn::kLinear, 7*sizeof(float)) == 0;
159}
static constexpr skcms_TransferFunction kLinear
Definition: SkColorSpace.h:51

◆ gamutTransformTo()

void SkColorSpace::gamutTransformTo ( const SkColorSpace dst,
skcms_Matrix3x3 src_to_dst 
) const

Definition at line 142 of file SkColorSpace.cpp.

142 {
143 dst->computeLazyDstFields();
144 *src_to_dst = skcms_Matrix3x3_concat(&dst->fFromXYZD50, &fToXYZD50);
145}
dst
Definition: cp.py:12
skcms_Matrix3x3 skcms_Matrix3x3_concat(const skcms_Matrix3x3 *A, const skcms_Matrix3x3 *B)
Definition: skcms.cc:1849

◆ hash()

uint64_t SkColorSpace::hash ( ) const
inline

Definition at line 222 of file SkColorSpace.h.

222{ return (uint64_t)fTransferFnHash << 32 | fToXYZD50Hash; }

◆ invTransferFn()

void SkColorSpace::invTransferFn ( skcms_TransferFunction fn) const

Definition at line 132 of file SkColorSpace.cpp.

132 {
133 this->computeLazyDstFields();
134 *fn = fInvTransferFn;
135}

◆ isNumericalTransferFn()

bool SkColorSpace::isNumericalTransferFn ( skcms_TransferFunction fn) const

Sets |fn| to the transfer function from this color space. Returns true if the transfer function can be represented as coefficients to the standard ICC 7-parameter equation. Returns false otherwise (eg, PQ, HLG).

Definition at line 116 of file SkColorSpace.cpp.

116 {
117 // TODO: Change transferFn/invTransferFn to just operate on skcms_TransferFunction (all callers
118 // already pass pointers to an skcms struct). Then remove this function, and update the two
119 // remaining callers to do the right thing with transferFn and classify.
120 this->transferFn(coeffs);
122}
skcms_TFType skcms_TransferFunction_getType(const skcms_TransferFunction *tf)
Definition: skcms.cc:183
@ skcms_TFType_sRGBish
Definition: skcms_public.h:56

◆ isSRGB()

bool SkColorSpace::isSRGB ( ) const

Returns true if the color space is sRGB. Returns false otherwise.

This allows a little bit of tolerance, given that we might see small numerical error in some cases: converting ICC fixed point to float, converting white point to D50, rounding decisions on transfer function and matrix.

This does not consider a 2.2f exponential transfer function to be sRGB. While these functions are similar (and it is sometimes useful to consider them together), this function checks for logical equality.

Definition at line 147 of file SkColorSpace.cpp.

147 {
148 return sk_srgb_singleton() == this;
149}
SkColorSpace * sk_srgb_singleton()

◆ Make()

sk_sp< SkColorSpace > SkColorSpace::Make ( const skcms_ICCProfile profile)
static

Create an SkColorSpace from a parsed (skcms) ICC profile.

Definition at line 193 of file SkColorSpace.cpp.

193 {
194 // TODO: move below ≈sRGB test?
195 if (!profile.has_toXYZD50 || !profile.has_trc) {
196 return nullptr;
197 }
198
200 return SkColorSpace::MakeSRGB();
201 }
202
203 // TODO: can we save this work and skip lazily inverting the matrix later?
205 if (!skcms_Matrix3x3_invert(&profile.toXYZD50, &inv)) {
206 return nullptr;
207 }
208
209 // We can't work with tables or mismatched parametric curves,
210 // but if they all look close enough to sRGB, that's fine.
211 // TODO: should we maybe do this unconditionally to snap near-sRGB parametrics to sRGB?
212 const skcms_Curve* trc = profile.trc;
213 if (trc[0].table_entries != 0 ||
214 trc[1].table_entries != 0 ||
215 trc[2].table_entries != 0 ||
216 0 != memcmp(&trc[0].parametric, &trc[1].parametric, sizeof(trc[0].parametric)) ||
217 0 != memcmp(&trc[0].parametric, &trc[2].parametric, sizeof(trc[0].parametric)))
218 {
221 }
222 return nullptr;
223 }
224
225 return SkColorSpace::MakeRGB(profile.trc[0].parametric, profile.toXYZD50);
226}
static SkM44 inv(const SkM44 &m)
Definition: 3d.cpp:26
static sk_sp< SkColorSpace > MakeSRGB()
bool skcms_Matrix3x3_invert(const skcms_Matrix3x3 *src, skcms_Matrix3x3 *dst)
Definition: skcms.cc:1792
const skcms_TransferFunction * skcms_sRGB_Inverse_TransferFunction()
Definition: skcms.cc:1591
const skcms_ICCProfile * skcms_sRGB_profile()
Definition: skcms.cc:1393
bool skcms_TRCs_AreApproximateInverse(const skcms_ICCProfile *profile, const skcms_TransferFunction *inv_tf)
Definition: skcms.cc:1679
bool skcms_ApproximatelyEqualProfiles(const skcms_ICCProfile *A, const skcms_ICCProfile *B)
Definition: skcms.cc:1621

◆ makeColorSpin()

sk_sp< SkColorSpace > SkColorSpace::makeColorSpin ( ) const

Returns a color space with the same transfer function as this one, but with the primary colors rotated. In other words, this produces a new color space that maps RGB to GBR (when applied to a source), and maps RGB to BRG (when applied to a destination).

This is used for testing, to construct color spaces that have severe and testable behavior.

Definition at line 175 of file SkColorSpace.cpp.

175 {
177 { 0, 0, 1 },
178 { 1, 0, 0 },
179 { 0, 1, 0 },
180 }};
181
182 skcms_Matrix3x3 spun = skcms_Matrix3x3_concat(&fToXYZD50, &spin);
183
184 return sk_sp<SkColorSpace>(new SkColorSpace(fTransferFn, spun));
185}
static sk_sp< SkColorFilter > spin(sk_sp< SkColorFilter > cf)

◆ makeLinearGamma()

sk_sp< SkColorSpace > SkColorSpace::makeLinearGamma ( ) const

Returns a color space with the same gamut as this one, but with a linear gamma.

Definition at line 161 of file SkColorSpace.cpp.

161 {
162 if (this->gammaIsLinear()) {
163 return sk_ref_sp(const_cast<SkColorSpace*>(this));
164 }
166}
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381
bool gammaIsLinear() const

◆ MakeRGB()

sk_sp< SkColorSpace > SkColorSpace::MakeRGB ( const skcms_TransferFunction transferFn,
const skcms_Matrix3x3 toXYZ 
)
static

Create an SkColorSpace from a transfer function and a row-major 3x3 transformation to XYZ.

Definition at line 42 of file SkColorSpace.cpp.

43 {
45 return nullptr;
46 }
47
49
53 }
55 } else if (is_almost_2dot2(transferFn)) {
57 } else if (is_almost_linear(transferFn)) {
60 }
62 }
63
64 return sk_sp<SkColorSpace>(new SkColorSpace(*tf, toXYZ));
65}
static bool is_almost_linear(const skcms_TransferFunction &coeffs)
static bool is_almost_2dot2(const skcms_TransferFunction &coeffs)
static bool is_almost_srgb(const skcms_TransferFunction &coeffs)
static bool xyz_almost_equal(const skcms_Matrix3x3 &mA, const skcms_Matrix3x3 &mB)
static sk_sp< SkColorSpace > MakeSRGBLinear()
static constexpr skcms_Matrix3x3 kSRGB
Definition: SkColorSpace.h:67
static constexpr skcms_TransferFunction k2Dot2
Definition: SkColorSpace.h:48
@ skcms_TFType_Invalid
Definition: skcms_public.h:55

◆ MakeSRGB()

sk_sp< SkColorSpace > SkColorSpace::MakeSRGB ( )
static

Create the sRGB color space.

Definition at line 87 of file SkColorSpace.cpp.

87 {
89}

◆ makeSRGBGamma()

sk_sp< SkColorSpace > SkColorSpace::makeSRGBGamma ( ) const

Returns a color space with the same gamut as this one, but with the sRGB transfer function.

Definition at line 168 of file SkColorSpace.cpp.

168 {
169 if (this->gammaCloseToSRGB()) {
170 return sk_ref_sp(const_cast<SkColorSpace*>(this));
171 }
173}
bool gammaCloseToSRGB() const

◆ MakeSRGBLinear()

sk_sp< SkColorSpace > SkColorSpace::MakeSRGBLinear ( )
static

Colorspace with the sRGB primaries, but a linear (1.0) gamma.

Definition at line 91 of file SkColorSpace.cpp.

91 {
93}
SkColorSpace * sk_srgb_linear_singleton()

◆ serialize()

sk_sp< SkData > SkColorSpace::serialize ( ) const

Returns a serialized representation of this color space.

Definition at line 260 of file SkColorSpace.cpp.

260 {
262 this->writeToMemory(data->writable_data());
263 return data;
264}
size_t writeToMemory(void *memory) const
static sk_sp< SkData > MakeUninitialized(size_t length)
Definition: SkData.cpp:116
void * writable_data()
Definition: SkData.h:52

◆ toProfile()

void SkColorSpace::toProfile ( skcms_ICCProfile profile) const

Convert this color space to an skcms ICC profile struct.

Definition at line 187 of file SkColorSpace.cpp.

187 {
189 skcms_SetTransferFunction(profile, &fTransferFn);
190 skcms_SetXYZD50 (profile, &fToXYZD50);
191}
static void skcms_SetXYZD50(skcms_ICCProfile *p, const skcms_Matrix3x3 *m)
Definition: skcms_public.h:399
static void skcms_SetTransferFunction(skcms_ICCProfile *p, const skcms_TransferFunction *tf)
Definition: skcms_public.h:390
static void skcms_Init(skcms_ICCProfile *p)
Definition: skcms_public.h:384

◆ toXYZD50()

bool SkColorSpace::toXYZD50 ( skcms_Matrix3x3 toXYZD50) const

Returns true and sets |toXYZD50|.

Definition at line 137 of file SkColorSpace.cpp.

137 {
138 *toXYZD50 = fToXYZD50;
139 return true;
140}
bool toXYZD50(skcms_Matrix3x3 *toXYZD50) const

◆ toXYZD50Hash()

uint32_t SkColorSpace::toXYZD50Hash ( ) const
inline

Returns a hash of the gamut transformation to XYZ D50. Allows for fast equality checking of gamuts, at the (very small) risk of collision.

Definition at line 161 of file SkColorSpace.h.

161{ return fToXYZD50Hash; }

◆ transferFn() [1/2]

void SkColorSpace::transferFn ( float  gabcdef[7]) const

Definition at line 124 of file SkColorSpace.cpp.

124 {
125 memcpy(gabcdef, &fTransferFn, 7*sizeof(float));
126}

◆ transferFn() [2/2]

void SkColorSpace::transferFn ( skcms_TransferFunction fn) const

Definition at line 128 of file SkColorSpace.cpp.

128 {
129 *fn = fTransferFn;
130}

◆ transferFnHash()

uint32_t SkColorSpace::transferFnHash ( ) const
inline

Definition at line 221 of file SkColorSpace.h.

221{ return fTransferFnHash; }

◆ writeToMemory()

size_t SkColorSpace::writeToMemory ( void *  memory) const

If |memory| is nullptr, returns the size required to serialize. Otherwise, serializes into |memory| and returns the size.

Definition at line 246 of file SkColorSpace.cpp.

246 {
247 if (memory) {
248 *((ColorSpaceHeader*) memory) = ColorSpaceHeader();
249 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader));
250
251 memcpy(memory, &fTransferFn, 7 * sizeof(float));
252 memory = SkTAddOffset<void>(memory, 7 * sizeof(float));
253
254 memcpy(memory, &fToXYZD50, 9 * sizeof(float));
255 }
256
257 return sizeof(ColorSpaceHeader) + 16 * sizeof(float);
258}

Friends And Related Function Documentation

◆ SkColorSpaceSingletonFactory

friend class SkColorSpaceSingletonFactory
friend

Definition at line 225 of file SkColorSpace.h.


The documentation for this class was generated from the following files: