// Copyright 2020 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 "media/base/mac/color_space_util_mac.h"

#include <simd/simd.h>
#include <vector>

#include "base/mac/foundation_util.h"
#include "base/no_destructor.h"
#include "third_party/skia/include/third_party/skcms/skcms.h"

namespace media {

namespace {

// Read the value for the key in |key| to CFString and convert it to IdType.
// Use the list of pairs in |cfstr_id_pairs| to do the conversion (by doing a
// linear lookup).
template <typename IdType, typename StringIdPair>
bool GetImageBufferProperty(CFTypeRef value_untyped,
                            const std::vector<StringIdPair>& cfstr_id_pairs,
                            IdType* value_as_id) {
  CFStringRef value_as_string = base::mac::CFCast<CFStringRef>(value_untyped);
  if (!value_as_string)
    return false;

  for (const auto& p : cfstr_id_pairs) {
    if (p.cfstr_cm)
      DCHECK(!CFStringCompare(p.cfstr_cv, p.cfstr_cm, 0));
    if (!CFStringCompare(value_as_string, p.cfstr_cv, 0)) {
      *value_as_id = p.id;
      return true;
    }
  }

  return false;
}

gfx::ColorSpace::PrimaryID GetCoreVideoPrimary(CFTypeRef primaries_untyped) {
  struct CVImagePrimary {
    const CFStringRef cfstr_cv;
    const CFStringRef cfstr_cm;
    const gfx::ColorSpace::PrimaryID id;
  };
  static const base::NoDestructor<std::vector<CVImagePrimary>>
      kSupportedPrimaries([] {
        std::vector<CVImagePrimary> supported_primaries;
        supported_primaries.push_back(
            {kCVImageBufferColorPrimaries_ITU_R_709_2,
             kCMFormatDescriptionColorPrimaries_ITU_R_709_2,
             gfx::ColorSpace::PrimaryID::BT709});
        supported_primaries.push_back(
            {kCVImageBufferColorPrimaries_EBU_3213,
             kCMFormatDescriptionColorPrimaries_EBU_3213,
             gfx::ColorSpace::PrimaryID::BT470BG});
        supported_primaries.push_back(
            {kCVImageBufferColorPrimaries_SMPTE_C,
             kCMFormatDescriptionColorPrimaries_SMPTE_C,
             gfx::ColorSpace::PrimaryID::SMPTE240M});
        supported_primaries.push_back(
            {kCVImageBufferColorPrimaries_ITU_R_2020,
             kCMFormatDescriptionColorPrimaries_ITU_R_2020,
             gfx::ColorSpace::PrimaryID::BT2020});
        return supported_primaries;
      }());

  // The named primaries. Default to BT709.
  auto primary_id = gfx::ColorSpace::PrimaryID::BT709;
  if (!GetImageBufferProperty(primaries_untyped, *kSupportedPrimaries,
                              &primary_id)) {
    DLOG(ERROR) << "Failed to find CVImageBufferRef primaries.";
  }
  return primary_id;
}

gfx::ColorSpace::TransferID GetCoreVideoTransferFn(CFTypeRef transfer_untyped,
                                                   CFTypeRef gamma_untyped,
                                                   double* gamma) {
  struct CVImageTransferFn {
    const CFStringRef cfstr_cv;
    const CFStringRef cfstr_cm;
    const gfx::ColorSpace::TransferID id;
  };
  static const base::NoDestructor<std::vector<CVImageTransferFn>>
      kSupportedTransferFuncs([] {
        std::vector<CVImageTransferFn> supported_transfer_funcs;
        supported_transfer_funcs.push_back(
            {kCVImageBufferTransferFunction_ITU_R_709_2,
             kCMFormatDescriptionTransferFunction_ITU_R_709_2,
             gfx::ColorSpace::TransferID::BT709_APPLE});
        supported_transfer_funcs.push_back(
            {kCVImageBufferTransferFunction_SMPTE_240M_1995,
             kCMFormatDescriptionTransferFunction_SMPTE_240M_1995,
             gfx::ColorSpace::TransferID::SMPTE240M});
        supported_transfer_funcs.push_back(
            {kCVImageBufferTransferFunction_UseGamma,
             kCMFormatDescriptionTransferFunction_UseGamma,
             gfx::ColorSpace::TransferID::CUSTOM});
        supported_transfer_funcs.push_back(
            {kCVImageBufferTransferFunction_ITU_R_2020,
             kCMFormatDescriptionTransferFunction_ITU_R_2020,
             gfx::ColorSpace::TransferID::BT2020_10});
        if (@available(macos 10.12, *)) {
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_SMPTE_ST_428_1,
               kCMFormatDescriptionTransferFunction_SMPTE_ST_428_1,
               gfx::ColorSpace::TransferID::SMPTEST428_1});
        }
        if (@available(macos 10.13, *)) {
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_SMPTE_ST_2084_PQ,
               kCMFormatDescriptionTransferFunction_SMPTE_ST_2084_PQ,
               gfx::ColorSpace::TransferID::SMPTEST2084});
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_ITU_R_2100_HLG,
               kCMFormatDescriptionTransferFunction_ITU_R_2100_HLG,
               gfx::ColorSpace::TransferID::ARIB_STD_B67});
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_sRGB, nullptr,
               gfx::ColorSpace::TransferID::IEC61966_2_1});
        }
        if (@available(macos 10.14, *)) {
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_Linear,
               kCMFormatDescriptionTransferFunction_Linear,
               gfx::ColorSpace::TransferID::LINEAR});
        }
        if (@available(macos 10.15, *)) {
          supported_transfer_funcs.push_back(
              {kCVImageBufferTransferFunction_sRGB,
               kCMFormatDescriptionTransferFunction_sRGB,
               gfx::ColorSpace::TransferID::IEC61966_2_1});
        }

        return supported_transfer_funcs;
      }());

  // The named transfer function.
  auto transfer_id = gfx::ColorSpace::TransferID::BT709;
  if (!GetImageBufferProperty(transfer_untyped, *kSupportedTransferFuncs,
                              &transfer_id)) {
    DLOG(ERROR) << "Failed to find CVImageBufferRef transfer.";
  }

  if (transfer_id != gfx::ColorSpace::TransferID::CUSTOM)
    return transfer_id;

  // If we fail to retrieve the gamma parameter, fall back to BT709.
  constexpr auto kDefaultTransferFn = gfx::ColorSpace::TransferID::BT709;
  CFNumberRef gamma_number = base::mac::CFCast<CFNumberRef>(gamma_untyped);
  if (!gamma_number) {
    DLOG(ERROR) << "Failed to get gamma level.";
    return kDefaultTransferFn;
  }

  // CGFloat is a double on 64-bit systems.
  CGFloat gamma_double = 0;
  if (!CFNumberGetValue(gamma_number, kCFNumberCGFloatType, &gamma_double)) {
    DLOG(ERROR) << "Failed to get CVImageBufferRef gamma level as float.";
    return kDefaultTransferFn;
  }

  if (gamma_double == 2.2)
    return gfx::ColorSpace::TransferID::GAMMA22;
  if (gamma_double == 2.8)
    return gfx::ColorSpace::TransferID::GAMMA28;

  *gamma = gamma_double;
  return transfer_id;
}

