blob: 42e4d04e4abc3e39d637bd65014fa7dc56549c46 [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
19import android.content.Context;
20import android.content.res.Resources;
21import android.util.Log;
22
23/**
24 * Intrinsic Histogram filter.
25 *
26 *
27 **/
28public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
29 private Allocation mOut;
30
Tim Murray7a629fa2013-11-19 12:45:54 -080031 private ScriptIntrinsicHistogram(long id, RenderScript rs) {
Jason Sams01e9f902013-06-18 11:53:03 -070032 super(id, rs);
33 }
34
35 /**
36 * Create an intrinsic for calculating the histogram of an uchar
37 * or uchar4 image.
38 *
Jason Sams92743842013-06-18 18:52:42 -070039 * Supported elements types are
40 * {@link Element#U8_4}, {@link Element#U8_3},
41 * {@link Element#U8_2}, {@link Element#U8}
Jason Sams01e9f902013-06-18 11:53:03 -070042 *
43 * @param rs The RenderScript context
Jason Sams1a3edb02013-06-18 18:23:37 -070044 * @param e Element type for inputs
Jason Sams01e9f902013-06-18 11:53:03 -070045 *
46 * @return ScriptIntrinsicHistogram
47 */
48 public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
Jason Sams1a3edb02013-06-18 18:23:37 -070049 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)))) {
Jason Sams01e9f902013-06-18 11:53:03 -070053 throw new RSIllegalArgumentException("Unsuported element type.");
54 }
Tim Murray7a629fa2013-11-19 12:45:54 -080055 long id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
Jason Sams01e9f902013-06-18 11:53:03 -070056 ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
57 return sib;
58 }
59
Jason Sams1a3edb02013-06-18 18:23:37 -070060 /**
61 * Process an input buffer and place the histogram into the
62 * output allocation. The output allocation may be a narrower
63 * vector size than the input. In this case the vector size of
64 * the output is used to determine how many of the input
65 * channels are used in the computation. This is useful if you
66 * have an RGBA input buffer but only want the histogram for
67 * RGB.
68 *
69 * 1D and 2D input allocations are supported.
70 *
71 * @param ain The input image
72 */
Jason Sams01e9f902013-06-18 11:53:03 -070073 public void forEach(Allocation ain) {
Jason Sams8ace2ac2013-06-18 17:34:34 -070074 if (ain.getType().getElement().getVectorSize() <
75 mOut.getType().getElement().getVectorSize()) {
76
77 throw new RSIllegalArgumentException(
Jason Sams1a3edb02013-06-18 18:23:37 -070078 "Input vector size must be >= output vector size.");
Jason Sams01e9f902013-06-18 11:53:03 -070079 }
80 if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
81 ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
82 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
83 }
84
85 forEach(0, ain, null, null);
86 }
87
Jason Sams1a3edb02013-06-18 18:23:37 -070088 /**
89 * Set the coefficients used for the RGBA to Luminocity
90 * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
91 *
92 * Coefficients must be >= 0 and sum to 1.0 or less.
93 *
94 * @param r Red coefficient
95 * @param g Green coefficient
96 * @param b Blue coefficient
97 * @param a Alpha coefficient
98 */
Jason Sams01e9f902013-06-18 11:53:03 -070099 public void setDotCoefficients(float r, float g, float b, float a) {
100 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
101 throw new RSIllegalArgumentException("Coefficient may not be negative.");
102 }
103 if ((r + g + b + a) > 1.f) {
104 throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
105 }
106
107 FieldPacker fp = new FieldPacker(16);
108 fp.addF32(r);
109 fp.addF32(g);
110 fp.addF32(b);
111 fp.addF32(a);
112 setVar(0, fp);
113 }
114
115 /**
Jason Sams1a3edb02013-06-18 18:23:37 -0700116 * Set the output of the histogram. 32 bit integer types are
117 * supported.
Jason Sams01e9f902013-06-18 11:53:03 -0700118 *
Jason Sams1a3edb02013-06-18 18:23:37 -0700119 * @param aout The output allocation
Jason Sams01e9f902013-06-18 11:53:03 -0700120 */
121 public void setOutput(Allocation aout) {
122 mOut = aout;
123 if (mOut.getType().getElement() != Element.U32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700124 mOut.getType().getElement() != Element.U32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700125 mOut.getType().getElement() != Element.U32_3(mRS) &&
126 mOut.getType().getElement() != Element.U32_4(mRS) &&
127 mOut.getType().getElement() != Element.I32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700128 mOut.getType().getElement() != Element.I32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700129 mOut.getType().getElement() != Element.I32_3(mRS) &&
130 mOut.getType().getElement() != Element.I32_4(mRS)) {
131
132 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
133 }
134 if ((mOut.getType().getX() != 256) ||
135 (mOut.getType().getY() != 0) ||
136 mOut.getType().hasMipmaps() ||
137 (mOut.getType().getYuv() != 0)) {
138
139 throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
140 }
141 setVar(1, aout);
142 }
143
Jason Sams1a3edb02013-06-18 18:23:37 -0700144 /**
145 * Process an input buffer and place the histogram into the
146 * output allocation. The dot product of the input channel and
147 * the coefficients from 'setDotCoefficients' are used to
148 * calculate the output values.
149 *
150 * 1D and 2D input allocations are supported.
151 *
152 * @param ain The input image
153 */
Jason Samsa49e89d2013-08-29 17:00:37 -0700154 public void forEach_Dot(Allocation ain) {
Jason Sams01e9f902013-06-18 11:53:03 -0700155 if (mOut.getType().getElement().getVectorSize() != 1) {
156 throw new RSIllegalArgumentException("Output vector size must be one.");
157 }
158 if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
159 ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
160 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
161 }
162
163 forEach(1, ain, null, null);
164 }
165
166
167
168 /**
169 * Get a KernelID for this intrinsic kernel.
170 *
171 * @return Script.KernelID The KernelID object.
172 */
Jason Samsa49e89d2013-08-29 17:00:37 -0700173 public Script.KernelID getKernelID_Separate() {
Jason Sams01e9f902013-06-18 11:53:03 -0700174 return createKernelID(0, 3, null, null);
175 }
176
177 /**
178 * Get a FieldID for the input field of this intrinsic.
179 *
180 * @return Script.FieldID The FieldID object.
181 */
182 public Script.FieldID getFieldID_Input() {
183 return createFieldID(1, null);
184 }
185}
186