// Copyright (c) 2012 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/color_space.h"

#include <iomanip>
#include <limits>
#include <map>
#include <sstream>

#include "base/atomic_sequence_num.h"
#include "base/lazy_instance.h"
#include "base/synchronization/lock.h"
#include "third_party/skia/include/core/SkColorSpace.h"
#include "third_party/skia/include/core/SkData.h"
#include "third_party/skia/include/core/SkICC.h"
#include "ui/gfx/icc_profile.h"
#include "ui/gfx/skia_color_space_util.h"

namespace gfx {

namespace {

base::AtomicSequenceNumber g_color_space_id;

static bool IsAlmostZero(float value) {
  return std::abs(value) < std::numeric_limits<float>::epsilon();
}

static bool FloatsEqualWithinTolerance(const float* a,
                                       const float* b,
                                       int n,
                                       float tol) {
  for (int i = 0; i < n; ++i) {
    if (std::abs(a[i] - b[i]) > tol) {
      return false;
    }
  }
  return true;
}

}  // namespace

// static
int ColorSpace::kInvalidId = -1;

ColorSpace::ColorSpace(PrimaryID primaries,
                       TransferID transfer)
    : primaries_(primaries),
      transfer_(transfer),
      matrix_(MatrixID::RGB),
      range_(RangeID::FULL) {}

ColorSpace::ColorSpace(PrimaryID primaries,
                       const SkColorSpaceTransferFn& fn,
                       MatrixID matrix,
                       RangeID range)
    : primaries_(primaries), matrix_(matrix), range_(range) {
  SetCustomTransferFunction(fn);
}

ColorSpace::ColorSpace(const SkColorSpace& sk_color_space)
    : ColorSpace(PrimaryID::INVALID,
                 TransferID::INVALID,
                 MatrixID::RGB,
                 RangeID::FULL) {
  SkColorSpaceTransferFn fn;
  skcms_Matrix3x3 to_XYZD50;
  if (!sk_color_space.isNumericalTransferFn(&fn) ||
      !sk_color_space.toXYZD50(&to_XYZD50)) {
    // Construct an invalid result: Unable to extract necessary parameters
    return;
  }
  SetCustomTransferFunction(fn);
  SetCustomPrimaries(to_XYZD50);
}

bool ColorSpace::IsValid() const {
  return primaries_ != PrimaryID::INVALID && transfer_ != TransferID::INVALID &&
         matrix_ != MatrixID::INVALID && range_ != RangeID::INVALID;
}

// static
ColorSpace ColorSpace::CreateCustom(const skcms_Matrix3x3& to_XYZD50,
                                    const SkColorSpaceTransferFn& fn) {
  ColorSpace result(ColorSpace::PrimaryID::CUSTOM,
                    ColorSpace::TransferID::CUSTOM, ColorSpace::MatrixID::RGB,
                    ColorSpace::RangeID::FULL);
  result.SetCustomPrimaries(to_XYZD50);
  result.SetCustomTransferFunction(fn);
  return result;
}

void ColorSpace::SetCustomPrimaries(const skcms_Matrix3x3& to_XYZD50) {
  const PrimaryID kIDsToCheck[] = {
      PrimaryID::BT709,
      PrimaryID::BT470M,
      PrimaryID::BT470BG,
      PrimaryID::SMPTE170M,
      PrimaryID::SMPTE240M,
      PrimaryID::FILM,
      PrimaryID::BT2020,
      PrimaryID::SMPTEST428_1,
      PrimaryID::SMPTEST431_2,
      PrimaryID::SMPTEST432_1,
      PrimaryID::XYZ_D50,
      PrimaryID::ADOBE_RGB,
      PrimaryID::APPLE_GENERIC_RGB,
      PrimaryID::WIDE_GAMUT_COLOR_SPIN,
  };
  for (PrimaryID id : kIDsToCheck) {
    skcms_Matrix3x3 matrix;
    GetPrimaryMatrix(id, &matrix);
    if (FloatsEqualWithinTolerance(&to_XYZD50.vals[0][0], &matrix.vals[0][0], 9,
                                   0.001f)) {
      primaries_ = id;
      return;
    }
  }

  memcpy(custom_primary_matrix_, &to_XYZD50, 9 * sizeof(float));
  primaries_ = PrimaryID::CUSTOM;
}

void ColorSpace::SetCustomTransferFunction(const SkColorSpaceTransferFn& fn) {
  // These are all TransferIDs that will return a transfer function from
  // GetTransferFunction. When multiple ids map to the same function, this list
  // prioritizes the most common name (eg IEC61966_2_1).
  const TransferID kIDsToCheck[] = {
      TransferID::IEC61966_2_1, TransferID::LINEAR,
      TransferID::GAMMA18,      TransferID::GAMMA22,
      TransferID::GAMMA24,      TransferID::GAMMA28,
      TransferID::SMPTE240M,    TransferID::BT709_APPLE,
      TransferID::SMPTEST428_1,
  };
  for (TransferID id : kIDsToCheck) {
    SkColorSpaceTransferFn id_fn;
    GetTransferFunction(id, &id_fn);
    if (FloatsEqualWithinTolerance(&fn.fG, &id_fn.fG, 7, 0.001f)) {
      transfer_ = id;
      return;
    }
  }

  custom_transfer_params_[0] = fn.fA;
  custom_transfer_params_[1] = fn.fB;
  custom_transfer_params_[2] = fn.fC;
  custom_transfer_params_[3] = fn.fD;
  custom_transfer_params_[4] = fn.fE;
  custom_transfer_params_[5] = fn.fF;
  custom_transfer_params_[6] = fn.fG;
  transfer_ = TransferID::CUSTOM;
}

// static
int ColorSpace::GetNextId() {
  return g_color_space_id.GetNext();
}

bool ColorSpace::operator==(const ColorSpace& other) const {
  if (primaries_ != other.primaries_ || transfer_ != other.transfer_ ||
      matrix_ != other.matrix_ || range_ != other.range_ ||
      icc_profile_id_ != other.icc_profile_id_)
    return false;
  if (primaries_ == PrimaryID::CUSTOM) {
    if (memcmp(custom_primary_matrix_, other.custom_primary_matrix_,
               sizeof(custom_primary_matrix_))) {
      return false;
    }
  }
  if (transfer_ == TransferID::CUSTOM) {
    if (memcmp(custom_transfer_params_, other.custom_transfer_params_,
               sizeof(custom_transfer_params_))) {
      return false;
    }
  }
  return true;
}

bool ColorSpace::IsHDR() const {
  return transfer_ == TransferID::SMPTEST2084 ||
         transfer_ == TransferID::ARIB_STD_B67 ||
         transfer_ == TransferID::LINEAR_HDR ||
         transfer_ == TransferID::IEC61966_2_1_HDR;
}

bool ColorSpace::FullRangeEncodedValues() const {
  return transfer_ == TransferID::LINEAR_HDR ||
         transfer_ == TransferID::IEC61966_2_1_HDR ||
         transfer_ == TransferID::BT1361_ECG ||
         transfer_ == TransferID::IEC61966_2_4;
}

bool ColorSpace::IsParametricAccurate() const {
  return icc_profile_id_ == 0;
}

ColorSpace ColorSpace::GetParametricApproximation() const {
  ColorSpace result = *this;
  result.icc_profile_id_ = 0;
  return result;
}

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

bool ColorSpace::operator<(const ColorSpace& other) const {
  if (primaries_ < other.primaries_)
    return true;
  if (primaries_ > other.primaries_)
    return false;
  if (transfer_ < other.transfer_)
    return true;
  if (transfer_ > other.transfer_)
    return false;
  if (matrix_ < other.matrix_)
    return true;
  if (matrix_ > other.matrix_)
    return false;
  if (range_ < other.range_)
    return true;
  if (range_ > other.range_)
    return false;
  if (icc_profile_id_ < other.icc_profile_id_)
    return true;
  if (icc_profile_id_ > other.icc_profile_id_)
    return false;
  if (primaries_ == PrimaryID::CUSTOM) {
    int primary_result =
        memcmp(custom_primary_matrix_, other.custom_primary_matrix_,
               sizeof(custom_primary_matrix_));
    if (primary_result < 0)
      return true;
    if (primary_result > 0)
      return false;
  }
  if (transfer_ == TransferID::CUSTOM) {
    int transfer_result =
        memcmp(custom_transfer_params_, other.custom_transfer_params_,
               sizeof(custom_transfer_params_));
    if (transfer_result < 0)
      return true;
    if (transfer_result > 0)
      return false;
  }
  return false;
}

size_t ColorSpace::GetHash() const {
  size_t result = (static_cast<size_t>(primaries_) << 0) |
                  (static_cast<size_t>(transfer_) << 8) |
                  (static_cast<size_t>(matrix_) << 16) |
                  (static_cast<size_t>(range_) << 24);
  if (primaries_ == PrimaryID::CUSTOM) {
    const uint32_t* params =
        reinterpret_cast<const uint32_t*>(custom_primary_matrix_);
    result ^= params[0];
    result ^= params[4];
    result ^= params[8];
  }
  if (transfer_ == TransferID::CUSTOM) {
    const uint32_t* params =
        reinterpret_cast<const uint32_t*>(custom_transfer_params_);
    result ^= params[3];
    result ^= params[6];
  }
  return result;
}

#define PRINT_ENUM_CASE(TYPE, NAME) \
  case TYPE::NAME:                  \
    ss << #NAME;                    \
    break;

std::string ColorSpace::ToString() const {
  std::stringstream ss;
  ss << std::fixed << std::setprecision(4);
  if (primaries_ != PrimaryID::CUSTOM)
    ss << "{primaries:";
  switch (primaries_) {
    PRINT_ENUM_CASE(PrimaryID, INVALID)
    PRINT_ENUM_CASE(PrimaryID, BT709)
    PRINT_ENUM_CASE(PrimaryID, BT470M)
    PRINT_ENUM_CASE(PrimaryID, BT470BG)
    PRINT_ENUM_CASE(PrimaryID, SMPTE170M)
    PRINT_ENUM_CASE(PrimaryID, SMPTE240M)
    PRINT_ENUM_CASE(PrimaryID, FILM)
    PRINT_ENUM_CASE(PrimaryID, BT2020)
    PRINT_ENUM_CASE(PrimaryID, SMPTEST428_1)
    PRINT_ENUM_CASE(PrimaryID, SMPTEST431_2)
    PRINT_ENUM_CASE(PrimaryID, SMPTEST432_1)
    PRINT_ENUM_CASE(PrimaryID, XYZ_D50)
    PRINT_ENUM_CASE(PrimaryID, ADOBE_RGB)
    PRINT_ENUM_CASE(PrimaryID, APPLE_GENERIC_RGB)
    PRINT_ENUM_CASE(PrimaryID, WIDE_GAMUT_COLOR_SPIN)
    case PrimaryID::CUSTOM:
      // |custom_primary_matrix_| is in row-major order.
      const float sum_R = custom_primary_matrix_[0] +
                          custom_primary_matrix_[3] + custom_primary_matrix_[6];
      const float sum_G = custom_primary_matrix_[1] +
                          custom_primary_matrix_[4] + custom_primary_matrix_[7];
      const float sum_B = custom_primary_matrix_[2] +
                          custom_primary_matrix_[5] + custom_primary_matrix_[8];
      if (IsAlmostZero(sum_R) || IsAlmostZero(sum_G) || IsAlmostZero(sum_B))
        break;

      ss << "{primaries_d50_referred: [[" << (custom_primary_matrix_[0] / sum_R)
         << ", " << (custom_primary_matrix_[3] / sum_R) << "], "
         << " [" << (custom_primary_matrix_[1] / sum_G) << ", "
         << (custom_primary_matrix_[4] / sum_G) << "], "
         << " [" << (custom_primary_matrix_[2] / sum_B) << ", "
         << (custom_primary_matrix_[5] / sum_B) << "]]";
      break;
  }
  ss << ", transfer:";
  switch (transfer_) {
    PRINT_ENUM_CASE(TransferID, INVALID)
    PRINT_ENUM_CASE(TransferID, BT709)
    PRINT_ENUM_CASE(TransferID, BT709_APPLE)
    PRINT_ENUM_CASE(TransferID, GAMMA18)
    PRINT_ENUM_CASE(TransferID, GAMMA22)
    PRINT_ENUM_CASE(TransferID, GAMMA24)
    PRINT_ENUM_CASE(TransferID, GAMMA28)
    PRINT_ENUM_CASE(TransferID, SMPTE170M)
    PRINT_ENUM_CASE(TransferID, SMPTE240M)
    PRINT_ENUM_CASE(TransferID, LINEAR)
    PRINT_ENUM_CASE(TransferID, LOG)
    PRINT_ENUM_CASE(TransferID, LOG_SQRT)
    PRINT_ENUM_CASE(TransferID, IEC61966_2_4)
    PRINT_ENUM_CASE(TransferID, BT1361_ECG)
    PRINT_ENUM_CASE(TransferID, IEC61966_2_1)
    PRINT_ENUM_CASE(TransferID, BT2020_10)
    PRINT_ENUM_CASE(TransferID, BT2020_12)
    PRINT_ENUM_CASE(TransferID, SMPTEST2084)
    PRINT_ENUM_CASE(TransferID, SMPTEST428_1)
    PRINT_ENUM_CASE(TransferID, ARIB_STD_B67)
    PRINT_ENUM_CASE(TransferID, SMPTEST2084_NON_HDR)
    PRINT_ENUM_CASE(TransferID, IEC61966_2_1_HDR)
    PRINT_ENUM_CASE(TransferID, LINEAR_HDR)
    case TransferID::CUSTOM: {
      SkColorSpaceTransferFn fn;
      GetTransferFunction(&fn);
      ss << fn.fC << "*x + " << fn.fF << " if x < " << fn.fD << " else (";
      ss << fn.fA << "*x + " << fn.fB << ")**" << fn.fG << " + " << fn.fE;
      break;
    }
  }
  ss << ", matrix:";
  switch (matrix_) {
    PRINT_ENUM_CASE(MatrixID, INVALID)
    PRINT_ENUM_CASE(MatrixID, RGB)
    PRINT_ENUM_CASE(MatrixID, BT709)
    PRINT_ENUM_CASE(MatrixID, FCC)
    PRINT_ENUM_CASE(MatrixID, BT470BG)
    PRINT_ENUM_CASE(MatrixID, SMPTE170M)
    PRINT_ENUM_CASE(MatrixID, SMPTE240M)
    PRINT_ENUM_CASE(MatrixID, YCOCG)
    PRINT_ENUM_CASE(MatrixID, BT2020_NCL)
    PRINT_ENUM_CASE(MatrixID, BT2020_CL)
    PRINT_ENUM_CASE(MatrixID, YDZDX)
    PRINT_ENUM_CASE(MatrixID, GBR)
  }
  ss << ", range:";
  switch (range_) {
    PRINT_ENUM_CASE(RangeID, INVALID)
    PRINT_ENUM_CASE(RangeID, LIMITED)
    PRINT_ENUM_CASE(RangeID, FULL)
    PRINT_ENUM_CASE(RangeID, DERIVED)
  }
  if (icc_profile_id_) {
    ss << ", icc_profile_id:" << icc_profile_id_;
  }
  ss << "}";
  return ss.str();
}

#undef PRINT_ENUM_CASE

ColorSpace ColorSpace::GetAsFullRangeRGB() const {
  ColorSpace result(*this);
  if (!IsValid())
    return result;
  result.matrix_ = MatrixID::RGB;
  result.range_ = RangeID::FULL;
  return result;
}

ColorSpace ColorSpace::GetAsRGB() const {
  ColorSpace result(*this);
  if (IsValid())
    result.matrix_ = MatrixID::RGB;
  return result;
}

ColorSpace ColorSpace::GetScaledColorSpace(float factor) const {
  ColorSpace result(*this);
  skcms_Matrix3x3 to_XYZD50;
  GetPrimaryMatrix(&to_XYZD50);
  for (int row = 0; row < 3; ++row) {
    for (int col = 0; col < 3; ++col) {
      to_XYZD50.vals[row][col] *= factor;
    }
  }
  result.SetCustomPrimaries(to_XYZD50);
  return result;
}

ColorSpace ColorSpace::GetRasterColorSpace() const {
  // Rasterization can only be done into parametric color spaces.
  if (icc_profile_id_)
    return GetParametricApproximation();

  // Rasterization doesn't support more than 8 bit unorm values. If the output
  // space has an extended range, use Display P3 for the rasterization space,
  // to get a somewhat wider color gamut.
  if (HasExtendedSkTransferFn())
    return CreateDisplayP3D65();

  return *this;
}

ColorSpace ColorSpace::GetBlendingColorSpace() const {
  // HDR output on windows requires output have a linear transfer function.
  // Linear blending breaks the web, so use extended-sRGB for blending.
  if (transfer_ == TransferID::LINEAR_HDR)
    return CreateExtendedSRGB();
  return *this;
}

sk_sp<SkColorSpace> ColorSpace::ToSkColorSpace() const {
  // Unspecified color spaces correspond to the null SkColorSpace.
  if (!IsValid())
    return nullptr;

  // Handle only full-range RGB spaces.
  if (matrix_ != MatrixID::RGB) {
    DLOG(ERROR) << "Not creating non-RGB SkColorSpace";
    return nullptr;
  }
  if (range_ != RangeID::FULL) {
    DLOG(ERROR) << "Not creating non-full-range SkColorSpace";
    return nullptr;
  }

  // If we got a specific SkColorSpace from the ICCProfile that this color space
  // was created from, use that.
  if (icc_profile_id_) {
    sk_sp<SkColorSpace> result =
        ICCProfile::GetSkColorSpaceFromId(icc_profile_id_);
    if (result)
      return result;

    // This will fall through to creating a parametric approximation. The
    // result will be that we will use an inaccurate transfer function.
    DLOG(ERROR) << "Unable to find ICCProfile for SkColorSpace.";
  }

  // Use the named SRGB and linear-SRGB instead of the generic constructors.
  if (primaries_ == PrimaryID::BT709) {
    if (transfer_ == TransferID::IEC61966_2_1)
      return SkColorSpace::MakeSRGB();
    if (transfer_ == TransferID::LINEAR || transfer_ == TransferID::LINEAR_HDR)
      return SkColorSpace::MakeSRGBLinear();
  }

  skcms_TransferFunction transfer_fn = SkNamedTransferFn::kSRGB;
  switch (transfer_) {
    case TransferID::IEC61966_2_1:
      break;
    case TransferID::LINEAR:
    case TransferID::LINEAR_HDR:
      transfer_fn = SkNamedTransferFn::kLinear;
      break;
    default:
      if (!GetTransferFunction((SkColorSpaceTransferFn*)&transfer_fn)) {
        DLOG(ERROR) << "Failed to transfer function for SkColorSpace";
        return nullptr;
      }
      break;
  }
  skcms_Matrix3x3 gamut = SkNamedGamut::kSRGB;
  switch (primaries_) {
    case PrimaryID::BT709:
      break;
    case PrimaryID::ADOBE_RGB:
      gamut = SkNamedGamut::kAdobeRGB;
      break;
    case PrimaryID::SMPTEST432_1:
      gamut = SkNamedGamut::kDCIP3;
      break;
    case PrimaryID::BT2020:
      gamut = SkNamedGamut::kRec2020;
      break;
    default:
      GetPrimaryMatrix(&gamut);
      break;
  }

  sk_sp<SkColorSpace> sk_color_space =
      SkColorSpace::MakeRGB(transfer_fn, gamut);
  if (!sk_color_space)
    DLOG(ERROR) << "SkColorSpace::MakeRGB failed.";

  return sk_color_space;
}

// static
void ColorSpace::GetPrimaryMatrix(PrimaryID primary_id,
                                  skcms_Matrix3x3* to_XYZD50) {
  SkColorSpacePrimaries primaries = {0};
  switch (primary_id) {
    case ColorSpace::PrimaryID::CUSTOM:
    case ColorSpace::PrimaryID::INVALID:
      *to_XYZD50 = SkNamedGamut::kXYZ;  // Identity
      return;

    case ColorSpace::PrimaryID::BT709:
      // BT709 is our default case. Put it after the switch just
      // in case we somehow get an id which is not listed in the switch.
      // (We don't want to use "default", because we want the compiler
      //  to tell us if we forgot some enum values.)
      primaries.fRX = 0.640f;
      primaries.fRY = 0.330f;
      primaries.fGX = 0.300f;
      primaries.fGY = 0.600f;
      primaries.fBX = 0.150f;
      primaries.fBY = 0.060f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::BT470M:
      primaries.fRX = 0.67f;
      primaries.fRY = 0.33f;
      primaries.fGX = 0.21f;
      primaries.fGY = 0.71f;
      primaries.fBX = 0.14f;
      primaries.fBY = 0.08f;
      primaries.fWX = 0.31f;
      primaries.fWY = 0.316f;
      break;

    case ColorSpace::PrimaryID::BT470BG:
      primaries.fRX = 0.64f;
      primaries.fRY = 0.33f;
      primaries.fGX = 0.29f;
      primaries.fGY = 0.60f;
      primaries.fBX = 0.15f;
      primaries.fBY = 0.06f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::SMPTE170M:
    case ColorSpace::PrimaryID::SMPTE240M:
      primaries.fRX = 0.630f;
      primaries.fRY = 0.340f;
      primaries.fGX = 0.310f;
      primaries.fGY = 0.595f;
      primaries.fBX = 0.155f;
      primaries.fBY = 0.070f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::APPLE_GENERIC_RGB:
      primaries.fRX = 0.63002f;
      primaries.fRY = 0.34000f;
      primaries.fGX = 0.29505f;
      primaries.fGY = 0.60498f;
      primaries.fBX = 0.15501f;
      primaries.fBY = 0.07701f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::WIDE_GAMUT_COLOR_SPIN:
      primaries.fRX = 0.01f;
      primaries.fRY = 0.98f;
      primaries.fGX = 0.01f;
      primaries.fGY = 0.01f;
      primaries.fBX = 0.98f;
      primaries.fBY = 0.01f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::FILM:
      primaries.fRX = 0.681f;
      primaries.fRY = 0.319f;
      primaries.fGX = 0.243f;
      primaries.fGY = 0.692f;
      primaries.fBX = 0.145f;
      primaries.fBY = 0.049f;
      primaries.fWX = 0.310f;
      primaries.fWY = 0.136f;
      break;

    case ColorSpace::PrimaryID::BT2020:
      primaries.fRX = 0.708f;
      primaries.fRY = 0.292f;
      primaries.fGX = 0.170f;
      primaries.fGY = 0.797f;
      primaries.fBX = 0.131f;
      primaries.fBY = 0.046f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::SMPTEST428_1:
      primaries.fRX = 1.0f;
      primaries.fRY = 0.0f;
      primaries.fGX = 0.0f;
      primaries.fGY = 1.0f;
      primaries.fBX = 0.0f;
      primaries.fBY = 0.0f;
      primaries.fWX = 1.0f / 3.0f;
      primaries.fWY = 1.0f / 3.0f;
      break;

    case ColorSpace::PrimaryID::SMPTEST431_2:
      primaries.fRX = 0.680f;
      primaries.fRY = 0.320f;
      primaries.fGX = 0.265f;
      primaries.fGY = 0.690f;
      primaries.fBX = 0.150f;
      primaries.fBY = 0.060f;
      primaries.fWX = 0.314f;
      primaries.fWY = 0.351f;
      break;

    case ColorSpace::PrimaryID::SMPTEST432_1:
      primaries.fRX = 0.680f;
      primaries.fRY = 0.320f;
      primaries.fGX = 0.265f;
      primaries.fGY = 0.690f;
      primaries.fBX = 0.150f;
      primaries.fBY = 0.060f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;

    case ColorSpace::PrimaryID::XYZ_D50:
      primaries.fRX = 1.0f;
      primaries.fRY = 0.0f;
      primaries.fGX = 0.0f;
      primaries.fGY = 1.0f;
      primaries.fBX = 0.0f;
      primaries.fBY = 0.0f;
      primaries.fWX = 0.34567f;
      primaries.fWY = 0.35850f;
      break;

    case ColorSpace::PrimaryID::ADOBE_RGB:
      primaries.fRX = 0.6400f;
      primaries.fRY = 0.3300f;
      primaries.fGX = 0.2100f;
      primaries.fGY = 0.7100f;
      primaries.fBX = 0.1500f;
      primaries.fBY = 0.0600f;
      primaries.fWX = 0.3127f;
      primaries.fWY = 0.3290f;
      break;
  }
  primaries.toXYZD50(to_XYZD50);
}

void ColorSpace::GetPrimaryMatrix(skcms_Matrix3x3* to_XYZD50) const {
  if (primaries_ == PrimaryID::CUSTOM) {
    memcpy(to_XYZD50, custom_primary_matrix_, 9 * sizeof(float));
  } else {
    GetPrimaryMatrix(primaries_, to_XYZD50);
  }
}

void ColorSpace::GetPrimaryMatrix(SkMatrix44* to_XYZD50) const {
  skcms_Matrix3x3 toXYZ_3x3;
  GetPrimaryMatrix(&toXYZ_3x3);
  to_XYZD50->set3x3RowMajorf(&toXYZ_3x3.vals[0][0]);
}

// static
bool ColorSpace::GetTransferFunction(TransferID transfer,
                                     SkColorSpaceTransferFn* fn) {
  // Default to F(x) = pow(x, 1)
  fn->fA = 1;
  fn->fB = 0;
  fn->fC = 0;
  fn->fD = 0;
  fn->fE = 0;
  fn->fF = 0;
  fn->fG = 1;

  switch (transfer) {
    case ColorSpace::TransferID::LINEAR:
    case ColorSpace::TransferID::LINEAR_HDR:
      return true;
    case ColorSpace::TransferID::GAMMA18:
      fn->fG = 1.801f;
      return true;
    case ColorSpace::TransferID::GAMMA22:
      fn->fG = 2.2f;
      return true;
    case ColorSpace::TransferID::GAMMA24:
      fn->fG = 2.4f;
      return true;
    case ColorSpace::TransferID::GAMMA28:
      fn->fG = 2.8f;
      return true;
    case ColorSpace::TransferID::SMPTE240M:
      fn->fA = 0.899626676224f;
      fn->fB = 0.100373323776f;
      fn->fC = 0.250000000000f;
      fn->fD = 0.091286342118f;
      fn->fG = 2.222222222222f;
      return true;
    case ColorSpace::TransferID::BT709:
    case ColorSpace::TransferID::SMPTE170M:
    case ColorSpace::TransferID::BT2020_10:
    case ColorSpace::TransferID::BT2020_12:
    // With respect to rendering BT709
    //  * SMPTE 1886 suggests that we should be using gamma 2.4.
    //  * Most displays actually use a gamma of 2.2, and most media playing
    //    software uses the sRGB transfer function.
    //  * User studies shows that users don't really care.
    //  * Apple's CoreVideo uses gamma=1.961.
    // Bearing all of that in mind, use the same transfer funciton as sRGB,
    // which will allow more optimization, and will more closely match other
    // media players.
    case ColorSpace::TransferID::IEC61966_2_1:
    case ColorSpace::TransferID::IEC61966_2_1_HDR:
      fn->fA = 0.947867345704f;
      fn->fB = 0.052132654296f;
      fn->fC = 0.077399380805f;
      fn->fD = 0.040449937172f;
      fn->fG = 2.400000000000f;
      return true;
    case ColorSpace::TransferID::BT709_APPLE:
      fn->fG = 1.961000000000f;
      return true;
    case ColorSpace::TransferID::SMPTEST428_1:
      fn->fA = 0.225615407568f;
      fn->fE = -1.091041666667f;
      fn->fG = 2.600000000000f;
      return true;
    case ColorSpace::TransferID::IEC61966_2_4:
      // This could potentially be represented the same as IEC61966_2_1, but
      // it handles negative values differently.
      break;
    case ColorSpace::TransferID::ARIB_STD_B67:
    case ColorSpace::TransferID::BT1361_ECG:
    case ColorSpace::TransferID::LOG:
    case ColorSpace::TransferID::LOG_SQRT:
    case ColorSpace::TransferID::SMPTEST2084:
    case ColorSpace::TransferID::SMPTEST2084_NON_HDR:
    case ColorSpace::TransferID::CUSTOM:
    case ColorSpace::TransferID::INVALID:
      break;
  }

  return false;
}

bool ColorSpace::GetTransferFunction(SkColorSpaceTransferFn* fn) const {
  if (transfer_ == TransferID::CUSTOM) {
    fn->fA = custom_transfer_params_[0];
    fn->fB = custom_transfer_params_[1];
    fn->fC = custom_transfer_params_[2];
    fn->fD = custom_transfer_params_[3];
    fn->fE = custom_transfer_params_[4];
    fn->fF = custom_transfer_params_[5];
    fn->fG = custom_transfer_params_[6];
    return true;
  } else {
    return GetTransferFunction(transfer_, fn);
  }
}

bool ColorSpace::GetInverseTransferFunction(SkColorSpaceTransferFn* fn) const {
  if (!GetTransferFunction(fn))
    return false;
  *fn = SkTransferFnInverse(*fn);
  return true;
}

bool ColorSpace::HasExtendedSkTransferFn() const {
  return transfer_ == TransferID::LINEAR_HDR ||
         transfer_ == TransferID::IEC61966_2_1_HDR;
}

void ColorSpace::GetTransferMatrix(SkMatrix44* matrix) const {
  float Kr = 0;
  float Kb = 0;
  switch (matrix_) {
    case ColorSpace::MatrixID::RGB:
    case ColorSpace::MatrixID::INVALID:
      matrix->setIdentity();
      return;

    case ColorSpace::MatrixID::BT709:
      Kr = 0.2126f;
      Kb = 0.0722f;
      break;

    case ColorSpace::MatrixID::FCC:
      Kr = 0.30f;
      Kb = 0.11f;
      break;

    case ColorSpace::MatrixID::BT470BG:
    case ColorSpace::MatrixID::SMPTE170M:
      Kr = 0.299f;
      Kb = 0.114f;
      break;

    case ColorSpace::MatrixID::SMPTE240M:
      Kr = 0.212f;
      Kb = 0.087f;
      break;

    case ColorSpace::MatrixID::YCOCG: {
      float data[16] = {
           0.25f, 0.5f,  0.25f, 0.5f,  // Y
          -0.25f, 0.5f, -0.25f, 0.5f,  // Cg
            0.5f, 0.0f,  -0.5f, 0.0f,  // Co
            0.0f, 0.0f,   0.0f, 1.0f
      };
      matrix->setRowMajorf(data);
      return;
    }

    // BT2020_CL is a special case.
    // Basically we return a matrix that transforms RYB values
    // to YUV values. (Note that the green component have been replaced
    // with the luminance.)
    case ColorSpace::MatrixID::BT2020_CL: {
      Kr = 0.2627f;
      Kb = 0.0593f;
      float data[16] = {1.0f, 0.0f,           0.0f, 0.0f,  // R
                        Kr,   1.0f - Kr - Kb, Kb,   0.0f,  // Y
                        0.0f, 0.0f,           1.0f, 0.0f,  // B
                        0.0f, 0.0f,           0.0f, 1.0f};
      matrix->setRowMajorf(data);
      return;
    }

    case ColorSpace::MatrixID::BT2020_NCL:
      Kr = 0.2627f;
      Kb = 0.0593f;
      break;

    case ColorSpace::MatrixID::YDZDX: {
      float data[16] = {
          0.0f,              1.0f,             0.0f, 0.0f,  // Y
          0.0f,             -0.5f, 0.986566f / 2.0f, 0.5f,  // DX or DZ
          0.5f, -0.991902f / 2.0f,             0.0f, 0.5f,  // DZ or DX
          0.0f,              0.0f,             0.0f, 1.0f,
      };
      matrix->setRowMajorf(data);
      return;
    }
    case ColorSpace::MatrixID::GBR: {
      float data[16] = {0.0f, 1.0f, 0.0f, 0.0f,  // G
                        0.0f, 0.0f, 1.0f, 0.0f,  // B
                        1.0f, 0.0f, 0.0f, 0.0f,  // R
                        0.0f, 0.0f, 0.0f, 1.0f};
      matrix->setRowMajorf(data);
      return;
    }
  }
  float Kg = 1.0f - Kr - Kb;
  float u_m = 0.5f / (1.0f - Kb);
  float v_m = 0.5f / (1.0f - Kr);
  float data[16] = {
                     Kr,        Kg,                Kb, 0.0f,  // Y
              u_m * -Kr, u_m * -Kg, u_m * (1.0f - Kb), 0.5f,  // U
      v_m * (1.0f - Kr), v_m * -Kg,         v_m * -Kb, 0.5f,  // V
                   0.0f,      0.0f,              0.0f, 1.0f,
  };
  matrix->setRowMajorf(data);
}

void ColorSpace::GetRangeAdjustMatrix(SkMatrix44* matrix) const {
  switch (range_) {
    case RangeID::FULL:
    case RangeID::INVALID:
      matrix->setIdentity();
      return;

    case RangeID::DERIVED:
    case RangeID::LIMITED:
      break;
  }
  switch (matrix_) {
    case MatrixID::RGB:
    case MatrixID::GBR:
    case MatrixID::INVALID:
    case MatrixID::YCOCG:
      matrix->setScale(255.0f/219.0f, 255.0f/219.0f, 255.0f/219.0f);
      matrix->postTranslate(-16.0f/219.0f, -16.0f/219.0f, -16.0f/219.0f);
      break;

    case MatrixID::BT709:
    case MatrixID::FCC:
    case MatrixID::BT470BG:
    case MatrixID::SMPTE170M:
    case MatrixID::SMPTE240M:
    case MatrixID::BT2020_NCL:
    case MatrixID::BT2020_CL:
    case MatrixID::YDZDX:
      matrix->setScale(255.0f/219.0f, 255.0f/224.0f, 255.0f/224.0f);
      matrix->postTranslate(-16.0f/219.0f, -15.5f/224.0f, -15.5f/224.0f);
      break;
  }
}

bool ColorSpace::ToSkYUVColorSpace(SkYUVColorSpace* out) const {
  if (range_ == RangeID::FULL) {
    *out = kJPEG_SkYUVColorSpace;
    return true;
  }
  switch (matrix_) {
    case MatrixID::BT709:
      *out = kRec709_SkYUVColorSpace;
      return true;

    case MatrixID::BT470BG:
    case MatrixID::SMPTE170M:
    case MatrixID::SMPTE240M:
      *out = kRec601_SkYUVColorSpace;
      return true;

    default:
      break;
  }
  return false;
}

std::ostream& operator<<(std::ostream& out, const ColorSpace& color_space) {
  return out << color_space.ToString();
}

}  // namespace gfx
