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 per-channel lookup table. Each
21  * channel of the input has an independant lookup table. The
22  * tables are 256 entries in size and can cover the full value
23  * range of {@link Element#U8_4}.
24  **/
25 public final class ScriptIntrinsicLUT extends ScriptIntrinsic {
26     private final Matrix4f mMatrix = new Matrix4f();
27     private Allocation mTables;
28     private final byte mCache[] = new byte[1024];
29     private boolean mDirty = true;
30 
ScriptIntrinsicLUT(long id, RenderScript rs)31     private ScriptIntrinsicLUT(long id, RenderScript rs) {
32         super(id, rs);
33         mTables = Allocation.createSized(rs, Element.U8(rs), 1024);
34         for (int ct=0; ct < 256; ct++) {
35             mCache[ct] = (byte)ct;
36             mCache[ct + 256] = (byte)ct;
37             mCache[ct + 512] = (byte)ct;
38             mCache[ct + 768] = (byte)ct;
39         }
40         setVar(0, mTables);
41     }
42 
43     /**
44      * Supported elements types are {@link Element#U8_4}
45      *
46      * The defaults tables are identity.
47      *
48      * @param rs The RenderScript context
49      * @param e Element type for intputs and outputs
50      *
51      * @return ScriptIntrinsicLUT
52      */
create(RenderScript rs, Element e)53     public static ScriptIntrinsicLUT create(RenderScript rs, Element e) {
54         long id = rs.nScriptIntrinsicCreate(3, e.getID(rs));
55         return new ScriptIntrinsicLUT(id, rs);
56 
57     }
58 
destroy()59     public void destroy() {
60         mTables.destroy();
61         super.destroy();
62     }
63 
validate(int index, int value)64     private void validate(int index, int value) {
65         if (index < 0 || index > 255) {
66             throw new RSIllegalArgumentException("Index out of range (0-255).");
67         }
68         if (value < 0 || value > 255) {
69             throw new RSIllegalArgumentException("Value out of range (0-255).");
70         }
71     }
72 
73     /**
74      * Set an entry in the red channel lookup table
75      *
76      * @param index Must be 0-255
77      * @param value Must be 0-255
78      */
setRed(int index, int value)79     public void setRed(int index, int value) {
80         validate(index, value);
81         mCache[index] = (byte)value;
82         mDirty = true;
83     }
84 
85     /**
86      * Set an entry in the green channel lookup table
87      *
88      * @param index Must be 0-255
89      * @param value Must be 0-255
90      */
setGreen(int index, int value)91     public void setGreen(int index, int value) {
92         validate(index, value);
93         mCache[index+256] = (byte)value;
94         mDirty = true;
95     }
96 
97     /**
98      * Set an entry in the blue channel lookup table
99      *
100      * @param index Must be 0-255
101      * @param value Must be 0-255
102      */
setBlue(int index, int value)103     public void setBlue(int index, int value) {
104         validate(index, value);
105         mCache[index+512] = (byte)value;
106         mDirty = true;
107     }
108 
109     /**
110      * Set an entry in the alpha channel lookup table
111      *
112      * @param index Must be 0-255
113      * @param value Must be 0-255
114      */
setAlpha(int index, int value)115     public void setAlpha(int index, int value) {
116         validate(index, value);
117         mCache[index+768] = (byte)value;
118         mDirty = true;
119     }
120 
121     /**
122      * Invoke the kernel and apply the lookup to each cell of ain
123      * and copy to aout.
124      *
125      * @param ain Input allocation
126      * @param aout Output allocation
127      */
forEach(Allocation ain, Allocation aout)128     public void forEach(Allocation ain, Allocation aout) {
129         forEach(ain, aout, null);
130     }
131 
132     /**
133      * Invoke the kernel and apply the lookup to each cell of ain
134      * and copy to aout.
135      *
136      * @param ain Input allocation
137      * @param aout Output allocation
138      * @param opt Options for clipping
139      */
forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt)140     public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) {
141         if (mDirty) {
142             mDirty = false;
143             mTables.copyFromUnchecked(mCache);
144         }
145         forEach(0, ain, aout, null, opt);
146     }
147 
148     /**
149      * Get a KernelID for this intrinsic kernel.
150      *
151      * @return Script.KernelID The KernelID object.
152      */
getKernelID()153     public Script.KernelID getKernelID() {
154         return createKernelID(0, 3, null, null);
155     }
156 }
157 
158