| 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 |