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 "SkAtomics.h" | 8 #include "SkAtomics.h" |
9 #include "SkColorSpace.h" | 9 #include "SkColorSpace.h" |
10 #include "SkOnce.h" | 10 #include "SkOnce.h" |
(...skipping 25 matching lines...) Expand all Loading... |
36 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) | 36 , fUniqueID(sk_atomic_inc(&gUniqueColorSpaceID)) |
37 , fNamed(kUnknown_Named) | 37 , fNamed(kUnknown_Named) |
38 {} | 38 {} |
39 | 39 |
40 const float gSRGB_toXYZD50[] { | 40 const float gSRGB_toXYZD50[] { |
41 0.4358f, 0.2224f, 0.0139f, // * R | 41 0.4358f, 0.2224f, 0.0139f, // * R |
42 0.3853f, 0.7170f, 0.0971f, // * G | 42 0.3853f, 0.7170f, 0.0971f, // * G |
43 0.1430f, 0.0606f, 0.7139f, // * B | 43 0.1430f, 0.0606f, 0.7139f, // * B |
44 }; | 44 }; |
45 | 45 |
| 46 const float gAdobeRGB_toXYZD50[] { |
| 47 0.6098f, 0.3111f, 0.0195f, // * R |
| 48 0.2052f, 0.6257f, 0.0609f, // * G |
| 49 0.1492f, 0.0632f, 0.7448f, // * B |
| 50 }; |
| 51 |
| 52 /** |
| 53 * Checks if our toXYZ matrix is a close match to a known color gamut. |
| 54 * |
| 55 * @param toXYZD50 transformation matrix deduced from profile data |
| 56 * @param standard 3x3 canonical transformation matrix |
| 57 */ |
| 58 static bool xyz_almost_equal(const SkMatrix44& toXYZD50, const float* standard)
{ |
| 59 return color_space_almost_equal(toXYZD50.getFloat(0, 0), standard[0]) && |
| 60 color_space_almost_equal(toXYZD50.getFloat(0, 1), standard[1]) && |
| 61 color_space_almost_equal(toXYZD50.getFloat(0, 2), standard[2]) && |
| 62 color_space_almost_equal(toXYZD50.getFloat(1, 0), standard[3]) && |
| 63 color_space_almost_equal(toXYZD50.getFloat(1, 1), standard[4]) && |
| 64 color_space_almost_equal(toXYZD50.getFloat(1, 2), standard[5]) && |
| 65 color_space_almost_equal(toXYZD50.getFloat(2, 0), standard[6]) && |
| 66 color_space_almost_equal(toXYZD50.getFloat(2, 1), standard[7]) && |
| 67 color_space_almost_equal(toXYZD50.getFloat(2, 2), standard[8]) && |
| 68 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && |
| 69 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && |
| 70 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && |
| 71 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && |
| 72 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && |
| 73 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && |
| 74 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f); |
| 75 } |
| 76 |
46 sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXY
ZD50) { | 77 sk_sp<SkColorSpace> SkColorSpace::NewRGB(SkGammas gammas, const SkMatrix44& toXY
ZD50) { |
47 // Check if we really have sRGB | 78 // Check if we really have sRGB or Adobe RGB |
48 if (color_space_almost_equal(2.2f, gammas.fRed.fValue) && | 79 if (color_space_almost_equal(2.2f, gammas.fRed.fValue) && |
49 color_space_almost_equal(2.2f, gammas.fGreen.fValue) && | 80 color_space_almost_equal(2.2f, gammas.fGreen.fValue) && |
50 color_space_almost_equal(2.2f, gammas.fBlue.fValue) && | 81 color_space_almost_equal(2.2f, gammas.fBlue.fValue)) |
51 color_space_almost_equal(toXYZD50.getFloat(0, 0), gSRGB_toXYZD50[0]) && | |
52 color_space_almost_equal(toXYZD50.getFloat(0, 1), gSRGB_toXYZD50[1]) && | |
53 color_space_almost_equal(toXYZD50.getFloat(0, 2), gSRGB_toXYZD50[2]) && | |
54 color_space_almost_equal(toXYZD50.getFloat(1, 0), gSRGB_toXYZD50[3]) && | |
55 color_space_almost_equal(toXYZD50.getFloat(1, 1), gSRGB_toXYZD50[4]) && | |
56 color_space_almost_equal(toXYZD50.getFloat(1, 2), gSRGB_toXYZD50[5]) && | |
57 color_space_almost_equal(toXYZD50.getFloat(2, 0), gSRGB_toXYZD50[6]) && | |
58 color_space_almost_equal(toXYZD50.getFloat(2, 1), gSRGB_toXYZD50[7]) && | |
59 color_space_almost_equal(toXYZD50.getFloat(2, 2), gSRGB_toXYZD50[8]) && | |
60 color_space_almost_equal(toXYZD50.getFloat(0, 3), 0.0f) && | |
61 color_space_almost_equal(toXYZD50.getFloat(1, 3), 0.0f) && | |
62 color_space_almost_equal(toXYZD50.getFloat(2, 3), 0.0f) && | |
63 color_space_almost_equal(toXYZD50.getFloat(3, 0), 0.0f) && | |
64 color_space_almost_equal(toXYZD50.getFloat(3, 1), 0.0f) && | |
65 color_space_almost_equal(toXYZD50.getFloat(3, 2), 0.0f) && | |
66 color_space_almost_equal(toXYZD50.getFloat(3, 3), 1.0f)) | |
67 { | 82 { |
68 return SkColorSpace::NewNamed(kSRGB_Named); | 83 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
| 84 return SkColorSpace::NewNamed(kSRGB_Named); |
| 85 } else if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { |
| 86 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
| 87 } |
69 } | 88 } |
70 | 89 |
71 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn
known_Named)); | 90 return sk_sp<SkColorSpace>(new SkColorSpace(std::move(gammas), toXYZD50, kUn
known_Named)); |
72 } | 91 } |
73 | 92 |
74 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 93 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
75 static SkOnce once; | 94 static SkOnce sRGBOnce; |
76 static SkColorSpace* sRGB; | 95 static SkColorSpace* sRGB; |
| 96 static SkOnce adobeRGBOnce; |
| 97 static SkColorSpace* adobeRGB; |
77 | 98 |
78 switch (named) { | 99 switch (named) { |
79 case kSRGB_Named: { | 100 case kSRGB_Named: { |
80 once([] { | 101 sRGBOnce([] { |
81 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 102 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
82 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); | 103 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); |
83 sRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50
, kSRGB_Named); | 104 sRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), srgbToxyzD50
, kSRGB_Named); |
84 }); | 105 }); |
85 return sk_ref_sp(sRGB); | 106 return sk_ref_sp(sRGB); |
86 } | 107 } |
| 108 case kAdobeRGB_Named: { |
| 109 adobeRGBOnce([] { |
| 110 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); |
| 111 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); |
| 112 adobeRGB = new SkColorSpace(SkGammas(2.2f, 2.2f, 2.2f), adobergb
ToxyzD50, |
| 113 kAdobeRGB_Named); |
| 114 }); |
| 115 return sk_ref_sp(adobeRGB); |
| 116 } |
87 default: | 117 default: |
88 break; | 118 break; |
89 } | 119 } |
90 return nullptr; | 120 return nullptr; |
91 } | 121 } |
92 | 122 |
93 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 123 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
94 | 124 |
95 #include "SkFixed.h" | 125 #include "SkFixed.h" |
96 #include "SkTemplates.h" | 126 #include "SkTemplates.h" |
(...skipping 562 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
659 toXYZ)); | 689 toXYZ)); |
660 } | 690 } |
661 | 691 |
662 } | 692 } |
663 default: | 693 default: |
664 break; | 694 break; |
665 } | 695 } |
666 | 696 |
667 return_null("ICC profile contains unsupported colorspace"); | 697 return_null("ICC profile contains unsupported colorspace"); |
668 } | 698 } |
OLD | NEW |