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 "SkColorSpace_A2B0.h" |
| 11 #include "SkColorSpace_XYZTRC.h" |
10 #include "SkColorSpacePriv.h" | 12 #include "SkColorSpacePriv.h" |
11 #include "SkOnce.h" | 13 #include "SkOnce.h" |
12 | 14 |
13 SkColorSpace_Base::SkColorSpace_Base(SkGammaNamed gammaNamed, const SkMatrix44&
toXYZD50) | 15 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkData> profileData, Type type) |
14 : fGammaNamed(gammaNamed) | 16 : fProfileData(std::move(profileData)) |
15 , fGammas(nullptr) | 17 , fType(type) |
16 , fProfileData(nullptr) | |
17 , fToXYZD50(toXYZD50) | |
18 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) | |
19 {} | |
20 | |
21 SkColorSpace_Base::SkColorSpace_Base(sk_sp<SkColorLookUpTable> colorLUT, SkGamma
Named gammaNamed, | |
22 sk_sp<SkGammas> gammas, const SkMatrix44& t
oXYZD50, | |
23 sk_sp<SkData> profileData) | |
24 : fColorLUT(std::move(colorLUT)) | |
25 , fGammaNamed(gammaNamed) | |
26 , fGammas(std::move(gammas)) | |
27 , fProfileData(std::move(profileData)) | |
28 , fToXYZD50(toXYZD50) | |
29 , fFromXYZD50(SkMatrix44::kUninitialized_Constructor) | |
30 {} | 18 {} |
31 | 19 |
32 static constexpr float gSRGB_toXYZD50[] { | 20 static constexpr float gSRGB_toXYZD50[] { |
33 0.4358f, 0.3853f, 0.1430f, // Rx, Gx, Bx | 21 0.4358f, 0.3853f, 0.1430f, // Rx, Gx, Bx |
34 0.2224f, 0.7170f, 0.0606f, // Ry, Gy, Gz | 22 0.2224f, 0.7170f, 0.0606f, // Ry, Gy, Gz |
35 0.0139f, 0.0971f, 0.7139f, // Rz, Gz, Bz | 23 0.0139f, 0.0971f, 0.7139f, // Rz, Gz, Bz |
36 }; | 24 }; |
37 | 25 |
38 static constexpr float gAdobeRGB_toXYZD50[] { | 26 static constexpr float gAdobeRGB_toXYZD50[] { |
39 0.6098f, 0.2052f, 0.1492f, // Rx, Gx, Bx | 27 0.6098f, 0.2052f, 0.1492f, // Rx, Gx, Bx |
(...skipping 43 matching lines...) Loading... |
83 } | 71 } |
84 | 72 |
85 if (kNonStandard_SkGammaNamed == gammaNamed) { | 73 if (kNonStandard_SkGammaNamed == gammaNamed) { |
86 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); | 74 sk_sp<SkGammas> gammas = sk_sp<SkGammas>(new SkGammas()); |
87 gammas->fRedType = SkGammas::Type::kValue_Type; | 75 gammas->fRedType = SkGammas::Type::kValue_Type; |
88 gammas->fGreenType = SkGammas::Type::kValue_Type; | 76 gammas->fGreenType = SkGammas::Type::kValue_Type; |
89 gammas->fBlueType = SkGammas::Type::kValue_Type; | 77 gammas->fBlueType = SkGammas::Type::kValue_Type; |
90 gammas->fRedData.fValue = values[0]; | 78 gammas->fRedData.fValue = values[0]; |
91 gammas->fGreenData.fValue = values[1]; | 79 gammas->fGreenData.fValue = values[1]; |
92 gammas->fBlueData.fValue = values[2]; | 80 gammas->fBlueData.fValue = values[2]; |
93 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, kNonStandard_S
kGammaNamed, gammas, | 81 return sk_sp<SkColorSpace>(new SkColorSpace_XYZTRC(kNonStandard_SkGammaN
amed, |
94 toXYZD50, nullptr)); | 82 gammas, toXYZD50, nul
lptr)); |
95 } | 83 } |
96 | 84 |
97 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); | 85 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
98 } | 86 } |
99 | 87 |
100 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
atrix44& toXYZD50) { | 88 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(SkGammaNamed gammaNamed, const SkM
atrix44& toXYZD50) { |
101 switch (gammaNamed) { | 89 switch (gammaNamed) { |
102 case kSRGB_SkGammaNamed: | 90 case kSRGB_SkGammaNamed: |
103 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 91 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
104 return SkColorSpace::NewNamed(kSRGB_Named); | 92 return SkColorSpace::NewNamed(kSRGB_Named); |
105 } | 93 } |
106 break; | 94 break; |
107 case k2Dot2Curve_SkGammaNamed: | 95 case k2Dot2Curve_SkGammaNamed: |
108 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { | 96 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { |
109 return SkColorSpace::NewNamed(kAdobeRGB_Named); | 97 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
110 } | 98 } |
111 break; | 99 break; |
112 case kLinear_SkGammaNamed: | 100 case kLinear_SkGammaNamed: |
113 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 101 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
114 return SkColorSpace::NewNamed(kSRGBLinear_Named); | 102 return SkColorSpace::NewNamed(kSRGBLinear_Named); |
115 } | 103 } |
116 break; | 104 break; |
117 case kNonStandard_SkGammaNamed: | 105 case kNonStandard_SkGammaNamed: |
118 // This is not allowed. | 106 // This is not allowed. |
119 return nullptr; | 107 return nullptr; |
120 default: | 108 default: |
121 break; | 109 break; |
122 } | 110 } |
123 | 111 |
124 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50)); | 112 return sk_sp<SkColorSpace>(new SkColorSpace_XYZTRC(gammaNamed, toXYZD50)); |
125 } | 113 } |
126 | 114 |
127 sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix
44& toXYZD50) { | 115 sk_sp<SkColorSpace> SkColorSpace::NewRGB(RenderTargetGamma gamma, const SkMatrix
44& toXYZD50) { |
128 switch (gamma) { | 116 switch (gamma) { |
129 case kLinear_RenderTargetGamma: | 117 case kLinear_RenderTargetGamma: |
130 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50); | 118 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, toXYZD50); |
131 case kSRGB_RenderTargetGamma: | 119 case kSRGB_RenderTargetGamma: |
132 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50); | 120 return SkColorSpace_Base::NewRGB(kSRGB_SkGammaNamed, toXYZD50); |
133 default: | 121 default: |
134 return nullptr; | 122 return nullptr; |
(...skipping 10 matching lines...) Loading... |
145 static SkOnce sRGBLinearOnce; | 133 static SkOnce sRGBLinearOnce; |
146 | 134 |
147 switch (named) { | 135 switch (named) { |
148 case kSRGB_Named: { | 136 case kSRGB_Named: { |
149 sRGBOnce([] { | 137 sRGBOnce([] { |
150 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 138 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
151 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 139 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); |
152 | 140 |
153 // Force the mutable type mask to be computed. This avoids race
s. | 141 // Force the mutable type mask to be computed. This avoids race
s. |
154 (void)srgbToxyzD50.getType(); | 142 (void)srgbToxyzD50.getType(); |
155 gSRGB = new SkColorSpace_Base(kSRGB_SkGammaNamed, srgbToxyzD50); | 143 gSRGB = new SkColorSpace_XYZTRC(kSRGB_SkGammaNamed, srgbToxyzD50
); |
156 }); | 144 }); |
157 return sk_ref_sp<SkColorSpace>(gSRGB); | 145 return sk_ref_sp<SkColorSpace>(gSRGB); |
158 } | 146 } |
159 case kAdobeRGB_Named: { | 147 case kAdobeRGB_Named: { |
160 adobeRGBOnce([] { | 148 adobeRGBOnce([] { |
161 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); | 149 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct
or); |
162 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); | 150 adobergbToxyzD50.set3x3RowMajorf(gAdobeRGB_toXYZD50); |
163 | 151 |
164 // Force the mutable type mask to be computed. This avoids race
s. | 152 // Force the mutable type mask to be computed. This avoids race
s. |
165 (void)adobergbToxyzD50.getType(); | 153 (void)adobergbToxyzD50.getType(); |
166 gAdobeRGB = new SkColorSpace_Base(k2Dot2Curve_SkGammaNamed, adob
ergbToxyzD50); | 154 gAdobeRGB = new SkColorSpace_XYZTRC(k2Dot2Curve_SkGammaNamed, ad
obergbToxyzD50); |
167 }); | 155 }); |
168 return sk_ref_sp<SkColorSpace>(gAdobeRGB); | 156 return sk_ref_sp<SkColorSpace>(gAdobeRGB); |
169 } | 157 } |
170 case kSRGBLinear_Named: { | 158 case kSRGBLinear_Named: { |
171 sRGBLinearOnce([] { | 159 sRGBLinearOnce([] { |
172 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 160 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
173 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 161 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); |
174 | 162 |
175 // Force the mutable type mask to be computed. This avoids race
s. | 163 // Force the mutable type mask to be computed. This avoids race
s. |
176 (void)srgbToxyzD50.getType(); | 164 (void)srgbToxyzD50.getType(); |
177 gSRGBLinear = new SkColorSpace_Base(kLinear_SkGammaNamed, srgbTo
xyzD50); | 165 gSRGBLinear = new SkColorSpace_XYZTRC(kLinear_SkGammaNamed, srgb
ToxyzD50); |
178 }); | 166 }); |
179 return sk_ref_sp<SkColorSpace>(gSRGBLinear); | 167 return sk_ref_sp<SkColorSpace>(gSRGBLinear); |
180 } | 168 } |
181 default: | 169 default: |
182 break; | 170 break; |
183 } | 171 } |
184 return nullptr; | 172 return nullptr; |
185 } | 173 } |
186 | 174 |
187 sk_sp<SkColorSpace> SkColorSpace::makeLinearGamma() { | 175 sk_sp<SkColorSpace> SkColorSpace::makeLinearGamma() { |
188 if (this->gammaIsLinear()) { | 176 if (this->gammaIsLinear()) { |
189 return sk_ref_sp(this); | 177 return sk_ref_sp(this); |
190 } | 178 } |
191 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, as_CSB(this)->fToXYZD
50); | 179 » // A2B0 Color Spaces do not have a single Gamma, so this method should n
ot be |
| 180 » // called on them. |
| 181 » SkASSERT(as_CSB(this)->type() == SkColorSpace_Base::Type::kXYZTRC); |
| 182 return SkColorSpace_Base::NewRGB(kLinear_SkGammaNamed, as_CSXYZ(this)->fToXY
ZD50); |
192 } | 183 } |
193 | 184 |
194 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 185 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
195 | 186 |
196 bool SkColorSpace::gammaCloseToSRGB() const { | 187 bool SkColorSpace::gammaCloseToSRGB() const { |
197 return kSRGB_SkGammaNamed == as_CSB(this)->fGammaNamed || | 188 switch (as_CSB(this)->type()) |
198 k2Dot2Curve_SkGammaNamed == as_CSB(this)->fGammaNamed; | 189 { |
| 190 case SkColorSpace_Base::Type::kXYZTRC: |
| 191 return kSRGB_SkGammaNamed == as_CSXYZ(this)->fGammaNamed || |
| 192 k2Dot2Curve_SkGammaNamed == as_CSXYZ(this)->fGammaNamed; |
| 193 case SkColorSpace_Base::Type::kA2B0: |
| 194 // Uncomment this assert later on |
| 195 //SkASSERT(false); |
| 196 return false; |
| 197 default: |
| 198 break; |
| 199 } |
| 200 SkASSERT(false); |
| 201 return false; |
199 } | 202 } |
200 | 203 |
201 bool SkColorSpace::gammaIsLinear() const { | 204 bool SkColorSpace::gammaIsLinear() const { |
202 return kLinear_SkGammaNamed == as_CSB(this)->fGammaNamed; | 205 switch (as_CSB(this)->type()) |
203 } | 206 { |
204 | 207 case SkColorSpace_Base::Type::kXYZTRC: |
205 const SkMatrix44& SkColorSpace_Base::fromXYZD50() const { | 208 return kLinear_SkGammaNamed == as_CSXYZ(this)->fGammaNamed; |
206 fFromXYZOnce([this] { | 209 case SkColorSpace_Base::Type::kA2B0: |
207 if (!fToXYZD50.invert(&fFromXYZD50)) { | 210 // Uncomment this assert later on |
208 // If a client gives us a dst gamut with a transform that we can't i
nvert, we will | 211 //SkASSERT(false); |
209 // simply give them back a transform to sRGB gamut. | 212 return false; |
210 SkDEBUGFAIL("Non-invertible XYZ matrix, defaulting to sRGB"); | 213 default: |
211 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 214 break; |
212 srgbToxyzD50.set3x3RowMajorf(gSRGB_toXYZD50); | 215 } |
213 srgbToxyzD50.invert(&fFromXYZD50); | 216 SkASSERT(false); |
214 } | 217 return false; |
215 }); | |
216 return fFromXYZD50; | |
217 } | 218 } |
218 | 219 |
219 ////////////////////////////////////////////////////////////////////////////////
/////////////////// | 220 ////////////////////////////////////////////////////////////////////////////////
/////////////////// |
220 | 221 |
221 enum Version { | 222 enum Version { |
222 k0_Version, // Initial version, header + flags for matrix and profile | 223 k0_Version, // Initial version, header + flags for matrix and profile |
223 }; | 224 }; |
224 | 225 |
225 struct ColorSpaceHeader { | 226 struct ColorSpaceHeader { |
226 /** | 227 /** |
(...skipping 39 matching lines...) Loading... |
266 uint8_t fVersion; // Always zero | 267 uint8_t fVersion; // Always zero |
267 uint8_t fNamed; // Must be a SkColorSpace::Named | 268 uint8_t fNamed; // Must be a SkColorSpace::Named |
268 uint8_t fGammaNamed; // Must be a SkGammaNamed | 269 uint8_t fGammaNamed; // Must be a SkGammaNamed |
269 uint8_t fFlags; // Some combination of the flags listed above | 270 uint8_t fFlags; // Some combination of the flags listed above |
270 }; | 271 }; |
271 | 272 |
272 size_t SkColorSpace::writeToMemory(void* memory) const { | 273 size_t SkColorSpace::writeToMemory(void* memory) const { |
273 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, | 274 // Start by trying the serialization fast path. If we haven't saved ICC pro
file data, |
274 // we must have a profile that we can serialize easily. | 275 // we must have a profile that we can serialize easily. |
275 if (!as_CSB(this)->fProfileData) { | 276 if (!as_CSB(this)->fProfileData) { |
| 277 // Profile data is mandatory for A2B0 color spaces. |
276 // If we have a named profile, only write the enum. | 278 // If we have a named profile, only write the enum. |
| 279 const SkGammaNamed gammaNamed = as_CSXYZ(this)->gammaNamed(); |
277 if (this == gSRGB) { | 280 if (this == gSRGB) { |
278 if (memory) { | 281 if (memory) { |
279 *((ColorSpaceHeader*) memory) = | 282 *((ColorSpaceHeader*) memory) = |
280 ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, | 283 ColorSpaceHeader::Pack(k0_Version, kSRGB_Named, gammaNam
ed, 0); |
281 as_CSB(this)->fGammaNamed, 0); | |
282 } | 284 } |
283 return sizeof(ColorSpaceHeader); | 285 return sizeof(ColorSpaceHeader); |
284 } else if (this == gAdobeRGB) { | 286 } else if (this == gAdobeRGB) { |
285 if (memory) { | 287 if (memory) { |
286 *((ColorSpaceHeader*) memory) = | 288 *((ColorSpaceHeader*) memory) = |
287 ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, | 289 ColorSpaceHeader::Pack(k0_Version, kAdobeRGB_Named, gamm
aNamed, 0); |
288 as_CSB(this)->fGammaNamed, 0); | |
289 } | 290 } |
290 return sizeof(ColorSpaceHeader); | 291 return sizeof(ColorSpaceHeader); |
291 } else if (this == gSRGBLinear) { | 292 } else if (this == gSRGBLinear) { |
292 if (memory) { | 293 if (memory) { |
293 *((ColorSpaceHeader*)memory) = | 294 *((ColorSpaceHeader*)memory) = |
294 ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named, | 295 ColorSpaceHeader::Pack(k0_Version, kSRGBLinear_Named, ga
mmaNamed, 0); |
295 as_CSB(this)->fGammaNamed, 0); | |
296 } | 296 } |
297 return sizeof(ColorSpaceHeader); | 297 return sizeof(ColorSpaceHeader); |
298 } | 298 } |
299 | 299 |
300 // If we have a named gamma, write the enum and the matrix. | 300 // If we have a named gamma, write the enum and the matrix. |
301 switch (as_CSB(this)->fGammaNamed) { | 301 switch (gammaNamed) { |
302 case kSRGB_SkGammaNamed: | 302 case kSRGB_SkGammaNamed: |
303 case k2Dot2Curve_SkGammaNamed: | 303 case k2Dot2Curve_SkGammaNamed: |
304 case kLinear_SkGammaNamed: { | 304 case kLinear_SkGammaNamed: { |
305 if (memory) { | 305 if (memory) { |
306 *((ColorSpaceHeader*) memory) = | 306 *((ColorSpaceHeader*) memory) = |
307 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->
fGammaNamed, | 307 ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed, |
308 ColorSpaceHeader::kMatrix_Fla
g); | 308 ColorSpaceHeader::kMatrix_Fla
g); |
309 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 309 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
310 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); | 310 as_CSXYZ(this)->toXYZD50().as3x4RowMajorf((float*) memory); |
311 } | 311 } |
312 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); | 312 return sizeof(ColorSpaceHeader) + 12 * sizeof(float); |
313 } | 313 } |
314 default: | 314 default: |
315 // Otherwise, write the gamma values and the matrix. | 315 // Otherwise, write the gamma values and the matrix. |
316 if (memory) { | 316 if (memory) { |
317 *((ColorSpaceHeader*) memory) = | 317 *((ColorSpaceHeader*) memory) = |
318 ColorSpaceHeader::Pack(k0_Version, 0, as_CSB(this)->
fGammaNamed, | 318 ColorSpaceHeader::Pack(k0_Version, 0, gammaNamed, |
319 ColorSpaceHeader::kFloatGamma
_Flag); | 319 ColorSpaceHeader::kFloatGamma
_Flag); |
320 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); | 320 memory = SkTAddOffset<void>(memory, sizeof(ColorSpaceHeader)
); |
321 | 321 |
322 const SkGammas* gammas = as_CSB(this)->gammas(); | 322 const SkGammas* gammas = as_CSXYZ(this)->gammas(); |
323 SkASSERT(gammas); | 323 SkASSERT(gammas); |
324 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && | 324 SkASSERT(SkGammas::Type::kValue_Type == gammas->fRedType && |
325 SkGammas::Type::kValue_Type == gammas->fGreenType &
& | 325 SkGammas::Type::kValue_Type == gammas->fGreenType &
& |
326 SkGammas::Type::kValue_Type == gammas->fBlueType); | 326 SkGammas::Type::kValue_Type == gammas->fBlueType); |
327 *(((float*) memory) + 0) = gammas->fRedData.fValue; | 327 *(((float*) memory) + 0) = gammas->fRedData.fValue; |
328 *(((float*) memory) + 1) = gammas->fGreenData.fValue; | 328 *(((float*) memory) + 1) = gammas->fGreenData.fValue; |
329 *(((float*) memory) + 2) = gammas->fBlueData.fValue; | 329 *(((float*) memory) + 2) = gammas->fBlueData.fValue; |
330 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); | 330 memory = SkTAddOffset<void>(memory, 3 * sizeof(float)); |
331 | 331 |
332 as_CSB(this)->fToXYZD50.as3x4RowMajorf((float*) memory); | 332 as_CSXYZ(this)->toXYZD50().as3x4RowMajorf((float*) memory); |
333 } | 333 } |
334 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); | 334 return sizeof(ColorSpaceHeader) + 15 * sizeof(float); |
335 } | 335 } |
336 } | 336 } |
337 | 337 |
338 // Otherwise, serialize the ICC data. | 338 // Otherwise, serialize the ICC data. |
339 size_t profileSize = as_CSB(this)->fProfileData->size(); | 339 size_t profileSize = as_CSB(this)->fProfileData->size(); |
340 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { | 340 if (SkAlign4(profileSize) != (uint32_t) SkAlign4(profileSize)) { |
341 return 0; | 341 return 0; |
342 } | 342 } |
(...skipping 88 matching lines...) Loading... |
431 } | 431 } |
432 | 432 |
433 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { | 433 bool SkColorSpace::Equals(const SkColorSpace* src, const SkColorSpace* dst) { |
434 if (src == dst) { | 434 if (src == dst) { |
435 return true; | 435 return true; |
436 } | 436 } |
437 | 437 |
438 if (!src || !dst) { | 438 if (!src || !dst) { |
439 return false; | 439 return false; |
440 } | 440 } |
| 441 |
| 442 if (as_CSB(src)->type() != as_CSB(dst)->type()) { |
| 443 return false; |
| 444 } |
441 | 445 |
442 SkData* srcData = as_CSB(src)->fProfileData.get(); | 446 SkData* srcData = as_CSB(src)->fProfileData.get(); |
443 SkData* dstData = as_CSB(dst)->fProfileData.get(); | 447 SkData* dstData = as_CSB(dst)->fProfileData.get(); |
444 if (srcData || dstData) { | 448 if (srcData || dstData) { |
445 if (srcData && dstData) { | 449 if (srcData && dstData) { |
446 return srcData->size() == dstData->size() && | 450 return srcData->size() == dstData->size() && |
447 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 451 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); |
448 } | 452 } |
449 | 453 |
450 return false; | 454 return false; |
451 } | 455 } |
452 | 456 |
453 // It's important to check fProfileData before named gammas. Some profiles
may have named | 457 // It's important to check fProfileData before named gammas. Some profiles
may have named |
454 // gammas, but also include other wacky features that cause us to save the d
ata. | 458 // gammas, but also include other wacky features that cause us to save the d
ata. |
455 switch (as_CSB(src)->fGammaNamed) { | 459 if (as_CSB(src)->type() == SkColorSpace_Base::Type::kXYZTRC) { |
456 case kSRGB_SkGammaNamed: | 460 switch (as_CSXYZ(src)->gammaNamed()) { |
457 case k2Dot2Curve_SkGammaNamed: | 461 case kSRGB_SkGammaNamed: |
458 case kLinear_SkGammaNamed: | 462 case k2Dot2Curve_SkGammaNamed: |
459 return (as_CSB(src)->fGammaNamed == as_CSB(dst)->fGammaNamed) && | 463 case kLinear_SkGammaNamed: |
460 (as_CSB(src)->fToXYZD50 == as_CSB(dst)->fToXYZD50); | 464 return (as_CSXYZ(src)->gammaNamed() == as_CSXYZ(dst)->gammaNamed
()) && |
461 default: | 465 (as_CSXYZ(src)->toXYZD50() == as_CSXYZ(dst)->toXYZD50()); |
462 if (as_CSB(src)->fGammaNamed != as_CSB(dst)->fGammaNamed) { | 466 default: |
| 467 if (as_CSXYZ(src)->gammaNamed() != as_CSXYZ(dst)->gammaNamed())
{ |
| 468 return false; |
| 469 } |
| 470 } |
| 471 // TRC tables still need checking |
| 472 } else { |
| 473 const SkGammaNamed aNamed = as_CSA2B(src)->aCurveNamed(); |
| 474 const SkGammaNamed bNamed = as_CSA2B(src)->bCurveNamed(); |
| 475 const SkGammaNamed mNamed = as_CSA2B(src)->mCurveNamed(); |
| 476 if ((aNamed != as_CSA2B(dst)->aCurveNamed()) || |
| 477 (bNamed != as_CSA2B(dst)->bCurveNamed()) || |
| 478 (mNamed != as_CSA2B(dst)->mCurveNamed())) { |
| 479 return false; |
| 480 } |
| 481 if (aNamed != kNonStandard_SkGammaNamed && |
| 482 bNamed != kNonStandard_SkGammaNamed && |
| 483 mNamed != kNonStandard_SkGammaNamed) { |
| 484 » » » // All gammas are the same type and are not tables, so s
ee if |
| 485 » » » // the matrices differ |
| 486 if ((as_CSA2B(src)->toPCS() != as_CSA2B(dst)->toPCS()) || |
| 487 (as_CSA2B(src)->toPCS() != as_CSA2B(dst)->toPCS()) || |
| 488 (as_CSA2B(src)->toPCS() != as_CSA2B(dst)->toPCS())) { |
463 return false; | 489 return false; |
464 } | 490 } |
| 491 } |
| 492 // a/b/m-curve tables (if applicable) and CLUT still needs checking |
| 493 } |
465 | 494 |
466 // It is unlikely that we will reach this case. | 495 // It is unlikely that we will reach this case. |
467 sk_sp<SkData> srcData = src->serialize(); | 496 sk_sp<SkData> serializedSrcData = src->serialize(); |
468 sk_sp<SkData> dstData = dst->serialize(); | 497 sk_sp<SkData> serializedDstData = dst->serialize(); |
469 return srcData->size() == dstData->size() && | 498 return serializedSrcData->size() == serializedDstData->size() && |
470 0 == memcmp(srcData->data(), dstData->data(), srcData->size()
); | 499 0 == memcmp(serializedSrcData->data(), serializedDstData->data(), |
471 } | 500 serializedSrcData->size()); |
472 } | 501 } |
OLD | NEW |