Chromium Code Reviews| 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 |