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" |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
118 break; | 118 break; |
119 } | 119 } |
120 | 120 |
121 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnkn
own_Named)); | 121 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnkn
own_Named)); |
122 } | 122 } |
123 | 123 |
124 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44
& toXYZD50) { | 124 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44
& toXYZD50) { |
125 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); | 125 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
126 } | 126 } |
127 | 127 |
| 128 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const GammaCoefficients& coeffs, |
| 129 const SkMatrix44& toXYZD50) { |
| 130 // TODO: Check if coeffs match sRGB, 2.2, or linear. |
| 131 // TODO: Make sure coefficients are non-crazy. Return nullptr if they are. |
| 132 void* memory = sk_malloc_throw(sizeof(SkGammas) + sizeof(SkColorSpace::Gamma
Params)); |
| 133 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new (memory) SkGammas()); |
| 134 void* storage = SkTAddOffset<void>(memory, sizeof(SkGammas)); |
| 135 memcpy(storage, &coeffs, sizeof(SkColorSpace::GammaParams)); |
| 136 gammas->fRedType = SkGammas::Type::kParam_Type; |
| 137 gammas->fGreenType = SkGammas::Type::kParam_Type; |
| 138 gammas->fBlueType = SkGammas::Type::kParam_Type; |
| 139 |
| 140 SkGammas::Data data; |
| 141 data.fParamOffset = 0; |
| 142 gammas->fRedData = data; |
| 143 gammas->fGreenData = data; |
| 144 gammas->fBlueData = data; |
| 145 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_Gamm
aNamed, |
| 146 std::move(gammas), toXYZD5
0, nullptr); |
| 147 } |
| 148 |
| 149 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const Primaries&
primaries) { |
| 150 SkMatrix44 toXYZD50; |
| 151 // TODO: Implement primaries_to_toXYZD50. |
| 152 if (!primaries_to_toXYZD50(&toXYZD50, primaries)) { |
| 153 return nullptr; |
| 154 } |
| 155 |
| 156 return NewRGB(gammaNamed, toXYZD50) |
| 157 } |
| 158 |
| 159 sk_sp<SkColorSpace> SkColorSpace::NewRGB(const GammaCoefficients& coeffs, |
| 160 const Primaries& primaries) { |
| 161 SkMatrix44 toXYZD50; |
| 162 if (!primaries_to_toXYZD50(&toXYZD50, primaries)) { |
| 163 return nullptr; |
| 164 } |
| 165 |
| 166 return NewRGB(coeffs, toXYZD50) |
| 167 } |
| 168 |
128 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 169 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
129 static SkOnce sRGBOnce; | 170 static SkOnce sRGBOnce; |
130 static sk_sp<SkColorSpace> sRGB; | 171 static sk_sp<SkColorSpace> sRGB; |
131 static SkOnce adobeRGBOnce; | 172 static SkOnce adobeRGBOnce; |
132 static sk_sp<SkColorSpace> adobeRGB; | 173 static sk_sp<SkColorSpace> adobeRGB; |
133 | 174 |
134 switch (named) { | 175 switch (named) { |
135 case kSRGB_Named: { | 176 case kSRGB_Named: { |
136 sRGBOnce([] { | 177 sRGBOnce([] { |
137 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 178 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
244 if (memory) { | 285 if (memory) { |
245 *((ColorSpaceHeader*) memory) = | 286 *((ColorSpaceHeader*) memory) = |
246 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, | 287 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, |
247 ColorSpaceHeader::kMatrix_Fla
g); | 288 ColorSpaceHeader::kMatrix_Fla
g); |
248 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 289 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
249 fToXYZD50.as4x3ColMajorf((float*) memory); | 290 fToXYZD50.as4x3ColMajorf((float*) memory); |
250 } | 291 } |
251 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); | 292 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); |
252 } | 293 } |
253 default: | 294 default: |
| 295 // TODO: This case gets trickier. The code below exists because
I allow |
| 296 // SkPngCodec to call a constructor with float gammas. |
| 297 // I think the best thing to do would be: |
| 298 // (1) Fix SkPngCodec to call one of the new constructors. |
| 299 // (2) Handle serializing the parametric gammas here. |
| 300 // TODO: In a separate CL, remove the idea of "exponential" gamm
as. |
| 301 // These can be consumed by the parametric case. Maybe th
is CL |
| 302 // should land first. |
| 303 |
254 // Otherwise, write the gamma values and the matrix. | 304 // Otherwise, write the gamma values and the matrix. |
255 if (memory) { | 305 if (memory) { |
256 *((ColorSpaceHeader*) memory) = | 306 *((ColorSpaceHeader*) memory) = |
257 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, | 307 ColorSpaceHeader::Pack(k0_Version, fNamed, fGammaNam
ed, |
258 ColorSpaceHeader::kFloatGamma
_Flag); | 308 ColorSpaceHeader::kFloatGamma
_Flag); |
259 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 309 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
260 | 310 |
261 const SkGammas* gammas = as_CSB(this)->gammas(); | 311 const SkGammas* gammas = as_CSB(this)->gammas(); |
262 SkASSERT(gammas); | 312 SkASSERT(gammas); |
263 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && | 313 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
347 uint32_t profileSize = *((uint32_t*) data); | 397 uint32_t profileSize = *((uint32_t*) data); |
348 data = SkTAddOffset<const void>(data, sizeof(uint32_t)); | 398 data = SkTAddOffset<const void>(data, sizeof(uint32_t)); |
349 length -= sizeof(uint32_t); | 399 length -= sizeof(uint32_t); |
350 if (length < profileSize) { | 400 if (length < profileSize) { |
351 return nullptr; | 401 return nullptr; |
352 } | 402 } |
353 | 403 |
354 return NewICC(data, profileSize); | 404 return NewICC(data, profileSize); |
355 } | 405 } |
356 case ColorSpaceHeader::kFloatGamma_Flag: { | 406 case ColorSpaceHeader::kFloatGamma_Flag: { |
| 407 // TODO: This needs to be fixed to match the new version of serializ
e(). |
| 408 |
357 if (length < 15 * sizeof(float)) { | 409 if (length < 15 * sizeof(float)) { |
358 return nullptr; | 410 return nullptr; |
359 } | 411 } |
360 | 412 |
361 float gammas[3]; | 413 float gammas[3]; |
362 gammas[0] = *(((const float*) data) + 0); | 414 gammas[0] = *(((const float*) data) + 0); |
363 gammas[1] = *(((const float*) data) + 1); | 415 gammas[1] = *(((const float*) data) + 1); |
364 gammas[2] = *(((const float*) data) + 2); | 416 gammas[2] = *(((const float*) data) + 2); |
365 data = SkTAddOffset<const void>(data, 3 * sizeof(float)); | 417 data = SkTAddOffset<const void>(data, 3 * sizeof(float)); |
366 | 418 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
408 // gammas, but also include other wacky features that cause us to save the d
ata. | 460 // gammas, but also include other wacky features that cause us to save the d
ata. |
409 switch (src->fGammaNamed) { | 461 switch (src->fGammaNamed) { |
410 case kSRGB_GammaNamed: | 462 case kSRGB_GammaNamed: |
411 case k2Dot2Curve_GammaNamed: | 463 case k2Dot2Curve_GammaNamed: |
412 case kLinear_GammaNamed: | 464 case kLinear_GammaNamed: |
413 return (src->fGammaNamed == dst->fGammaNamed) && (src->fToXYZD50 ==
dst->fToXYZD50); | 465 return (src->fGammaNamed == dst->fGammaNamed) && (src->fToXYZD50 ==
dst->fToXYZD50); |
414 default: | 466 default: |
415 if (src->fGammaNamed != dst->fGammaNamed) { | 467 if (src->fGammaNamed != dst->fGammaNamed) { |
416 return false; | 468 return false; |
417 } | 469 } |
| 470 // This should still work :). |
418 | 471 |
419 // It is unlikely that we will reach this case. | 472 // It is unlikely that we will reach this case. |
420 sk_sp<SkData> srcData = src->serialize(); | 473 sk_sp<SkData> srcData = src->serialize(); |
421 sk_sp<SkData> dstData = dst->serialize(); | 474 sk_sp<SkData> dstData = dst->serialize(); |
422 return srcData->size() == dstData->size() && | 475 return srcData->size() == dstData->size() && |
423 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 476 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); |
424 } | 477 } |
425 } | 478 } |
426 | 479 |
427 bool SkColorSpace::gammasAreMatching() const { | 480 bool SkColorSpace::gammasAreMatching() const { |
(...skipping 27 matching lines...) Expand all Loading... |
455 gammas->fBlueType == SkGammas::Type::kTable_Type; | 508 gammas->fBlueType == SkGammas::Type::kTable_Type; |
456 } | 509 } |
457 | 510 |
458 bool SkColorSpace::gammasAreParams() const { | 511 bool SkColorSpace::gammasAreParams() const { |
459 const SkGammas* gammas = as_CSB(this)->gammas(); | 512 const SkGammas* gammas = as_CSB(this)->gammas(); |
460 SkASSERT(gammas); | 513 SkASSERT(gammas); |
461 return gammas->fRedType == SkGammas::Type::kParam_Type && | 514 return gammas->fRedType == SkGammas::Type::kParam_Type && |
462 gammas->fGreenType == SkGammas::Type::kParam_Type && | 515 gammas->fGreenType == SkGammas::Type::kParam_Type && |
463 gammas->fBlueType == SkGammas::Type::kParam_Type; | 516 gammas->fBlueType == SkGammas::Type::kParam_Type; |
464 } | 517 } |
OLD | NEW |