/*
 * 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.google.android.renderscript

import android.graphics.Bitmap
import java.lang.IllegalArgumentException

// This string is used for error messages.
private const val externalName = "RenderScript Toolkit"

/**
 * A collection of high-performance graphic utility functions like blur and blend.
 *
 * This toolkit provides ten image manipulation functions: blend, blur, color matrix, convolve,
 * histogram, histogramDot, lut, lut3d, resize, and YUV to RGB. These functions execute
 * multithreaded on the CPU.
 *
 * Most of the functions have two variants: one that manipulates Bitmaps, the other ByteArrays.
 * For ByteArrays, you need to specify the width and height of the data to be processed, as
 * well as the number of bytes per pixel. For most use cases, this will be 4.
 *
 * The Toolkit creates a thread pool that's used for processing the functions. The threads live
 * for the duration of the application. They can be destroyed by calling the method shutdown().
 *
 * This library is thread safe. You can call methods from different poolThreads. The functions will
 * execute sequentially.
 *
 * A native C++ version of this Toolkit is available. Check the RenderScriptToolkit.h file in the
 * cpp directory.
 *
 * This toolkit can be used as a replacement for most RenderScript Intrinsic functions. Compared
 * to RenderScript, it's simpler to use and more than twice as fast on the CPU. However RenderScript
 * Intrinsics allow more flexibility for the type of allocation supported. In particular, this
 * toolkit does not support allocations of floats.
 */
object Toolkit {
    /**
     * Blends a source buffer with the destination buffer.
     *
     * Blends a source buffer and a destination buffer, placing the result in the destination
     * buffer. The blending is done pairwise between two corresponding RGBA values found in
     * each buffer. The mode parameter specifies one of fifteen supported blending operations.
     * See {@link BlendingMode}.
     *
     * A variant of this method is also available to blend Bitmaps.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY.
     *
     * The source and destination buffer must have the same dimensions. Both arrays should have
     * a size greater or equal to sizeX * sizeY * 4. The buffers have a row-major layout.
     *
     * @param mode The specific blending operation to do.
     * @param sourceArray The RGBA input buffer.
     * @param destArray The destination buffer. Used for input and output.
     * @param sizeX The width of both buffers, as a number of RGBA values.
     * @param sizeY The height of both buffers, as a number of RGBA values.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     */
    @JvmOverloads
    fun blend(
        mode: BlendingMode,
        sourceArray: ByteArray,
        destArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        restriction: Range2d? = null
    ) {
        require(sourceArray.size >= sizeX * sizeY * 4) {
            "$externalName blend. sourceArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*4 < ${sourceArray.size}."
        }
        require(destArray.size >= sizeX * sizeY * 4) {
            "$externalName blend. sourceArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*4 < ${sourceArray.size}."
        }
        validateRestriction("blend", sizeX, sizeY, restriction)

        nativeBlend(nativeHandle, mode.value, sourceArray, destArray, sizeX, sizeY, restriction)
    }

    /**
     * Blends a source bitmap with the destination bitmap.
     *
     * Blends a source bitmap and a destination bitmap, placing the result in the destination
     * bitmap. The blending is done pairwise between two corresponding RGBA values found in
     * each bitmap. The mode parameter specify one of fifteen supported blending operations.
     * See {@link BlendingMode}.
     *
     * A variant of this method is available to blend ByteArrays.
     *
     * The bitmaps should have identical width and height, and have a config of ARGB_8888.
     * Bitmaps with a stride different than width * vectorSize are not currently supported.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each bitmap. If provided, the range must be wholly contained with the dimensions
     * of the bitmap.
     *
     * @param mode The specific blending operation to do.
     * @param sourceBitmap The RGBA input buffer.
     * @param destBitmap The destination buffer. Used for input and output.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     */
    @JvmOverloads
    fun blend(
        mode: BlendingMode,
        sourceBitmap: Bitmap,
        destBitmap: Bitmap,
        restriction: Range2d? = null
    ) {
        validateBitmap("blend", sourceBitmap)
        validateBitmap("blend", destBitmap)
        require(
            sourceBitmap.width == destBitmap.width &&
                    sourceBitmap.height == destBitmap.height
        ) {
            "$externalName blend. Source and destination bitmaps should be the same size. " +
                    "${sourceBitmap.width}x${sourceBitmap.height} and " +
                    "${destBitmap.width}x${destBitmap.height} provided."
        }
        require(sourceBitmap.config == destBitmap.config) {
            "RenderScript Toolkit blend. Source and destination bitmaps should have the same " +
                    "config. ${sourceBitmap.config} and ${destBitmap.config} provided."
        }
        validateRestriction("blend", sourceBitmap.width, sourceBitmap.height, restriction)

        nativeBlendBitmap(nativeHandle, mode.value, sourceBitmap, destBitmap, restriction)
    }

    /**
     * Blurs an image.
     *
     * Performs a Gaussian blur of an image and returns result in a ByteArray buffer. A variant of
     * this method is available to blur Bitmaps.
     *
     * The radius determines which pixels are used to compute each blurred pixels. This Toolkit
     * accepts values between 1 and 25. Larger values create a more blurred effect but also
     * take longer to compute. When the radius extends past the edge, the edge pixel will
     * be used as replacement for the pixel that's out off boundary.
     *
     * Each input pixel can either be represented by four bytes (RGBA format) or one byte
     * for the less common blurring of alpha channel only image.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output buffer will still be full size, with the
     * section that's not blurred all set to 0. This is to stay compatible with RenderScript.
     *
     * The source buffer should be large enough for sizeX * sizeY * mVectorSize bytes. It has a
     * row-major layout.
     *
     * @param inputArray The buffer of the image to be blurred.
     * @param vectorSize Either 1 or 4, the number of bytes in each cell, i.e. A vs. RGBA.
     * @param sizeX The width of both buffers, as a number of 1 or 4 byte cells.
     * @param sizeY The height of both buffers, as a number of 1 or 4 byte cells.
     * @param radius The radius of the pixels used to blur, a value from 1 to 25.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The blurred pixels, a ByteArray of size.
     */
    @JvmOverloads
    fun blur(
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        radius: Int = 5,
        restriction: Range2d? = null
    ): ByteArray {
        require(vectorSize == 1 || vectorSize == 4) {
            "$externalName blur. The vectorSize should be 1 or 4. $vectorSize provided."
        }
        require(inputArray.size >= sizeX * sizeY * vectorSize) {
            "$externalName blur. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*$vectorSize < ${inputArray.size}."
        }
        require(radius in 1..25) {
            "$externalName blur. The radius should be between 1 and 25. $radius provided."
        }
        validateRestriction("blur", sizeX, sizeY, restriction)

        val outputArray = ByteArray(inputArray.size)
        nativeBlur(
            nativeHandle, inputArray, vectorSize, sizeX, sizeY, radius, outputArray, restriction
        )
        return outputArray
    }

