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 Convolve operation.
23  */
24 @ExperimentalUnsignedTypes
25 fun referenceConvolve(
26     inputArray: ByteArray,
27     vectorSize: Int,
28     sizeX: Int,
29     sizeY: Int,
30     coefficients: FloatArray,
31     restriction: Range2d?
32 ): ByteArray {
33     val input = Vector2dArray(inputArray.asUByteArray(), vectorSize, sizeX, sizeY)
34     val radius = when (coefficients.size) {
35         9 -> 1
36         25 -> 2
37         else -> {
38             throw IllegalArgumentException("RenderScriptToolkit Convolve. Only 3x3 and 5x5 convolutions are supported. ${coefficients.size} coefficients provided.")
39         }
40     }
41 
42     input.clipReadToRange = true
43     val output = input.createSameSized()
44     input.forEach(restriction) { x, y ->
45         output[x, y] = convolveOne(input, x, y, coefficients, radius)
46     }
47     return output.values.asByteArray()
48 }
49 
50 @ExperimentalUnsignedTypes
convolveOnenull51 private fun convolveOne(
52     inputAlloc: Vector2dArray,
53     x: Int,
54     y: Int,
55     coefficients: FloatArray,
56     radius: Int
57 ): UByteArray {
58     var sum = FloatArray(paddedSize(inputAlloc.vectorSize))
59     var coefficientIndex = 0
60     for (deltaY in -radius..radius) {
61         for (deltaX in -radius..radius) {
62             val inputVector = inputAlloc[x + deltaX, y + deltaY]
63             sum += inputVector.toFloatArray() * coefficients[coefficientIndex]
64             coefficientIndex++
65         }
66     }
67     return sum.clampToUByte()
68 }
69