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 "SkEndian.h" | 10 #include "SkEndian.h" |
| 11 #include "SkOnce.h" | 11 #include "SkOnce.h" |
| 12 #include "SkReadBuffer.h" | |
| 13 #include "SkWriteBuffer.h" | |
| 12 | 14 |
| 13 #define SkColorSpacePrintf(...) | 15 #define SkColorSpacePrintf(...) |
| 14 | 16 |
| 15 static bool color_space_almost_equal(float a, float b) { | 17 static bool color_space_almost_equal(float a, float b) { |
| 16 return SkTAbs(a - b) < 0.01f; | 18 return SkTAbs(a - b) < 0.01f; |
| 17 } | 19 } |
| 18 | 20 |
| 19 //////////////////////////////////////////////////////////////////////////////// ////////////////// | 21 //////////////////////////////////////////////////////////////////////////////// ////////////////// |
| 20 | 22 |
| 21 SkColorSpace::SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Na med named) | 23 SkColorSpace::SkColorSpace(GammaNamed gammaNamed, const SkMatrix44& toXYZD50, Na med named) |
| 22 : fGammaNamed(gammaNamed) | 24 : fGammaNamed(gammaNamed) |
| 23 , fToXYZD50(toXYZD50) | 25 , fToXYZD50(toXYZD50) |
| 24 , fNamed(named) | 26 , fNamed(named) |
| 25 {} | 27 {} |
| 26 | 28 |
| 27 SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& to XYZD50, Named named, | 29 SkColorSpace_Base::SkColorSpace_Base(GammaNamed gammaNamed, const SkMatrix44& to XYZD50, Named named) |
| 28 sk_sp<SkData> profileData) | |
| 29 : INHERITED(gammaNamed, toXYZD50, named) | 30 : INHERITED(gammaNamed, toXYZD50, named) |
| 30 , fGammas(nullptr) | 31 , fGammas(nullptr) |
| 31 , fProfileData(std::move(profileData)) | 32 , fProfileData(nullptr) |
| 32 {} | 33 {} |
| 33 | 34 |
| 34 SkColorSpace_Base::SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGamma s> gammas, | 35 SkColorSpace_Base::SkColorSpace_Base(SkColorLookUpTable* colorLUT, sk_sp<SkGamma s> gammas, |
| 35 const SkMatrix44& toXYZD50, sk_sp<SkData> p rofileData) | 36 const SkMatrix44& toXYZD50, sk_sp<SkData> p rofileData) |
| 36 : INHERITED(kNonStandard_GammaNamed, toXYZD50, kUnknown_Named) | 37 : INHERITED(kNonStandard_GammaNamed, toXYZD50, kUnknown_Named) |
| 37 , fColorLUT(colorLUT) | 38 , fColorLUT(colorLUT) |
| 38 , fGammas(std::move(gammas)) | 39 , fGammas(std::move(gammas)) |
| 39 , fProfileData(std::move(profileData)) | 40 , fProfileData(std::move(profileData)) |
| 40 {} | 41 {} |
| 41 | 42 |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 95 set_gamma_value(&curves[1], values[1]); | 96 set_gamma_value(&curves[1], values[1]); |
| 96 set_gamma_value(&curves[2], values[2]); | 97 set_gamma_value(&curves[2], values[2]); |
| 97 | 98 |
| 98 GammaNamed gammaNamed = SkGammas::Named(curves); | 99 GammaNamed gammaNamed = SkGammas::Named(curves); |
| 99 if (kNonStandard_GammaNamed == gammaNamed) { | 100 if (kNonStandard_GammaNamed == gammaNamed) { |
| 100 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::move(curv es[1]), | 101 sk_sp<SkGammas> gammas(new SkGammas(std::move(curves[0]), std::move(curv es[1]), |
| 101 std::move(curves[2]))); | 102 std::move(curves[2]))); |
| 102 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, gammas, toXYZD 50, nullptr)); | 103 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, gammas, toXYZD 50, nullptr)); |
| 103 } | 104 } |
| 104 | 105 |
| 105 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50, nullptr); | 106 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
| 106 } | 107 } |
| 107 | 108 |
| 108 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(GammaNamed gammaNamed, const SkMat rix44& toXYZD50, | 109 sk_sp<SkColorSpace> SkColorSpace_Base::NewRGB(GammaNamed gammaNamed, const SkMat rix44& toXYZD50) { |
| 109 sk_sp<SkData> profileData) { | |
| 110 switch (gammaNamed) { | 110 switch (gammaNamed) { |
| 111 case kSRGB_GammaNamed: | 111 case kSRGB_GammaNamed: |
| 112 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { | 112 if (xyz_almost_equal(toXYZD50, gSRGB_toXYZD50)) { |
| 113 return SkColorSpace::NewNamed(kSRGB_Named); | 113 return SkColorSpace::NewNamed(kSRGB_Named); |
| 114 } | 114 } |
| 115 break; | 115 break; |
| 116 case k2Dot2Curve_GammaNamed: | 116 case k2Dot2Curve_GammaNamed: |
| 117 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { | 117 if (xyz_almost_equal(toXYZD50, gAdobeRGB_toXYZD50)) { |
| 118 return SkColorSpace::NewNamed(kAdobeRGB_Named); | 118 return SkColorSpace::NewNamed(kAdobeRGB_Named); |
| 119 } | 119 } |
| 120 break; | 120 break; |
| 121 case kNonStandard_GammaNamed: | 121 case kNonStandard_GammaNamed: |
| 122 // This is not allowed. | 122 // This is not allowed. |
| 123 return nullptr; | 123 return nullptr; |
| 124 default: | 124 default: |
| 125 break; | 125 break; |
| 126 } | 126 } |
| 127 | 127 |
| 128 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnkn own_Named, | 128 return sk_sp<SkColorSpace>(new SkColorSpace_Base(gammaNamed, toXYZD50, kUnkn own_Named)); |
| 129 profileData)); | |
| 130 } | 129 } |
| 131 | 130 |
| 132 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44 & toXYZD50) { | 131 sk_sp<SkColorSpace> SkColorSpace::NewRGB(GammaNamed gammaNamed, const SkMatrix44 & toXYZD50) { |
| 133 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50, nullptr); | 132 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZD50); |
| 134 } | 133 } |
| 135 | 134 |
| 136 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { | 135 sk_sp<SkColorSpace> SkColorSpace::NewNamed(Named named) { |
| 137 static SkOnce sRGBOnce; | 136 static SkOnce sRGBOnce; |
| 138 static SkColorSpace* sRGB; | 137 static SkColorSpace* sRGB; |
| 139 static SkOnce adobeRGBOnce; | 138 static SkOnce adobeRGBOnce; |
| 140 static SkColorSpace* adobeRGB; | 139 static SkColorSpace* adobeRGB; |
| 141 | 140 |
| 142 switch (named) { | 141 switch (named) { |
| 143 case kSRGB_Named: { | 142 case kSRGB_Named: { |
| 144 sRGBOnce([] { | 143 sRGBOnce([] { |
| 145 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); | 144 SkMatrix44 srgbToxyzD50(SkMatrix44::kUninitialized_Constructor); |
| 146 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); | 145 srgbToxyzD50.set3x3ColMajorf(gSRGB_toXYZD50); |
| 147 sRGB = new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50, kSR GB_Named, nullptr); | 146 sRGB = new SkColorSpace_Base(kSRGB_GammaNamed, srgbToxyzD50, kSR GB_Named); |
| 148 }); | 147 }); |
| 149 return sk_ref_sp(sRGB); | 148 return sk_ref_sp(sRGB); |
| 150 } | 149 } |
| 151 case kAdobeRGB_Named: { | 150 case kAdobeRGB_Named: { |
| 152 adobeRGBOnce([] { | 151 adobeRGBOnce([] { |
| 153 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct or); | 152 SkMatrix44 adobergbToxyzD50(SkMatrix44::kUninitialized_Construct or); |
| 154 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); | 153 adobergbToxyzD50.set3x3ColMajorf(gAdobeRGB_toXYZD50); |
| 155 adobeRGB = new SkColorSpace_Base(k2Dot2Curve_GammaNamed, adoberg bToxyzD50, | 154 adobeRGB = new SkColorSpace_Base(k2Dot2Curve_GammaNamed, adoberg bToxyzD50, |
| 156 kAdobeRGB_Named, nullptr); | 155 kAdobeRGB_Named); |
| 157 }); | 156 }); |
| 158 return sk_ref_sp(adobeRGB); | 157 return sk_ref_sp(adobeRGB); |
| 159 } | 158 } |
| 160 default: | 159 default: |
| 161 break; | 160 break; |
| 162 } | 161 } |
| 163 return nullptr; | 162 return nullptr; |
| 164 } | 163 } |
| 165 | 164 |
| 166 //////////////////////////////////////////////////////////////////////////////// /////////////////// | 165 //////////////////////////////////////////////////////////////////////////////// /////////////////// |
| (...skipping 756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 923 } | 922 } |
| 924 | 923 |
| 925 GammaNamed gammaNamed = SkGammas::Named(curves); | 924 GammaNamed gammaNamed = SkGammas::Named(curves); |
| 926 if (kNonStandard_GammaNamed == gammaNamed) { | 925 if (kNonStandard_GammaNamed == gammaNamed) { |
| 927 sk_sp<SkGammas> gammas = sk_make_sp<SkGammas>(std::move(curv es[0]), | 926 sk_sp<SkGammas> gammas = sk_make_sp<SkGammas>(std::move(curv es[0]), |
| 928 std::move(curv es[1]), | 927 std::move(curv es[1]), |
| 929 std::move(curv es[2])); | 928 std::move(curv es[2])); |
| 930 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, st d::move(gammas), | 929 return sk_sp<SkColorSpace>(new SkColorSpace_Base(nullptr, st d::move(gammas), |
| 931 mat, std::m ove(data))); | 930 mat, std::m ove(data))); |
| 932 } else { | 931 } else { |
| 933 return SkColorSpace_Base::NewRGB(gammaNamed, mat, std::move( data)); | 932 return SkColorSpace_Base::NewRGB(gammaNamed, mat); |
| 934 } | 933 } |
| 935 } | 934 } |
| 936 | 935 |
| 937 // Recognize color profile specified by A2B0 tag. | 936 // Recognize color profile specified by A2B0 tag. |
| 938 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); | 937 const ICCTag* a2b0 = ICCTag::Find(tags.get(), tagCount, kTAG_A2B0); |
| 939 if (a2b0) { | 938 if (a2b0) { |
| 940 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl e()); | 939 SkAutoTDelete<SkColorLookUpTable> colorLUT(new SkColorLookUpTabl e()); |
| 941 SkGammaCurve curves[3]; | 940 SkGammaCurve curves[3]; |
| 942 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); | 941 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); |
| 943 if (!load_a2b0(colorLUT, curves, &toXYZ, a2b0->addr((const uint8 _t*) base), | 942 if (!load_a2b0(colorLUT, curves, &toXYZ, a2b0->addr((const uint8 _t*) base), |
| 944 a2b0->fLength)) { | 943 a2b0->fLength)) { |
| 945 return_null("Failed to parse A2B0 tag"); | 944 return_null("Failed to parse A2B0 tag"); |
| 946 } | 945 } |
| 947 | 946 |
| 948 GammaNamed gammaNamed = SkGammas::Named(curves); | 947 GammaNamed gammaNamed = SkGammas::Named(curves); |
| 949 if (colorLUT->fTable || kNonStandard_GammaNamed == gammaNamed) { | 948 if (colorLUT->fTable || kNonStandard_GammaNamed == gammaNamed) { |
| 950 sk_sp<SkGammas> gammas = sk_make_sp<SkGammas>(std::move(curv es[0]), | 949 sk_sp<SkGammas> gammas = sk_make_sp<SkGammas>(std::move(curv es[0]), |
| 951 std::move(curv es[1]), | 950 std::move(curv es[1]), |
| 952 std::move(curv es[2])); | 951 std::move(curv es[2])); |
| 953 | 952 |
| 954 return sk_sp<SkColorSpace>(new SkColorSpace_Base(colorLUT.re lease(), | 953 return sk_sp<SkColorSpace>(new SkColorSpace_Base(colorLUT.re lease(), |
| 955 std::move(g ammas), toXYZ, | 954 std::move(g ammas), toXYZ, |
| 956 std::move(d ata))); | 955 std::move(d ata))); |
| 957 } else { | 956 } else { |
| 958 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ, std::mov e(data)); | 957 return SkColorSpace_Base::NewRGB(gammaNamed, toXYZ); |
| 959 } | 958 } |
| 960 } | 959 } |
| 961 } | 960 } |
| 962 default: | 961 default: |
| 963 break; | 962 break; |
| 964 } | 963 } |
| 965 | 964 |
| 966 return_null("ICC profile contains unsupported colorspace"); | 965 return_null("ICC profile contains unsupported colorspace"); |
| 967 } | 966 } |
| 968 | 967 |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1201 ptr32[4] = SkEndian_SwapBE32(0x000116cc); | 1200 ptr32[4] = SkEndian_SwapBE32(0x000116cc); |
| 1202 ptr += kTAG_XYZ_Bytes; | 1201 ptr += kTAG_XYZ_Bytes; |
| 1203 | 1202 |
| 1204 // Write copyright tag | 1203 // Write copyright tag |
| 1205 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); | 1204 memcpy(ptr, gEmptyTextTag, sizeof(gEmptyTextTag)); |
| 1206 | 1205 |
| 1207 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if | 1206 // TODO (msarett): Should we try to hold onto the data so we can return imme diately if |
| 1208 // the client calls again? | 1207 // the client calls again? |
| 1209 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); | 1208 return SkData::MakeFromMalloc(profile.release(), kICCProfileSize); |
| 1210 } | 1209 } |
| 1210 | |
| 1211 //////////////////////////////////////////////////////////////////////////////// /////////////////// | |
|
reed1
2016/06/21 14:58:34
Some thoughts.
I think we should be more explicit
msarett
2016/06/21 16:41:57
The implementation with Header sgtm, along with st
| |
| 1212 | |
| 1213 sk_sp<SkData> SkColorSpace::serialize() const { | |
| 1214 // If we have a named profile, only write the enum. | |
| 1215 switch (fNamed) { | |
| 1216 case kSRGB_Named: | |
| 1217 case kAdobeRGB_Named: { | |
| 1218 sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(Named)); | |
| 1219 *((Named*) data->writable_data()) = fNamed; | |
| 1220 return data; | |
| 1221 } | |
| 1222 default: | |
| 1223 break; | |
| 1224 } | |
| 1225 | |
| 1226 // If we have a named gamma, write the enum and the matrix. | |
| 1227 switch (fGammaNamed) { | |
| 1228 case kSRGB_GammaNamed: | |
| 1229 case k2Dot2Curve_GammaNamed: | |
| 1230 case kLinear_GammaNamed: { | |
| 1231 sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(Named) + sizeo f(GammaNamed) + | |
| 1232 16 * sizeof(float)); | |
| 1233 void* dataPtr = data->writable_data(); | |
| 1234 | |
| 1235 *((Named*) dataPtr) = fNamed; | |
| 1236 dataPtr = SkTAddOffset<void>(dataPtr, sizeof(fNamed)); | |
| 1237 | |
| 1238 *((GammaNamed*) dataPtr) = fGammaNamed; | |
| 1239 dataPtr = SkTAddOffset<void>(dataPtr, sizeof(fGammaNamed)); | |
| 1240 | |
| 1241 fToXYZD50.asColMajorf((float*) dataPtr); | |
| 1242 return data; | |
| 1243 } | |
| 1244 default: | |
| 1245 break; | |
| 1246 } | |
| 1247 | |
| 1248 // If we do not have a named gamma, this must have been created from an ICC profile. | |
| 1249 // Since we were unable to recognize the gamma, we will have saved the ICC d ata. | |
| 1250 SkASSERT(as_CSB(this)->fProfileData); | |
| 1251 | |
| 1252 sk_sp<SkData> data = SkData::MakeUninitialized(sizeof(Named) + sizeof(GammaN amed) + | |
| 1253 as_CSB(this)->fProfileData->s ize()); | |
| 1254 void* dataPtr = data->writable_data(); | |
| 1255 | |
| 1256 *((Named*) dataPtr) = fNamed; | |
| 1257 dataPtr = SkTAddOffset<void>(dataPtr, sizeof(fNamed)); | |
| 1258 | |
| 1259 *((GammaNamed*) dataPtr) = fGammaNamed; | |
| 1260 dataPtr = SkTAddOffset<void>(dataPtr, sizeof(fGammaNamed)); | |
| 1261 | |
| 1262 memcpy(dataPtr, as_CSB(this)->fProfileData->data(), as_CSB(this)->fProfileDa ta->size()); | |
| 1263 return data; | |
| 1264 } | |
| 1265 | |
| 1266 sk_sp<SkColorSpace> SkColorSpace::Deserialize(const void* data, size_t length) { | |
| 1267 if (length < sizeof(Named)) { | |
| 1268 return nullptr; | |
| 1269 } | |
| 1270 | |
| 1271 Named named = *((const Named*) data); | |
| 1272 data = SkTAddOffset<const void>(data, sizeof(Named)); | |
| 1273 length -= sizeof(Named); | |
| 1274 switch (named) { | |
| 1275 case kSRGB_Named: | |
| 1276 case kAdobeRGB_Named: | |
| 1277 return NewNamed(named); | |
| 1278 default: | |
| 1279 break; | |
| 1280 } | |
| 1281 | |
| 1282 if (length < sizeof(GammaNamed)) { | |
| 1283 return nullptr; | |
| 1284 } | |
| 1285 | |
| 1286 GammaNamed gammaNamed = *((const GammaNamed*) data); | |
| 1287 data = SkTAddOffset<const void>(data, sizeof(GammaNamed)); | |
| 1288 length -= sizeof(GammaNamed); | |
| 1289 switch (gammaNamed) { | |
| 1290 case kSRGB_GammaNamed: | |
| 1291 case k2Dot2Curve_GammaNamed: | |
| 1292 case kLinear_GammaNamed: { | |
| 1293 if (length < 16 * sizeof(float)) { | |
| 1294 return nullptr; | |
| 1295 } | |
| 1296 | |
| 1297 SkMatrix44 toXYZ(SkMatrix44::kUninitialized_Constructor); | |
| 1298 toXYZ.setColMajorf((const float*) data); | |
| 1299 return NewRGB(gammaNamed, toXYZ); | |
| 1300 } | |
| 1301 default: | |
| 1302 break; | |
| 1303 } | |
| 1304 | |
| 1305 return NewICC(data, length); | |
| 1306 } | |
| OLD | NEW |