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 "SkColorSpacePriv.h" | 10 #include "SkColorSpacePriv.h" |
11 #include "SkOnce.h" | 11 #include "SkOnce.h" |
12 | 12 |
13 SkColorSpace::SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50) | 13 SkColorSpace::SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Na
med named) |
14 : fGammaNamed(gammaNamed) | 14 : fGammaNamed(gammaNamed) |
15 , fToXYZD50(toXYZD50) | 15 , fToXYZD50(toXYZD50) |
| 16 , fNamed(named) |
16 {} | 17 {} |
17 | 18 |
18 SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& to
XYZD50) | 19 SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& to
XYZD50, Named named) |
19 : INHERITED(gammaNamed, toXYZD50) | 20 : INHERITED(gammaNamed, toXYZD50, named) |
20 , fGammas(nullptr) | 21 , fGammas(nullptr) |
21 , fProfileData(nullptr) | 22 , fProfileData(nullptr) |
22 {} | 23 {} |
23 | 24 |
24 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, GammaNa
med gammaNamed, | 25 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, GammaNa
med gammaNamed, |
25 sk_sp<SkGammas> gammas, const SkMatrix44& t
oXYZD50, | 26 sk_sp<SkGammas> gammas, const SkMatrix44& t
oXYZD50, |
26 sk_sp<SkData> profileData) | 27 sk_sp<SkData> profileData) |
27 : INHERITED(gammaNamed, toXYZD50) | 28 : INHERITED(gammaNamed, toXYZD50, kUnknown_Named) |
28 , fColorLUT(std::move(colorLUT)) | 29 , fColorLUT(std::move(colorLUT)) |
29 , fGammas(std::move(gammas)) | 30 , fGammas(std::move(gammas)) |
30 , fProfileData(std::move(profileData)) | 31 , fProfileData(std::move(profileData)) |
31 {} | 32 {} |
32 | 33 |
33 static constexpr float gSRGB_toXYZD50[] { | 34 static constexpr float gSRGB_toXYZD50[] { |
34 0.4358f, 0.2224f, 0.0139f, // * R | 35 0.4358f, 0.2224f, 0.0139f, // * R |
35 0.3853f, 0.7170f, 0.0971f, // * G | 36 0.3853f, 0.7170f, 0.0971f, // * G |
36 0.1430f, 0.0606f, 0.7139f, // * B | 37 0.1430f, 0.0606f, 0.7139f, // * B |
37 }; | 38 }; |
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
110 return SkColorSpace::NewNamed(kAdobeRGB_Named); | 111 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
111 } | 112 } |
112 break; | 113 break; |
113 case kNonStandard_GammaNamed: | 114 case kNonStandard_GammaNamed: |
114 // This is not allowed. | 115 // This is not allowed. |
115 return nullptr; | 116 return nullptr; |
116 default: | 117 default: |
117 break; | 118 break; |
118 } | 119 } |
119 | 120 |
120 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50)); | 121 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnkn
own_Named)); |
121 } | 122 } |
122 | 123 |
123 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44
& toXYZD50) { | 124 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44
& toXYZD50) { |
124 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); | 125 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
125 } | 126 } |
126 | 127 |
127 static sk_sp<SkColorSpace> gAdobeRGB; | |
128 static sk_sp<SkColorSpace> gSRGB; | |
129 | |
130 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 128 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
131 static SkOnce sRGBOnce; | 129 static SkOnce sRGBOnce; |
| 130 static sk_sp<SkColorSpace> sRGB; |
132 static SkOnce adobeRGBOnce; | 131 static SkOnce adobeRGBOnce; |
| 132 static sk_sp<SkColorSpace> adobeRGB; |
133 | 133 |
134 switch (named) { | 134 switch (named) { |
135 case kSRGB_Named: { | 135 case kSRGB_Named: { |
136 sRGBOnce([] { | 136 sRGBOnce([] { |
137 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 137 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
138 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 138 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); |
139 | 139 |
140 // Force the mutable type mask to be computed. This avoids race
s. | 140 // Force the mutable type mask to be computed. This avoids race
s. |
141 (void)srgbToxyzD50.getType(); | 141 (void)srgbToxyzD50.getType(); |
142 gSRGB.reset(new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50
)); | 142 sRGB.reset(new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50,
kSRGB_Named)); |
143 }); | 143 }); |
144 return gSRGB; | 144 return sRGB; |
145 } | 145 } |
146 case kAdobeRGB_Named: { | 146 case kAdobeRGB_Named: { |
147 adobeRGBOnce([] { | 147 adobeRGBOnce([] { |
148 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); | 148 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); |
149 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); | 149 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); |
150 | 150 |
151 // Force the mutable type mask to be computed. This avoids race
s. | 151 // Force the mutable type mask to be computed. This avoids race
s. |
152 (void)adobergbToxyzD50.getType(); | 152 (void)adobergbToxyzD50.getType(); |
153 gAdobeRGB.reset(new SkColorSpace_Base(k2Dot2Curve_GammaNamed, ad
obergbToxyzD50)); | 153 adobeRGB.reset(new SkColorSpace_Base(k2Dot2Curve_GammaNamed, ado
bergbToxyzD50, |
| 154 kAdobeRGB_Named)); |
154 }); | 155 }); |
155 return gAdobeRGB; | 156 return adobeRGB; |
156 } | 157 } |
157 default: | 158 default: |
158 break; | 159 break; |
159 } | 160 } |
160 return nullptr; | 161 return nullptr; |
161 } | 162 } |
162 | 163 |
163 sk_sp<SkColorSpace> SkColorSpace::makeLinearGamma() { | 164 sk_sp<SkColorSpace> SkColorSpace::makeLinearGamma() { |
164 return SkColorSpace_Base::NewRGB(kLinear_GammaNamed, fToXYZD50); | 165 return SkColorSpace_Base::NewRGB(kLinear_GammaNamed, fToXYZD50); |
165 } | 166 } |
(...skipping 20 matching lines...) Expand all Loading... |
186 static constexpr uint8_t kICC_Flag = 1 << 1; | 187 static constexpr uint8_t kICC_Flag = 1 << 1; |
187 | 188 |
188 /** | 189 /** |
189 * If kFloatGamma_Flag is set, we will write 15 floats after the header. | 190 * If kFloatGamma_Flag is set, we will write 15 floats after the header. |
190 * The first three are the gamma values, and the next twelve are the | 191 * The first three are the gamma values, and the next twelve are the |
191 * matrix. | 192 * matrix. |
192 * Should not be set at the same time as the kICC_Flag or kMatrix_Flag. | 193 * Should not be set at the same time as the kICC_Flag or kMatrix_Flag. |
193 */ | 194 */ |
194 static constexpr uint8_t kFloatGamma_Flag = 1 << 2; | 195 static constexpr uint8_t kFloatGamma_Flag = 1 << 2; |
195 | 196 |
196 static ColorSpaceHeader Pack(Version version, uint8_t named, uint8_t gammaNa
med, uint8_t flags) | 197 static ColorSpaceHeader Pack(Version version, SkColorSpace::Named named, |
197 { | 198 SkColorSpace::GammaNamed gammaNamed, uint8_t fl
ags) { |
198 ColorSpaceHeader header; | 199 ColorSpaceHeader header; |
199 | 200 |
200 SkASSERT(k0_Version == version); | 201 SkASSERT(k0_Version == version); |
201 header.fVersion = (uint8_t) version; | 202 header.fVersion = (uint8_t) version; |
202 | 203 |
203 SkASSERT(named <= SkColorSpace::kAdobeRGB_Named); | 204 SkASSERT(named <= SkColorSpace::kAdobeRGB_Named); |
204 header.fNamed = (uint8_t) named; | 205 header.fNamed = (uint8_t) named; |
205 | 206 |
206 SkASSERT(gammaNamed <= SkColorSpace::kNonStandard_GammaNamed); | 207 SkASSERT(gammaNamed <= SkColorSpace::kNonStandard_GammaNamed); |
207 header.fGammaNamed = (uint8_t) gammaNamed; | 208 header.fGammaNamed = (uint8_t) gammaNamed; |
208 | 209 |
209 SkASSERT(flags <= kFloatGamma_Flag); | 210 SkASSERT(flags <= kFloatGamma_Flag); |
210 header.fFlags = flags; | 211 header.fFlags = flags; |
211 return header; | 212 return header; |
212 } | 213 } |
213 | 214 |
214 uint8_t fVersion; // Always zero | 215 uint8_t fVersion; // Always zero |
215 uint8_t fNamed; // Must be a SkColorSpace::Named | 216 uint8_t fNamed; // Must be a SkColorSpace::Named |
216 uint8_t fGammaNamed; // Must be a SkColorSpace::GammaNamed | 217 uint8_t fGammaNamed; // Must be a SkColorSpace::GammaNamed |
217 uint8_t fFlags; // Some combination of the flags listed above | 218 uint8_t fFlags; // Some combination of the flags listed above |
218 }; | 219 }; |
219 | 220 |
220 size_t SkColorSpace::writeToMemory(void* memory) const { | 221 size_t SkColorSpace::writeToMemory(void* memory) const { |
221 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, | 222 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, |
222 // we must have a profile that we can serialize easily. | 223 // we must have a profile that we can serialize easily. |
223 if (!as_CSB(this)->fProfileData) { | 224 if (!as_CSB(this)->fProfileData) { |
224 // If we have a named profile, only write the enum. | 225 // If we have a named profile, only write the enum. |
225 if (this == gSRGB.get()) { | 226 switch (fNamed) { |
226 if (memory) { | 227 case kSRGB_Named: |
227 *((ColorSpaceHeader*) memory) = | 228 case kAdobeRGB_Named: { |
228 ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, fGammaNa
med, 0); | 229 if (memory) { |
| 230 *((ColorSpaceHeader*) memory) = |
| 231 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, 0); |
| 232 } |
| 233 return sizeof(ColorSpaceHeader); |
229 } | 234 } |
230 return sizeof(ColorSpaceHeader); | 235 default: |
231 } else if (this == gAdobeRGB.get()) { | 236 break; |
232 if (memory) { | |
233 *((ColorSpaceHeader*) memory) = | |
234 ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, fGam
maNamed, 0); | |
235 } | |
236 } | 237 } |
237 | 238 |
238 // If we have a named gamma, write the enum and the matrix. | 239 // If we have a named gamma, write the enum and the matrix. |
239 switch (fGammaNamed) { | 240 switch (fGammaNamed) { |
240 case kSRGB_GammaNamed: | 241 case kSRGB_GammaNamed: |
241 case k2Dot2Curve_GammaNamed: | 242 case k2Dot2Curve_GammaNamed: |
242 case kLinear_GammaNamed: { | 243 case kLinear_GammaNamed: { |
243 if (memory) { | 244 if (memory) { |
244 *((ColorSpaceHeader*) memory) = | 245 *((ColorSpaceHeader*) memory) = |
245 ColorSpaceHeader::Pack(k0_Version, 0, fGammaNamed, | 246 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, |
246 ColorSpaceHeader::kMatrix_Fla
g); | 247 ColorSpaceHeader::kMatrix_Fla
g); |
247 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 248 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
248 fToXYZD50.as4x3ColMajorf((float*) memory); | 249 fToXYZD50.as4x3ColMajorf((float*) memory); |
249 } | 250 } |
250 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); | 251 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); |
251 } | 252 } |
252 default: | 253 default: |
253 // Otherwise, write the gamma values and the matrix. | 254 // Otherwise, write the gamma values and the matrix. |
254 if (memory) { | 255 if (memory) { |
255 *((ColorSpaceHeader*) memory) = | 256 *((ColorSpaceHeader*) memory) = |
256 ColorSpaceHeader::Pack(k0_Version, 0, fGammaNamed, | 257 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, |
257 ColorSpaceHeader::kFloatGamma
_Flag); | 258 ColorSpaceHeader::kFloatGamma
_Flag); |
258 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 259 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
259 | 260 |
260 const SkGammas* gammas = as_CSB(this)->gammas(); | 261 const SkGammas* gammas = as_CSB(this)->gammas(); |
261 SkASSERT(gammas); | 262 SkASSERT(gammas); |
262 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && | 263 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && |
263 SkGammas::Type::kValue_Type == gammas->fGreenType &
& | 264 SkGammas::Type::kValue_Type == gammas->fGreenType &
& |
264 SkGammas::Type::kValue_Type == gammas->fBlueType); | 265 SkGammas::Type::kValue_Type == gammas->fBlueType); |
265 *(((float*) memory) + 0) = gammas->fRedData.fValue; | 266 *(((float*) memory) + 0) = gammas->fRedData.fValue; |
266 *(((float*) memory) + 1) = gammas->fGreenData.fValue; | 267 *(((float*) memory) + 1) = gammas->fGreenData.fValue; |
267 *(((float*) memory) + 2) = gammas->fBlueData.fValue; | 268 *(((float*) memory) + 2) = gammas->fBlueData.fValue; |
268 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); | 269 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); |
269 | 270 |
270 fToXYZD50.as4x3ColMajorf((float*) memory); | 271 fToXYZD50.as4x3ColMajorf((float*) memory); |
271 } | 272 } |
272 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); | 273 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); |
273 } | 274 } |
274 } | 275 } |
275 | 276 |
276 // Otherwise, serialize the ICC data. | 277 // Otherwise, serialize the ICC data. |
277 size_t profileSize = as_CSB(this)->fProfileData->size(); | 278 size_t profileSize = as_CSB(this)->fProfileData->size(); |
278 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { | 279 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { |
279 return 0; | 280 return 0; |
280 } | 281 } |
281 | 282 |
282 if (memory) { | 283 if (memory) { |
283 *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(k0_Version, 0, | 284 *((ColorSpaceHeader*) memory) = ColorSpaceHeader::Pack(k0_Version, kUnkn
own_Named, |
284 kNonStandard_Gamm
aNamed, | 285 kNonStandard_Gamm
aNamed, |
285 ColorSpaceHeader:
:kICC_Flag); | 286 ColorSpaceHeader:
:kICC_Flag); |
286 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)); | 287 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)); |
287 | 288 |
288 *((uint32_t*) memory) = (uint32_t) SkAlign4(profileSize); | 289 *((uint32_t*) memory) = (uint32_t) SkAlign4(profileSize); |
289 memory = SkTAddOffset<void>(memory, sizeof(uint32_t)); | 290 memory = SkTAddOffset<void>(memory, sizeof(uint32_t)); |
290 | 291 |
291 memcpy(memory, as_CSB(this)->fProfileData->data(), profileSize); | 292 memcpy(memory, as_CSB(this)->fProfileData->data(), profileSize); |
292 memset(SkTAddOffset<void>(memory, profileSize), 0, SkAlign4(profileSize)
- profileSize); | 293 memset(SkTAddOffset<void>(memory, profileSize), 0, SkAlign4(profileSize)
- profileSize); |
293 } | 294 } |
(...skipping 12 matching lines...) Expand all Loading... |
306 } | 307 } |
307 | 308 |
308 sk_sp<SkColorSpace> SkColorSpace::Deserialize(const void* data, size_t length) { | 309 sk_sp<SkColorSpace> SkColorSpace::Deserialize(const void* data, size_t length) { |
309 if (length < sizeof(ColorSpaceHeader)) { | 310 if (length < sizeof(ColorSpaceHeader)) { |
310 return nullptr; | 311 return nullptr; |
311 } | 312 } |
312 | 313 |
313 ColorSpaceHeader header = *((const ColorSpaceHeader*) data); | 314 ColorSpaceHeader header = *((const ColorSpaceHeader*) data); |
314 data = SkTAddOffset<const void>(data, sizeof(ColorSpaceHeader)); | 315 data = SkTAddOffset<const void>(data, sizeof(ColorSpaceHeader)); |
315 length -= sizeof(ColorSpaceHeader); | 316 length -= sizeof(ColorSpaceHeader); |
316 if (0 == header.fFlags) { | 317 switch ((Named) header.fNamed) { |
317 return NewNamed((Named) header.fNamed); | 318 case kSRGB_Named: |
| 319 case kAdobeRGB_Named: |
| 320 return NewNamed((Named) header.fNamed); |
| 321 default: |
| 322 break; |
318 } | 323 } |
319 | 324 |
320 switch ((GammaNamed) header.fGammaNamed) { | 325 switch ((GammaNamed) header.fGammaNamed) { |
321 case kSRGB_GammaNamed: | 326 case kSRGB_GammaNamed: |
322 case k2Dot2Curve_GammaNamed: | 327 case k2Dot2Curve_GammaNamed: |
323 case kLinear_GammaNamed: { | 328 case kLinear_GammaNamed: { |
324 if (ColorSpaceHeader::kMatrix_Flag != header.fFlags || length < 12 *
sizeof(float)) { | 329 if (ColorSpaceHeader::kMatrix_Flag != header.fFlags || length < 12 *
sizeof(float)) { |
325 return nullptr; | 330 return nullptr; |
326 } | 331 } |
327 | 332 |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
370 | 375 |
371 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { | 376 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { |
372 if (src == dst) { | 377 if (src == dst) { |
373 return true; | 378 return true; |
374 } | 379 } |
375 | 380 |
376 if (!src || !dst) { | 381 if (!src || !dst) { |
377 return false; | 382 return false; |
378 } | 383 } |
379 | 384 |
| 385 switch (src->fNamed) { |
| 386 case kSRGB_Named: |
| 387 case kAdobeRGB_Named: |
| 388 return src->fNamed == dst->fNamed; |
| 389 case kUnknown_Named: |
| 390 if (kUnknown_Named != dst->fNamed) { |
| 391 return false; |
| 392 } |
| 393 break; |
| 394 } |
| 395 |
380 SkData* srcData = as_CSB(src)->fProfileData.get(); | 396 SkData* srcData = as_CSB(src)->fProfileData.get(); |
381 SkData* dstData = as_CSB(dst)->fProfileData.get(); | 397 SkData* dstData = as_CSB(dst)->fProfileData.get(); |
382 if (srcData || dstData) { | 398 if (srcData || dstData) { |
383 if (srcData && dstData) { | 399 if (srcData && dstData) { |
384 return srcData->size() == dstData->size() && | 400 return srcData->size() == dstData->size() && |
385 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 401 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); |
386 } | 402 } |
387 | 403 |
388 return false; | 404 return false; |
389 } | 405 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
439 gammas->fBlueType == SkGammas::Type::kTable_Type; | 455 gammas->fBlueType == SkGammas::Type::kTable_Type; |
440 } | 456 } |
441 | 457 |
442 bool SkColorSpace::gammasAreParams() const { | 458 bool SkColorSpace::gammasAreParams() const { |
443 const SkGammas* gammas = as_CSB(this)->gammas(); | 459 const SkGammas* gammas = as_CSB(this)->gammas(); |
444 SkASSERT(gammas); | 460 SkASSERT(gammas); |
445 return gammas->fRedType == SkGammas::Type::kParam_Type && | 461 return gammas->fRedType == SkGammas::Type::kParam_Type && |
446 gammas->fGreenType == SkGammas::Type::kParam_Type && | 462 gammas->fGreenType == SkGammas::Type::kParam_Type && |
447 gammas->fBlueType == SkGammas::Type::kParam_Type; | 463 gammas->fBlueType == SkGammas::Type::kParam_Type; |
448 } | 464 } |
OLD | NEW |