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