    /**
     * Blurs an image.
     *
     * Performs a Gaussian blur of a Bitmap and returns result as a Bitmap. A variant of
     * this method is available to blur ByteArrays.
     *
     * The radius determines which pixels are used to compute each blurred pixels. This Toolkit
     * accepts values between 1 and 25. Larger values create a more blurred effect but also
     * take longer to compute. When the radius extends past the edge, the edge pixel will
     * be used as replacement for the pixel that's out off boundary.
     *
     * This method supports input Bitmap of config ARGB_8888 and ALPHA_8. Bitmaps with a stride
     * different than width * vectorSize are not currently supported. The returned Bitmap has the
     * same config.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output Bitmap will still be full size, with the
     * section that's not blurred all set to 0. This is to stay compatible with RenderScript.
     *
     * @param inputBitmap The buffer of the image to be blurred.
     * @param radius The radius of the pixels used to blur, a value from 1 to 25. Default is 5.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The blurred Bitmap.
     */
    @JvmOverloads
    fun blur(inputBitmap: Bitmap, radius: Int = 5, restriction: Range2d? = null): Bitmap {
        validateBitmap("blur", inputBitmap)
        require(radius in 1..25) {
            "$externalName blur. The radius should be between 1 and 25. $radius provided."
        }
        validateRestriction("blur", inputBitmap.width, inputBitmap.height, restriction)

        val outputBitmap = createCompatibleBitmap(inputBitmap)
        nativeBlurBitmap(nativeHandle, inputBitmap, outputBitmap, radius, restriction)
        return outputBitmap
    }

    /**
     * Identity matrix that can be passed to the {@link RenderScriptToolkit::colorMatrix} method.
     *
     * Using this matrix will result in no change to the pixel through multiplication although
     * the pixel value can still be modified by the add vector, or transformed to a different
     * format.
     */
    val identityMatrix: FloatArray
        get() = floatArrayOf(
            1f, 0f, 0f, 0f,
            0f, 1f, 0f, 0f,
            0f, 0f, 1f, 0f,
            0f, 0f, 0f, 1f
        )

    /**
     * Matrix to turn color pixels to a grey scale.
     *
     * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert an
     * image from color to greyscale.
     */
    val greyScaleColorMatrix: FloatArray
        get() = floatArrayOf(
            0.299f, 0.299f, 0.299f, 0f,
            0.587f, 0.587f, 0.587f, 0f,
            0.114f, 0.114f, 0.114f, 0f,
            0f, 0f, 0f, 1f
        )

    /**
     * Matrix to convert RGB to YUV.
     *
     * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert the
     * first three bytes of each pixel from RGB to YUV. This leaves the last byte (the alpha
     * channel) untouched.
     *
     * This is a simplistic conversion. Most YUV buffers have more complicated format, not supported
     * by this method.
     */
    val rgbToYuvMatrix: FloatArray
        get() = floatArrayOf(
            0.299f, -0.14713f, 0.615f, 0f,
            0.587f, -0.28886f, -0.51499f, 0f,
            0.114f, 0.436f, -0.10001f, 0f,
            0f, 0f, 0f, 1f
        )

    /**
     * Matrix to convert YUV to RGB.
     *
     * Use this matrix with the {@link RenderScriptToolkit::colorMatrix} method to convert the
     * first three bytes of each pixel from YUV to RGB. This leaves the last byte (the alpha
     * channel) untouched.
     *
     * This is a simplistic conversion. Most YUV buffers have more complicated format, not supported
     * by this method. Use {@link RenderScriptToolkit::yuvToRgb} to convert these buffers.
     */
    val yuvToRgbMatrix: FloatArray
        get() = floatArrayOf(
            1f, 1f, 1f, 0f,
            0f, -0.39465f, 2.03211f, 0f,
            1.13983f, -0.5806f, 0f, 0f,
            0f, 0f, 0f, 1f
        )

    /**
     * Transform an image using a color matrix.
     *
     * Converts a 2D array of vectors of unsigned bytes, multiplying each vectors by a 4x4 matrix
     * and adding an optional vector.
     *
     * Each input vector is composed of 1-4 unsigned bytes. If less than 4 bytes, it's extended to
     * 4, padding with zeroes. The unsigned bytes are converted from 0-255 to 0.0-1.0 floats
     * before the multiplication is done.
     *
     * The resulting value is normalized from 0.0-1.0 to a 0-255 value and stored in the output.
     * If the output vector size is less than four, the unused channels are discarded.
     *
     * If addVector is not specified, a vector of zeroes is added, i.e. a noop.
     *
     * Like the RenderScript Intrinsics, vectorSize of size 3 are padded to occupy 4 bytes.
     *
     * Check identityMatrix, greyScaleColorMatrix, rgbToYuvMatrix, and yuvToRgbMatrix for sample
     * matrices. The YUV conversion may not work for all color spaces.
     *
     * @param inputArray The buffer of the image to be converted.
     * @param inputVectorSize The number of bytes in each input cell, a value from 1 to 4.
     * @param sizeX The width of both buffers, as a number of 1 to 4 byte cells.
     * @param sizeY The height of both buffers, as a number of 1 to 4 byte cells.
     * @param outputVectorSize The number of bytes in each output cell, a value from 1 to 4.
     * @param matrix The 4x4 matrix to multiply, in row major format.
     * @param addVector A vector of four floats that's added to the result of the multiplication.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The converted buffer.
     */
    @JvmOverloads
    fun colorMatrix(
        inputArray: ByteArray,
        inputVectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        outputVectorSize: Int,
        matrix: FloatArray,
        addVector: FloatArray = floatArrayOf(0f, 0f, 0f, 0f),
        restriction: Range2d? = null
    ): ByteArray {
        require(inputVectorSize in 1..4) {
            "$externalName colorMatrix. The inputVectorSize should be between 1 and 4. " +
                    "$inputVectorSize provided."
        }
        require(outputVectorSize in 1..4) {
            "$externalName colorMatrix. The outputVectorSize should be between 1 and 4. " +
                    "$outputVectorSize provided."
        }
        require(inputArray.size >= sizeX * sizeY * inputVectorSize) {
            "$externalName colorMatrix. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*$inputVectorSize < ${inputArray.size}."
        }
        require(matrix.size == 16) {
            "$externalName colorMatrix. matrix should have 16 entries. ${matrix.size} provided."
        }
        require(addVector.size == 4) {
            "$externalName colorMatrix. addVector should have 4 entries. " +
                    "${addVector.size} provided."
        }
        validateRestriction("colorMatrix", sizeX, sizeY, restriction)

        val outputArray = ByteArray(sizeX * sizeY * paddedSize(outputVectorSize))
        nativeColorMatrix(
            nativeHandle, inputArray, inputVectorSize, sizeX, sizeY, outputArray, outputVectorSize,
            matrix, addVector, restriction
        )
        return outputArray
    }

