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