/*
 * Copyright (C) 2021 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.example.testapp

import android.renderscript.toolkit.YuvFormat
import java.lang.IllegalArgumentException

/**
 * Reference implementation of a YUV to RGB operation.
 */
@ExperimentalUnsignedTypes
fun referenceYuvToRgb(inputSignedArray: ByteArray, sizeX: Int, sizeY: Int, format: YuvFormat): ByteArray {
    require(sizeX % 2 == 0) { "The width of the input should be even."}
    val inputArray = inputSignedArray.asUByteArray()

    val outputArray = ByteArray(sizeX * sizeY * 4)
    val output = Vector2dArray(outputArray.asUByteArray(), 4, sizeX, sizeY)

    when (format) {
        YuvFormat.NV21 -> {
            val startY = 0
            val startU = sizeX * sizeY + 1
            val startV = sizeX * sizeY

            for (y in 0 until sizeY) {
                for (x in 0 until sizeX) {
                    val offsetY = y * sizeX + x
                    val offsetU = ((y shr 1) * sizeX + (x shr 1) * 2)
                    val offsetV = ((y shr 1) * sizeX + (x shr 1) * 2)
                    output[x, y] = yuvToRGBA4(
                        inputArray[startY + offsetY],
                        inputArray[startU + offsetU],
                        inputArray[startV + offsetV]
                    )
                }
            }
        }

        YuvFormat.YV12 -> {
            /* According to https://developer.android.com/reference/kotlin/android/graphics/ImageFormat#yv12,
             * strideX and strideUV should be aligned to 16 byte boundaries. If we do this, we
             * won't get the same results as RenderScript.
             *
             * We may want to test & require that sizeX is a multiple of 16/32.
             */
            val strideX = roundUpTo16(sizeX) // sizeX //
            val strideUV = roundUpTo16(strideX / 2) // strideX / 2 //
            val startY = 0
            val startU = strideX * sizeY
            val startV = startU + strideUV * sizeY / 2

            for (y in 0 until sizeY) {
                for (x in 0 until sizeX) {
                    val offsetY = y * sizeX + x
                    val offsetUV = (y shr 1) * strideUV + (x shr 1)
                    output[x, y] = yuvToRGBA4(
                        inputArray[startY + offsetY],
                        inputArray[startU + offsetUV],
                        inputArray[startV + offsetUV],
                    )
                }
            }
        }
        else -> throw IllegalArgumentException("Unknown YUV format $format")
    }

    return outputArray
}

@ExperimentalUnsignedTypes
private fun yuvToRGBA4(y: UByte, u: UByte, v: UByte): UByteArray {
    val intY = y.toInt() - 16
    val intU = u.toInt() - 128
    val intV = v.toInt() - 128
    val p = intArrayOf(
        intY * 298 + intV * 409 + 128 shr 8,
        intY * 298 - intU * 100 - intV * 208 + 128 shr 8,
        intY * 298 + intU * 516 + 128 shr 8,
        255
    )
    return UByteArray(4) { p[it].clampToUByte() }
}

/* To be used if we support Float
private fun yuvToRGBA_f4(y: UByte, u: UByte, v: UByte): UByteArray {
    val yuv_U_values = floatArrayOf(0f, -0.392f * 0.003921569f, 2.02f * 0.003921569f, 0f)
    val yuv_V_values = floatArrayOf(1.603f * 0.003921569f, -0.815f * 0.003921569f, 0f, 0f)

    var color = FloatArray(4) {y.toFloat() * 0.003921569f}
    val fU = FloatArray(4) {u.toFloat() - 128f}
    val fV = FloatArray(4) {v.toFloat() - 128f}

    color += fU * yuv_U_values;
    color += fV * yuv_V_values;
    //color = clamp(color, 0.f, 1.f);
    return UByteArray(4) { unitFloatClampedToUByte(color[it]) }
}
*/