    /**
     * Transform an image using a color matrix.
     *
     * Converts a bitmap, multiplying each RGBA value by a 4x4 matrix and adding an optional vector.
     * Each byte of the RGBA is converted from 0-255 to 0.0-1.0 floats before the multiplication
     * is done.
     *
     * Bitmaps with a stride different than width * vectorSize are not currently supported.
     *
     * The resulting value is normalized from 0.0-1.0 to a 0-255 value and stored in the output.
     *
     * If addVector is not specified, a vector of zeroes is added, i.e. a noop.
     *
     * Check identityMatrix, greyScaleColorMatrix, rgbToYuvMatrix, and yuvToRgbMatrix for sample
     * matrices. The YUV conversion may not work for all color spaces.
     *
     * @param inputBitmap The image to be converted.
     * @param matrix The 4x4 matrix to multiply, in row major format.
     * @param addVector A vector of four floats that's added to the result of the multiplication.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The converted buffer.
     */
    @JvmOverloads
    fun colorMatrix(
        inputBitmap: Bitmap,
        matrix: FloatArray,
        addVector: FloatArray = floatArrayOf(0f, 0f, 0f, 0f),
        restriction: Range2d? = null
    ): Bitmap {
        validateBitmap("colorMatrix", inputBitmap)
        require(matrix.size == 16) {
            "$externalName colorMatrix. matrix should have 16 entries. ${matrix.size} provided."
        }
        require(addVector.size == 4) {
            "$externalName colorMatrix. addVector should have 4 entries."
        }
        validateRestriction("colorMatrix", inputBitmap.width, inputBitmap.height, restriction)

        val outputBitmap = createCompatibleBitmap(inputBitmap)
        nativeColorMatrixBitmap(
            nativeHandle,
            inputBitmap,
            outputBitmap,
            matrix,
            addVector,
            restriction
        )
        return outputBitmap
    }

    /**
     * Convolve a ByteArray.
     *
     * Applies a 3x3 or 5x5 convolution to the input array using the provided coefficients.
     * A variant of this method is available to convolve Bitmaps.
     *
     * For 3x3 convolutions, 9 coefficients must be provided. For 5x5, 25 coefficients are needed.
     * The coefficients should be provided in row-major format.
     *
     * When the square extends past the edge, the edge values will be used as replacement for the
     * values that's are off boundary.
     *
     * Each input cell can either be represented by one to four bytes. Each byte is multiplied
     * and accumulated independently of the other bytes of the cell.
     *
     * An optional range parameter can be set to restrict the convolve operation to a rectangular
     * subset of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output buffer will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * The source array should be large enough for sizeX * sizeY * vectorSize bytes. It has a
     * row-major layout. The output array will have the same dimensions.
     *
     * Like the RenderScript Intrinsics, vectorSize of size 3 are padded to occupy 4 bytes.
     *
     * @param inputArray The buffer of the image to be blurred.
     * @param vectorSize The number of bytes in each cell, a value from 1 to 4.
     * @param sizeX The width of both buffers, as a number of 1 or 4 byte cells.
     * @param sizeY The height of both buffers, as a number of 1 or 4 byte cells.
     * @param coefficients A FloatArray of size 9 or 25, containing the multipliers.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The convolved array.
     */
    @JvmOverloads
    fun convolve(
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        coefficients: FloatArray,
        restriction: Range2d? = null
    ): ByteArray {
        require(vectorSize in 1..4) {
            "$externalName convolve. The vectorSize should be between 1 and 4. " +
                    "$vectorSize provided."
        }
        require(inputArray.size >= sizeX * sizeY * vectorSize) {
            "$externalName convolve. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*$vectorSize < ${inputArray.size}."
        }
        require(coefficients.size == 9 || coefficients.size == 25) {
            "$externalName convolve. Only 3x3 or 5x5 convolutions are supported. " +
                    "${coefficients.size} coefficients provided."
        }
        validateRestriction("convolve", sizeX, sizeY, restriction)

        val outputArray = ByteArray(inputArray.size)
        nativeConvolve(
            nativeHandle,
            inputArray,
            vectorSize,
            sizeX,
            sizeY,
            outputArray,
            coefficients,
            restriction
        )
        return outputArray
    }

    /**
     * Convolve a Bitmap.
     *
     * Applies a 3x3 or 5x5 convolution to the input Bitmap using the provided coefficients.
     * A variant of this method is available to convolve ByteArrays. Bitmaps with a stride different
     * than width * vectorSize are not currently supported.
     *
     * For 3x3 convolutions, 9 coefficients must be provided. For 5x5, 25 coefficients are needed.
     * The coefficients should be provided in row-major format.
     *
     * Each input cell can either be represented by one to four bytes. Each byte is multiplied
     * and accumulated independently of the other bytes of the cell.
     *
     * An optional range parameter can be set to restrict the convolve operation to a rectangular
     * subset of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output Bitmap will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * @param inputBitmap The image to be blurred.
     * @param coefficients A FloatArray of size 9 or 25, containing the multipliers.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The convolved Bitmap.
     */
    @JvmOverloads
    fun convolve(
        inputBitmap: Bitmap,
        coefficients: FloatArray,
        restriction: Range2d? = null
    ): Bitmap {
        validateBitmap("convolve", inputBitmap)
        require(coefficients.size == 9 || coefficients.size == 25) {
            "$externalName convolve. Only 3x3 or 5x5 convolutions are supported. " +
                    "${coefficients.size} coefficients provided."
        }
        validateRestriction("convolve", inputBitmap, restriction)

        val outputBitmap = createCompatibleBitmap(inputBitmap)
        nativeConvolveBitmap(nativeHandle, inputBitmap, outputBitmap, coefficients, restriction)
        return outputBitmap
    }

