1 /*
<lambda>null2 * Copyright (C) 2021 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 package com.example.testapp
18
19 import android.renderscript.toolkit.Range2d
20
21 /**
22 * Reference implementation of a Histogram operation.
23 *
24 * Return an array of 4 * 256 ints.
25 * Position 0 is the number of R with a value of 0,
26 * Position 1 is the number of G with a value of 0,
27 * Position 2 is the number of B with a value of 0,
28 * Position 3 is the number of A with a value of 0,
29 * Position 4 is the number of R with a value of 1,
30 * etc.
31 */
32 @ExperimentalUnsignedTypes
33 fun referenceHistogram(
34 inputArray: ByteArray,
35 vectorSize: Int,
36 sizeX: Int,
37 sizeY: Int,
38 restriction: Range2d?
39 ): IntArray {
40 val input = Vector2dArray(inputArray.asUByteArray(), vectorSize, sizeX, sizeY)
41
42 val counts = IntArray(paddedSize(input.vectorSize) * 256)
43 input.forEach(restriction) { x, y ->
44 val value = input[x, y]
45 for (i in 0 until vectorSize) {
46 counts[value[i].toInt() * paddedSize(input.vectorSize) + i]++
47 }
48 }
49 return counts
50 }
51
52 /**
53 * Reference implementation of a HistogramDot operation.
54 *
55 * Each RGBA input value is dot-multiplied first by the specified coefficients.
56 * The resulting value is converted to an integer and used for the histogram.
57 */
58 @ExperimentalUnsignedTypes
referenceHistogramDotnull59 fun referenceHistogramDot(
60 inputArray: ByteArray,
61 vectorSize: Int,
62 sizeX: Int,
63 sizeY: Int,
64 coefficients: FloatArray?,
65 restriction: Range2d?
66 ): IntArray {
67 val floatCoefficients = coefficients ?: floatArrayOf(0.299f, 0.587f, 0.114f, 0f)
68 val input = Vector2dArray(inputArray.asUByteArray(), vectorSize, sizeX, sizeY)
69 var coefficientSum = 0f
70 for (c in floatCoefficients) {
71 require (c >= 0) {
72 "RenderScriptToolkit histogramDot. Coefficients must be positive. $c provided."
73 }
74 coefficientSum += c
75 }
76 require(coefficientSum <= 1f) { "RenderScriptToolkit histogramDot. Coefficients should " +
77 "add to 1.0 or less. $coefficientSum provided." }
78
79 // Compute integer
80 val intCoefficients = IntArray(input.vectorSize) { (floatCoefficients[it] * 256f + 0.5f).toInt() }
81
82 val counts = IntArray(256)
83 input.forEach(restriction) { x, y ->
84 val value = input[x, y]
85 // While we could do the computation using floats, we won't get the same results as
86 // the existing intrinsics.
87 var sum = 0
88 // We don't use value.indices because we want to accumulate only 3 values, in the case
89 // of vectorSize == 3.
90 for (i in 0 until vectorSize) {
91 sum += intCoefficients[i] * value[i].toInt()
92 }
93 // Round up and normalize
94 val index = (sum + 0x7f) shr 8
95 counts[index]++
96 }
97 return counts
98 }
99