blob: 0e8b36c11952383af95888c987f91a6337086f16 [file] [log] [blame]
Jason Sams01e9f902013-06-18 11:53:03 -07001/*
2 * Copyright (C) 2013 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 android.renderscript;
18
Jason Sams01e9f902013-06-18 11:53:03 -070019/**
20 * Intrinsic Histogram filter.
21 *
22 *
23 **/
24public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
25 private Allocation mOut;
26
Tim Murray460a0492013-11-19 12:45:54 -080027 private ScriptIntrinsicHistogram(long id, RenderScript rs) {
Jason Sams01e9f902013-06-18 11:53:03 -070028 super(id, rs);
29 }
30
31 /**
32 * Create an intrinsic for calculating the histogram of an uchar
33 * or uchar4 image.
34 *
Jason Sams92743842013-06-18 18:52:42 -070035 * Supported elements types are
36 * {@link Element#U8_4}, {@link Element#U8_3},
37 * {@link Element#U8_2}, {@link Element#U8}
Jason Sams01e9f902013-06-18 11:53:03 -070038 *
39 * @param rs The RenderScript context
Jason Sams1a3edb02013-06-18 18:23:37 -070040 * @param e Element type for inputs
Jason Sams01e9f902013-06-18 11:53:03 -070041 *
42 * @return ScriptIntrinsicHistogram
43 */
44 public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
Jason Sams1a3edb02013-06-18 18:23:37 -070045 if ((!e.isCompatible(Element.U8_4(rs))) &&
46 (!e.isCompatible(Element.U8_3(rs))) &&
47 (!e.isCompatible(Element.U8_2(rs))) &&
48 (!e.isCompatible(Element.U8(rs)))) {
Stephen Hinesad57e332016-04-11 13:05:55 -070049 throw new RSIllegalArgumentException("Unsupported element type.");
Jason Sams01e9f902013-06-18 11:53:03 -070050 }
Tim Murray460a0492013-11-19 12:45:54 -080051 long id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
Jason Sams01e9f902013-06-18 11:53:03 -070052 ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
53 return sib;
54 }
55
Jason Sams1a3edb02013-06-18 18:23:37 -070056 /**
57 * Process an input buffer and place the histogram into the
58 * output allocation. The output allocation may be a narrower
59 * vector size than the input. In this case the vector size of
60 * the output is used to determine how many of the input
61 * channels are used in the computation. This is useful if you
62 * have an RGBA input buffer but only want the histogram for
63 * RGB.
64 *
65 * 1D and 2D input allocations are supported.
66 *
67 * @param ain The input image
68 */
Jason Sams01e9f902013-06-18 11:53:03 -070069 public void forEach(Allocation ain) {
Tim Murray6f842ac2014-01-13 11:47:53 -080070 forEach(ain, null);
71 }
72
73 /**
74 * Process an input buffer and place the histogram into the
75 * output allocation. The output allocation may be a narrower
76 * vector size than the input. In this case the vector size of
77 * the output is used to determine how many of the input
78 * channels are used in the computation. This is useful if you
79 * have an RGBA input buffer but only want the histogram for
80 * RGB.
81 *
82 * 1D and 2D input allocations are supported.
83 *
84 * @param ain The input image
85 * @param opt LaunchOptions for clipping
86 */
87 public void forEach(Allocation ain, Script.LaunchOptions opt) {
Jason Sams8ace2ac2013-06-18 17:34:34 -070088 if (ain.getType().getElement().getVectorSize() <
89 mOut.getType().getElement().getVectorSize()) {
90
91 throw new RSIllegalArgumentException(
Jason Sams1a3edb02013-06-18 18:23:37 -070092 "Input vector size must be >= output vector size.");
Jason Sams01e9f902013-06-18 11:53:03 -070093 }
Miao Wangb590b352015-01-15 11:09:23 -080094 if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
Miao Wang8a126532015-01-23 09:41:04 -080095 !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
96 !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
Miao Wangb590b352015-01-15 11:09:23 -080097 !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
Miao Wang8a126532015-01-23 09:41:04 -080098 throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
Jason Sams01e9f902013-06-18 11:53:03 -070099 }
100
Tim Murray6f842ac2014-01-13 11:47:53 -0800101 forEach(0, ain, null, null, opt);
Jason Sams01e9f902013-06-18 11:53:03 -0700102 }
103
Tim Murray6f842ac2014-01-13 11:47:53 -0800104
105
Jason Sams1a3edb02013-06-18 18:23:37 -0700106 /**
107 * Set the coefficients used for the RGBA to Luminocity
108 * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
109 *
110 * Coefficients must be >= 0 and sum to 1.0 or less.
111 *
112 * @param r Red coefficient
113 * @param g Green coefficient
114 * @param b Blue coefficient
115 * @param a Alpha coefficient
116 */
Jason Sams01e9f902013-06-18 11:53:03 -0700117 public void setDotCoefficients(float r, float g, float b, float a) {
118 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
119 throw new RSIllegalArgumentException("Coefficient may not be negative.");
120 }
121 if ((r + g + b + a) > 1.f) {
122 throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
123 }
124
125 FieldPacker fp = new FieldPacker(16);
126 fp.addF32(r);
127 fp.addF32(g);
128 fp.addF32(b);
129 fp.addF32(a);
130 setVar(0, fp);
131 }
132
133 /**
Jason Sams1a3edb02013-06-18 18:23:37 -0700134 * Set the output of the histogram. 32 bit integer types are
135 * supported.
Jason Sams01e9f902013-06-18 11:53:03 -0700136 *
Jason Sams1a3edb02013-06-18 18:23:37 -0700137 * @param aout The output allocation
Jason Sams01e9f902013-06-18 11:53:03 -0700138 */
139 public void setOutput(Allocation aout) {
140 mOut = aout;
141 if (mOut.getType().getElement() != Element.U32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700142 mOut.getType().getElement() != Element.U32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700143 mOut.getType().getElement() != Element.U32_3(mRS) &&
144 mOut.getType().getElement() != Element.U32_4(mRS) &&
145 mOut.getType().getElement() != Element.I32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700146 mOut.getType().getElement() != Element.I32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700147 mOut.getType().getElement() != Element.I32_3(mRS) &&
148 mOut.getType().getElement() != Element.I32_4(mRS)) {
149
150 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
151 }
152 if ((mOut.getType().getX() != 256) ||
153 (mOut.getType().getY() != 0) ||
154 mOut.getType().hasMipmaps() ||
155 (mOut.getType().getYuv() != 0)) {
156
157 throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
158 }
159 setVar(1, aout);
160 }
161
Tim Murray6f842ac2014-01-13 11:47:53 -0800162
Jason Sams1a3edb02013-06-18 18:23:37 -0700163 /**
164 * Process an input buffer and place the histogram into the
165 * output allocation. The dot product of the input channel and
166 * the coefficients from 'setDotCoefficients' are used to
167 * calculate the output values.
168 *
169 * 1D and 2D input allocations are supported.
170 *
171 * @param ain The input image
172 */
Jason Samsa49e89d2013-08-29 17:00:37 -0700173 public void forEach_Dot(Allocation ain) {
Tim Murray6f842ac2014-01-13 11:47:53 -0800174 forEach_Dot(ain, null);
175 }
176
177 /**
178 * Process an input buffer and place the histogram into the
179 * output allocation. The dot product of the input channel and
180 * the coefficients from 'setDotCoefficients' are used to
181 * calculate the output values.
182 *
183 * 1D and 2D input allocations are supported.
184 *
185 * @param ain The input image
186 * @param opt LaunchOptions for clipping
187 */
188 public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
Jason Sams01e9f902013-06-18 11:53:03 -0700189 if (mOut.getType().getElement().getVectorSize() != 1) {
190 throw new RSIllegalArgumentException("Output vector size must be one.");
191 }
Miao Wangb590b352015-01-15 11:09:23 -0800192 if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
Miao Wang8a126532015-01-23 09:41:04 -0800193 !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
194 !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
Miao Wangb590b352015-01-15 11:09:23 -0800195 !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
Miao Wang8a126532015-01-23 09:41:04 -0800196 throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
Jason Sams01e9f902013-06-18 11:53:03 -0700197 }
198
Tim Murray6f842ac2014-01-13 11:47:53 -0800199 forEach(1, ain, null, null, opt);
Jason Sams01e9f902013-06-18 11:53:03 -0700200 }
201
202
203
204 /**
205 * Get a KernelID for this intrinsic kernel.
206 *
207 * @return Script.KernelID The KernelID object.
208 */
Jason Samsa49e89d2013-08-29 17:00:37 -0700209 public Script.KernelID getKernelID_Separate() {
Jason Sams01e9f902013-06-18 11:53:03 -0700210 return createKernelID(0, 3, null, null);
211 }
212
213 /**
214 * Get a FieldID for the input field of this intrinsic.
215 *
216 * @return Script.FieldID The FieldID object.
217 */
218 public Script.FieldID getFieldID_Input() {
219 return createFieldID(1, null);
220 }
221}
222