/* * 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.Range2d /** * Reference implementation of a Histogram operation. * * Return an array of 4 * 256 ints. * Position 0 is the number of R with a value of 0, * Position 1 is the number of G with a value of 0, * Position 2 is the number of B with a value of 0, * Position 3 is the number of A with a value of 0, * Position 4 is the number of R with a value of 1, * etc. */ @ExperimentalUnsignedTypes fun referenceHistogram( inputArray: ByteArray, vectorSize: Int, sizeX: Int, sizeY: Int, restriction: Range2d? ): IntArray { val input = Vector2dArray(inputArray.asUByteArray(), vectorSize, sizeX, sizeY) val counts = IntArray(paddedSize(input.vectorSize) * 256) input.forEach(restriction) { x, y -> val value = input[x, y] for (i in 0 until vectorSize) { counts[value[i].toInt() * paddedSize(input.vectorSize) + i]++ } } return counts } /** * Reference implementation of a HistogramDot operation. * * Each RGBA input value is dot-multiplied first by the specified coefficients. * The resulting value is converted to an integer and used for the histogram. */ @ExperimentalUnsignedTypes fun referenceHistogramDot( inputArray: ByteArray, vectorSize: Int, sizeX: Int, sizeY: Int, coefficients: FloatArray?, restriction: Range2d? ): IntArray { val floatCoefficients = coefficients ?: floatArrayOf(0.299f, 0.587f, 0.114f, 0f) val input = Vector2dArray(inputArray.asUByteArray(), vectorSize, sizeX, sizeY) var coefficientSum = 0f for (c in floatCoefficients) { require (c >= 0) { "RenderScriptToolkit histogramDot. Coefficients must be positive. $c provided." } coefficientSum += c } require(coefficientSum <= 1f) { "RenderScriptToolkit histogramDot. Coefficients should " + "add to 1.0 or less. $coefficientSum provided." } // Compute integer val intCoefficients = IntArray(input.vectorSize) { (floatCoefficients[it] * 256f + 0.5f).toInt() } val counts = IntArray(256) input.forEach(restriction) { x, y -> val value = input[x, y] // While we could do the computation using floats, we won't get the same results as // the existing intrinsics. var sum = 0 // We don't use value.indices because we want to accumulate only 3 values, in the case // of vectorSize == 3. for (i in 0 until vectorSize) { sum += intCoefficients[i] * value[i].toInt() } // Round up and normalize val index = (sum + 0x7f) shr 8 counts[index]++ } return counts }