// Copyright 2016 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "ui/gfx/icc_profile.h"

#include <list>
#include <set>

#include "base/command_line.h"
#include "base/containers/mru_cache.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/synchronization/lock.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/third_party/skcms/skcms.h"
#include "ui/gfx/skia_color_space_util.h"

namespace gfx {

namespace {

static const size_t kMaxCachedICCProfiles = 16;

// An MRU cache mapping data to ICCProfile objects, to avoid re-parsing
// profiles every time they are read.
using DataToProfileCacheBase = base::MRUCache<std::vector<char>, ICCProfile>;
class DataToProfileCache : public DataToProfileCacheBase {
 public:
  DataToProfileCache() : DataToProfileCacheBase(kMaxCachedICCProfiles) {}
};
base::LazyInstance<DataToProfileCache>::Leaky g_data_to_profile_cache =
    LAZY_INSTANCE_INITIALIZER;

// Lock that must be held to access |g_data_to_profile_cache|.
base::LazyInstance<base::Lock>::Leaky g_icc_profile_lock =
    LAZY_INSTANCE_INITIALIZER;

}  // namespace

void ICCProfile::Internals::Initialize() {
  // Start out with no parametric data.
  if (data_.empty())
    return;

  // Parse the profile.
  skcms_ICCProfile profile;
  if (!skcms_Parse(data_.data(), data_.size(), &profile)) {
    DLOG(ERROR) << "Failed to parse ICC profile.";
    return;
  }

  // We have seen many users with profiles that don't have a D50 white point.
  // Windows appears to detect these profiles, and not use them for OS drawing.
  // It still returns them when we query the system for the installed profile.
  // For consistency (and to match old behavior) we reject these profiles on
  // all platforms.
  // https://crbug.com/847024
  const skcms_Matrix3x3& m(profile.toXYZD50);
  float wX = m.vals[0][0] + m.vals[0][1] + m.vals[0][2];
  float wY = m.vals[1][0] + m.vals[1][1] + m.vals[1][2];
  float wZ = m.vals[2][0] + m.vals[2][1] + m.vals[2][2];
  static const float kD50_WhitePoint[3] = { 0.96420f, 1.00000f, 0.82491f };
  if (fabsf(wX - kD50_WhitePoint[0]) > 0.04f ||
      fabsf(wY - kD50_WhitePoint[1]) > 0.04f ||
      fabsf(wZ - kD50_WhitePoint[2]) > 0.04f) {
    return;
  }

  // At this point, the profile is considered valid. We still need to determine
  // if it's representable with a parametric transfer function.
  is_valid_ = true;

  // Extract the primary matrix, and assume that transfer function is sRGB until
  // we get something more precise.
  to_XYZD50_ = profile.toXYZD50;
  transfer_fn_ = SkNamedTransferFn::kSRGB;

  // Coerce it into a rasterization destination (if possible). If the profile
  // can't be approximated accurately, then use an sRGB transfer function and
  // return failure. We will continue to use the gamut from this profile.
  if (!skcms_MakeUsableAsDestinationWithSingleCurve(&profile)) {
    DLOG(ERROR) << "Parsed ICC profile but can't make usable as destination, "
                   "using sRGB gamma";
    return;
  }

  // If SkColorSpace will treat the gamma as that of sRGB, then use the named
  // constants.
  sk_sp<SkColorSpace> sk_color_space = SkColorSpace::Make(profile);
  if (!sk_color_space) {
    DLOG(ERROR) << "Parsed ICC profile but cannot create SkColorSpace from it, "
                   "using sRGB gamma.";
    return;
  }

  // We were able to get a parametric representation of the transfer function.
  is_parametric_ = true;

  if (sk_color_space->gammaCloseToSRGB())
    return;

  // We assume that if we accurately approximated the profile, then the
  // single-curve version (which may have higher error) is also okay. If we
  // want to maintain the distinction between accurate and inaccurate profiles,
  // we could check to see if the single-curve version is/ approximately equal
  // to the original (or to the multi-channel approximation).
  transfer_fn_ = profile.trc[0].parametric;
}

ICCProfile::ICCProfile() = default;
ICCProfile::ICCProfile(ICCProfile&& other) = default;
ICCProfile::ICCProfile(const ICCProfile& other) = default;
ICCProfile& ICCProfile::operator=(ICCProfile&& other) = default;
ICCProfile& ICCProfile::operator=(const ICCProfile& other) = default;
ICCProfile::~ICCProfile() = default;

bool ICCProfile::operator==(const ICCProfile& other) const {
  if (!internals_ && !other.internals_)
    return true;
  if (internals_ && other.internals_) {
    return internals_->data_ == other.internals_->data_;
  }
  return false;
}

bool ICCProfile::operator!=(const ICCProfile& other) const {
  return !(*this == other);
}

bool ICCProfile::IsValid() const {
  return internals_ ? internals_->is_valid_ : false;
}

std::vector<char> ICCProfile::GetData() const {
  return internals_ ? internals_->data_ : std::vector<char>();
}

// static
ICCProfile ICCProfile::FromData(const void* data_as_void, size_t size) {
  const char* data_as_byte = reinterpret_cast<const char*>(data_as_void);
  std::vector<char> data(data_as_byte, data_as_byte + size);

  base::AutoLock lock(g_icc_profile_lock.Get());

  // See if there is already an entry with the same data. If so, return that
  // entry. If not, parse the data.
  ICCProfile icc_profile;
  auto found_by_data = g_data_to_profile_cache.Get().Get(data);
  if (found_by_data != g_data_to_profile_cache.Get().end()) {
    icc_profile = found_by_data->second;
  } else {
    icc_profile.internals_ = base::MakeRefCounted<Internals>(std::move(data));
  }

  // Insert the profile into all caches.
  g_data_to_profile_cache.Get().Put(icc_profile.internals_->data_, icc_profile);

  return icc_profile;
}

ColorSpace ICCProfile::GetColorSpace() const {
  if (!internals_ || !internals_->is_valid_)
    return ColorSpace();

  return ColorSpace(ColorSpace::PrimaryID::CUSTOM,
                    ColorSpace::TransferID::CUSTOM, ColorSpace::MatrixID::RGB,
                    ColorSpace::RangeID::FULL, &internals_->to_XYZD50_,
                    &internals_->transfer_fn_);
}

ColorSpace ICCProfile::GetPrimariesOnlyColorSpace() const {
  if (!internals_ || !internals_->is_valid_)
    return ColorSpace();

  return ColorSpace(ColorSpace::PrimaryID::CUSTOM,
                    ColorSpace::TransferID::IEC61966_2_1,
                    ColorSpace::MatrixID::RGB, ColorSpace::RangeID::FULL,
                    &internals_->to_XYZD50_, nullptr);
}

bool ICCProfile::IsColorSpaceAccurate() const {
  if (!internals_)
    return false;

  if (!internals_->is_valid_)
    return false;

  return internals_->is_parametric_;
}

// static
ICCProfile ICCProfile::FromColorSpace(const ColorSpace& color_space) {
  if (!color_space.IsValid()) {
    return ICCProfile();
  }
  if (color_space.GetMatrixID() != ColorSpace::MatrixID::RGB) {
    DLOG(ERROR) << "Not creating non-RGB ICCProfile";
    return ICCProfile();
  }
  if (color_space.GetRangeID() != ColorSpace::RangeID::FULL) {
    DLOG(ERROR) << "Not creating non-full-range ICCProfile";
    return ICCProfile();
  }
  skcms_Matrix3x3 to_XYZD50_matrix;
  color_space.GetPrimaryMatrix(&to_XYZD50_matrix);
  skcms_TransferFunction fn;
  if (!color_space.GetTransferFunction(&fn)) {
    DLOG(ERROR) << "Failed to get ColorSpace transfer function for ICCProfile.";
    return ICCProfile();
  }
  sk_sp<SkData> data = SkWriteICCProfile(fn, to_XYZD50_matrix);
  if (!data) {
    DLOG(ERROR) << "Failed to create SkICC.";
    return ICCProfile();
  }
  return FromData(data->data(), data->size());
}

ICCProfile::Internals::Internals(std::vector<char> data)
    : data_(std::move(data)) {
  // Parse the ICC profile
  Initialize();
}

ICCProfile::Internals::~Internals() {}

}  // namespace gfx
