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.ScriptIntrinsicBlend
25 import android.renderscript.Type
26 import android.renderscript.toolkit.BlendingMode
27 import android.renderscript.toolkit.Range2d
28 
29 /**
30  * Does a Blend operation using the RenderScript Intrinsics.
31  */
intrinsicBlendnull32 fun intrinsicBlend(
33     context: RenderScript,
34     mode: BlendingMode,
35     sourceArray: ByteArray,
36     destArray: ByteArray,
37     sizeX: Int,
38     sizeY: Int,
39     restriction: Range2d?
40 ) {
41     val scriptBlend = ScriptIntrinsicBlend.create(context, Element.U8_4(context))
42     val builder = Type.Builder(context, Element.U8_4(context))
43     builder.setX(sizeX)
44     builder.setY(sizeY)
45     val arrayType = builder.create()
46     val sourceAllocation = Allocation.createTyped(context, arrayType)
47     val destAllocation = Allocation.createTyped(context, arrayType)
48     sourceAllocation.copyFrom(sourceArray)
49     destAllocation.copyFrom(destArray)
50 
51     callBlendForEach(scriptBlend, sourceAllocation, destAllocation, mode, restriction)
52     destAllocation.copyTo(destArray)
53 
54     sourceAllocation.destroy()
55     destAllocation.destroy()
56     arrayType.destroy()
57     scriptBlend.destroy()
58 }
59 
intrinsicBlendnull60 fun intrinsicBlend(
61     context: RenderScript,
62     mode: BlendingMode,
63     sourceBitmap: Bitmap,
64     destBitmap: Bitmap,
65     restriction: Range2d?
66 ) {
67     val scriptBlend = ScriptIntrinsicBlend.create(context, Element.U8_4(context))
68     val sourceAllocation = Allocation.createFromBitmap(context, sourceBitmap)
69     val destAllocation = Allocation.createFromBitmap(context, destBitmap)
70     sourceAllocation.copyFrom(sourceBitmap)
71     destAllocation.copyFrom(destBitmap)
72 
73     callBlendForEach(scriptBlend, sourceAllocation, destAllocation, mode, restriction)
74     destAllocation.copyTo(destBitmap)
75 
76     sourceAllocation.destroy()
77     destAllocation.destroy()
78     scriptBlend.destroy()
79 }
80 
callBlendForEachnull81 private fun callBlendForEach(
82     scriptBlend: ScriptIntrinsicBlend,
83     sourceAllocation: Allocation,
84     destAllocation: Allocation,
85     mode: BlendingMode,
86     restriction: Range2d?
87 ) {
88     if (restriction != null) {
89         val options = Script.LaunchOptions()
90         options.setX(restriction.startX, restriction.endX)
91         options.setY(restriction.startY, restriction.endY)
92         when (mode) {
93             BlendingMode.CLEAR -> scriptBlend.forEachClear(
94                 sourceAllocation, destAllocation, options
95             )
96             BlendingMode.SRC -> scriptBlend.forEachSrc(
97                 sourceAllocation, destAllocation, options
98             )
99             BlendingMode.DST -> scriptBlend.forEachDst(
100                 sourceAllocation, destAllocation, options
101             )
102             BlendingMode.SRC_OVER -> scriptBlend.forEachSrcOver(
103                 sourceAllocation, destAllocation, options
104             )
105             BlendingMode.DST_OVER -> scriptBlend.forEachDstOver(
106                 sourceAllocation, destAllocation, options
107             )
108             BlendingMode.SRC_IN -> scriptBlend.forEachSrcIn(
109                 sourceAllocation, destAllocation, options
110             )
111             BlendingMode.DST_IN -> scriptBlend.forEachDstIn(
112                 sourceAllocation, destAllocation, options
113             )
114             BlendingMode.SRC_OUT -> scriptBlend.forEachSrcOut(
115                 sourceAllocation, destAllocation, options
116             )
117             BlendingMode.DST_OUT -> scriptBlend.forEachDstOut(
118                 sourceAllocation, destAllocation, options
119             )
120             BlendingMode.SRC_ATOP -> scriptBlend.forEachSrcAtop(
121                 sourceAllocation, destAllocation, options
122             )
123             BlendingMode.DST_ATOP -> scriptBlend.forEachDstAtop(
124                 sourceAllocation, destAllocation, options
125             )
126             BlendingMode.XOR -> scriptBlend.forEachXor(
127                 sourceAllocation, destAllocation, options
128             )
129             BlendingMode.MULTIPLY -> scriptBlend.forEachMultiply(
130                 sourceAllocation, destAllocation, options
131             )
132             BlendingMode.ADD -> scriptBlend.forEachAdd(
133                 sourceAllocation, destAllocation, options
134             )
135             BlendingMode.SUBTRACT -> scriptBlend.forEachSubtract(
136                 sourceAllocation, destAllocation, options
137             )
138         }
139     } else {
140         when (mode) {
141             BlendingMode.CLEAR -> scriptBlend.forEachClear(
142                 sourceAllocation, destAllocation
143             )
144             BlendingMode.SRC -> scriptBlend.forEachSrc(
145                 sourceAllocation, destAllocation
146             )
147             BlendingMode.DST -> scriptBlend.forEachDst(
148                 sourceAllocation, destAllocation
149             )
150             BlendingMode.SRC_OVER -> scriptBlend.forEachSrcOver(
151                 sourceAllocation, destAllocation
152             )
153             BlendingMode.DST_OVER -> scriptBlend.forEachDstOver(
154                 sourceAllocation, destAllocation
155             )
156             BlendingMode.SRC_IN -> scriptBlend.forEachSrcIn(
157                 sourceAllocation, destAllocation
158             )
159             BlendingMode.DST_IN -> scriptBlend.forEachDstIn(
160                 sourceAllocation, destAllocation
161             )
162             BlendingMode.SRC_OUT -> scriptBlend.forEachSrcOut(
163                 sourceAllocation, destAllocation
164             )
165             BlendingMode.DST_OUT -> scriptBlend.forEachDstOut(
166                 sourceAllocation, destAllocation
167             )
168             BlendingMode.SRC_ATOP -> scriptBlend.forEachSrcAtop(
169                 sourceAllocation, destAllocation
170             )
171             BlendingMode.DST_ATOP -> scriptBlend.forEachDstAtop(
172                 sourceAllocation, destAllocation
173             )
174             BlendingMode.XOR -> scriptBlend.forEachXor(
175                 sourceAllocation, destAllocation
176             )
177             BlendingMode.MULTIPLY -> scriptBlend.forEachMultiply(
178                 sourceAllocation, destAllocation
179             )
180             BlendingMode.ADD -> scriptBlend.forEachAdd(
181                 sourceAllocation, destAllocation
182             )
183             BlendingMode.SUBTRACT -> scriptBlend.forEachSubtract(
184                 sourceAllocation, destAllocation
185             )
186         }
187     }
188 }
189