blob: 3437f2c211ab473e7f26223fbbfc51113831ce97 [file] [log] [blame]
Alan Viverette3da604b2020-06-10 18:34:39 +00001/*
2 * Copyright (C) 2015 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
17package androidx.renderscript;
18
19import android.util.Log;
20
21/**
22 * Intrinsic Histogram filter.
23 *
24 *
25 **/
26public class ScriptIntrinsicHistogram extends ScriptIntrinsic {
27 private Allocation mOut;
28 // API level for the intrinsic
29 private static final int INTRINSIC_API_LEVEL = 19;
30
31 protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
32 super(id, rs);
33 }
34
35 /**
36 * Create an intrinsic for calculating the histogram of an uchar
37 * or uchar4 image.
38 *
39 * Supported elements types are
40 * {@link Element#U8_4}, {@link Element#U8_3},
41 * {@link Element#U8_2}, {@link Element#U8}
42 *
43 * @param rs The RenderScript context
44 * @param e Element type for inputs
45 *
46 * @return ScriptIntrinsicHistogram
47 */
48 public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
49 if ((!e.isCompatible(Element.U8_4(rs))) &&
50 (!e.isCompatible(Element.U8_3(rs))) &&
51 (!e.isCompatible(Element.U8_2(rs))) &&
52 (!e.isCompatible(Element.U8(rs)))) {
53 throw new RSIllegalArgumentException("Unsupported element type.");
54 }
55 long id;
56 boolean mUseIncSupp = rs.isUseNative() &&
57 android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
58
59 id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);
60
61 ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
62 si.setIncSupp(mUseIncSupp);
63 return si;
64 }
65
66 /**
67 * Process an input buffer and place the histogram into the
68 * output allocation. The output allocation may be a narrower
69 * vector size than the input. In this case the vector size of
70 * the output is used to determine how many of the input
71 * channels are used in the computation. This is useful if you
72 * have an RGBA input buffer but only want the histogram for
73 * RGB.
74 *
75 * 1D and 2D input allocations are supported.
76 *
77 * @param ain The input image
78 */
79 public void forEach(Allocation ain) {
80 forEach(ain, null);
81 }
82
83 /**
84 * Process an input buffer and place the histogram into the
85 * output allocation. The output allocation may be a narrower
86 * vector size than the input. In this case the vector size of
87 * the output is used to determine how many of the input
88 * channels are used in the computation. This is useful if you
89 * have an RGBA input buffer but only want the histogram for
90 * RGB.
91 *
92 * 1D and 2D input allocations are supported.
93 *
94 * @param ain The input image
95 * @param opt LaunchOptions for clipping
96 */
97 public void forEach(Allocation ain, Script.LaunchOptions opt) {
98 if (ain.getType().getElement().getVectorSize() <
99 mOut.getType().getElement().getVectorSize()) {
100
101 throw new RSIllegalArgumentException(
102 "Input vector size must be >= output vector size.");
103 }
104 if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
105 !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
106 !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
107 !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
108 throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
109 }
110
111 forEach(0, ain, null, null, opt);
112 }
113
114
115
116 /**
117 * Set the coefficients used for the RGBA to Luminocity
118 * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
119 *
120 * Coefficients must be >= 0 and sum to 1.0 or less.
121 *
122 * @param r Red coefficient
123 * @param g Green coefficient
124 * @param b Blue coefficient
125 * @param a Alpha coefficient
126 */
127 public void setDotCoefficients(float r, float g, float b, float a) {
128 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
129 throw new RSIllegalArgumentException("Coefficient may not be negative.");
130 }
131 if ((r + g + b + a) > 1.f) {
132 throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
133 }
134
135 FieldPacker fp = new FieldPacker(16);
136 fp.addF32(r);
137 fp.addF32(g);
138 fp.addF32(b);
139 fp.addF32(a);
140 setVar(0, fp);
141 }
142
143 /**
144 * Set the output of the histogram. 32 bit integer types are
145 * supported.
146 *
147 * @param aout The output allocation
148 */
149 public void setOutput(Allocation aout) {
150 mOut = aout;
151 if (mOut.getType().getElement() != Element.U32(mRS) &&
152 mOut.getType().getElement() != Element.U32_2(mRS) &&
153 mOut.getType().getElement() != Element.U32_3(mRS) &&
154 mOut.getType().getElement() != Element.U32_4(mRS) &&
155 mOut.getType().getElement() != Element.I32(mRS) &&
156 mOut.getType().getElement() != Element.I32_2(mRS) &&
157 mOut.getType().getElement() != Element.I32_3(mRS) &&
158 mOut.getType().getElement() != Element.I32_4(mRS)) {
159
160 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
161 }
162 if ((mOut.getType().getX() != 256) ||
163 (mOut.getType().getY() != 0) ||
164 mOut.getType().hasMipmaps() ||
165 (mOut.getType().getYuv() != 0)) {
166
167 throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
168 }
169 setVar(1, aout);
170 }
171
172
173 /**
174 * Process an input buffer and place the histogram into the
175 * output allocation. The dot product of the input channel and
176 * the coefficients from 'setDotCoefficients' are used to
177 * calculate the output values.
178 *
179 * 1D and 2D input allocations are supported.
180 *
181 * @param ain The input image
182 */
183 public void forEach_Dot(Allocation ain) {
184 forEach_Dot(ain, null);
185 }
186
187 /**
188 * Process an input buffer and place the histogram into the
189 * output allocation. The dot product of the input channel and
190 * the coefficients from 'setDotCoefficients' are used to
191 * calculate the output values.
192 *
193 * 1D and 2D input allocations are supported.
194 *
195 * @param ain The input image
196 * @param opt LaunchOptions for clipping
197 */
198 public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
199 if (mOut.getType().getElement().getVectorSize() != 1) {
200 throw new RSIllegalArgumentException("Output vector size must be one.");
201 }
202 if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
203 !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
204 !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
205 !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
206 throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
207 }
208
209 forEach(1, ain, null, null, opt);
210 }
211
212
213
214 /**
215 * Get a KernelID for this intrinsic kernel.
216 *
217 * @return Script.KernelID The KernelID object.
218 */
219 public Script.KernelID getKernelID_Separate() {
220 return createKernelID(0, 3, null, null);
221 }
222
223 /**
224 * Get a FieldID for the input field of this intrinsic.
225 *
226 * @return Script.FieldID The FieldID object.
227 */
228 public Script.FieldID getFieldID_Input() {
229 return createFieldID(1, null);
230 }
231}
232