blob: d471abb78e00a2c2ebf46e75b9728678af8b19f2 [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
31 private ScriptIntrinsicHistogram(int 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 {@link Element#U8_4, @link
Jason Sams1a3edb02013-06-18 18:23:37 -070040 * Element#U8_3, @link Element#U8_2, @link Element#U8}
Jason Sams01e9f902013-06-18 11:53:03 -070041 *
42 * @param rs The RenderScript context
Jason Sams1a3edb02013-06-18 18:23:37 -070043 * @param e Element type for inputs
Jason Sams01e9f902013-06-18 11:53:03 -070044 *
45 * @return ScriptIntrinsicHistogram
46 */
47 public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
Jason Sams1a3edb02013-06-18 18:23:37 -070048 if ((!e.isCompatible(Element.U8_4(rs))) &&
49 (!e.isCompatible(Element.U8_3(rs))) &&
50 (!e.isCompatible(Element.U8_2(rs))) &&
51 (!e.isCompatible(Element.U8(rs)))) {
Jason Sams01e9f902013-06-18 11:53:03 -070052 throw new RSIllegalArgumentException("Unsuported element type.");
53 }
54 int id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
55 ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
56 return sib;
57 }
58
Jason Sams1a3edb02013-06-18 18:23:37 -070059 /**
60 * Process an input buffer and place the histogram into the
61 * output allocation. The output allocation may be a narrower
62 * vector size than the input. In this case the vector size of
63 * the output is used to determine how many of the input
64 * channels are used in the computation. This is useful if you
65 * have an RGBA input buffer but only want the histogram for
66 * RGB.
67 *
68 * 1D and 2D input allocations are supported.
69 *
70 * @param ain The input image
71 */
Jason Sams01e9f902013-06-18 11:53:03 -070072 public void forEach(Allocation ain) {
Jason Sams8ace2ac2013-06-18 17:34:34 -070073 if (ain.getType().getElement().getVectorSize() <
74 mOut.getType().getElement().getVectorSize()) {
75
76 throw new RSIllegalArgumentException(
Jason Sams1a3edb02013-06-18 18:23:37 -070077 "Input vector size must be >= output vector size.");
Jason Sams01e9f902013-06-18 11:53:03 -070078 }
79 if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
80 ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
81 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
82 }
83
84 forEach(0, ain, null, null);
85 }
86
Jason Sams1a3edb02013-06-18 18:23:37 -070087 /**
88 * Set the coefficients used for the RGBA to Luminocity
89 * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
90 *
91 * Coefficients must be >= 0 and sum to 1.0 or less.
92 *
93 * @param r Red coefficient
94 * @param g Green coefficient
95 * @param b Blue coefficient
96 * @param a Alpha coefficient
97 */
Jason Sams01e9f902013-06-18 11:53:03 -070098 public void setDotCoefficients(float r, float g, float b, float a) {
99 if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
100 throw new RSIllegalArgumentException("Coefficient may not be negative.");
101 }
102 if ((r + g + b + a) > 1.f) {
103 throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
104 }
105
106 FieldPacker fp = new FieldPacker(16);
107 fp.addF32(r);
108 fp.addF32(g);
109 fp.addF32(b);
110 fp.addF32(a);
111 setVar(0, fp);
112 }
113
114 /**
Jason Sams1a3edb02013-06-18 18:23:37 -0700115 * Set the output of the histogram. 32 bit integer types are
116 * supported.
Jason Sams01e9f902013-06-18 11:53:03 -0700117 *
Jason Sams1a3edb02013-06-18 18:23:37 -0700118 * @param aout The output allocation
Jason Sams01e9f902013-06-18 11:53:03 -0700119 */
120 public void setOutput(Allocation aout) {
121 mOut = aout;
122 if (mOut.getType().getElement() != Element.U32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700123 mOut.getType().getElement() != Element.U32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700124 mOut.getType().getElement() != Element.U32_3(mRS) &&
125 mOut.getType().getElement() != Element.U32_4(mRS) &&
126 mOut.getType().getElement() != Element.I32(mRS) &&
Jason Sams8ace2ac2013-06-18 17:34:34 -0700127 mOut.getType().getElement() != Element.I32_2(mRS) &&
Jason Sams01e9f902013-06-18 11:53:03 -0700128 mOut.getType().getElement() != Element.I32_3(mRS) &&
129 mOut.getType().getElement() != Element.I32_4(mRS)) {
130
131 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
132 }
133 if ((mOut.getType().getX() != 256) ||
134 (mOut.getType().getY() != 0) ||
135 mOut.getType().hasMipmaps() ||
136 (mOut.getType().getYuv() != 0)) {
137
138 throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
139 }
140 setVar(1, aout);
141 }
142
Jason Sams1a3edb02013-06-18 18:23:37 -0700143 /**
144 * Process an input buffer and place the histogram into the
145 * output allocation. The dot product of the input channel and
146 * the coefficients from 'setDotCoefficients' are used to
147 * calculate the output values.
148 *
149 * 1D and 2D input allocations are supported.
150 *
151 * @param ain The input image
152 */
Jason Sams01e9f902013-06-18 11:53:03 -0700153 public void forEach_dot(Allocation ain) {
154 if (mOut.getType().getElement().getVectorSize() != 1) {
155 throw new RSIllegalArgumentException("Output vector size must be one.");
156 }
157 if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
158 ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
159 throw new RSIllegalArgumentException("Output type must be U32 or I32.");
160 }
161
162 forEach(1, ain, null, null);
163 }
164
165
166
167 /**
168 * Get a KernelID for this intrinsic kernel.
169 *
170 * @return Script.KernelID The KernelID object.
171 */
172 public Script.KernelID getKernelID_seperate() {
173 return createKernelID(0, 3, null, null);
174 }
175
176 /**
177 * Get a FieldID for the input field of this intrinsic.
178 *
179 * @return Script.FieldID The FieldID object.
180 */
181 public Script.FieldID getFieldID_Input() {
182 return createFieldID(1, null);
183 }
184}
185