/* * 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.graphics.Bitmap import android.renderscript.Allocation import android.renderscript.Element import android.renderscript.RenderScript import android.renderscript.Script import android.renderscript.ScriptIntrinsicConvolve3x3 import android.renderscript.ScriptIntrinsicConvolve5x5 import android.renderscript.Type import android.renderscript.toolkit.Range2d /** * Does a Convolve operation using the RenderScript Intrinsics. */ fun intrinsicConvolve( context: RenderScript, inputArray: ByteArray, vectorSize: Int, sizeX: Int, sizeY: Int, coefficients: FloatArray, restriction: Range2d? ): ByteArray { val baseElement = renderScriptVectorElementForU8(context, vectorSize) val builder = Type.Builder(context, baseElement) builder.setX(sizeX) builder.setY(sizeY) val arrayType = builder.create() val inputAllocation = Allocation.createTyped(context, arrayType) val outAllocation = Allocation.createTyped(context, arrayType) inputAllocation.copyFrom(inputArray) val intrinsicOutArray = ByteArray(sizeX * sizeY * paddedSize(vectorSize)) if (restriction != null) { outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero } invokeConvolveKernel( coefficients, context, baseElement, inputAllocation, restriction, outAllocation ) outAllocation.copyTo(intrinsicOutArray) inputAllocation.destroy() outAllocation.destroy() arrayType.destroy() return intrinsicOutArray } fun intrinsicConvolve( context: RenderScript, bitmap: Bitmap, coefficients: FloatArray, restriction: Range2d? ): ByteArray { val baseElement = renderScriptElementForBitmap(context, bitmap) val inputAllocation = Allocation.createFromBitmap(context, bitmap) val outAllocation = Allocation.createTyped(context, inputAllocation.type) val intrinsicOutArray = ByteArray(bitmap.byteCount) inputAllocation.copyFrom(bitmap) if (restriction != null) { outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero } invokeConvolveKernel( coefficients, context, baseElement, inputAllocation, restriction, outAllocation ) outAllocation.copyTo(intrinsicOutArray) inputAllocation.destroy() outAllocation.destroy() return intrinsicOutArray } private fun invokeConvolveKernel( coefficients: FloatArray, context: RenderScript, baseElement: Element, inputAllocation: Allocation?, restriction: Range2d?, outAllocation: Allocation? ) { when (coefficients.size) { 9 -> { val scriptConvolve3x3 = ScriptIntrinsicConvolve3x3.create(context, baseElement) scriptConvolve3x3.setCoefficients(coefficients) scriptConvolve3x3.setInput(inputAllocation) if (restriction != null) { val options = Script.LaunchOptions() options.setX(restriction.startX, restriction.endX) options.setY(restriction.startY, restriction.endY) scriptConvolve3x3.forEach(outAllocation, options) } else { scriptConvolve3x3.forEach(outAllocation) } scriptConvolve3x3.destroy() } 25 -> { val scriptConvolve5x5 = ScriptIntrinsicConvolve5x5.create(context, baseElement) scriptConvolve5x5.setCoefficients(coefficients) scriptConvolve5x5.setInput(inputAllocation) if (restriction != null) { val options = Script.LaunchOptions() options.setX(restriction.startX, restriction.endX) options.setY(restriction.startY, restriction.endY) scriptConvolve5x5.forEach(outAllocation, options) } else { scriptConvolve5x5.forEach(outAllocation) } scriptConvolve5x5.destroy() } else -> { throw IllegalArgumentException("RenderScriptToolkit tests. Only 3x3 and 5x5 convolutions are supported. ${coefficients.size} coefficients provided.") } } }