    /**
     * Compute the histogram of an image.
     *
     * Tallies how many times each of the 256 possible values of a byte is found in the input.
     * A variant of this method is available to do the histogram of a Bitmap.
     *
     * An input cell can be represented by one to four bytes. The tally is done independently
     * for each of the bytes of the cell. Correspondingly, the returned IntArray will have
     * 256 * vectorSize entries. The counts for value 0 are consecutive, followed by those for
     * value 1, etc.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY.
     *
     * The source buffer should be large enough for sizeX * sizeY * vectorSize bytes. It has a
     * row-major layout.
     *
     * Like the RenderScript Intrinsics, vectorSize of size 3 are padded to occupy 4 bytes.
     *
     * @param inputArray The buffer of the image to be analyzed.
     * @param vectorSize The number of bytes in each cell, a value from 1 to 4.
     * @param sizeX The width of the input buffers, as a number of 1 to 4 byte cells.
     * @param sizeY The height of the input buffers, as a number of 1 to 4 byte cells.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The resulting array of counts.
     */
    @JvmOverloads
    fun histogram(
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        restriction: Range2d? = null
    ): IntArray {
        require(vectorSize in 1..4) {
            "$externalName histogram. The vectorSize should be between 1 and 4. " +
                    "$vectorSize provided."
        }
        require(inputArray.size >= sizeX * sizeY * vectorSize) {
            "$externalName histogram. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*$vectorSize < ${inputArray.size}."
        }
        validateRestriction("histogram", sizeX, sizeY, restriction)

        val outputArray = IntArray(256 * paddedSize(vectorSize))
        nativeHistogram(
            nativeHandle,
            inputArray,
            vectorSize,
            sizeX,
            sizeY,
            outputArray,
            restriction
        )
        return outputArray
    }

    /**
     * Compute the histogram of an image.
     *
     * Tallies how many times each of the 256 possible values of a byte is found in the bitmap.
     * This method supports Bitmaps of config ARGB_8888 and ALPHA_8.
     *
     * For ARGB_8888, the tally is done independently of the four bytes. Correspondingly, the
     * returned IntArray will have 4 * 256 entries. The counts for value 0 are consecutive,
     * followed by those for value 1, etc.
     *
     * For ALPHA_8, an IntArray of size 256 is returned.
     *
     * Bitmaps with a stride different than width * vectorSize are not currently supported.
     *
     * A variant of this method is available to do the histogram of a ByteArray.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY.
     *
     * @param inputBitmap The bitmap to be analyzed.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The resulting array of counts.
     */
    @JvmOverloads
    fun histogram(
        inputBitmap: Bitmap,
        restriction: Range2d? = null
    ): IntArray {
        validateBitmap("histogram", inputBitmap)
        validateRestriction("histogram", inputBitmap, restriction)

        val outputArray = IntArray(256 * vectorSize(inputBitmap))
        nativeHistogramBitmap(nativeHandle, inputBitmap, outputArray, restriction)
        return outputArray
    }

    /**
     * Compute the histogram of the dot product of an image.
     *
     * This method supports cells of 1 to 4 bytes in length. For each cell of the array,
     * the dot product of its bytes with the provided coefficients is computed. The resulting
     * floating point value is converted to an unsigned byte and tallied in the histogram.
     *
     * If coefficients is null, the coefficients used for RGBA luminosity calculation will be used,
     * i.e. the values [0.299f, 0.587f, 0.114f, 0.f].
     *
     * Each coefficients must be >= 0 and their sum must be 1.0 or less. There must be the same
     * number of coefficients as vectorSize.
     *
     * A variant of this method is available to do the histogram of a Bitmap.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY.
     *
     * The source buffer should be large enough for sizeX * sizeY * vectorSize bytes. The returned
     * array will have 256 ints.
     *
     * Like the RenderScript Intrinsics, vectorSize of size 3 are padded to occupy 4 bytes.
     *
     * @param inputArray The buffer of the image to be analyzed.
     * @param vectorSize The number of bytes in each cell, a value from 1 to 4.
     * @param sizeX The width of the input buffers, as a number of 1 to 4 byte cells.
     * @param sizeY The height of the input buffers, as a number of 1 to 4 byte cells.
     * @param coefficients The dot product multipliers. Size should equal vectorSize. Can be null.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The resulting vector of counts.
     */
    @JvmOverloads
    fun histogramDot(
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        coefficients: FloatArray? = null,
        restriction: Range2d? = null
    ): IntArray {
        require(vectorSize in 1..4) {
            "$externalName histogramDot. The vectorSize should be between 1 and 4. " +
                    "$vectorSize provided."
        }
        require(inputArray.size >= sizeX * sizeY * vectorSize) {
            "$externalName histogramDot. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*$vectorSize < ${inputArray.size}."
        }
        validateHistogramDotCoefficients(coefficients, vectorSize)
        validateRestriction("histogramDot", sizeX, sizeY, restriction)

        val outputArray = IntArray(256)
        val actualCoefficients = coefficients ?: floatArrayOf(0.299f, 0.587f, 0.114f, 0f)
        nativeHistogramDot(
            nativeHandle,
            inputArray,
            vectorSize,
            sizeX,
            sizeY,
            outputArray,
            actualCoefficients,
            restriction
        )
        return outputArray
    }

