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