gfx::ColorSpace::MatrixID GetCoreVideoMatrix(CFTypeRef matrix_untyped) {
  struct CVImageMatrix {
    const CFStringRef cfstr_cv;
    const CFStringRef cfstr_cm;
    gfx::ColorSpace::MatrixID id;
  };
  static const base::NoDestructor<std::vector<CVImageMatrix>>
      kSupportedMatrices([] {
        std::vector<CVImageMatrix> supported_matrices;
        supported_matrices.push_back(
            {kCVImageBufferYCbCrMatrix_ITU_R_709_2,
             kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2,
             gfx::ColorSpace::MatrixID::BT709});
        supported_matrices.push_back(
            {kCVImageBufferYCbCrMatrix_ITU_R_601_4,
             kCMFormatDescriptionYCbCrMatrix_ITU_R_601_4,
             gfx::ColorSpace::MatrixID::SMPTE170M});
        supported_matrices.push_back(
            {kCVImageBufferYCbCrMatrix_SMPTE_240M_1995,
             kCMFormatDescriptionYCbCrMatrix_SMPTE_240M_1995,
             gfx::ColorSpace::MatrixID::SMPTE240M});
        supported_matrices.push_back(
            {kCVImageBufferYCbCrMatrix_ITU_R_2020,
             kCMFormatDescriptionYCbCrMatrix_ITU_R_2020,
             gfx::ColorSpace::MatrixID::BT2020_NCL});
        return supported_matrices;
      }());

  auto matrix_id = gfx::ColorSpace::MatrixID::INVALID;
  if (!GetImageBufferProperty(matrix_untyped, *kSupportedMatrices,
                              &matrix_id)) {
    DLOG(ERROR) << "Failed to find CVImageBufferRef YUV matrix.";
  }
  return matrix_id;
}

