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.ScriptIntrinsicConvolve3x3
25 import android.renderscript.ScriptIntrinsicConvolve5x5
26 import android.renderscript.Type
27 import android.renderscript.toolkit.Range2d
28
29 /**
30 * Does a Convolve operation using the RenderScript Intrinsics.
31 */
intrinsicConvolvenull32 fun intrinsicConvolve(
33 context: RenderScript,
34 inputArray: ByteArray,
35 vectorSize: Int,
36 sizeX: Int,
37 sizeY: Int,
38 coefficients: FloatArray,
39 restriction: Range2d?
40 ): ByteArray {
41 val baseElement = renderScriptVectorElementForU8(context, vectorSize)
42 val builder = Type.Builder(context, baseElement)
43 builder.setX(sizeX)
44 builder.setY(sizeY)
45 val arrayType = builder.create()
46 val inputAllocation = Allocation.createTyped(context, arrayType)
47 val outAllocation = Allocation.createTyped(context, arrayType)
48 inputAllocation.copyFrom(inputArray)
49 val intrinsicOutArray = ByteArray(sizeX * sizeY * paddedSize(vectorSize))
50 if (restriction != null) {
51 outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
52 }
53 invokeConvolveKernel(
54 coefficients,
55 context,
56 baseElement,
57 inputAllocation,
58 restriction,
59 outAllocation
60 )
61 outAllocation.copyTo(intrinsicOutArray)
62 inputAllocation.destroy()
63 outAllocation.destroy()
64 arrayType.destroy()
65 return intrinsicOutArray
66 }
67
intrinsicConvolvenull68 fun intrinsicConvolve(
69 context: RenderScript,
70 bitmap: Bitmap,
71 coefficients: FloatArray,
72 restriction: Range2d?
73 ): ByteArray {
74 val baseElement = renderScriptElementForBitmap(context, bitmap)
75
76 val inputAllocation = Allocation.createFromBitmap(context, bitmap)
77 val outAllocation = Allocation.createTyped(context, inputAllocation.type)
78 val intrinsicOutArray = ByteArray(bitmap.byteCount)
79 inputAllocation.copyFrom(bitmap)
80 if (restriction != null) {
81 outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
82 }
83 invokeConvolveKernel(
84 coefficients,
85 context,
86 baseElement,
87 inputAllocation,
88 restriction,
89 outAllocation
90 )
91 outAllocation.copyTo(intrinsicOutArray)
92 inputAllocation.destroy()
93 outAllocation.destroy()
94 return intrinsicOutArray
95 }
96
invokeConvolveKernelnull97 private fun invokeConvolveKernel(
98 coefficients: FloatArray,
99 context: RenderScript,
100 baseElement: Element,
101 inputAllocation: Allocation?,
102 restriction: Range2d?,
103 outAllocation: Allocation?
104 ) {
105 when (coefficients.size) {
106 9 -> {
107 val scriptConvolve3x3 =
108 ScriptIntrinsicConvolve3x3.create(context, baseElement)
109 scriptConvolve3x3.setCoefficients(coefficients)
110 scriptConvolve3x3.setInput(inputAllocation)
111 if (restriction != null) {
112 val options = Script.LaunchOptions()
113 options.setX(restriction.startX, restriction.endX)
114 options.setY(restriction.startY, restriction.endY)
115 scriptConvolve3x3.forEach(outAllocation, options)
116 } else {
117 scriptConvolve3x3.forEach(outAllocation)
118 }
119 scriptConvolve3x3.destroy()
120 }
121 25 -> {
122 val scriptConvolve5x5 =
123 ScriptIntrinsicConvolve5x5.create(context, baseElement)
124 scriptConvolve5x5.setCoefficients(coefficients)
125 scriptConvolve5x5.setInput(inputAllocation)
126 if (restriction != null) {
127 val options = Script.LaunchOptions()
128 options.setX(restriction.startX, restriction.endX)
129 options.setY(restriction.startY, restriction.endY)
130 scriptConvolve5x5.forEach(outAllocation, options)
131 } else {
132 scriptConvolve5x5.forEach(outAllocation)
133 }
134 scriptConvolve5x5.destroy()
135 }
136 else -> {
137 throw IllegalArgumentException("RenderScriptToolkit tests. Only 3x3 and 5x5 convolutions are supported. ${coefficients.size} coefficients provided.")
138 }
139 }
140 }
141