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 #include "SkPoint3.h" |
| 13 |
| 14 static inline bool is_zero_to_one(float v) { |
| 15 return (0.0f <= v) && (v <= 1.0f); |
| 16 } |
| 17 |
| 18 bool SkColorSpacePrimaries::toXYZD50(SkMatrix44* toXYZ_D50) const { |
| 19 if (!is_zero_to_one(fRX) || !is_zero_to_one(fRY) || |
| 20 !is_zero_to_one(fGX) || !is_zero_to_one(fGY) || |
| 21 !is_zero_to_one(fBX) || !is_zero_to_one(fBY) || |
| 22 !is_zero_to_one(fWX) || !is_zero_to_one(fWY)) |
| 23 { |
| 24 return false; |
| 25 } |
| 26 |
| 27 // First, we need to convert xy values (primaries) to XYZ. |
| 28 SkMatrix primaries; |
| 29 primaries.setAll( fRX, fGX, fBX, |
| 30 fRY, fGY, fBY, |
| 31 1.0f - fRX - fRY, 1.0f - fGX - fGY, 1.0f - fBX - fBY); |
| 32 SkMatrix primariesInv; |
| 33 if (!primaries.invert(&primariesInv)) { |
| 34 return false; |
| 35 } |
| 36 |
| 37 // Assumes that Y is 1.0f. |
| 38 SkVector3 wXYZ = SkVector3::Make(fWX / fWY, 1.0f, (1.0f - fWX - fWY) / fWY); |
| 39 SkVector3 XYZ; |
| 40 XYZ.fX = primariesInv[0] * wXYZ.fX + primariesInv[1] * wXYZ.fY + primariesIn
v[2] * wXYZ.fZ; |
| 41 XYZ.fY = primariesInv[3] * wXYZ.fX + primariesInv[4] * wXYZ.fY + primariesIn
v[5] * wXYZ.fZ; |
| 42 XYZ.fZ = primariesInv[6] * wXYZ.fX + primariesInv[7] * wXYZ.fY + primariesIn
v[8] * wXYZ.fZ; |
| 43 SkMatrix toXYZ; |
| 44 toXYZ.setAll(XYZ.fX, 0.0f, 0.0f, |
| 45 0.0f, XYZ.fY, 0.0f, |
| 46 0.0f, 0.0f, XYZ.fZ); |
| 47 toXYZ.postConcat(primaries); |
| 48 |
| 49 // Now convert toXYZ matrix to toXYZD50. |
| 50 SkVector3 wXYZD50 = SkVector3::Make(0.96422f, 1.0f, 0.82521f); |
| 51 |
| 52 // Calculate the chromatic adaptation matrix. We will use the Bradford meth
od, thus |
| 53 // the matrices below. The Bradford method is used by Adobe and is widely c
onsidered |
| 54 // to be the best. |
| 55 SkMatrix mA, mAInv; |
| 56 mA.setAll(+0.8951f, +0.2664f, -0.1614f, |
| 57 -0.7502f, +1.7135f, +0.0367f, |
| 58 +0.0389f, -0.0685f, +1.0296f); |
| 59 mAInv.setAll(+0.9869929f, -0.1470543f, +0.1599627f, |
| 60 +0.4323053f, +0.5183603f, +0.0492912f, |
| 61 -0.0085287f, +0.0400428f, +0.9684867f); |
| 62 |
| 63 SkVector3 srcCone; |
| 64 srcCone.fX = mA[0] * wXYZ.fX + mA[1] * wXYZ.fY + mA[2] * wXYZ.fZ; |
| 65 srcCone.fY = mA[3] * wXYZ.fX + mA[4] * wXYZ.fY + mA[5] * wXYZ.fZ; |
| 66 srcCone.fZ = mA[6] * wXYZ.fX + mA[7] * wXYZ.fY + mA[8] * wXYZ.fZ; |
| 67 SkVector3 dstCone; |
| 68 dstCone.fX = mA[0] * wXYZD50.fX + mA[1] * wXYZD50.fY + mA[2] * wXYZD50.fZ; |
| 69 dstCone.fY = mA[3] * wXYZD50.fX + mA[4] * wXYZD50.fY + mA[5] * wXYZD50.fZ; |
| 70 dstCone.fZ = mA[6] * wXYZD50.fX + mA[7] * wXYZD50.fY + mA[8] * wXYZD50.fZ; |
| 71 |
| 72 SkMatrix DXToD50; |
| 73 DXToD50.setIdentity(); |
| 74 DXToD50[0] = dstCone.fX / srcCone.fX; |
| 75 DXToD50[4] = dstCone.fY / srcCone.fY; |
| 76 DXToD50[8] = dstCone.fZ / srcCone.fZ; |
| 77 DXToD50.postConcat(mAInv); |
| 78 DXToD50.preConcat(mA); |
| 79 |
| 80 toXYZ.postConcat(DXToD50); |
| 81 toXYZ_D50->set3x3(toXYZ[0], toXYZ[3], toXYZ[6], |
| 82 toXYZ[1], toXYZ[4], toXYZ[7], |
| 83 toXYZ[2], toXYZ[5], toXYZ[8]); |
| 84 return true; |
| 85 } |
| 86 |
| 87 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
12 | 88 |
13 SkColorSpace_Base::SkColorSpace_Base(SkGammaNamed gammaNamed, const SkMatrix44&
toXYZD50) | 89 SkColorSpace_Base::SkColorSpace_Base(SkGammaNamed gammaNamed, const SkMatrix44&
toXYZD50) |
14 : fGammaNamed(gammaNamed) | 90 : fGammaNamed(gammaNamed) |
15 , fGammas(nullptr) | 91 , fGammas(nullptr) |
16 , fProfileData(nullptr) | 92 , fProfileData(nullptr) |
17 , fToXYZD50(toXYZD50) | 93 , fToXYZD50(toXYZD50) |
18 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) | 94 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) |
19 {} | 95 {} |
20 | 96 |
21 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGamma
Named gammaNamed, | 97 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGamma
Named gammaNamed, |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
463 return false; | 539 return false; |
464 } | 540 } |
465 | 541 |
466 // It is unlikely that we will reach this case. | 542 // It is unlikely that we will reach this case. |
467 sk_sp<SkData> srcData = src->serialize(); | 543 sk_sp<SkData> srcData = src->serialize(); |
468 sk_sp<SkData> dstData = dst->serialize(); | 544 sk_sp<SkData> dstData = dst->serialize(); |
469 return srcData->size() == dstData->size() && | 545 return srcData->size() == dstData->size() && |
470 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 546 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); |
471 } | 547 } |
472 } | 548 } |
OLD | NEW |