gfx::ColorSpace GetCoreVideoColorSpaceInternal(CFTypeRef primaries_untyped,
                                               CFTypeRef transfer_untyped,
                                               CFTypeRef gamma_untyped,
                                               CFTypeRef matrix_untyped) {
  double gamma;
  auto primary_id = GetCoreVideoPrimary(primaries_untyped);
  auto matrix_id = GetCoreVideoMatrix(matrix_untyped);
  auto transfer_id =
      GetCoreVideoTransferFn(transfer_untyped, gamma_untyped, &gamma);

  // Use a matrix id that is coherent with a primary id. Useful when we fail to
  // parse the matrix. Previously it was always defaulting to MatrixID::BT709
  // See http://crbug.com/788236.
  if (matrix_id == gfx::ColorSpace::MatrixID::INVALID) {
    if (primary_id == gfx::ColorSpace::PrimaryID::BT470BG)
      matrix_id = gfx::ColorSpace::MatrixID::BT470BG;
    else
      matrix_id = gfx::ColorSpace::MatrixID::BT709;
  }

  // It is specified to the decoder to use luma=[16,235] chroma=[16,240] via
  // the kCVPixelFormatType_420YpCbCr8BiPlanarVideoRange.
  //
  // TODO(crbug.com/1103432): We'll probably need support for more than limited
  // range content if we want this to be used for more than video sites.
  auto range_id = gfx::ColorSpace::RangeID::LIMITED;

  if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM) {
    // Transfer functions can also be specified as a gamma value.
    skcms_TransferFunction custom_tr_fn = {2.2f, 1, 0, 1, 0, 0, 0};
    if (transfer_id == gfx::ColorSpace::TransferID::CUSTOM)
      custom_tr_fn.g = gamma;

    return gfx::ColorSpace(primary_id, gfx::ColorSpace::TransferID::CUSTOM,
                           matrix_id, range_id, nullptr, &custom_tr_fn);
  }

  return gfx::ColorSpace(primary_id, transfer_id, matrix_id, range_id);
}

}  // anonymous namespace

gfx::ColorSpace GetImageBufferColorSpace(CVImageBufferRef image_buffer) {
  return GetCoreVideoColorSpaceInternal(
      CVBufferGetAttachment(image_buffer, kCVImageBufferColorPrimariesKey,
                            nullptr),
      CVBufferGetAttachment(image_buffer, kCVImageBufferTransferFunctionKey,
                            nullptr),
      CVBufferGetAttachment(image_buffer, kCVImageBufferGammaLevelKey, nullptr),
      CVBufferGetAttachment(image_buffer, kCVImageBufferYCbCrMatrixKey,
                            nullptr));
}

