1*e1eccf28SAndroid Build Coastguard Worker /*
<lambda>null2*e1eccf28SAndroid Build Coastguard Worker * Copyright (C) 2021 The Android Open Source Project
3*e1eccf28SAndroid Build Coastguard Worker *
4*e1eccf28SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*e1eccf28SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*e1eccf28SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*e1eccf28SAndroid Build Coastguard Worker *
8*e1eccf28SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*e1eccf28SAndroid Build Coastguard Worker *
10*e1eccf28SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*e1eccf28SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*e1eccf28SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*e1eccf28SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*e1eccf28SAndroid Build Coastguard Worker * limitations under the License.
15*e1eccf28SAndroid Build Coastguard Worker */
16*e1eccf28SAndroid Build Coastguard Worker
17*e1eccf28SAndroid Build Coastguard Worker package com.example.testapp
18*e1eccf28SAndroid Build Coastguard Worker
19*e1eccf28SAndroid Build Coastguard Worker import android.renderscript.toolkit.BlendingMode
20*e1eccf28SAndroid Build Coastguard Worker import android.renderscript.toolkit.Range2d
21*e1eccf28SAndroid Build Coastguard Worker
22*e1eccf28SAndroid Build Coastguard Worker /**
23*e1eccf28SAndroid Build Coastguard Worker * Reference implementation of a Blend operation.
24*e1eccf28SAndroid Build Coastguard Worker *
25*e1eccf28SAndroid Build Coastguard Worker * See the class Rgba for details of arithmetic operation using that class.
26*e1eccf28SAndroid Build Coastguard Worker */
27*e1eccf28SAndroid Build Coastguard Worker @ExperimentalUnsignedTypes
28*e1eccf28SAndroid Build Coastguard Worker fun referenceBlend(
29*e1eccf28SAndroid Build Coastguard Worker mode: BlendingMode,
30*e1eccf28SAndroid Build Coastguard Worker sourceArray: ByteArray,
31*e1eccf28SAndroid Build Coastguard Worker destArray: ByteArray,
32*e1eccf28SAndroid Build Coastguard Worker sizeX: Int,
33*e1eccf28SAndroid Build Coastguard Worker sizeY: Int,
34*e1eccf28SAndroid Build Coastguard Worker restriction: Range2d?
35*e1eccf28SAndroid Build Coastguard Worker ) {
36*e1eccf28SAndroid Build Coastguard Worker val source = Rgba2dArray(sourceArray, sizeX, sizeY)
37*e1eccf28SAndroid Build Coastguard Worker val dest = Rgba2dArray(destArray, sizeX, sizeY)
38*e1eccf28SAndroid Build Coastguard Worker
39*e1eccf28SAndroid Build Coastguard Worker /**
40*e1eccf28SAndroid Build Coastguard Worker * For each corresponding RGBA value of the source and destination arrays, invoke the blend
41*e1eccf28SAndroid Build Coastguard Worker * function and store the result in the destination array.
42*e1eccf28SAndroid Build Coastguard Worker */
43*e1eccf28SAndroid Build Coastguard Worker fun blendEachPair(blendFunction: (src: Rgba, dst: Rgba) -> Rgba) {
44*e1eccf28SAndroid Build Coastguard Worker dest.forEachCell(restriction) { x, y ->
45*e1eccf28SAndroid Build Coastguard Worker dest[x, y] = blendFunction(source[x, y], dest[x, y])
46*e1eccf28SAndroid Build Coastguard Worker }
47*e1eccf28SAndroid Build Coastguard Worker }
48*e1eccf28SAndroid Build Coastguard Worker
49*e1eccf28SAndroid Build Coastguard Worker when (mode) {
50*e1eccf28SAndroid Build Coastguard Worker BlendingMode.CLEAR -> blendEachPair { _, _ -> Rgba(0, 0, 0, 0) }
51*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SRC -> blendEachPair { src, _ -> src }
52*e1eccf28SAndroid Build Coastguard Worker BlendingMode.DST -> { /* This doesn't do anything. */ }
53*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SRC_OVER -> blendEachPair { src, dst -> blendOver(src, dst) }
54*e1eccf28SAndroid Build Coastguard Worker BlendingMode.DST_OVER -> blendEachPair { src, dst -> blendOver(dst, src) }
55*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SRC_IN -> blendEachPair { src, dst -> blendIn(src, dst) }
56*e1eccf28SAndroid Build Coastguard Worker BlendingMode.DST_IN -> blendEachPair { src, dst -> blendIn(dst, src) }
57*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SRC_OUT -> blendEachPair { src, dst -> blendOut(src, dst) }
58*e1eccf28SAndroid Build Coastguard Worker BlendingMode.DST_OUT -> blendEachPair { src, dst -> blendOut(dst, src) }
59*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SRC_ATOP -> blendEachPair { src, dst -> blendAtop(src, dst) }
60*e1eccf28SAndroid Build Coastguard Worker BlendingMode.DST_ATOP -> blendEachPair { src, dst -> blendAtop(dst, src) }
61*e1eccf28SAndroid Build Coastguard Worker BlendingMode.XOR -> blendEachPair { src, dst -> src xor dst }
62*e1eccf28SAndroid Build Coastguard Worker BlendingMode.MULTIPLY -> blendEachPair { src, dst -> src * dst }
63*e1eccf28SAndroid Build Coastguard Worker BlendingMode.ADD -> blendEachPair { src, dst -> dst + src }
64*e1eccf28SAndroid Build Coastguard Worker BlendingMode.SUBTRACT -> blendEachPair { src, dst -> dst - src }
65*e1eccf28SAndroid Build Coastguard Worker }
66*e1eccf28SAndroid Build Coastguard Worker }
67*e1eccf28SAndroid Build Coastguard Worker
68*e1eccf28SAndroid Build Coastguard Worker @ExperimentalUnsignedTypes
blendOvernull69*e1eccf28SAndroid Build Coastguard Worker private fun blendOver(src: Rgba, dst: Rgba) = src + (dst * (255 - src.a))
70*e1eccf28SAndroid Build Coastguard Worker
71*e1eccf28SAndroid Build Coastguard Worker @ExperimentalUnsignedTypes
72*e1eccf28SAndroid Build Coastguard Worker private fun blendIn(src: Rgba, dst: Rgba) = src * dst.a
73*e1eccf28SAndroid Build Coastguard Worker
74*e1eccf28SAndroid Build Coastguard Worker @ExperimentalUnsignedTypes
75*e1eccf28SAndroid Build Coastguard Worker private fun blendOut(src: Rgba, dst: Rgba) = src * (255 - dst.a)
76*e1eccf28SAndroid Build Coastguard Worker
77*e1eccf28SAndroid Build Coastguard Worker @ExperimentalUnsignedTypes
78*e1eccf28SAndroid Build Coastguard Worker private fun blendAtop(src: Rgba, dst: Rgba): Rgba {
79*e1eccf28SAndroid Build Coastguard Worker val value = src * dst.a + dst * (255 - src.a)
80*e1eccf28SAndroid Build Coastguard Worker value.a = dst.a
81*e1eccf28SAndroid Build Coastguard Worker return value
82*e1eccf28SAndroid Build Coastguard Worker }
83