#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;
}

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 textureSampleExternal(texture2d<float, access::sample> plane0, texture2d<float, access::sample> plane1, sampler smp, float2 coord, ExternalTextureParams params) {
  float2 const modifiedCoords = (params.coordTransformationMatrix * float3(coord, 1.0f));
  float2 const plane0_dims = float2(uint2(plane0.get_width(0), plane0.get_height(0)));
  float2 const plane0_half_texel = (float2(0.5f) / plane0_dims);
  float2 const plane0_clamped = clamp(modifiedCoords, plane0_half_texel, (1.0f - plane0_half_texel));
  float2 const plane1_dims = float2(uint2(plane1.get_width(0), plane1.get_height(0)));
  float2 const plane1_half_texel = (float2(0.5f) / plane1_dims);
  float2 const plane1_clamped = clamp(modifiedCoords, plane1_half_texel, (1.0f - plane1_half_texel));
  float4 color = 0.0f;
  if ((params.numPlanes == 1u)) {
    color = plane0.sample(smp, plane0_clamped, level(0.0f)).rgba;
  } else {
    color = float4((float4(plane0.sample(smp, plane0_clamped, level(0.0f))[0], plane1.sample(smp, plane1_clamped, level(0.0f)).rg, 1.0f) * params.yuvToRgbConversionMatrix), 1.0f);
  }
  if ((params.doYuvToRgbConversionOnly == 0u)) {
    color = float4(gammaCorrection(color.rgb, params.gammaDecodeParams), color[3]);
    color = float4((params.gamutConversionMatrix * color.rgb), color[3]);
    color = float4(gammaCorrection(color.rgb, params.gammaEncodeParams), color[3]);
  }
  return color;
}

void textureSampleBaseClampToEdge_7c04e6(texture2d<float, access::sample> tint_symbol_1, texture2d<float, access::sample> tint_symbol_2, sampler tint_symbol_3, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_4, device float4* const tint_symbol_5) {
  float2 arg_2 = float2(1.0f);
  float4 res = textureSampleExternal(tint_symbol_1, tint_symbol_2, tint_symbol_3, arg_2, tint_unpack_vec3_in_composite_1(*(tint_symbol_4)));
  *(tint_symbol_5) = res;
}

struct tint_symbol {
  float4 value [[position]];
};

float4 vertex_main_inner(texture2d<float, access::sample> tint_symbol_6, texture2d<float, access::sample> tint_symbol_7, sampler tint_symbol_8, const constant ExternalTextureParams_tint_packed_vec3* const tint_symbol_9, device float4* const tint_symbol_10) {
  textureSampleBaseClampToEdge_7c04e6(tint_symbol_6, tint_symbol_7, tint_symbol_8, tint_symbol_9, tint_symbol_10);
  return float4(0.0f);
}

vertex tint_symbol vertex_main(texture2d<float, access::sample> tint_symbol_11 [[texture(0)]], texture2d<float, access::sample> tint_symbol_12 [[texture(1)]], sampler tint_symbol_13 [[sampler(0)]], const constant ExternalTextureParams_tint_packed_vec3* tint_symbol_14 [[buffer(2)]], device float4* tint_symbol_15 [[buffer(0)]]) {
  float4 const inner_result = vertex_main_inner(tint_symbol_11, tint_symbol_12, tint_symbol_13, tint_symbol_14, tint_symbol_15);
  tint_symbol wrapper_result = {};
  wrapper_result.value = inner_result;
  return wrapper_result;
}

fragment void fragment_main(texture2d<float, access::sample> tint_symbol_16 [[texture(0)]], texture2d<float, access::sample> tint_symbol_17 [[texture(1)]], sampler tint_symbol_18 [[sampler(0)]], const constant ExternalTextureParams_tint_packed_vec3* tint_symbol_19 [[buffer(2)]], device float4* tint_symbol_20 [[buffer(0)]]) {
  textureSampleBaseClampToEdge_7c04e6(tint_symbol_16, tint_symbol_17, tint_symbol_18, tint_symbol_19, tint_symbol_20);
  return;
}

kernel void compute_main(texture2d<float, access::sample> tint_symbol_21 [[texture(0)]], texture2d<float, access::sample> tint_symbol_22 [[texture(1)]], sampler tint_symbol_23 [[sampler(0)]], const constant ExternalTextureParams_tint_packed_vec3* tint_symbol_24 [[buffer(2)]], device float4* tint_symbol_25 [[buffer(0)]]) {
  textureSampleBaseClampToEdge_7c04e6(tint_symbol_21, tint_symbol_22, tint_symbol_23, tint_symbol_24, tint_symbol_25);
  return;
}

