#include <metal_stdlib>

using namespace metal;

template<typename T, size_t N>
struct tint_array {
    const constant T& operator[](size_t i) const constant { return elements[i]; }
    device T& operator[](size_t i) device { return elements[i]; }
    const device T& operator[](size_t i) const device { return elements[i]; }
    thread T& operator[](size_t i) thread { return elements[i]; }
    const thread T& operator[](size_t i) const thread { return elements[i]; }
    threadgroup T& operator[](size_t i) threadgroup { return elements[i]; }
    const threadgroup T& operator[](size_t i) const threadgroup { return elements[i]; }
    T elements[N];
};

struct tint_packed_vec3_f32_array_element {
  /* 0x0000 */ packed_float3 elements;
  /* 0x000c */ tint_array<int8_t, 4> tint_pad;
};

struct GammaTransferParams {
  /* 0x0000 */ float G;
  /* 0x0004 */ float A;
  /* 0x0008 */ float B;
  /* 0x000c */ float C;
  /* 0x0010 */ float D;
  /* 0x0014 */ float E;
  /* 0x0018 */ float F;
  /* 0x001c */ uint padding;
};

struct ExternalTextureParams_tint_packed_vec3 {
  /* 0x0000 */ uint numPlanes;
  /* 0x0004 */ uint doYuvToRgbConversionOnly;
  /* 0x0008 */ tint_array<int8_t, 8> tint_pad_1;
  /* 0x0010 */ float3x4 yuvToRgbConversionMatrix;
  /* 0x0040 */ GammaTransferParams gammaDecodeParams;
  /* 0x0060 */ GammaTransferParams gammaEncodeParams;
  /* 0x0080 */ tint_array<tint_packed_vec3_f32_array_element, 3> gamutConversionMatrix;
  /* 0x00b0 */ float3x2 coordTransformationMatrix;
  /* 0x00c8 */ tint_array<int8_t, 8> tint_pad_2;
};

float3x3 tint_unpack_vec3_in_composite(tint_array<tint_packed_vec3_f32_array_element, 3> in) {
  float3x3 result = float3x3(0.0f);
  for(uint i = 0u; (i < 3u); i = (i + 1u)) {
    result[i] = float3(in[i].elements);
  }
  return result;
}

struct ExternalTextureParams {
  uint numPlanes;
  uint doYuvToRgbConversionOnly;
  float3x4 yuvToRgbConversionMatrix;
  GammaTransferParams gammaDecodeParams;
  GammaTransferParams gammaEncodeParams;
  float3x3 gamutConversionMatrix;
  float3x2 coordTransformationMatrix;
};

ExternalTextureParams tint_unpack_vec3_in_composite_1(ExternalTextureParams_tint_packed_vec3 in) {
  ExternalTextureParams result = {};
  result.numPlanes = in.numPlanes;
  result.doYuvToRgbConversionOnly = in.doYuvToRgbConversionOnly;
  result.yuvToRgbConversionMatrix = in.yuvToRgbConversionMatrix;
  result.gammaDecodeParams = in.gammaDecodeParams;
  result.gammaEncodeParams = in.gammaEncodeParams;
  result.gamutConversionMatrix = tint_unpack_vec3_in_composite(in.gamutConversionMatrix);
  result.coordTransformationMatrix = in.coordTransformationMatrix;
  return result;
}

int2 tint_clamp(int2 e, int2 low, int2 high) {
  return min(max(e, low), high);
}

float3 gammaCorrection(float3 v, GammaTransferParams params) {
  bool3 const cond = (fabs(v) < float3(params.D));
  float3 const t = (sign(v) * ((params.C * fabs(v)) + params.F));
  float3 const f = (sign(v) * (pow(((params.A * fabs(v)) + params.B), float3(params.G)) + params.E));
  return select(f, t, cond);
}

float4 textureLoadExternal(texture2d<float, access::sample> plane0, texture2d<float, access::sample> plane1, int2 coord, ExternalTextureParams params) {
  int2 const coord1 = (coord >> uint2(1u));
  float3 color = 0.0f;
  if ((params.numPlanes == 1u)) {
    color = plane0.read(uint2(coord), 0).rgb;
  } else {
    color = (float4(plane0.read(uint2(coord), 0)[0], plane1.read(uint2(coord1), 0).rg, 1.0f) * params.yuvToRgbConversionMatrix);
  }
  if ((params.doYuvToRgbConversionOnly == 0u)) {
    color = gammaCorrection(color, params.gammaDecodeParams);
    color = (params.gamutConversionMatrix * color);
    color = gammaCorrection(color, params.gammaEncodeParams);
  }
  return float4(color, 1.0f);
}

kernel void tint_symbol(texture2d<float, access::sample> tint_symbol_1 [[texture(1)]], texture2d<float, access::sample> tint_symbol_2 [[texture(2)]], const constant ExternalTextureParams_tint_packed_vec3* tint_symbol_3 [[buffer(3)]], texture2d<float, access::write> tint_symbol_4 [[texture(0)]]) {
  float4 red = textureLoadExternal(tint_symbol_1, tint_symbol_2, tint_clamp(int2(10), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
  tint_symbol_4.write(red, uint2(tint_clamp(int2(0), int2(0), int2((uint2(tint_symbol_4.get_width(), tint_symbol_4.get_height()) - uint2(1u))))));
  float4 green = textureLoadExternal(tint_symbol_1, tint_symbol_2, tint_clamp(int2(70, 118), int2(0), int2((uint2(tint_symbol_1.get_width(), tint_symbol_1.get_height()) - uint2(1u)))), tint_unpack_vec3_in_composite_1(*(tint_symbol_3)));
  tint_symbol_4.write(green, uint2(tint_clamp(int2(1, 0), int2(0), int2((uint2(tint_symbol_4.get_width(), tint_symbol_4.get_height()) - uint2(1u))))));
  return;
}