gfx::ColorSpace GetFormatDescriptionColorSpace(
    CMFormatDescriptionRef format_description) {
  return GetCoreVideoColorSpaceInternal(
      CMFormatDescriptionGetExtension(
          format_description, kCMFormatDescriptionExtension_ColorPrimaries),
      CMFormatDescriptionGetExtension(
          format_description, kCMFormatDescriptionExtension_TransferFunction),
      CMFormatDescriptionGetExtension(format_description,
                                      kCMFormatDescriptionExtension_GammaLevel),
      CMFormatDescriptionGetExtension(
          format_description, kCMFormatDescriptionExtension_YCbCrMatrix));
}

CFDataRef GenerateContentLightLevelInfo(const gfx::HDRMetadata& hdr_metadata) {
  // This is a SMPTEST2086 Content Light Level Information box.
  struct ContentLightLevelInfoSEI {
    uint16_t max_content_light_level;
    uint16_t max_frame_average_light_level;
  } __attribute__((packed, aligned(2)));
  static_assert(sizeof(ContentLightLevelInfoSEI) == 4, "Must be 4 bytes");

  // Values are stored in big-endian...
  ContentLightLevelInfoSEI sei;
  sei.max_content_light_level =
      __builtin_bswap16(hdr_metadata.max_content_light_level);
  sei.max_frame_average_light_level =
      __builtin_bswap16(hdr_metadata.max_frame_average_light_level);

  NSData* nsdata_sei = [NSData dataWithBytes:&sei length:4];
  return base::mac::NSToCFCast(nsdata_sei);
}

CFDataRef GenerateMasteringDisplayColorVolume(
    const gfx::HDRMetadata& hdr_metadata) {
  // This is a SMPTEST2086 Mastering Display Color Volume box.
  struct MasteringDisplayColorVolumeSEI {
    vector_ushort2 primaries[3];  // GBR
    vector_ushort2 white_point;
    uint32_t luminance_max;
    uint32_t luminance_min;
  } __attribute__((packed, aligned(4)));
  static_assert(sizeof(MasteringDisplayColorVolumeSEI) == 24,
                "Must be 24 bytes");

  // Make a copy which we can manipulate.
  auto md = hdr_metadata.color_volume_metadata;

  constexpr float kColorCoordinateUpperBound = 50000.0f;
  md.primary_r.Scale(kColorCoordinateUpperBound);
  md.primary_g.Scale(kColorCoordinateUpperBound);
  md.primary_b.Scale(kColorCoordinateUpperBound);
  md.white_point.Scale(kColorCoordinateUpperBound);

  constexpr float kUnitOfMasteringLuminance = 10000.0f;
  md.luminance_max *= kUnitOfMasteringLuminance;
  md.luminance_min *= kUnitOfMasteringLuminance;

  // Values are stored in big-endian...
  MasteringDisplayColorVolumeSEI sei;
  sei.primaries[0].x = __builtin_bswap16(md.primary_g.x() + 0.5f);
  sei.primaries[0].y = __builtin_bswap16(md.primary_g.y() + 0.5f);
  sei.primaries[1].x = __builtin_bswap16(md.primary_b.x() + 0.5f);
  sei.primaries[1].y = __builtin_bswap16(md.primary_b.y() + 0.5f);
  sei.primaries[2].x = __builtin_bswap16(md.primary_r.x() + 0.5f);
  sei.primaries[2].y = __builtin_bswap16(md.primary_r.y() + 0.5f);
  sei.white_point.x = __builtin_bswap16(md.white_point.x() + 0.5f);
  sei.white_point.y = __builtin_bswap16(md.white_point.y() + 0.5f);
  sei.luminance_max = __builtin_bswap32(md.luminance_max + 0.5f);
  sei.luminance_min = __builtin_bswap32(md.luminance_min + 0.5f);

  NSData* nsdata_sei = [NSData dataWithBytes:&sei length:24];
  return base::mac::NSToCFCast(nsdata_sei);
}

}  // namespace media