    /**
     * Compute the histogram of the dot product of an image.
     *
     * This method supports Bitmaps of config ARGB_8888 and ALPHA_8. For each pixel of the bitmap,
     * the dot product of its bytes with the provided coefficients is computed. The resulting
     * floating point value is converted to an unsigned byte and tallied in the histogram.
     *
     * If coefficients is null, the coefficients used for RGBA luminosity calculation will be used,
     * i.e. the values [0.299f, 0.587f, 0.114f, 0.f].
     *
     * Each coefficients must be >= 0 and their sum must be 1.0 or less. For ARGB_8888, four values
     * must be provided; for ALPHA_8, one.
     *
     * Bitmaps with a stride different than width * vectorSize are not currently supported.
     *
     * A variant of this method is available to do the histogram of a ByteArray.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY.
     *
     * The returned array will have 256 ints.
     *
     * @param inputBitmap The bitmap to be analyzed.
     * @param coefficients The one or four values used for the dot product. Can be null.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The resulting vector of counts.
     */
    @JvmOverloads
    fun histogramDot(
        inputBitmap: Bitmap,
        coefficients: FloatArray? = null,
        restriction: Range2d? = null
    ): IntArray {
        validateBitmap("histogramDot", inputBitmap)
        validateHistogramDotCoefficients(coefficients, vectorSize(inputBitmap))
        validateRestriction("histogramDot", inputBitmap, restriction)

        val outputArray = IntArray(256)
        val actualCoefficients = coefficients ?: floatArrayOf(0.299f, 0.587f, 0.114f, 0f)
        nativeHistogramDotBitmap(
            nativeHandle, inputBitmap, outputArray, actualCoefficients, restriction
        )
        return outputArray
    }

    /**
     * Transform an image using a look up table
     *
     * Transforms an image by using a per-channel lookup table. Each channel of the input has an
     * independent lookup table. The tables are 256 entries in size and can cover the full value
     * range of a byte.
     *
     * The input array should be in RGBA format, where four consecutive bytes form an cell.
     * A variant of this method is available to transform a Bitmap.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output Bitmap will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * The source array should be large enough for sizeX * sizeY * vectorSize bytes. The returned
     * ray has the same dimensions as the input. The arrays have a row-major layout.
     *
     * @param inputArray The buffer of the image to be transformed.
     * @param sizeX The width of both buffers, as a number of 4 byte cells.
     * @param sizeY The height of both buffers, as a number of 4 byte cells.
     * @param table The four arrays of 256 values that's used to convert each channel.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The transformed image.
     */
    @JvmOverloads
    fun lut(
        inputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        table: LookupTable,
        restriction: Range2d? = null
    ): ByteArray {
        require(inputArray.size >= sizeX * sizeY * 4) {
            "$externalName lut. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*4 < ${inputArray.size}."
        }
        validateRestriction("lut", sizeX, sizeY, restriction)

        val outputArray = ByteArray(inputArray.size)
        nativeLut(
            nativeHandle,
            inputArray,
            outputArray,
            sizeX,
            sizeY,
            table.red,
            table.green,
            table.blue,
            table.alpha,
            restriction
        )
        return outputArray
    }

    /**
     * Transform an image using a look up table
     *
     * Transforms an image by using a per-channel lookup table. Each channel of the input has an
     * independent lookup table. The tables are 256 entries in size and can cover the full value
     * range of a byte.
     *
     * The input Bitmap should be in config ARGB_8888. A variant of this method is available to
     * transform a ByteArray. Bitmaps with a stride different than width * vectorSize are not
     * currently supported.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output Bitmap will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * @param inputBitmap The buffer of the image to be transformed.
     * @param table The four arrays of 256 values that's used to convert each channel.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The transformed image.
     */
    @JvmOverloads
    fun lut(
        inputBitmap: Bitmap,
        table: LookupTable,
        restriction: Range2d? = null
    ): Bitmap {
        validateBitmap("lut", inputBitmap)
        validateRestriction("lut", inputBitmap, restriction)

        val outputBitmap = createCompatibleBitmap(inputBitmap)
        nativeLutBitmap(
            nativeHandle,
            inputBitmap,
            outputBitmap,
            table.red,
            table.green,
            table.blue,
            table.alpha,
            restriction
        )
        return outputBitmap
    }

    /**
     * Transform an image using a 3D look up table
     *
     * Transforms an image, converting RGB to RGBA by using a 3D lookup table. The incoming R, G,
     * and B values are normalized to the dimensions of the provided 3D buffer. The eight nearest
     * values in that 3D buffer are sampled and linearly interpolated. The resulting RGBA entry
     * is returned in the output array.
     *
     * The input array should be in RGBA format, where four consecutive bytes form an cell.
     * The fourth byte of each input cell is ignored. A variant of this method is also available
     * to transform Bitmaps.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output array will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * The source array should be large enough for sizeX * sizeY * vectorSize bytes. The returned
     * array will have the same dimensions. The arrays have a row-major layout.
     *
     * @param inputArray The buffer of the image to be transformed.
     * @param sizeX The width of both buffers, as a number of 4 byte cells.
     * @param sizeY The height of both buffers, as a number of 4 byte cells.
     * @param cube The translation cube.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The transformed image.
     */
    @JvmOverloads
    fun lut3d(
        inputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        cube: Rgba3dArray,
        restriction: Range2d? = null
    ): ByteArray {
        require(inputArray.size >= sizeX * sizeY * 4) {
            "$externalName lut3d. inputArray is too small for the given dimensions. " +
                    "$sizeX*$sizeY*4 < ${inputArray.size}."
        }
        require(
            cube.sizeX >= 2 && cube.sizeY >= 2 && cube.sizeZ >= 2 &&
                    cube.sizeX <= 256 && cube.sizeY <= 256 && cube.sizeZ <= 256
        ) {
            "$externalName lut3d. The dimensions of the cube should be between 2 and 256. " +
                    "(${cube.sizeX}, ${cube.sizeY}, ${cube.sizeZ}) provided."
        }
        validateRestriction("lut3d", sizeX, sizeY, restriction)

        val outputArray = ByteArray(inputArray.size)
        nativeLut3d(
            nativeHandle, inputArray, outputArray, sizeX, sizeY, cube.values, cube.sizeX,
            cube.sizeY, cube.sizeZ, restriction
        )
        return outputArray
    }

