OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "ui/gfx/color_space.h" | 5 #include "ui/gfx/color_space.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
11 #include "third_party/skia/include/core/SkColorSpace.h" | 11 #include "third_party/skia/include/core/SkColorSpace.h" |
12 #include "ui/gfx/icc_profile.h" | 12 #include "ui/gfx/icc_profile.h" |
13 | 13 |
14 namespace gfx { | 14 namespace gfx { |
15 | 15 |
| 16 namespace { |
| 17 |
| 18 SkColorSpaceTransferFn InvertTransferFn(SkColorSpaceTransferFn fn) { |
| 19 SkColorSpaceTransferFn fn_inv = {0}; |
| 20 if (fn.fA > 0 && fn.fG > 0) { |
| 21 double a_to_the_g = pow(fn.fA, fn.fG); |
| 22 fn_inv.fA = 1.f / a_to_the_g; |
| 23 fn_inv.fB = -fn.fE / a_to_the_g; |
| 24 fn_inv.fG = 1.f / fn.fG; |
| 25 } |
| 26 fn_inv.fD = fn.fC * fn.fD + fn.fF; |
| 27 fn_inv.fE = -fn.fB / fn.fA; |
| 28 if (fn.fC != 0) { |
| 29 fn_inv.fC = 1.f / fn.fC; |
| 30 fn_inv.fF = -fn.fF / fn.fC; |
| 31 } |
| 32 return fn_inv; |
| 33 } |
| 34 }; |
| 35 |
16 ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) { | 36 ColorSpace::PrimaryID ColorSpace::PrimaryIDFromInt(int primary_id) { |
17 if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST)) | 37 if (primary_id < 0 || primary_id > static_cast<int>(PrimaryID::LAST)) |
18 return PrimaryID::UNKNOWN; | 38 return PrimaryID::UNKNOWN; |
19 if (primary_id > static_cast<int>(PrimaryID::LAST_STANDARD_VALUE) && | 39 if (primary_id > static_cast<int>(PrimaryID::LAST_STANDARD_VALUE) && |
20 primary_id < 1000) | 40 primary_id < 1000) |
21 return PrimaryID::UNKNOWN; | 41 return PrimaryID::UNKNOWN; |
22 return static_cast<PrimaryID>(primary_id); | 42 return static_cast<PrimaryID>(primary_id); |
23 } | 43 } |
24 | 44 |
25 ColorSpace::TransferID ColorSpace::TransferIDFromInt(int transfer_id) { | 45 ColorSpace::TransferID ColorSpace::TransferIDFromInt(int transfer_id) { |
26 if (transfer_id < 0 || transfer_id > static_cast<int>(TransferID::LAST)) | 46 if (transfer_id < 0 || transfer_id > static_cast<int>(TransferID::LAST)) |
27 return TransferID::UNKNOWN; | 47 return TransferID::UNKNOWN; |
28 if (transfer_id > static_cast<int>(TransferID::LAST_STANDARD_VALUE) && | 48 if (transfer_id > static_cast<int>(TransferID::LAST_STANDARD_VALUE) && |
29 transfer_id < 1000) | 49 transfer_id < 1000) |
30 return TransferID::UNKNOWN; | 50 return TransferID::UNKNOWN; |
31 return static_cast<TransferID>(transfer_id); | 51 return static_cast<TransferID>(transfer_id); |
32 } | 52 } |
33 | 53 |
34 ColorSpace::MatrixID ColorSpace::MatrixIDFromInt(int matrix_id) { | 54 ColorSpace::MatrixID ColorSpace::MatrixIDFromInt(int matrix_id) { |
35 if (matrix_id < 0 || matrix_id > static_cast<int>(MatrixID::LAST)) | 55 if (matrix_id < 0 || matrix_id > static_cast<int>(MatrixID::LAST)) |
36 return MatrixID::UNKNOWN; | 56 return MatrixID::UNKNOWN; |
37 if (matrix_id > static_cast<int>(MatrixID::LAST_STANDARD_VALUE) && | 57 if (matrix_id > static_cast<int>(MatrixID::LAST_STANDARD_VALUE) && |
38 matrix_id < 1000) | 58 matrix_id < 1000) |
39 return MatrixID::UNKNOWN; | 59 return MatrixID::UNKNOWN; |
40 return static_cast<MatrixID>(matrix_id); | 60 return static_cast<MatrixID>(matrix_id); |
41 } | 61 } |
42 | 62 |
43 ColorSpace::ColorSpace() { | 63 ColorSpace::ColorSpace() {} |
44 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_)); | |
45 } | |
46 | 64 |
47 ColorSpace::ColorSpace(PrimaryID primaries, | 65 ColorSpace::ColorSpace(PrimaryID primaries, |
48 TransferID transfer, | 66 TransferID transfer, |
49 MatrixID matrix, | 67 MatrixID matrix, |
50 RangeID range) | 68 RangeID range) |
51 : primaries_(primaries), | 69 : primaries_(primaries), |
52 transfer_(transfer), | 70 transfer_(transfer), |
53 matrix_(matrix), | 71 matrix_(matrix), |
54 range_(range) { | 72 range_(range) {} |
55 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_)); | |
56 // TODO: Set profile_id_ | |
57 } | |
58 | 73 |
59 ColorSpace::ColorSpace(int primaries, int transfer, int matrix, RangeID range) | 74 ColorSpace::ColorSpace(int primaries, int transfer, int matrix, RangeID range) |
60 : primaries_(PrimaryIDFromInt(primaries)), | 75 : primaries_(PrimaryIDFromInt(primaries)), |
61 transfer_(TransferIDFromInt(transfer)), | 76 transfer_(TransferIDFromInt(transfer)), |
62 matrix_(MatrixIDFromInt(matrix)), | 77 matrix_(MatrixIDFromInt(matrix)), |
63 range_(range) { | 78 range_(range) {} |
64 memset(custom_primary_matrix_, 0, sizeof(custom_primary_matrix_)); | |
65 // TODO: Set profile_id_ | |
66 } | |
67 | 79 |
68 ColorSpace::ColorSpace(const ColorSpace& other) | 80 ColorSpace::ColorSpace(const ColorSpace& other) |
69 : primaries_(other.primaries_), | 81 : primaries_(other.primaries_), |
70 transfer_(other.transfer_), | 82 transfer_(other.transfer_), |
71 matrix_(other.matrix_), | 83 matrix_(other.matrix_), |
72 range_(other.range_), | 84 range_(other.range_), |
73 icc_profile_id_(other.icc_profile_id_), | 85 icc_profile_id_(other.icc_profile_id_), |
74 sk_color_space_(other.sk_color_space_) { | 86 icc_profile_sk_color_space_(other.icc_profile_sk_color_space_) { |
75 memcpy(custom_primary_matrix_, other.custom_primary_matrix_, | 87 if (transfer_ == TransferID::CUSTOM) { |
76 sizeof(custom_primary_matrix_)); | 88 memcpy(custom_transfer_params_, other.custom_transfer_params_, |
| 89 sizeof(custom_transfer_params_)); |
| 90 } |
| 91 if (primaries_ == PrimaryID::CUSTOM) { |
| 92 memcpy(custom_primary_matrix_, other.custom_primary_matrix_, |
| 93 sizeof(custom_primary_matrix_)); |
| 94 } |
77 } | 95 } |
78 | 96 |
79 ColorSpace::~ColorSpace() = default; | 97 ColorSpace::~ColorSpace() = default; |
80 | 98 |
81 // static | 99 // static |
82 ColorSpace ColorSpace::CreateSRGB() { | 100 ColorSpace ColorSpace::CreateSRGB() { |
83 ColorSpace result(PrimaryID::BT709, TransferID::IEC61966_2_1, MatrixID::RGB, | 101 return ColorSpace(PrimaryID::BT709, TransferID::IEC61966_2_1, MatrixID::RGB, |
84 RangeID::FULL); | 102 RangeID::FULL); |
85 result.sk_color_space_ = SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); | |
86 return result; | |
87 } | 103 } |
88 | 104 |
89 // static | 105 // static |
90 ColorSpace ColorSpace::CreateSCRGBLinear() { | 106 ColorSpace ColorSpace::CreateSCRGBLinear() { |
91 return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB, | 107 return ColorSpace(PrimaryID::BT709, TransferID::LINEAR_HDR, MatrixID::RGB, |
92 RangeID::FULL); | 108 RangeID::FULL); |
93 } | 109 } |
94 | 110 |
95 // Static | 111 // Static |
96 ColorSpace ColorSpace::CreateXYZD50() { | 112 ColorSpace ColorSpace::CreateXYZD50() { |
(...skipping 20 matching lines...) Expand all Loading... |
117 } | 133 } |
118 | 134 |
119 bool ColorSpace::operator==(const ColorSpace& other) const { | 135 bool ColorSpace::operator==(const ColorSpace& other) const { |
120 if (primaries_ != other.primaries_ || transfer_ != other.transfer_ || | 136 if (primaries_ != other.primaries_ || transfer_ != other.transfer_ || |
121 matrix_ != other.matrix_ || range_ != other.range_) | 137 matrix_ != other.matrix_ || range_ != other.range_) |
122 return false; | 138 return false; |
123 if (primaries_ == PrimaryID::CUSTOM && | 139 if (primaries_ == PrimaryID::CUSTOM && |
124 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, | 140 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, |
125 sizeof(custom_primary_matrix_))) | 141 sizeof(custom_primary_matrix_))) |
126 return false; | 142 return false; |
| 143 if (transfer_ == TransferID::CUSTOM && |
| 144 memcmp(custom_transfer_params_, other.custom_transfer_params_, |
| 145 sizeof(custom_transfer_params_))) |
| 146 return false; |
127 return true; | 147 return true; |
128 } | 148 } |
129 | 149 |
130 bool ColorSpace::IsHDR() const { | 150 bool ColorSpace::IsHDR() const { |
131 return transfer_ == TransferID::SMPTEST2084 || | 151 return transfer_ == TransferID::SMPTEST2084 || |
132 transfer_ == TransferID::ARIB_STD_B67 || | 152 transfer_ == TransferID::ARIB_STD_B67 || |
133 transfer_ == TransferID::LINEAR_HDR; | 153 transfer_ == TransferID::LINEAR_HDR; |
134 } | 154 } |
135 | 155 |
136 bool ColorSpace::operator!=(const ColorSpace& other) const { | 156 bool ColorSpace::operator!=(const ColorSpace& other) const { |
(...skipping 19 matching lines...) Expand all Loading... |
156 return false; | 176 return false; |
157 if (primaries_ == PrimaryID::CUSTOM) { | 177 if (primaries_ == PrimaryID::CUSTOM) { |
158 int primary_result = | 178 int primary_result = |
159 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, | 179 memcmp(custom_primary_matrix_, other.custom_primary_matrix_, |
160 sizeof(custom_primary_matrix_)); | 180 sizeof(custom_primary_matrix_)); |
161 if (primary_result < 0) | 181 if (primary_result < 0) |
162 return true; | 182 return true; |
163 if (primary_result > 0) | 183 if (primary_result > 0) |
164 return false; | 184 return false; |
165 } | 185 } |
| 186 if (transfer_ == TransferID::CUSTOM) { |
| 187 int transfer_result = |
| 188 memcmp(custom_transfer_params_, other.custom_transfer_params_, |
| 189 sizeof(custom_transfer_params_)); |
| 190 if (transfer_result < 0) |
| 191 return true; |
| 192 if (transfer_result > 0) |
| 193 return false; |
| 194 } |
166 return false; | 195 return false; |
167 } | 196 } |
168 | 197 |
| 198 sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace() const { |
| 199 // If we got a specific SkColorSpace from the ICCProfile that this color space |
| 200 // was created from, use that. |
| 201 if (icc_profile_sk_color_space_) |
| 202 return icc_profile_sk_color_space_; |
| 203 |
| 204 // Unspecified color spaces correspond to the null SkColorSpace. |
| 205 if (primaries_ == PrimaryID::UNSPECIFIED || |
| 206 transfer_ == TransferID::UNSPECIFIED) { |
| 207 return nullptr; |
| 208 } |
| 209 |
| 210 // Handle only full-range RGB spaces. |
| 211 if (matrix_ != MatrixID::RGB) { |
| 212 DLOG(ERROR) << "Not creating non-RGB SkColorSpace"; |
| 213 return nullptr; |
| 214 } |
| 215 if (range_ != RangeID::FULL) { |
| 216 DLOG(ERROR) << "Not creating non-full-range SkColorSpace"; |
| 217 return nullptr; |
| 218 } |
| 219 |
| 220 // Use the named SRGB and linear-SRGB instead of the generic constructors. |
| 221 if (primaries_ == PrimaryID::BT709) { |
| 222 if (transfer_ == TransferID::IEC61966_2_1) |
| 223 return SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named); |
| 224 if (transfer_ == TransferID::LINEAR || transfer_ == TransferID::LINEAR_HDR) |
| 225 return SkColorSpace::MakeNamed(SkColorSpace::kSRGBLinear_Named); |
| 226 } |
| 227 |
| 228 SkMatrix44 to_xyz_d50; |
| 229 GetPrimaryMatrix(&to_xyz_d50); |
| 230 |
| 231 // Use the named sRGB and linear transfer functions. |
| 232 if (transfer_ == TransferID::IEC61966_2_1) { |
| 233 return SkColorSpace::MakeRGB(SkColorSpace::kLinear_RenderTargetGamma, |
| 234 to_xyz_d50); |
| 235 } |
| 236 if (transfer_ == TransferID::LINEAR || transfer_ == TransferID::LINEAR_HDR) { |
| 237 return SkColorSpace::MakeRGB(SkColorSpace::kSRGB_RenderTargetGamma, |
| 238 to_xyz_d50); |
| 239 } |
| 240 |
| 241 // Use the parametric transfer function if no other option is available. |
| 242 SkColorSpaceTransferFn fn; |
| 243 if (!GetTransferFunction(&fn)) { |
| 244 DLOG(ERROR) << "Failed to parameterize transfer function for SkColorSpace"; |
| 245 return nullptr; |
| 246 } |
| 247 return SkColorSpace::MakeRGB(fn, to_xyz_d50); |
| 248 } |
| 249 |
169 ColorSpace ColorSpace::FromSkColorSpace( | 250 ColorSpace ColorSpace::FromSkColorSpace( |
170 const sk_sp<SkColorSpace>& sk_color_space) { | 251 const sk_sp<SkColorSpace>& sk_color_space) { |
171 if (!sk_color_space) | 252 if (!sk_color_space) |
172 return gfx::ColorSpace(); | 253 return gfx::ColorSpace(); |
173 if (SkColorSpace::Equals( | 254 if (SkColorSpace::Equals( |
174 sk_color_space.get(), | 255 sk_color_space.get(), |
175 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get())) | 256 SkColorSpace::MakeNamed(SkColorSpace::kSRGB_Named).get())) |
176 return gfx::ColorSpace::CreateSRGB(); | 257 return gfx::ColorSpace::CreateSRGB(); |
177 | 258 |
178 // TODO(crbug.com/634102): Add conversion to gfx::ColorSpace for | 259 // TODO(crbug.com/634102): Add conversion to gfx::ColorSpace for |
179 // non-ICC-profile based color spaces. | 260 // non-ICC-profile based color spaces. |
180 ICCProfile icc_profile = ICCProfile::FromSkColorSpace(sk_color_space); | 261 ICCProfile icc_profile = ICCProfile::FromSkColorSpace(sk_color_space); |
181 return icc_profile.GetColorSpace(); | 262 return icc_profile.GetColorSpace(); |
182 } | 263 } |
183 | 264 |
| 265 void ColorSpace::GetPrimaryMatrix(SkMatrix44* to_XYZD50) const { |
| 266 SkColorSpacePrimaries primaries = {0}; |
| 267 switch (primaries_) { |
| 268 case ColorSpace::PrimaryID::CUSTOM: |
| 269 to_XYZD50->set3x3RowMajorf(custom_primary_matrix_); |
| 270 return; |
| 271 |
| 272 case ColorSpace::PrimaryID::RESERVED0: |
| 273 case ColorSpace::PrimaryID::RESERVED: |
| 274 case ColorSpace::PrimaryID::UNSPECIFIED: |
| 275 case ColorSpace::PrimaryID::UNKNOWN: |
| 276 case ColorSpace::PrimaryID::BT709: |
| 277 // BT709 is our default case. Put it after the switch just |
| 278 // in case we somehow get an id which is not listed in the switch. |
| 279 // (We don't want to use "default", because we want the compiler |
| 280 // to tell us if we forgot some enum values.) |
| 281 primaries.fRX = 0.640f; |
| 282 primaries.fRY = 0.330f; |
| 283 primaries.fGX = 0.300f; |
| 284 primaries.fGY = 0.600f; |
| 285 primaries.fBX = 0.150f; |
| 286 primaries.fBY = 0.060f; |
| 287 primaries.fWX = 0.3127f; |
| 288 primaries.fWY = 0.3290f; |
| 289 break; |
| 290 |
| 291 case ColorSpace::PrimaryID::BT470M: |
| 292 primaries.fRX = 0.67f; |
| 293 primaries.fRY = 0.33f; |
| 294 primaries.fGX = 0.21f; |
| 295 primaries.fGY = 0.71f; |
| 296 primaries.fBX = 0.14f; |
| 297 primaries.fBY = 0.08f; |
| 298 primaries.fWX = 0.31f; |
| 299 primaries.fWY = 0.316f; |
| 300 break; |
| 301 |
| 302 case ColorSpace::PrimaryID::BT470BG: |
| 303 primaries.fRX = 0.64f; |
| 304 primaries.fRY = 0.33f; |
| 305 primaries.fGX = 0.29f; |
| 306 primaries.fGY = 0.60f; |
| 307 primaries.fBX = 0.15f; |
| 308 primaries.fBY = 0.06f; |
| 309 primaries.fWX = 0.3127f; |
| 310 primaries.fWY = 0.3290f; |
| 311 break; |
| 312 |
| 313 case ColorSpace::PrimaryID::SMPTE170M: |
| 314 case ColorSpace::PrimaryID::SMPTE240M: |
| 315 primaries.fRX = 0.630f; |
| 316 primaries.fRY = 0.340f; |
| 317 primaries.fGX = 0.310f; |
| 318 primaries.fGY = 0.595f; |
| 319 primaries.fBX = 0.155f; |
| 320 primaries.fBY = 0.070f; |
| 321 primaries.fWX = 0.3127f; |
| 322 primaries.fWY = 0.3290f; |
| 323 break; |
| 324 |
| 325 case ColorSpace::PrimaryID::FILM: |
| 326 primaries.fRX = 0.681f; |
| 327 primaries.fRY = 0.319f; |
| 328 primaries.fGX = 0.243f; |
| 329 primaries.fGY = 0.692f; |
| 330 primaries.fBX = 0.145f; |
| 331 primaries.fBY = 0.049f; |
| 332 primaries.fWX = 0.310f; |
| 333 primaries.fWY = 0.136f; |
| 334 break; |
| 335 |
| 336 case ColorSpace::PrimaryID::BT2020: |
| 337 primaries.fRX = 0.708f; |
| 338 primaries.fRY = 0.292f; |
| 339 primaries.fGX = 0.170f; |
| 340 primaries.fGY = 0.797f; |
| 341 primaries.fBX = 0.131f; |
| 342 primaries.fBY = 0.046f; |
| 343 primaries.fWX = 0.3127f; |
| 344 primaries.fWY = 0.3290f; |
| 345 break; |
| 346 |
| 347 case ColorSpace::PrimaryID::SMPTEST428_1: |
| 348 primaries.fRX = 1.0f; |
| 349 primaries.fRY = 0.0f; |
| 350 primaries.fGX = 0.0f; |
| 351 primaries.fGY = 1.0f; |
| 352 primaries.fBX = 0.0f; |
| 353 primaries.fBY = 0.0f; |
| 354 primaries.fWX = 1.0f / 3.0f; |
| 355 primaries.fWY = 1.0f / 3.0f; |
| 356 break; |
| 357 |
| 358 case ColorSpace::PrimaryID::SMPTEST431_2: |
| 359 primaries.fRX = 0.680f; |
| 360 primaries.fRY = 0.320f; |
| 361 primaries.fGX = 0.265f; |
| 362 primaries.fGY = 0.690f; |
| 363 primaries.fBX = 0.150f; |
| 364 primaries.fBY = 0.060f; |
| 365 primaries.fWX = 0.314f; |
| 366 primaries.fWY = 0.351f; |
| 367 break; |
| 368 |
| 369 case ColorSpace::PrimaryID::SMPTEST432_1: |
| 370 primaries.fRX = 0.680f; |
| 371 primaries.fRY = 0.320f; |
| 372 primaries.fGX = 0.265f; |
| 373 primaries.fGY = 0.690f; |
| 374 primaries.fBX = 0.150f; |
| 375 primaries.fBY = 0.060f; |
| 376 primaries.fWX = 0.3127f; |
| 377 primaries.fWY = 0.3290f; |
| 378 break; |
| 379 |
| 380 case ColorSpace::PrimaryID::XYZ_D50: |
| 381 primaries.fRX = 1.0f; |
| 382 primaries.fRY = 0.0f; |
| 383 primaries.fGX = 0.0f; |
| 384 primaries.fGY = 1.0f; |
| 385 primaries.fBX = 0.0f; |
| 386 primaries.fBY = 0.0f; |
| 387 primaries.fWX = 0.34567f; |
| 388 primaries.fWY = 0.35850f; |
| 389 break; |
| 390 } |
| 391 primaries.toXYZD50(to_XYZD50); |
| 392 } |
| 393 |
| 394 bool ColorSpace::GetTransferFunction(SkColorSpaceTransferFn* fn) const { |
| 395 // Default to F(x) = pow(x, 1) |
| 396 fn->fA = 1; |
| 397 fn->fB = 0; |
| 398 fn->fC = 1; |
| 399 fn->fD = 0; |
| 400 fn->fE = 0; |
| 401 fn->fF = 0; |
| 402 fn->fG = 1; |
| 403 |
| 404 switch (transfer_) { |
| 405 case ColorSpace::TransferID::CUSTOM: |
| 406 fn->fA = custom_transfer_params_[0]; |
| 407 fn->fB = custom_transfer_params_[1]; |
| 408 fn->fC = custom_transfer_params_[2]; |
| 409 fn->fD = custom_transfer_params_[3]; |
| 410 fn->fE = custom_transfer_params_[4]; |
| 411 fn->fF = custom_transfer_params_[5]; |
| 412 fn->fG = custom_transfer_params_[6]; |
| 413 return true; |
| 414 case ColorSpace::TransferID::LINEAR: |
| 415 case ColorSpace::TransferID::LINEAR_HDR: |
| 416 return true; |
| 417 case ColorSpace::TransferID::GAMMA22: |
| 418 fn->fG = 2.2f; |
| 419 return true; |
| 420 case ColorSpace::TransferID::GAMMA24: |
| 421 fn->fG = 2.4f; |
| 422 return true; |
| 423 case ColorSpace::TransferID::GAMMA28: |
| 424 fn->fG = 2.8f; |
| 425 return true; |
| 426 case ColorSpace::TransferID::RESERVED0: |
| 427 case ColorSpace::TransferID::RESERVED: |
| 428 case ColorSpace::TransferID::UNSPECIFIED: |
| 429 case ColorSpace::TransferID::UNKNOWN: |
| 430 // All unknown values default to BT709 |
| 431 case ColorSpace::TransferID::BT709: |
| 432 case ColorSpace::TransferID::SMPTE170M: |
| 433 case ColorSpace::TransferID::BT2020_10: |
| 434 case ColorSpace::TransferID::BT2020_12: |
| 435 fn->fA = 0.909672431050f; |
| 436 fn->fB = 0.090327568950f; |
| 437 fn->fC = 0.222222222222f; |
| 438 fn->fD = 0.081242862158f; |
| 439 fn->fG = 2.222222222222f; |
| 440 return true; |
| 441 case ColorSpace::TransferID::SMPTE240M: |
| 442 fn->fA = 0.899626676224f; |
| 443 fn->fB = 0.100373323776f; |
| 444 fn->fC = 0.250000000000f; |
| 445 fn->fD = 0.091286342118f; |
| 446 fn->fG = 2.222222222222f; |
| 447 return true; |
| 448 case ColorSpace::TransferID::IEC61966_2_1: |
| 449 fn->fA = 0.947867345704f; |
| 450 fn->fB = 0.052132654296f; |
| 451 fn->fC = 0.077399380805f; |
| 452 fn->fD = 0.040449937172f; |
| 453 fn->fG = 2.400000000000f; |
| 454 return true; |
| 455 case ColorSpace::TransferID::SMPTEST428_1: |
| 456 fn->fA = 0.225615407568f; |
| 457 fn->fE = -1.091041666667f; |
| 458 fn->fG = 2.600000000000f; |
| 459 return true; |
| 460 case ColorSpace::TransferID::IEC61966_2_4: |
| 461 // This could potentially be represented the same as IEC61966_2_1, but |
| 462 // it handles negative values differently. |
| 463 break; |
| 464 case ColorSpace::TransferID::ARIB_STD_B67: |
| 465 case ColorSpace::TransferID::BT1361_ECG: |
| 466 case ColorSpace::TransferID::LOG: |
| 467 case ColorSpace::TransferID::LOG_SQRT: |
| 468 case ColorSpace::TransferID::SMPTEST2084: |
| 469 case ColorSpace::TransferID::SMPTEST2084_NON_HDR: |
| 470 break; |
| 471 } |
| 472 |
| 473 return false; |
| 474 } |
| 475 |
| 476 bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const { |
| 477 if (!GetTransferFunction(fn)) |
| 478 return false; |
| 479 *fn = InvertTransferFn(*fn); |
| 480 return true; |
| 481 } |
| 482 |
184 } // namespace gfx | 483 } // namespace gfx |
OLD | NEW |