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.ScriptIntrinsicLUT
25 import android.renderscript.Type
26 import android.renderscript.toolkit.Range2d
27 
28 /**
29  * Does a LookUpTable operation using the RenderScript Intrinsics.
30  */
31 @ExperimentalUnsignedTypes
intrinsicLutnull32 fun intrinsicLut(
33     context: RenderScript,
34     inputArray: ByteArray,
35     sizeX: Int,
36     sizeY: Int,
37     newRed: ByteArray,
38     newGreen: ByteArray,
39     newBlue: ByteArray,
40     newAlpha: ByteArray,
41     restriction: Range2d?
42 ): ByteArray {
43     val scriptLut: ScriptIntrinsicLUT = ScriptIntrinsicLUT.create(
44         context,
45         Element.U8_4(context)
46     )
47     val builder = Type.Builder(context, Element.U8_4(context))
48     builder.setX(sizeX)
49     builder.setY(sizeY)
50     val arrayType = builder.create()
51     val inputAllocation = Allocation.createTyped(context, arrayType)
52     val outAllocation = Allocation.createTyped(context, arrayType)
53     inputAllocation.copyFrom(inputArray)
54     val intrinsicOutArray = ByteArray(sizeX * sizeY * 4)
55 
56     for (v in 0..255) {
57         scriptLut.setRed(v, newRed[v].toUByte().toInt())
58         scriptLut.setGreen(v, newGreen[v].toUByte().toInt())
59         scriptLut.setBlue(v, newBlue[v].toUByte().toInt())
60         scriptLut.setAlpha(v, newAlpha[v].toUByte().toInt())
61     }
62     if (restriction != null) {
63         outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
64         val options = Script.LaunchOptions()
65         options.setX(restriction.startX, restriction.endX)
66         options.setY(restriction.startY, restriction.endY)
67         scriptLut.forEach(inputAllocation, outAllocation, options)
68     } else {
69         scriptLut.forEach(inputAllocation, outAllocation)
70     }
71 
72     outAllocation.copyTo(intrinsicOutArray)
73     inputAllocation.destroy()
74     outAllocation.destroy()
75     arrayType.destroy()
76     scriptLut.destroy()
77     return intrinsicOutArray
78 }
79 
80 @ExperimentalUnsignedTypes
intrinsicLutnull81 fun intrinsicLut(
82     context: RenderScript,
83     bitmap: Bitmap,
84     newRed: ByteArray,
85     newGreen: ByteArray,
86     newBlue: ByteArray,
87     newAlpha: ByteArray,
88     restriction: Range2d?
89 ): ByteArray {
90     val baseElement = renderScriptElementForBitmap(context, bitmap)
91     val scriptLut: ScriptIntrinsicLUT = ScriptIntrinsicLUT.create(context, baseElement)
92     val inputAllocation = Allocation.createFromBitmap(context, bitmap)
93     inputAllocation.copyFrom(bitmap)
94     val outAllocation = Allocation.createTyped(context, inputAllocation.type)
95     val intrinsicOutArray = ByteArray(bitmap.byteCount)
96 
97     for (v in 0..255) {
98         scriptLut.setRed(v, newRed[v].toUByte().toInt())
99         scriptLut.setGreen(v, newGreen[v].toUByte().toInt())
100         scriptLut.setBlue(v, newBlue[v].toUByte().toInt())
101         scriptLut.setAlpha(v, newAlpha[v].toUByte().toInt())
102     }
103     if (restriction != null) {
104         outAllocation.copyFrom(intrinsicOutArray) // To initialize to zero
105         val options = Script.LaunchOptions()
106         options.setX(restriction.startX, restriction.endX)
107         options.setY(restriction.startY, restriction.endY)
108         scriptLut.forEach(inputAllocation, outAllocation, options)
109     } else {
110         scriptLut.forEach(inputAllocation, outAllocation)
111     }
112 
113     outAllocation.copyTo(intrinsicOutArray)
114     inputAllocation.destroy()
115     outAllocation.destroy()
116     scriptLut.destroy()
117     return intrinsicOutArray
118 }
119