    /**
     * Transform an image using a 3D look up table
     *
     * Transforms an image, converting RGB to RGBA by using a 3D lookup table. The incoming R, G,
     * and B values are normalized to the dimensions of the provided 3D buffer. The eight nearest
     * values in that 3D buffer are sampled and linearly interpolated. The resulting RGBA entry
     * is returned in the output array.
     *
     * The input bitmap should be in RGBA_8888 format. The A channel is preserved. A variant of this
     * method is also available to transform ByteArray. Bitmaps with a stride different than
     * width * vectorSize are not currently supported.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of each buffer. If provided, the range must be wholly contained with the dimensions
     * described by sizeX and sizeY. NOTE: The output array will still be full size, with the
     * section that's not convolved all set to 0. This is to stay compatible with RenderScript.
     *
     * The source array should be large enough for sizeX * sizeY * vectorSize bytes. The returned
     * array will have the same dimensions. The arrays have a row-major layout.
     *
     * @param inputBitmap The image to be transformed.
     * @param cube The translation cube.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return The transformed image.
     */
    @JvmOverloads
    fun lut3d(
        inputBitmap: Bitmap,
        cube: Rgba3dArray,
        restriction: Range2d? = null
    ): Bitmap {
        validateBitmap("lut3d", inputBitmap)
        validateRestriction("lut3d", inputBitmap, restriction)

        val outputBitmap = createCompatibleBitmap(inputBitmap)
        nativeLut3dBitmap(
            nativeHandle, inputBitmap, outputBitmap, cube.values, cube.sizeX,
            cube.sizeY, cube.sizeZ, restriction
        )
        return outputBitmap
    }

    /**
     * Resize an image.
     *
     * Resizes an image using bicubic interpolation.
     *
     * This method supports elements of 1 to 4 bytes in length. Each byte of the element is
     * interpolated independently from the others.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of the output buffer. The corresponding scaled range of the input will be used. If provided,
     * the range must be wholly contained with the dimensions described by outputSizeX and
     * outputSizeY.
     *
     * The input and output arrays have a row-major layout. The input array should be
     * large enough for sizeX * sizeY * vectorSize bytes.
     *
     * Like the RenderScript Intrinsics, vectorSize of size 3 are padded to occupy 4 bytes.
     *
     * @param inputArray The buffer of the image to be resized.
     * @param vectorSize The number of bytes in each element of both buffers. A value from 1 to 4.
     * @param inputSizeX The width of the input buffer, as a number of 1-4 byte elements.
     * @param inputSizeY The height of the input buffer, as a number of 1-4 byte elements.
     * @param outputSizeX The width of the output buffer, as a number of 1-4 byte elements.
     * @param outputSizeY The height of the output buffer, as a number of 1-4 byte elements.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return An array that contains the rescaled image.
     */
    @JvmOverloads
    fun resize(
        inputArray: ByteArray,
        vectorSize: Int,
        inputSizeX: Int,
        inputSizeY: Int,
        outputSizeX: Int,
        outputSizeY: Int,
        restriction: Range2d? = null
    ): ByteArray {
        require(vectorSize in 1..4) {
            "$externalName resize. The vectorSize should be between 1 and 4. $vectorSize provided."
        }
        require(inputArray.size >= inputSizeX * inputSizeY * vectorSize) {
            "$externalName resize. inputArray is too small for the given dimensions. " +
                    "$inputSizeX*$inputSizeY*$vectorSize < ${inputArray.size}."
        }
        validateRestriction("resize", outputSizeX, outputSizeY, restriction)

        val outputArray = ByteArray(outputSizeX * outputSizeY * paddedSize(vectorSize))
        nativeResize(
            nativeHandle,
            inputArray,
            vectorSize,
            inputSizeX,
            inputSizeY,
            outputArray,
            outputSizeX,
            outputSizeY,
            restriction
        )
        return outputArray
    }

    /**
     * Resize an image.
     *
     * Resizes an image using bicubic interpolation.
     *
     * This method supports input Bitmap of config ARGB_8888 and ALPHA_8. The returned Bitmap
     * has the same config. Bitmaps with a stride different than width * vectorSize are not
     * currently supported.
     *
     * An optional range parameter can be set to restrict the operation to a rectangular subset
     * of the output buffer. The corresponding scaled range of the input will be used. If provided,
     * the range must be wholly contained with the dimensions described by outputSizeX and
     * outputSizeY.
     *
     * @param inputBitmap The Bitmap to be resized.
     * @param outputSizeX The width of the output buffer, as a number of 1-4 byte elements.
     * @param outputSizeY The height of the output buffer, as a number of 1-4 byte elements.
     * @param restriction When not null, restricts the operation to a 2D range of pixels.
     * @return A Bitmap that contains the rescaled image.
     */
    @JvmOverloads
    fun resize(
        inputBitmap: Bitmap,
        outputSizeX: Int,
        outputSizeY: Int,
        restriction: Range2d? = null
    ): Bitmap {
        validateBitmap("resize", inputBitmap)
        validateRestriction("resize", outputSizeX, outputSizeY, restriction)

        val outputBitmap = Bitmap.createBitmap(outputSizeX, outputSizeY, Bitmap.Config.ARGB_8888)
        nativeResizeBitmap(nativeHandle, inputBitmap, outputBitmap, restriction)
        return outputBitmap
    }

    /**
     * Convert an image from YUV to RGB.
     *
     * Converts a YUV buffer to RGB. The input array should be supplied in a supported YUV format.
     * The output is RGBA; the alpha channel will be set to 255.
     *
     * Note that for YV12 and a sizeX that's not a multiple of 32, the RenderScript Intrinsic may
     * not have converted the image correctly. This Toolkit method should.
     *
     * @param inputArray The buffer of the image to be converted.
     * @param sizeX The width in pixels of the image.
     * @param sizeY The height in pixels of the image.
     * @param format Either YV12 or NV21.
     * @return The converted image as a byte array.
     */
    fun yuvToRgb(inputArray: ByteArray, sizeX: Int, sizeY: Int, format: YuvFormat): ByteArray {
        require(sizeX % 2 == 0 && sizeY % 2 == 0) {
            "$externalName yuvToRgb. Non-even dimensions are not supported. " +
                    "$sizeX and $sizeY were provided."
        }

        val outputArray = ByteArray(sizeX * sizeY * 4)
        nativeYuvToRgb(nativeHandle, inputArray, outputArray, sizeX, sizeY, format.value)
        return outputArray
    }

