1 /*
2  * 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.graphics.Bitmap
20 import android.renderscript.Allocation
21 import android.renderscript.Element
22 import android.renderscript.RenderScript
23 import android.renderscript.Script
24 import android.renderscript.ScriptIntrinsicHistogram
25 import android.renderscript.Type
26 import android.renderscript.toolkit.Range2d
27 
28 /**
29  * Does a Histogram operation using the RenderScript Intrinsics.
30  */
intrinsicHistogramnull31 fun intrinsicHistogram(
32     context: RenderScript,
33     inputArray: ByteArray,
34     vectorSize: Int,
35     sizeX: Int,
36     sizeY: Int,
37     restriction: Range2d?
38 ): IntArray {
39     val element = renderScriptVectorElementForU8(context, vectorSize)
40     val scriptHistogram = ScriptIntrinsicHistogram.create(context, element)
41     val builder = Type.Builder(context, element)
42     builder.setX(sizeX)
43     builder.setY(sizeY)
44     val arrayType = builder.create()
45     val inputAllocation = Allocation.createTyped(context, arrayType)
46     val outAllocation =
47         Allocation.createSized(
48             context,
49             renderScriptVectorElementForI32(context, vectorSize),
50             256
51         )
52     inputAllocation.copyFrom(inputArray)
53     scriptHistogram.setOutput(outAllocation)
54     if (restriction != null) {
55         val options = Script.LaunchOptions()
56         options.setX(restriction.startX, restriction.endX)
57         options.setY(restriction.startY, restriction.endY)
58         scriptHistogram.forEach(inputAllocation, options)
59     } else {
60         scriptHistogram.forEach(inputAllocation)
61     }
62 
63     val intrinsicOutArray = IntArray(256 * paddedSize(vectorSize))
64     outAllocation.copyTo(intrinsicOutArray)
65     inputAllocation.destroy()
66     outAllocation.destroy()
67     arrayType.destroy()
68     scriptHistogram.destroy()
69     return intrinsicOutArray
70 }
71 
intrinsicHistogramnull72 fun intrinsicHistogram(
73     context: RenderScript,
74     bitmap: Bitmap,
75     restriction: Range2d?
76 ): IntArray {
77     val baseElement = renderScriptElementForBitmap(context, bitmap)
78     val scriptHistogram = ScriptIntrinsicHistogram.create(context, baseElement)
79     val inputAllocation = Allocation.createFromBitmap(context, bitmap)
80     inputAllocation.copyFrom(bitmap)
81     val vectorSize = vectorSizeOfBitmap(bitmap)
82     val outAllocation =
83         Allocation.createSized(
84             context,
85             renderScriptVectorElementForI32(context, vectorSize),
86             256
87         )
88     scriptHistogram.setOutput(outAllocation)
89     if (restriction != null) {
90         val options = Script.LaunchOptions()
91         options.setX(restriction.startX, restriction.endX)
92         options.setY(restriction.startY, restriction.endY)
93         scriptHistogram.forEach(inputAllocation, options)
94     } else {
95         scriptHistogram.forEach(inputAllocation)
96     }
97 
98     val intrinsicOutArray = IntArray(256 * vectorSize)
99     outAllocation.copyTo(intrinsicOutArray)
100     inputAllocation.destroy()
101     outAllocation.destroy()
102     scriptHistogram.destroy()
103     return intrinsicOutArray
104 }
105 
intrinsicHistogramDotnull106 fun intrinsicHistogramDot(
107     context: RenderScript,
108     inputArray: ByteArray,
109     vectorSize: Int,
110     sizeX: Int,
111     sizeY: Int,
112     coefficients: FloatArray?,
113     restriction: Range2d?
114 ): IntArray {
115     val element = renderScriptVectorElementForU8(context, vectorSize)
116     val scriptHistogram = ScriptIntrinsicHistogram.create(context, element)
117     val builder = Type.Builder(context, element)
118     builder.setX(sizeX)
119     builder.setY(sizeY)
120     val arrayType = builder.create()
121     val inputAllocation = Allocation.createTyped(context, arrayType)
122     val outAllocation =
123         Allocation.createSized(context, Element.I32(context), 256)
124     inputAllocation.copyFrom(inputArray)
125 
126     if (coefficients != null) {
127         require(coefficients.size == vectorSize) {
128             "RenderScriptToolkit tests. $vectorSize coefficients are required for histogram. " +
129                 "${coefficients.size} provided."
130         }
131         scriptHistogram.setDotCoefficients(
132             coefficients[0],
133             if (vectorSize > 1) coefficients[1] else 0f,
134             if (vectorSize > 2) coefficients[2] else 0f,
135             if (vectorSize > 3) coefficients[3] else 0f
136         )
137     }
138     scriptHistogram.setOutput(outAllocation)
139     if (restriction != null) {
140         val options = Script.LaunchOptions()
141         options.setX(restriction.startX, restriction.endX)
142         options.setY(restriction.startY, restriction.endY)
143         scriptHistogram.forEach_Dot(inputAllocation, options)
144     } else {
145         scriptHistogram.forEach_Dot(inputAllocation)
146     }
147     val intrinsicOutArray = IntArray(256)
148     outAllocation.copyTo(intrinsicOutArray)
149     inputAllocation.destroy()
150     outAllocation.destroy()
151     arrayType.destroy()
152     scriptHistogram.destroy()
153     return intrinsicOutArray
154 }
155 
intrinsicHistogramDotnull156 fun intrinsicHistogramDot(
157     context: RenderScript,
158     bitmap: Bitmap,
159     coefficients: FloatArray?,
160     restriction: Range2d?
161 ): IntArray {
162     val baseElement = renderScriptElementForBitmap(context, bitmap)
163     val scriptHistogram = ScriptIntrinsicHistogram.create(context, baseElement)
164     val inputAllocation = Allocation.createFromBitmap(context, bitmap)
165     inputAllocation.copyFrom(bitmap)
166     val outAllocation =
167         Allocation.createSized(context, Element.I32(context), 256)
168 
169     if (coefficients != null) {
170         require(coefficients.size == 4) {
171             "RenderScriptToolkit tests. Four coefficients are required for histogram. " +
172                 "${coefficients.size} provided."
173         }
174         scriptHistogram.setDotCoefficients(
175             coefficients[0],
176             coefficients[1],
177             coefficients[2],
178             coefficients[3]
179         )
180     }
181     scriptHistogram.setOutput(outAllocation)
182     if (restriction != null) {
183         val options = Script.LaunchOptions()
184         options.setX(restriction.startX, restriction.endX)
185         options.setY(restriction.startY, restriction.endY)
186         scriptHistogram.forEach_Dot(inputAllocation, options)
187     } else {
188         scriptHistogram.forEach_Dot(inputAllocation)
189     }
190     val intrinsicOutArray = IntArray(256)
191     outAllocation.copyTo(intrinsicOutArray)
192     inputAllocation.destroy()
193     outAllocation.destroy()
194     scriptHistogram.destroy()
195     return intrinsicOutArray
196 }
197