OLD | NEW |
1 /* | 1 /* |
2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
6 */ | 6 */ |
7 | 7 |
8 #include "SkColorSpace.h" | 8 #include "SkColorSpace.h" |
9 #include "SkColorSpace_Base.h" | 9 #include "SkColorSpace_Base.h" |
| 10 #include "SkColorSpace_XYZ.h" |
10 #include "SkColorSpacePriv.h" | 11 #include "SkColorSpacePriv.h" |
11 #include "SkColorSpaceXform_Base.h" | |
12 #include "SkOnce.h" | 12 #include "SkOnce.h" |
13 #include "SkPoint3.h" | 13 #include "SkPoint3.h" |
14 | 14 |
15 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const { | 15 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const { |
16 if (!is_zero_to_one(fRX) || !is_zero_to_one(fRY) || | 16 if (!is_zero_to_one(fRX) || !is_zero_to_one(fRY) || |
17 !is_zero_to_one(fGX) || !is_zero_to_one(fGY) || | 17 !is_zero_to_one(fGX) || !is_zero_to_one(fGY) || |
18 !is_zero_to_one(fBX) || !is_zero_to_one(fBY) || | 18 !is_zero_to_one(fBX) || !is_zero_to_one(fBY) || |
19 !is_zero_to_one(fWX) || !is_zero_to_one(fWY)) | 19 !is_zero_to_one(fWX) || !is_zero_to_one(fWY)) |
20 { | 20 { |
21 return false; | 21 return false; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 | 76 |
77 toXYZ.postConcat(DXToD50); | 77 toXYZ.postConcat(DXToD50); |
78 toXYZ_D50->set3x3(toXYZ[0], toXYZ[3], toXYZ[6], | 78 toXYZ_D50->set3x3(toXYZ[0], toXYZ[3], toXYZ[6], |
79 toXYZ[1], toXYZ[4], toXYZ[7], | 79 toXYZ[1], toXYZ[4], toXYZ[7], |
80 toXYZ[2], toXYZ[5], toXYZ[8]); | 80 toXYZ[2], toXYZ[5], toXYZ[8]); |
81 return true; | 81 return true; |
82 } | 82 } |
83 | 83 |
84 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 84 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
85 | 85 |
86 SkColorSpace_Base::SkColorSpace_Base(SkGammaNamed gammaNamed, const SkMatrix44&
toXYZD50) | 86 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkData> profileData) |
87 : fGammaNamed(gammaNamed) | 87 : fProfileData(std::move(profileData)) |
88 , fGammas(nullptr) | |
89 , fProfileData(nullptr) | |
90 , fToXYZD50(toXYZD50) | |
91 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) | |
92 {} | |
93 | |
94 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGamma
Named gammaNamed, | |
95 sk_sp<SkGammas> gammas, const SkMatrix44& t
oXYZD50, | |
96 sk_sp<SkData> profileData) | |
97 : fColorLUT(std::move(colorLUT)) | |
98 , fGammaNamed(gammaNamed) | |
99 , fGammas(std::move(gammas)) | |
100 , fProfileData(std::move(profileData)) | |
101 , fToXYZD50(toXYZD50) | |
102 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) | |
103 {} | 88 {} |
104 | 89 |
105 static constexpr float gSRGB_toXYZD50[] { | 90 static constexpr float gSRGB_toXYZD50[] { |
106 0.4358f, 0.3853f, 0.1430f, // Rx, Gx, Bx | 91 0.4358f, 0.3853f, 0.1430f, // Rx, Gx, Bx |
107 0.2224f, 0.7170f, 0.0606f, // Ry, Gy, Gz | 92 0.2224f, 0.7170f, 0.0606f, // Ry, Gy, Gz |
108 0.0139f, 0.0971f, 0.7139f, // Rz, Gz, Bz | 93 0.0139f, 0.0971f, 0.7139f, // Rz, Gz, Bz |
109 }; | 94 }; |
110 | 95 |
111 static constexpr float gAdobeRGB_toXYZD50[] { | 96 static constexpr float gAdobeRGB_toXYZD50[] { |
112 0.6098f, 0.2052f, 0.1492f, // Rx, Gx, Bx | 97 0.6098f, 0.2052f, 0.1492f, // Rx, Gx, Bx |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 } | 141 } |
157 | 142 |
158 if (kNonStandard_SkGammaNamed == gammaNamed) { | 143 if (kNonStandard_SkGammaNamed == gammaNamed) { |
159 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); | 144 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); |
160 gammas->fRedType = SkGammas::Type::kValue_Type; | 145 gammas->fRedType = SkGammas::Type::kValue_Type; |
161 gammas->fGreenType = SkGammas::Type::kValue_Type; | 146 gammas->fGreenType = SkGammas::Type::kValue_Type; |
162 gammas->fBlueType = SkGammas::Type::kValue_Type; | 147 gammas->fBlueType = SkGammas::Type::kValue_Type; |
163 gammas->fRedData.fValue = values[0]; | 148 gammas->fRedData.fValue = values[0]; |
164 gammas->fGreenData.fValue = values[1]; | 149 gammas->fGreenData.fValue = values[1]; |
165 gammas->fBlueData.fValue = values[2]; | 150 gammas->fBlueData.fValue = values[2]; |
166 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_S
kGammaNamed, gammas, | 151 return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaName
d, |
167 toXYZD50, nullptr)); | 152 gammas, toXYZD50, nullpt
r)); |
168 } | 153 } |
169 | 154 |
170 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); | 155 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
171 } | 156 } |
172 | 157 |
173 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
atrix44& toXYZD50) { | 158 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
atrix44& toXYZD50) { |
174 switch (gammaNamed) { | 159 switch (gammaNamed) { |
175 case kSRGB_SkGammaNamed: | 160 case kSRGB_SkGammaNamed: |
176 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 161 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
177 return SkColorSpace::NewNamed(kSRGB_Named); | 162 return SkColorSpace::NewNamed(kSRGB_Named); |
178 } | 163 } |
179 break; | 164 break; |
180 case k2Dot2Curve_SkGammaNamed: | 165 case k2Dot2Curve_SkGammaNamed: |
181 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { | 166 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { |
182 return SkColorSpace::NewNamed(kAdobeRGB_Named); | 167 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
183 } | 168 } |
184 break; | 169 break; |
185 case kLinear_SkGammaNamed: | 170 case kLinear_SkGammaNamed: |
186 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 171 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
187 return SkColorSpace::NewNamed(kSRGBLinear_Named); | 172 return SkColorSpace::NewNamed(kSRGBLinear_Named); |
188 } | 173 } |
189 break; | 174 break; |
190 case kNonStandard_SkGammaNamed: | 175 case kNonStandard_SkGammaNamed: |
191 // This is not allowed. | 176 // This is not allowed. |
192 return nullptr; | 177 return nullptr; |
193 default: | 178 default: |
194 break; | 179 break; |
195 } | 180 } |
196 | 181 |
197 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50)); | 182 return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(gammaNamed, toXYZD50)); |
198 } | 183 } |
199 | 184 |
200 sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix
44& toXYZD50) { | 185 sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix
44& toXYZD50) { |
201 switch (gamma) { | 186 switch (gamma) { |
202 case kLinear_RenderTargetGamma: | 187 case kLinear_RenderTargetGamma: |
203 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50); | 188 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50); |
204 case kSRGB_RenderTargetGamma: | 189 case kSRGB_RenderTargetGamma: |
205 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50); | 190 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50); |
206 default: | 191 default: |
207 return nullptr; | 192 return nullptr; |
(...skipping 20 matching lines...) Expand all Loading... |
228 *fn = coeffs; | 213 *fn = coeffs; |
229 gammas->fRedType = SkGammas::Type::kParam_Type; | 214 gammas->fRedType = SkGammas::Type::kParam_Type; |
230 gammas->fGreenType = SkGammas::Type::kParam_Type; | 215 gammas->fGreenType = SkGammas::Type::kParam_Type; |
231 gammas->fBlueType = SkGammas::Type::kParam_Type; | 216 gammas->fBlueType = SkGammas::Type::kParam_Type; |
232 | 217 |
233 SkGammas::Data data; | 218 SkGammas::Data data; |
234 data.fParamOffset = 0; | 219 data.fParamOffset = 0; |
235 gammas->fRedData = data; | 220 gammas->fRedData = data; |
236 gammas->fGreenData = data; | 221 gammas->fGreenData = data; |
237 gammas->fBlueData = data; | 222 gammas->fBlueData = data; |
238 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_SkGam
maNamed, | 223 return sk_sp<SkColorSpace>(new SkColorSpace_XYZ(kNonStandard_SkGammaNamed, |
239 std::move(gammas), toXYZD50
, nullptr)); | 224 std::move(gammas), toXYZD50,
nullptr)); |
240 } | 225 } |
241 | 226 |
242 static SkColorSpace* gAdobeRGB; | 227 static SkColorSpace* gAdobeRGB; |
243 static SkColorSpace* gSRGB; | 228 static SkColorSpace* gSRGB; |
244 static SkColorSpace* gSRGBLinear; | 229 static SkColorSpace* gSRGBLinear; |
245 | 230 |
246 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 231 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
247 static SkOnce sRGBOnce; | 232 static SkOnce sRGBOnce; |
248 static SkOnce adobeRGBOnce; | 233 static SkOnce adobeRGBOnce; |
249 static SkOnce sRGBLinearOnce; | 234 static SkOnce sRGBLinearOnce; |
250 | 235 |
251 switch (named) { | 236 switch (named) { |
252 case kSRGB_Named: { | 237 case kSRGB_Named: { |
253 sRGBOnce([] { | 238 sRGBOnce([] { |
254 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 239 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
255 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 240 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); |
256 | 241 |
257 // Force the mutable type mask to be computed. This avoids race
s. | 242 // Force the mutable type mask to be computed. This avoids race
s. |
258 (void)srgbToxyzD50.getType(); | 243 (void)srgbToxyzD50.getType(); |
259 gSRGB = new SkColorSpace_Base(kSRGB_SkGammaNamed, srgbToxyzD50); | 244 gSRGB = new SkColorSpace_XYZ(kSRGB_SkGammaNamed, srgbToxyzD50); |
260 }); | 245 }); |
261 return sk_ref_sp<SkColorSpace>(gSRGB); | 246 return sk_ref_sp<SkColorSpace>(gSRGB); |
262 } | 247 } |
263 case kAdobeRGB_Named: { | 248 case kAdobeRGB_Named: { |
264 adobeRGBOnce([] { | 249 adobeRGBOnce([] { |
265 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); | 250 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); |
266 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); | 251 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); |
267 | 252 |
268 // Force the mutable type mask to be computed. This avoids race
s. | 253 // Force the mutable type mask to be computed. This avoids race
s. |
269 (void)adobergbToxyzD50.getType(); | 254 (void)adobergbToxyzD50.getType(); |
270 gAdobeRGB = new SkColorSpace_Base(k2Dot2Curve_SkGammaNamed, adob
ergbToxyzD50); | 255 gAdobeRGB = new SkColorSpace_XYZ(k2Dot2Curve_SkGammaNamed, adobe
rgbToxyzD50); |
271 }); | 256 }); |
272 return sk_ref_sp<SkColorSpace>(gAdobeRGB); | 257 return sk_ref_sp<SkColorSpace>(gAdobeRGB); |
273 } | 258 } |
274 case kSRGBLinear_Named: { | 259 case kSRGBLinear_Named: { |
275 sRGBLinearOnce([] { | 260 sRGBLinearOnce([] { |
276 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 261 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
277 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 262 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); |
278 | 263 |
279 // Force the mutable type mask to be computed. This avoids race
s. | 264 // Force the mutable type mask to be computed. This avoids race
s. |
280 (void)srgbToxyzD50.getType(); | 265 (void)srgbToxyzD50.getType(); |
281 gSRGBLinear = new SkColorSpace_Base(kLinear_SkGammaNamed, srgbTo
xyzD50); | 266 gSRGBLinear = new SkColorSpace_XYZ(kLinear_SkGammaNamed, srgbTox
yzD50); |
282 }); | 267 }); |
283 return sk_ref_sp<SkColorSpace>(gSRGBLinear); | 268 return sk_ref_sp<SkColorSpace>(gSRGBLinear); |
284 } | 269 } |
285 default: | 270 default: |
286 break; | 271 break; |
287 } | 272 } |
288 return nullptr; | 273 return nullptr; |
289 } | 274 } |
290 | 275 |
291 sk_sp<SkColorSpace> SkColorSpace_Base::makeLinearGamma() { | |
292 if (this->gammaIsLinear()) { | |
293 return sk_ref_sp(this); | |
294 } | |
295 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, as_CSB(this)->fToXYZD
50); | |
296 } | |
297 | |
298 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 276 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
299 | 277 |
300 bool SkColorSpace::gammaCloseToSRGB() const { | 278 bool SkColorSpace::gammaCloseToSRGB() const { |
301 return kSRGB_SkGammaNamed == as_CSB(this)->fGammaNamed || | 279 return as_CSB(this)->onGammaCloseToSRGB(); |
302 k2Dot2Curve_SkGammaNamed == as_CSB(this)->fGammaNamed; | |
303 } | 280 } |
304 | 281 |
305 bool SkColorSpace::gammaIsLinear() const { | 282 bool SkColorSpace::gammaIsLinear() const { |
306 return kLinear_SkGammaNamed == as_CSB(this)->fGammaNamed; | 283 return as_CSB(this)->onGammaIsLinear(); |
307 } | |
308 | |
309 const SkMatrix44& SkColorSpace_Base::fromXYZD50() const { | |
310 fFromXYZOnce([this] { | |
311 if (!fToXYZD50.invert(&fFromXYZD50)) { | |
312 // If a client gives us a dst gamut with a transform that we can't i
nvert, we will | |
313 // simply give them back a transform to sRGB gamut. | |
314 SkDEBUGFAIL("Non-invertible XYZ matrix, defaulting to sRGB"); | |
315 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | |
316 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | |
317 srgbToxyzD50.invert(&fFromXYZD50); | |
318 } | |
319 }); | |
320 return fFromXYZD50; | |
321 } | |
322 | |
323 void SkColorSpace_Base::toDstGammaTables(const uint8_t* tables[3], sk_sp<SkData>
* storage, | |
324 int numTables) const { | |
325 fToDstGammaOnce([this, numTables] { | |
326 const bool gammasAreMatching = numTables <= 1; | |
327 fDstStorage = | |
328 SkData::MakeUninitialized(numTables * SkColorSpaceXform_Base::kD
stGammaTableSize); | |
329 SkColorSpaceXform_Base::BuildDstGammaTables(fToDstGammaTables, | |
330 (uint8_t*) fDstStorage->writ
able_data(), this, | |
331 gammasAreMatching); | |
332 }); | |
333 | |
334 *storage = fDstStorage; | |
335 tables[0] = fToDstGammaTables[0]; | |
336 tables[1] = fToDstGammaTables[1]; | |
337 tables[2] = fToDstGammaTables[2]; | |
338 } | 284 } |
339 | 285 |
340 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 286 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
341 | 287 |
342 enum Version { | 288 enum Version { |
343 k0_Version, // Initial version, header + flags for matrix and profile | 289 k0_Version, // Initial version, header + flags for matrix and profile |
344 }; | 290 }; |
345 | 291 |
346 struct ColorSpaceHeader { | 292 struct ColorSpaceHeader { |
347 /** | 293 /** |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 uint8_t fVersion; // Always zero | 342 uint8_t fVersion; // Always zero |
397 uint8_t fNamed; // Must be a SkColorSpace::Named | 343 uint8_t fNamed; // Must be a SkColorSpace::Named |
398 uint8_t fGammaNamed; // Must be a SkGammaNamed | 344 uint8_t fGammaNamed; // Must be a SkGammaNamed |
399 uint8_t fFlags; // Some combination of the flags listed above | 345 uint8_t fFlags; // Some combination of the flags listed above |
400 }; | 346 }; |
401 | 347 |
402 size_t SkColorSpace::writeToMemory(void* memory) const { | 348 size_t SkColorSpace::writeToMemory(void* memory) const { |
403 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, | 349 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, |
404 // we must have a profile that we can serialize easily. | 350 // we must have a profile that we can serialize easily. |
405 if (!as_CSB(this)->fProfileData) { | 351 if (!as_CSB(this)->fProfileData) { |
| 352 // Profile data is mandatory for A2B0 color spaces. |
| 353 SkASSERT(SkColorSpace_Base::Type::kXYZ == as_CSB(this)->type()); |
| 354 const SkColorSpace_XYZ* thisXYZ = static_cast<const SkColorSpace_XYZ*>(t
his); |
406 // If we have a named profile, only write the enum. | 355 // If we have a named profile, only write the enum. |
| 356 const SkGammaNamed gammaNamed = thisXYZ->gammaNamed(); |
407 if (this == gSRGB) { | 357 if (this == gSRGB) { |
408 if (memory) { | 358 if (memory) { |
409 *((ColorSpaceHeader*) memory) = | 359 *((ColorSpaceHeader*) memory) = |
410 ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, | 360 ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, gammaNam
ed, 0); |
411 as_CSB(this)->fGammaNamed, 0); | |
412 } | 361 } |
413 return sizeof(ColorSpaceHeader); | 362 return sizeof(ColorSpaceHeader); |
414 } else if (this == gAdobeRGB) { | 363 } else if (this == gAdobeRGB) { |
415 if (memory) { | 364 if (memory) { |
416 *((ColorSpaceHeader*) memory) = | 365 *((ColorSpaceHeader*) memory) = |
417 ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, | 366 ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, gamm
aNamed, 0); |
418 as_CSB(this)->fGammaNamed, 0); | |
419 } | 367 } |
420 return sizeof(ColorSpaceHeader); | 368 return sizeof(ColorSpaceHeader); |
421 } else if (this == gSRGBLinear) { | 369 } else if (this == gSRGBLinear) { |
422 if (memory) { | 370 if (memory) { |
423 *((ColorSpaceHeader*)memory) = | 371 *((ColorSpaceHeader*) memory) = |
424 ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named, | 372 ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named, ga
mmaNamed, 0); |
425 as_CSB(this)->fGammaNamed, 0); | |
426 } | 373 } |
427 return sizeof(ColorSpaceHeader); | 374 return sizeof(ColorSpaceHeader); |
428 } | 375 } |
429 | 376 |
430 // If we have a named gamma, write the enum and the matrix. | 377 // If we have a named gamma, write the enum and the matrix. |
431 switch (as_CSB(this)->fGammaNamed) { | 378 switch (gammaNamed) { |
432 case kSRGB_SkGammaNamed: | 379 case kSRGB_SkGammaNamed: |
433 case k2Dot2Curve_SkGammaNamed: | 380 case k2Dot2Curve_SkGammaNamed: |
434 case kLinear_SkGammaNamed: { | 381 case kLinear_SkGammaNamed: { |
435 if (memory) { | 382 if (memory) { |
436 *((ColorSpaceHeader*) memory) = | 383 *((ColorSpaceHeader*) memory) = |
437 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->
fGammaNamed, | 384 ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed, |
438 ColorSpaceHeader::kMatrix_Fla
g); | 385 ColorSpaceHeader::kMatrix_Fla
g); |
439 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 386 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
440 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); | 387 thisXYZ->toXYZD50()->as3x4RowMajorf((float*) memory); |
441 } | 388 } |
442 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); | 389 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); |
443 } | 390 } |
444 default: | 391 default: |
445 const SkGammas* gammas = as_CSB(this)->gammas(); | 392 const SkGammas* gammas = thisXYZ->gammas(); |
446 SkASSERT(gammas); | 393 SkASSERT(gammas); |
447 if (gammas->isValue(0) && gammas->isValue(1) && gammas->isValue(
2)) { | 394 if (gammas->isValue(0) && gammas->isValue(1) && gammas->isValue(
2)) { |
448 if (memory) { | 395 if (memory) { |
449 *((ColorSpaceHeader*) memory) = | 396 *((ColorSpaceHeader*) memory) = |
450 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(thi
s)->fGammaNamed, | 397 ColorSpaceHeader::Pack(k0_Version, 0, thisXYZ->f
GammaNamed, |
451 ColorSpaceHeader::kFloatG
amma_Flag); | 398 ColorSpaceHeader::kFloatG
amma_Flag); |
452 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea
der)); | 399 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea
der)); |
453 | 400 |
454 *(((float*) memory) + 0) = gammas->fRedData.fValue; | 401 *(((float*) memory) + 0) = gammas->fRedData.fValue; |
455 *(((float*) memory) + 1) = gammas->fGreenData.fValue; | 402 *(((float*) memory) + 1) = gammas->fGreenData.fValue; |
456 *(((float*) memory) + 2) = gammas->fBlueData.fValue; | 403 *(((float*) memory) + 2) = gammas->fBlueData.fValue; |
457 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); | 404 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); |
458 | 405 |
459 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); | 406 thisXYZ->fToXYZD50.as3x4RowMajorf((float*) memory); |
460 } | 407 } |
461 | 408 |
462 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); | 409 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); |
463 } else { | 410 } else { |
464 SkASSERT(gammas->isParametric(0)); | 411 SkASSERT(gammas->isParametric(0)); |
465 SkASSERT(gammas->isParametric(1)); | 412 SkASSERT(gammas->isParametric(1)); |
466 SkASSERT(gammas->isParametric(2)); | 413 SkASSERT(gammas->isParametric(2)); |
467 SkASSERT(gammas->data(0) == gammas->data(1)); | 414 SkASSERT(gammas->data(0) == gammas->data(1)); |
468 SkASSERT(gammas->data(0) == gammas->data(2)); | 415 SkASSERT(gammas->data(0) == gammas->data(2)); |
469 | 416 |
470 if (memory) { | 417 if (memory) { |
471 *((ColorSpaceHeader*) memory) = | 418 *((ColorSpaceHeader*) memory) = |
472 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(thi
s)->fGammaNamed, | 419 ColorSpaceHeader::Pack(k0_Version, 0, thisXYZ->f
GammaNamed, |
473 ColorSpaceHeader::kTransf
erFn_Flag); | 420 ColorSpaceHeader::kTransf
erFn_Flag); |
474 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea
der)); | 421 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHea
der)); |
475 | 422 |
476 *(((float*) memory) + 0) = gammas->params(0).fA; | 423 *(((float*) memory) + 0) = gammas->params(0).fA; |
477 *(((float*) memory) + 1) = gammas->params(0).fB; | 424 *(((float*) memory) + 1) = gammas->params(0).fB; |
478 *(((float*) memory) + 2) = gammas->params(0).fC; | 425 *(((float*) memory) + 2) = gammas->params(0).fC; |
479 *(((float*) memory) + 3) = gammas->params(0).fD; | 426 *(((float*) memory) + 3) = gammas->params(0).fD; |
480 *(((float*) memory) + 4) = gammas->params(0).fE; | 427 *(((float*) memory) + 4) = gammas->params(0).fE; |
481 *(((float*) memory) + 5) = gammas->params(0).fF; | 428 *(((float*) memory) + 5) = gammas->params(0).fF; |
482 *(((float*) memory) + 6) = gammas->params(0).fG; | 429 *(((float*) memory) + 6) = gammas->params(0).fG; |
483 memory = SkTAddOffset<void>(memory, 7 * sizeof(float)); | 430 memory = SkTAddOffset<void>(memory, 7 * sizeof(float)); |
484 | 431 |
485 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); | 432 thisXYZ->fToXYZD50.as3x4RowMajorf((float*) memory); |
486 } | 433 } |
487 | 434 |
488 return sizeof(ColorSpaceHeader) + 19 * sizeof(float); | 435 return sizeof(ColorSpaceHeader) + 19 * sizeof(float); |
489 } | 436 } |
490 } | 437 } |
491 } | 438 } |
492 | 439 |
493 // Otherwise, serialize the ICC data. | 440 // Otherwise, serialize the ICC data. |
494 size_t profileSize = as_CSB(this)->fProfileData->size(); | 441 size_t profileSize = as_CSB(this)->fProfileData->size(); |
495 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { | 442 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
617 SkData* dstData = as_CSB(dst)->fProfileData.get(); | 564 SkData* dstData = as_CSB(dst)->fProfileData.get(); |
618 if (srcData || dstData) { | 565 if (srcData || dstData) { |
619 if (srcData && dstData) { | 566 if (srcData && dstData) { |
620 return srcData->size() == dstData->size() && | 567 return srcData->size() == dstData->size() && |
621 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 568 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); |
622 } | 569 } |
623 | 570 |
624 return false; | 571 return false; |
625 } | 572 } |
626 | 573 |
627 // It's important to check fProfileData before named gammas. Some profiles
may have named | 574 // profiles are mandatory for A2B0 color spaces |
628 // gammas, but also include other wacky features that cause us to save the d
ata. | 575 SkASSERT(as_CSB(src)->type() == SkColorSpace_Base::Type::kXYZ); |
629 switch (as_CSB(src)->fGammaNamed) { | 576 const SkColorSpace_XYZ* srcXYZ = static_cast<const SkColorSpace_XYZ*>(src); |
| 577 const SkColorSpace_XYZ* dstXYZ = static_cast<const SkColorSpace_XYZ*>(dst); |
| 578 |
| 579 switch (srcXYZ->gammaNamed()) { |
630 case kSRGB_SkGammaNamed: | 580 case kSRGB_SkGammaNamed: |
631 case k2Dot2Curve_SkGammaNamed: | 581 case k2Dot2Curve_SkGammaNamed: |
632 case kLinear_SkGammaNamed: | 582 case kLinear_SkGammaNamed: |
633 return (as_CSB(src)->fGammaNamed == as_CSB(dst)->fGammaNamed) && | 583 return (srcXYZ->gammaNamed() == dstXYZ->gammaNamed()) && |
634 (as_CSB(src)->fToXYZD50 == as_CSB(dst)->fToXYZD50); | 584 (*srcXYZ->toXYZD50() == *dstXYZ->toXYZD50()); |
635 default: | 585 default: |
636 if (as_CSB(src)->fGammaNamed != as_CSB(dst)->fGammaNamed) { | 586 if (srcXYZ->gammaNamed() != dstXYZ->gammaNamed()) { |
637 return false; | 587 return false; |
638 } | 588 } |
639 | |
640 // It is unlikely that we will reach this case. | 589 // It is unlikely that we will reach this case. |
641 sk_sp<SkData> srcData = src->serialize(); | 590 sk_sp<SkData> serializedSrcData = src->serialize(); |
642 sk_sp<SkData> dstData = dst->serialize(); | 591 sk_sp<SkData> serializedDstData = dst->serialize(); |
643 return srcData->size() == dstData->size() && | 592 return serializedSrcData->size() == serializedDstData->size() && |
644 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 593 0 == memcmp(serializedSrcData->data(), serializedDstData->dat
a(), |
| 594 serializedSrcData->size()); |
645 } | 595 } |
646 } | 596 } |
OLD | NEW |