    /**
     * Convert an image from YUV to an RGB Bitmap.
     *
     * Converts a YUV buffer to an RGB Bitmap. The input array should be supplied in a supported
     * YUV format. The output is RGBA; the alpha channel will be set to 255.
     *
     * Note that for YV12 and a sizeX that's not a multiple of 32, the RenderScript Intrinsic may
     * not have converted the image correctly. This Toolkit method should.
     *
     * @param inputArray The buffer of the image to be converted.
     * @param sizeX The width in pixels of the image.
     * @param sizeY The height in pixels of the image.
     * @param format Either YV12 or NV21.
     * @return The converted image.
     */
    fun yuvToRgbBitmap(inputArray: ByteArray, sizeX: Int, sizeY: Int, format: YuvFormat): Bitmap {
        require(sizeX % 2 == 0 && sizeY % 2 == 0) {
            "$externalName yuvToRgbBitmap. Non-even dimensions are not supported. " +
                    "$sizeX and $sizeY were provided."
        }

        val outputBitmap = Bitmap.createBitmap(sizeX, sizeY, Bitmap.Config.ARGB_8888)
        nativeYuvToRgbBitmap(nativeHandle, inputArray, sizeX, sizeY, outputBitmap, format.value)
        return outputBitmap
    }

    init {
        System.loadLibrary("renderscript-toolkit")
        nativeHandle = createNative()
    }

    /**
     * Shutdown the thread pool.
     *
     * Waits for the threads to complete their work and destroys them.
     *
     * An application should call this method only if it is sure that it won't call the
     * toolkit again, as it is irreversible.
     */
    fun shutdown() {
        destroyNative(nativeHandle)
        nativeHandle = 0
    }

    private var nativeHandle: Long = 0

    private external fun createNative(): Long

    private external fun destroyNative(nativeHandle: Long)

    private external fun nativeBlend(
        nativeHandle: Long,
        mode: Int,
        sourceArray: ByteArray,
        destArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        restriction: Range2d?
    )

    private external fun nativeBlendBitmap(
        nativeHandle: Long,
        mode: Int,
        sourceBitmap: Bitmap,
        destBitmap: Bitmap,
        restriction: Range2d?
    )

    private external fun nativeBlur(
        nativeHandle: Long,
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        radius: Int,
        outputArray: ByteArray,
        restriction: Range2d?
    )

    private external fun nativeBlurBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        radius: Int,
        restriction: Range2d?
    )

    private external fun nativeColorMatrix(
        nativeHandle: Long,
        inputArray: ByteArray,
        inputVectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        outputArray: ByteArray,
        outputVectorSize: Int,
        matrix: FloatArray,
        addVector: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeColorMatrixBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        matrix: FloatArray,
        addVector: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeConvolve(
        nativeHandle: Long,
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        outputArray: ByteArray,
        coefficients: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeConvolveBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        coefficients: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeHistogram(
        nativeHandle: Long,
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        outputArray: IntArray,
        restriction: Range2d?
    )

    private external fun nativeHistogramBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputArray: IntArray,
        restriction: Range2d?
    )

    private external fun nativeHistogramDot(
        nativeHandle: Long,
        inputArray: ByteArray,
        vectorSize: Int,
        sizeX: Int,
        sizeY: Int,
        outputArray: IntArray,
        coefficients: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeHistogramDotBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputArray: IntArray,
        coefficients: FloatArray,
        restriction: Range2d?
    )

    private external fun nativeLut(
        nativeHandle: Long,
        inputArray: ByteArray,
        outputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        red: ByteArray,
        green: ByteArray,
        blue: ByteArray,
        alpha: ByteArray,
        restriction: Range2d?
    )

    private external fun nativeLutBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        red: ByteArray,
        green: ByteArray,
        blue: ByteArray,
        alpha: ByteArray,
        restriction: Range2d?
    )

    private external fun nativeLut3d(
        nativeHandle: Long,
        inputArray: ByteArray,
        outputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        cube: ByteArray,
        cubeSizeX: Int,
        cubeSizeY: Int,
        cubeSizeZ: Int,
        restriction: Range2d?
    )

    private external fun nativeLut3dBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        cube: ByteArray,
        cubeSizeX: Int,
        cubeSizeY: Int,
        cubeSizeZ: Int,
        restriction: Range2d?
    )

    private external fun nativeResize(
        nativeHandle: Long,
        inputArray: ByteArray,
        vectorSize: Int,
        inputSizeX: Int,
        inputSizeY: Int,
        outputArray: ByteArray,
        outputSizeX: Int,
        outputSizeY: Int,
        restriction: Range2d?
    )

    private external fun nativeResizeBitmap(
        nativeHandle: Long,
        inputBitmap: Bitmap,
        outputBitmap: Bitmap,
        restriction: Range2d?
    )

    private external fun nativeYuvToRgb(
        nativeHandle: Long,
        inputArray: ByteArray,
        outputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        format: Int
    )

    private external fun nativeYuvToRgbBitmap(
        nativeHandle: Long,
        inputArray: ByteArray,
        sizeX: Int,
        sizeY: Int,
        outputBitmap: Bitmap,
        value: Int
    )
}

/**
 * Determines how a source buffer is blended into a destination buffer.
 * See {@link RenderScriptToolkit::blend}.
 *
 * blend only works on 4 byte RGBA data. In the descriptions below, ".a" represents
 * the alpha channel.
 */
enum class BlendingMode(val value: Int) {
    /**
     * dest = 0
     *
     * The destination is cleared, i.e. each pixel is set to (0, 0, 0, 0)
     */
    CLEAR(0),

    /**
     * dest = src
     *
     * Sets each pixel of the destination to the corresponding one in the source.
     */
    SRC(1),

    /**
     * dest = dest
     *
     * Leaves the destination untouched. This is a no-op.
     */
    DST(2),

    /**
     * dest = src + dest * (1.0 - src.a)
     */
    SRC_OVER(3),

    /**
     * dest = dest + src * (1.0 - dest.a)
     */
    DST_OVER(4),

    /**
     * dest = src * dest.a
     */
    SRC_IN(5),

    /**
     * dest = dest * src.a
     */
    DST_IN(6),

    /**
     * dest = src * (1.0 - dest.a)
     */
    SRC_OUT(7),

    /**
     * dest = dest * (1.0 - src.a)
     */
    DST_OUT(8),

    /**
     * dest.rgb = src.rgb * dest.a + (1.0 - src.a) * dest.rgb, dest.a = dest.a
     */
    SRC_ATOP(9),

    /**
     * dest = dest.rgb * src.a + (1.0 - dest.a) * src.rgb, dest.a = src.a
     */
    DST_ATOP(10),

