1 /*
2  * Copyright (C) 2012 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 android.renderscript;
18 
19 /**
20  * Intrinsic for applying a color matrix to allocations.
21  *
22  * If the element type is {@link Element.DataType#UNSIGNED_8},
23  * it is converted to {@link Element.DataType#FLOAT_32} and
24  * normalized from (0-255) to (0-1). If the incoming vector size
25  * is less than four, a {@link Element#F32_4} is created by
26  * filling the missing vector channels with zero. This value is
27  * then multiplied by the 4x4 color matrix as performed by
28  * rsMatrixMultiply(), adding a {@link Element#F32_4}, and then
29  * writing it to the output {@link Allocation}.
30  *
31  * If the ouptut type is unsigned, the value is normalized from
32  * (0-1) to (0-255) and converted. If the output vector size is
33  * less than four, the unused channels are discarded.
34  *
35  * Supported elements types are {@link Element#U8}, {@link
36  * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4},
37  * {@link Element#F32}, {@link Element#F32_2}, {@link
38  * Element#F32_3}, and {@link Element#F32_4}.
39  *
40  * @deprecated Renderscript has been deprecated in API level 31. Please refer to the <a
41  * href="https://developer.android.com/guide/topics/renderscript/migration-guide">migration
42  * guide</a> for the proposed alternatives.
43  **/
44 @Deprecated
45 public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic {
46     private final Matrix4f mMatrix = new Matrix4f();
47     private final Float4 mAdd = new Float4();
48 
ScriptIntrinsicColorMatrix(long id, RenderScript rs)49     private ScriptIntrinsicColorMatrix(long id, RenderScript rs) {
50         super(id, rs);
51     }
52 
53     /**
54      * Create an intrinsic for applying a color matrix to an
55      * allocation.
56      *
57      * @param rs The RenderScript context
58      * @param e Element type for inputs and outputs, As of API 19,
59      *          this parameter is ignored. The Element type check is
60      *          performed in the kernel launch.
61      *
62      * @deprecated Use the single argument version as Element is now
63      *             ignored.
64      *
65      * @return ScriptIntrinsicColorMatrix
66      */
67     @Deprecated
create(RenderScript rs, Element e)68     public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) {
69         return create(rs);
70     }
71 
72     /**
73      * Create an intrinsic for applying a color matrix to an
74      * allocation.
75      *
76      * @param rs The RenderScript context
77      *
78      * @return ScriptIntrinsicColorMatrix
79      */
create(RenderScript rs)80     public static ScriptIntrinsicColorMatrix create(RenderScript rs) {
81         long id = rs.nScriptIntrinsicCreate(2, 0);
82         return new ScriptIntrinsicColorMatrix(id, rs);
83 
84     }
85 
setMatrix()86     private void setMatrix() {
87         FieldPacker fp = new FieldPacker(16*4);
88         fp.addMatrix(mMatrix);
89         setVar(0, fp);
90     }
91 
92     /**
93      * Set the color matrix which will be applied to each cell of
94      * the image.
95      *
96      * @param m The 4x4 matrix to set.
97      */
setColorMatrix(Matrix4f m)98     public void setColorMatrix(Matrix4f m) {
99         mMatrix.load(m);
100         setMatrix();
101     }
102 
103     /**
104      * Set the color matrix which will be applied to each cell of the image.
105      * This will set the alpha channel to be a copy.
106      *
107      * @param m The 3x3 matrix to set.
108      */
setColorMatrix(Matrix3f m)109     public void setColorMatrix(Matrix3f m) {
110         mMatrix.load(m);
111         setMatrix();
112     }
113 
114     /**
115      * Set the value to be added after the color matrix has been
116      * applied. The default value is {0, 0, 0, 0}
117      *
118      * @param f The float4 value to be added.
119      */
setAdd(Float4 f)120     public void setAdd(Float4 f) {
121         mAdd.x = f.x;
122         mAdd.y = f.y;
123         mAdd.z = f.z;
124         mAdd.w = f.w;
125 
126         FieldPacker fp = new FieldPacker(4*4);
127         fp.addF32(f.x);
128         fp.addF32(f.y);
129         fp.addF32(f.z);
130         fp.addF32(f.w);
131         setVar(1, fp);
132     }
133 
134     /**
135      * Set the value to be added after the color matrix has been
136      * applied. The default value is {0, 0, 0, 0}
137      *
138      * @param r The red add value.
139      * @param g The green add value.
140      * @param b The blue add value.
141      * @param a The alpha add value.
142      */
setAdd(float r, float g, float b, float a)143     public void setAdd(float r, float g, float b, float a) {
144         mAdd.x = r;
145         mAdd.y = g;
146         mAdd.z = b;
147         mAdd.w = a;
148 
149         FieldPacker fp = new FieldPacker(4*4);
150         fp.addF32(mAdd.x);
151         fp.addF32(mAdd.y);
152         fp.addF32(mAdd.z);
153         fp.addF32(mAdd.w);
154         setVar(1, fp);
155     }
156 
157     /**
158      * Set a color matrix to convert from RGB to luminance. The alpha channel
159      * will be a copy.
160      *
161      */
setGreyscale()162     public void setGreyscale() {
163         mMatrix.loadIdentity();
164         mMatrix.set(0, 0, 0.299f);
165         mMatrix.set(1, 0, 0.587f);
166         mMatrix.set(2, 0, 0.114f);
167         mMatrix.set(0, 1, 0.299f);
168         mMatrix.set(1, 1, 0.587f);
169         mMatrix.set(2, 1, 0.114f);
170         mMatrix.set(0, 2, 0.299f);
171         mMatrix.set(1, 2, 0.587f);
172         mMatrix.set(2, 2, 0.114f);
173         setMatrix();
174     }
175 
176     /**
177      * Set the matrix to convert from YUV to RGB with a direct copy of the 4th
178      * channel.
179      *
180      */
setYUVtoRGB()181     public void setYUVtoRGB() {
182         mMatrix.loadIdentity();
183         mMatrix.set(0, 0, 1.f);
184         mMatrix.set(1, 0, 0.f);
185         mMatrix.set(2, 0, 1.13983f);
186         mMatrix.set(0, 1, 1.f);
187         mMatrix.set(1, 1, -0.39465f);
188         mMatrix.set(2, 1, -0.5806f);
189         mMatrix.set(0, 2, 1.f);
190         mMatrix.set(1, 2, 2.03211f);
191         mMatrix.set(2, 2, 0.f);
192         setMatrix();
193     }
194 
195     /**
196      * Set the matrix to convert from RGB to YUV with a direct copy of the 4th
197      * channel.
198      *
199      */
setRGBtoYUV()200     public void setRGBtoYUV() {
201         mMatrix.loadIdentity();
202         mMatrix.set(0, 0, 0.299f);
203         mMatrix.set(1, 0, 0.587f);
204         mMatrix.set(2, 0, 0.114f);
205         mMatrix.set(0, 1, -0.14713f);
206         mMatrix.set(1, 1, -0.28886f);
207         mMatrix.set(2, 1, 0.436f);
208         mMatrix.set(0, 2, 0.615f);
209         mMatrix.set(1, 2, -0.51499f);
210         mMatrix.set(2, 2, -0.10001f);
211         setMatrix();
212     }
213 
214     /**
215      * Invoke the kernel and apply the matrix to each cell of input
216      * {@link Allocation} and copy to the output {@link Allocation}.
217      *
218      * If the vector size of the input is less than four, the
219      * remaining components are treated as zero for the matrix
220      * multiply.
221      *
222      * If the output vector size is less than four, the unused
223      * vector components are discarded.
224      *
225      *
226      * @param ain Input allocation
227      * @param aout Output allocation
228      */
forEach(Allocation ain, Allocation aout)229     public void forEach(Allocation ain, Allocation aout) {
230         forEach(ain, aout, null);
231     }
232 
233     /**
234      * Invoke the kernel and apply the matrix to each cell of input
235      * {@link Allocation} and copy to the output {@link Allocation}.
236      *
237      * If the vector size of the input is less than four, the
238      * remaining components are treated as zero for the matrix
239      * multiply.
240      *
241      * If the output vector size is less than four, the unused
242      * vector components are discarded.
243      *
244      *
245      * @param ain Input allocation
246      * @param aout Output allocation
247      * @param opt LaunchOptions for clipping
248      */
forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt)249     public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
250         if (!ain.getElement().isCompatible(Element.U8(mRS)) &&
251             !ain.getElement().isCompatible(Element.U8_2(mRS)) &&
252             !ain.getElement().isCompatible(Element.U8_3(mRS)) &&
253             !ain.getElement().isCompatible(Element.U8_4(mRS)) &&
254             !ain.getElement().isCompatible(Element.F32(mRS)) &&
255             !ain.getElement().isCompatible(Element.F32_2(mRS)) &&
256             !ain.getElement().isCompatible(Element.F32_3(mRS)) &&
257             !ain.getElement().isCompatible(Element.F32_4(mRS))) {
258 
259             throw new RSIllegalArgumentException("Unsupported element type.");
260         }
261 
262         if (!aout.getElement().isCompatible(Element.U8(mRS)) &&
263             !aout.getElement().isCompatible(Element.U8_2(mRS)) &&
264             !aout.getElement().isCompatible(Element.U8_3(mRS)) &&
265             !aout.getElement().isCompatible(Element.U8_4(mRS)) &&
266             !aout.getElement().isCompatible(Element.F32(mRS)) &&
267             !aout.getElement().isCompatible(Element.F32_2(mRS)) &&
268             !aout.getElement().isCompatible(Element.F32_3(mRS)) &&
269             !aout.getElement().isCompatible(Element.F32_4(mRS))) {
270 
271             throw new RSIllegalArgumentException("Unsupported element type.");
272         }
273 
274         forEach(0, ain, aout, null, opt);
275     }
276 
277     /**
278      * Get a KernelID for this intrinsic kernel.
279      *
280      * @return Script.KernelID The KernelID object.
281      */
getKernelID()282     public Script.KernelID getKernelID() {
283         return createKernelID(0, 3, null, null);
284     }
285 
286 }
287 
288