| Index: ui/gfx/icc_profile.cc
|
| diff --git a/ui/gfx/icc_profile.cc b/ui/gfx/icc_profile.cc
|
| index 2635586a946b8607554731cba31123e52381fbee..9f04bd8d77023d5a47274fc1fd4d5487195d7048 100644
|
| --- a/ui/gfx/icc_profile.cc
|
| +++ b/ui/gfx/icc_profile.cc
|
| @@ -9,7 +9,6 @@
|
| #include "base/containers/mru_cache.h"
|
| #include "base/lazy_instance.h"
|
| #include "base/synchronization/lock.h"
|
| -#include "third_party/skia/include/core/SkData.h"
|
| #include "third_party/skia/include/core/SkICC.h"
|
| #include "ui/gfx/color_transform.h"
|
|
|
| @@ -57,6 +56,10 @@ bool ICCProfile::operator!=(const ICCProfile& other) const {
|
| return !(*this == other);
|
| }
|
|
|
| +bool ICCProfile::IsValid() const {
|
| + return successfully_parsed_by_sk_icc_;
|
| +}
|
| +
|
| // static
|
| ICCProfile ICCProfile::FromData(const void* data, size_t size) {
|
| return FromDataWithId(data, size, 0);
|
| @@ -107,43 +110,6 @@ ICCProfile ICCProfile::FromBestMonitor() {
|
| #endif
|
|
|
| // static
|
| -ICCProfile ICCProfile::FromColorSpace(const gfx::ColorSpace& color_space) {
|
| - if (color_space == gfx::ColorSpace())
|
| - return ICCProfile();
|
| -
|
| - // If |color_space| was created from an ICC profile, retrieve that exact
|
| - // profile.
|
| - if (color_space.icc_profile_id_) {
|
| - Cache& cache = g_cache.Get();
|
| - base::AutoLock lock(cache.lock);
|
| - auto found = cache.id_to_icc_profile_mru.Get(color_space.icc_profile_id_);
|
| - if (found != cache.id_to_icc_profile_mru.end())
|
| - return found->second;
|
| - }
|
| -
|
| - // Otherwise, construct an ICC profile based on the best approximated
|
| - // primaries and matrix.
|
| - SkMatrix44 to_XYZD50_matrix;
|
| - color_space.GetPrimaryMatrix(&to_XYZD50_matrix);
|
| - SkColorSpaceTransferFn fn;
|
| - if (!color_space.GetTransferFunction(&fn)) {
|
| - DLOG(ERROR) << "Failed to get ColorSpace transfer function for ICCProfile.";
|
| - return ICCProfile();
|
| - }
|
| -
|
| - sk_sp<SkData> data = SkICC::WriteToICC(fn, to_XYZD50_matrix);
|
| - if (!data) {
|
| - DLOG(ERROR) << "Failed to create SkICC.";
|
| - return ICCProfile();
|
| - }
|
| -
|
| - // gfx::ColorTransform assumes that this will return an empty profile for any
|
| - // color space that was not constructed from an ICC profile.
|
| - // TODO(ccameron): Fix this assumption.
|
| - // return FromData(data->data(), data->size());
|
| - return ICCProfile();
|
| -}
|
| -
|
| const std::vector<char>& ICCProfile::GetData() const {
|
| return data_;
|
| }
|
| @@ -161,6 +127,28 @@ const ColorSpace& ICCProfile::GetColorSpace() const {
|
| return color_space_;
|
| }
|
|
|
| +// static
|
| +bool ICCProfile::FromId(uint64_t id,
|
| + bool only_if_needed,
|
| + ICCProfile* icc_profile) {
|
| + if (!id)
|
| + return false;
|
| +
|
| + Cache& cache = g_cache.Get();
|
| + base::AutoLock lock(cache.lock);
|
| +
|
| + auto found = cache.id_to_icc_profile_mru.Get(id);
|
| + if (found == cache.id_to_icc_profile_mru.end())
|
| + return false;
|
| +
|
| + const ICCProfile& found_icc_profile = found->second;
|
| + if (found_icc_profile.color_space_is_accurate_ && only_if_needed)
|
| + return false;
|
| +
|
| + *icc_profile = found_icc_profile;
|
| + return true;
|
| +}
|
| +
|
| void ICCProfile::ComputeColorSpaceAndCache() {
|
| if (!id_)
|
| return;
|
| @@ -172,55 +160,47 @@ void ICCProfile::ComputeColorSpaceAndCache() {
|
| auto found = cache.id_to_icc_profile_mru.Get(id_);
|
| if (found != cache.id_to_icc_profile_mru.end()) {
|
| color_space_ = found->second.color_space_;
|
| + successfully_parsed_by_sk_icc_ =
|
| + found->second.successfully_parsed_by_sk_icc_;
|
| return;
|
| }
|
| }
|
|
|
| - // Compute the color space.
|
| - color_space_ = gfx::ColorSpace(
|
| - ColorSpace::PrimaryID::CUSTOM, ColorSpace::TransferID::CUSTOM,
|
| - ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL);
|
| - color_space_.icc_profile_id_ = id_;
|
| - color_space_.icc_profile_sk_color_space_ =
|
| - SkColorSpace::MakeICC(data_.data(), data_.size());
|
| -
|
| + color_space_is_accurate_ = true;
|
| + SkMatrix44 to_XYZD50_matrix;
|
| + SkColorSpaceTransferFn fn;
|
| sk_sp<SkICC> sk_icc = SkICC::Make(data_.data(), data_.size());
|
| if (sk_icc) {
|
| - bool result;
|
| - SkMatrix44 to_XYZD50_matrix;
|
| - result = sk_icc->toXYZD50(&to_XYZD50_matrix);
|
| - if (result) {
|
| - for (int row = 0; row < 3; ++row) {
|
| - for (int col = 0; col < 3; ++col) {
|
| - color_space_.custom_primary_matrix_[3 * row + col] =
|
| - to_XYZD50_matrix.get(row, col);
|
| - }
|
| - }
|
| - } else {
|
| + successfully_parsed_by_sk_icc_ = true;
|
| + if (!sk_icc->toXYZD50(&to_XYZD50_matrix)) {
|
| // Just say that the primaries were the sRGB primaries if we can't
|
| // extract them.
|
| - color_space_.primaries_ = ColorSpace::PrimaryID::BT709;
|
| + gfx::ColorSpace::CreateSRGB().GetPrimaryMatrix(&to_XYZD50_matrix);
|
| + color_space_is_accurate_ = false;
|
| DLOG(ERROR) << "Unable to handle ICCProfile primaries.";
|
| }
|
| - SkColorSpaceTransferFn fn;
|
| - result = sk_icc->isNumericalTransferFn(&fn);
|
| - if (result) {
|
| - color_space_.custom_transfer_params_[0] = fn.fA;
|
| - color_space_.custom_transfer_params_[1] = fn.fB;
|
| - color_space_.custom_transfer_params_[2] = fn.fC;
|
| - color_space_.custom_transfer_params_[3] = fn.fD;
|
| - color_space_.custom_transfer_params_[4] = fn.fE;
|
| - color_space_.custom_transfer_params_[5] = fn.fF;
|
| - color_space_.custom_transfer_params_[6] = fn.fG;
|
| - } else {
|
| + if (!sk_icc->isNumericalTransferFn(&fn)) {
|
| // Just say that the transfer function was sRGB if we cannot read it.
|
| // TODO(ccameron): Use a least squares approximation of the transfer
|
| // function when it is not numerical.
|
| - color_space_.transfer_ = ColorSpace::TransferID::IEC61966_2_1;
|
| + gfx::ColorSpace::CreateSRGB().GetTransferFunction(&fn);
|
| + color_space_is_accurate_ = false;
|
| DLOG(ERROR) << "Unable to handle ICCProfile transfer function.";
|
| }
|
| + } else {
|
| + successfully_parsed_by_sk_icc_ = false;
|
| + gfx::ColorSpace::CreateSRGB().GetPrimaryMatrix(&to_XYZD50_matrix);
|
| + gfx::ColorSpace::CreateSRGB().GetTransferFunction(&fn);
|
| + color_space_is_accurate_ = false;
|
| + DLOG(ERROR) << "Unable parse ICCProfile.";
|
| }
|
|
|
| + // Compute the color space.
|
| + color_space_ = gfx::ColorSpace::CreateCustom(to_XYZD50_matrix, fn);
|
| + color_space_.icc_profile_id_ = id_;
|
| + color_space_.icc_profile_sk_color_space_ =
|
| + SkColorSpace::MakeICC(data_.data(), data_.size());
|
| +
|
| // Add to the cache.
|
| {
|
| Cache& cache = g_cache.Get();
|
|
|