    /**
     * dest = {src.r ^ dest.r, src.g ^ dest.g, src.b ^ dest.b, src.a ^ dest.a}
     *
     * Note: this is NOT the Porter/Duff XOR mode; this is a bitwise xor.
     */
    XOR(11),

    /**
     * dest = src * dest
     */
    MULTIPLY(12),

    /**
     * dest = min(src + dest, 1.0)
     */
    ADD(13),

    /**
     * dest = max(dest - src, 0.0)
     */
    SUBTRACT(14)
}

/**
 * A translation table used by the lut method. For each potential red, green, blue, and alpha
 * value, specifies it's replacement value.
 *
 * The fields are initialized to be a no-op operation, i.e. replace 1 by 1, 2 by 2, etc.
 * You can modify just the values you're interested in having a translation.
 */
class LookupTable {
    var red = ByteArray(256) { it.toByte() }
    var green = ByteArray(256) { it.toByte() }
    var blue = ByteArray(256) { it.toByte() }
    var alpha = ByteArray(256) { it.toByte() }
}

/**
 * The YUV formats supported by yuvToRgb.
 */
enum class YuvFormat(val value: Int) {
    NV21(0x11),
    YV12(0x32315659),
}

/**
 * Define a range of data to process.
 *
 * This class is used to restrict a [Toolkit] operation to a rectangular subset of the input
 * tensor.
 *
 * @property startX The index of the first value to be included on the X axis.
 * @property endX The index after the last value to be included on the X axis.
 * @property startY The index of the first value to be included on the Y axis.
 * @property endY The index after the last value to be included on the Y axis.
 */
data class Range2d(
    val startX: Int,
    val endX: Int,
    val startY: Int,
    val endY: Int
) {
    constructor() : this(0, 0, 0, 0)
}

class Rgba3dArray(val values: ByteArray, val sizeX: Int, val sizeY: Int, val sizeZ: Int) {
    init {
        require(values.size >= sizeX * sizeY * sizeZ * 4)
    }

    operator fun get(x: Int, y: Int, z: Int): ByteArray {
        val index = indexOfVector(x, y, z)
        return ByteArray(4) { values[index + it] }
    }

    operator fun set(x: Int, y: Int, z: Int, value: ByteArray) {
        require(value.size == 4)
        val index = indexOfVector(x, y, z)
        for (i in 0..3) {
            values[index + i] = value[i]
        }
    }

    private fun indexOfVector(x: Int, y: Int, z: Int): Int {
        require(x in 0 until sizeX)
        require(y in 0 until sizeY)
        require(z in 0 until sizeZ)
        return ((z * sizeY + y) * sizeX + x) * 4
    }
}

internal fun validateBitmap(
    function: String,
    inputBitmap: Bitmap,
    alphaAllowed: Boolean = true
) {
    if (alphaAllowed) {
        require(
            inputBitmap.config == Bitmap.Config.ARGB_8888 ||
                    inputBitmap.config == Bitmap.Config.ALPHA_8
        ) {
            "$externalName. $function supports only ARGB_8888 and ALPHA_8 bitmaps. " +
                    "${inputBitmap.config} provided."
        }
    } else {
        require(inputBitmap.config == Bitmap.Config.ARGB_8888) {
            "$externalName. $function supports only ARGB_8888. " +
                    "${inputBitmap.config} provided."
        }
    }
    require(inputBitmap.width * vectorSize(inputBitmap) == inputBitmap.rowBytes) {
        "$externalName $function. Only bitmaps with rowSize equal to the width * vectorSize are " +
                "currently supported. Provided were rowBytes=${inputBitmap.rowBytes}, " +
                "width={${inputBitmap.width}, and vectorSize=${vectorSize(inputBitmap)}."
    }
}

internal fun createCompatibleBitmap(inputBitmap: Bitmap) =
    Bitmap.createBitmap(inputBitmap.width, inputBitmap.height, inputBitmap.config)

internal fun validateHistogramDotCoefficients(
    coefficients: FloatArray?,
    vectorSize: Int
) {
    require(coefficients == null || coefficients.size == vectorSize) {
        "$externalName histogramDot. The coefficients should be null or have $vectorSize values."
    }
    if (coefficients !== null) {
        var sum = 0f
        for (i in 0 until vectorSize) {
            require(coefficients[i] >= 0.0f) {
                "$externalName histogramDot. Coefficients should not be negative. " +
                        "Coefficient $i was ${coefficients[i]}."
            }
            sum += coefficients[i]
        }
        require(sum <= 1.0f) {
            "$externalName histogramDot. Coefficients should add to 1 or less. Their sum is $sum."
        }
    }
}

internal fun validateRestriction(tag: String, bitmap: Bitmap, restriction: Range2d? = null) {
    validateRestriction(tag, bitmap.width, bitmap.height, restriction)
}

internal fun validateRestriction(
    tag: String,
    sizeX: Int,
    sizeY: Int,
    restriction: Range2d? = null
) {
    if (restriction == null) return
    require(restriction.startX < sizeX && restriction.endX <= sizeX) {
        "$externalName $tag. sizeX should be greater than restriction.startX and greater " +
                "or equal to restriction.endX. $sizeX, ${restriction.startX}, " +
                "and ${restriction.endX} were provided respectively."
    }
    require(restriction.startY < sizeY && restriction.endY <= sizeY) {
        "$externalName $tag. sizeY should be greater than restriction.startY and greater " +
                "or equal to restriction.endY. $sizeY, ${restriction.startY}, " +
                "and ${restriction.endY} were provided respectively."
    }
    require(restriction.startX < restriction.endX) {
        "$externalName $tag. Restriction startX should be less than endX. " +
                "${restriction.startX} and ${restriction.endX} were provided respectively."
    }
    require(restriction.startY < restriction.endY) {
        "$externalName $tag. Restriction startY should be less than endY. " +
                "${restriction.startY} and ${restriction.endY} were provided respectively."
    }
}

internal fun vectorSize(bitmap: Bitmap): Int {
    return when (bitmap.config) {
        Bitmap.Config.ARGB_8888 -> 4
        Bitmap.Config.ALPHA_8 -> 1
        else -> throw IllegalArgumentException(
            "$externalName. Only ARGB_8888 and ALPHA_8 Bitmap are supported."
        )
    }
}

internal fun paddedSize(vectorSize: Int) = if (vectorSize == 3) 4 else vectorSize
