1059fede7f200350b6131fc131f76248085485722Miao Wang/*
2059fede7f200350b6131fc131f76248085485722Miao Wang * Copyright (C) 2015 The Android Open Source Project
3059fede7f200350b6131fc131f76248085485722Miao Wang *
4059fede7f200350b6131fc131f76248085485722Miao Wang * Licensed under the Apache License, Version 2.0 (the "License");
5059fede7f200350b6131fc131f76248085485722Miao Wang * you may not use this file except in compliance with the License.
6059fede7f200350b6131fc131f76248085485722Miao Wang * You may obtain a copy of the License at
7059fede7f200350b6131fc131f76248085485722Miao Wang *
8059fede7f200350b6131fc131f76248085485722Miao Wang *      http://www.apache.org/licenses/LICENSE-2.0
9059fede7f200350b6131fc131f76248085485722Miao Wang *
10059fede7f200350b6131fc131f76248085485722Miao Wang * Unless required by applicable law or agreed to in writing, software
11059fede7f200350b6131fc131f76248085485722Miao Wang * distributed under the License is distributed on an "AS IS" BASIS,
12059fede7f200350b6131fc131f76248085485722Miao Wang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13059fede7f200350b6131fc131f76248085485722Miao Wang * See the License for the specific language governing permissions and
14059fede7f200350b6131fc131f76248085485722Miao Wang * limitations under the License.
15059fede7f200350b6131fc131f76248085485722Miao Wang */
16059fede7f200350b6131fc131f76248085485722Miao Wang
17059fede7f200350b6131fc131f76248085485722Miao Wangpackage android.support.v8.renderscript;
18059fede7f200350b6131fc131f76248085485722Miao Wang
19059fede7f200350b6131fc131f76248085485722Miao Wangimport android.util.Log;
20059fede7f200350b6131fc131f76248085485722Miao Wang
21059fede7f200350b6131fc131f76248085485722Miao Wang/**
22059fede7f200350b6131fc131f76248085485722Miao Wang * Intrinsic Histogram filter.
23059fede7f200350b6131fc131f76248085485722Miao Wang *
24059fede7f200350b6131fc131f76248085485722Miao Wang *
25059fede7f200350b6131fc131f76248085485722Miao Wang **/
26059fede7f200350b6131fc131f76248085485722Miao Wangpublic class ScriptIntrinsicHistogram extends ScriptIntrinsic {
27059fede7f200350b6131fc131f76248085485722Miao Wang    private Allocation mOut;
28059fede7f200350b6131fc131f76248085485722Miao Wang    // API level for the intrinsic
29059fede7f200350b6131fc131f76248085485722Miao Wang    private static final int INTRINSIC_API_LEVEL = 19;
30059fede7f200350b6131fc131f76248085485722Miao Wang
310c57ffa1823435763f7a813166ea67cbc8bfe8d3Miao Wang    protected ScriptIntrinsicHistogram(long id, RenderScript rs) {
32059fede7f200350b6131fc131f76248085485722Miao Wang        super(id, rs);
33059fede7f200350b6131fc131f76248085485722Miao Wang    }
34059fede7f200350b6131fc131f76248085485722Miao Wang
35059fede7f200350b6131fc131f76248085485722Miao Wang    /**
36059fede7f200350b6131fc131f76248085485722Miao Wang     * Create an intrinsic for calculating the histogram of an uchar
37059fede7f200350b6131fc131f76248085485722Miao Wang     * or uchar4 image.
38059fede7f200350b6131fc131f76248085485722Miao Wang     *
39059fede7f200350b6131fc131f76248085485722Miao Wang     * Supported elements types are
40059fede7f200350b6131fc131f76248085485722Miao Wang     * {@link Element#U8_4}, {@link Element#U8_3},
41059fede7f200350b6131fc131f76248085485722Miao Wang     * {@link Element#U8_2}, {@link Element#U8}
42059fede7f200350b6131fc131f76248085485722Miao Wang     *
43059fede7f200350b6131fc131f76248085485722Miao Wang     * @param rs The RenderScript context
44059fede7f200350b6131fc131f76248085485722Miao Wang     * @param e Element type for inputs
45059fede7f200350b6131fc131f76248085485722Miao Wang     *
46059fede7f200350b6131fc131f76248085485722Miao Wang     * @return ScriptIntrinsicHistogram
47059fede7f200350b6131fc131f76248085485722Miao Wang     */
48059fede7f200350b6131fc131f76248085485722Miao Wang    public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
49059fede7f200350b6131fc131f76248085485722Miao Wang        if ((!e.isCompatible(Element.U8_4(rs))) &&
50059fede7f200350b6131fc131f76248085485722Miao Wang            (!e.isCompatible(Element.U8_3(rs))) &&
51059fede7f200350b6131fc131f76248085485722Miao Wang            (!e.isCompatible(Element.U8_2(rs))) &&
52059fede7f200350b6131fc131f76248085485722Miao Wang            (!e.isCompatible(Element.U8(rs)))) {
53059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Unsuported element type.");
54059fede7f200350b6131fc131f76248085485722Miao Wang        }
55059fede7f200350b6131fc131f76248085485722Miao Wang        long id;
56059fede7f200350b6131fc131f76248085485722Miao Wang        boolean mUseIncSupp = rs.isUseNative() &&
57059fede7f200350b6131fc131f76248085485722Miao Wang                              android.os.Build.VERSION.SDK_INT < INTRINSIC_API_LEVEL;
58059fede7f200350b6131fc131f76248085485722Miao Wang
59059fede7f200350b6131fc131f76248085485722Miao Wang        id = rs.nScriptIntrinsicCreate(9, e.getID(rs), mUseIncSupp);
60059fede7f200350b6131fc131f76248085485722Miao Wang
61059fede7f200350b6131fc131f76248085485722Miao Wang        ScriptIntrinsicHistogram si = new ScriptIntrinsicHistogram(id, rs);
62059fede7f200350b6131fc131f76248085485722Miao Wang        si.setIncSupp(mUseIncSupp);
63059fede7f200350b6131fc131f76248085485722Miao Wang        return si;
64059fede7f200350b6131fc131f76248085485722Miao Wang    }
65059fede7f200350b6131fc131f76248085485722Miao Wang
66059fede7f200350b6131fc131f76248085485722Miao Wang    /**
67059fede7f200350b6131fc131f76248085485722Miao Wang     * Process an input buffer and place the histogram into the
68059fede7f200350b6131fc131f76248085485722Miao Wang     * output allocation. The output allocation may be a narrower
69059fede7f200350b6131fc131f76248085485722Miao Wang     * vector size than the input. In this case the vector size of
70059fede7f200350b6131fc131f76248085485722Miao Wang     * the output is used to determine how many of the input
71059fede7f200350b6131fc131f76248085485722Miao Wang     * channels are used in the computation. This is useful if you
72059fede7f200350b6131fc131f76248085485722Miao Wang     * have an RGBA input buffer but only want the histogram for
73059fede7f200350b6131fc131f76248085485722Miao Wang     * RGB.
74059fede7f200350b6131fc131f76248085485722Miao Wang     *
75059fede7f200350b6131fc131f76248085485722Miao Wang     * 1D and 2D input allocations are supported.
76059fede7f200350b6131fc131f76248085485722Miao Wang     *
77059fede7f200350b6131fc131f76248085485722Miao Wang     * @param ain The input image
78059fede7f200350b6131fc131f76248085485722Miao Wang     */
79059fede7f200350b6131fc131f76248085485722Miao Wang    public void forEach(Allocation ain) {
80059fede7f200350b6131fc131f76248085485722Miao Wang        forEach(ain, null);
81059fede7f200350b6131fc131f76248085485722Miao Wang    }
82059fede7f200350b6131fc131f76248085485722Miao Wang
83059fede7f200350b6131fc131f76248085485722Miao Wang    /**
84059fede7f200350b6131fc131f76248085485722Miao Wang     * Process an input buffer and place the histogram into the
85059fede7f200350b6131fc131f76248085485722Miao Wang     * output allocation. The output allocation may be a narrower
86059fede7f200350b6131fc131f76248085485722Miao Wang     * vector size than the input. In this case the vector size of
87059fede7f200350b6131fc131f76248085485722Miao Wang     * the output is used to determine how many of the input
88059fede7f200350b6131fc131f76248085485722Miao Wang     * channels are used in the computation. This is useful if you
89059fede7f200350b6131fc131f76248085485722Miao Wang     * have an RGBA input buffer but only want the histogram for
90059fede7f200350b6131fc131f76248085485722Miao Wang     * RGB.
91059fede7f200350b6131fc131f76248085485722Miao Wang     *
92059fede7f200350b6131fc131f76248085485722Miao Wang     * 1D and 2D input allocations are supported.
93059fede7f200350b6131fc131f76248085485722Miao Wang     *
94059fede7f200350b6131fc131f76248085485722Miao Wang     * @param ain The input image
95059fede7f200350b6131fc131f76248085485722Miao Wang     * @param opt LaunchOptions for clipping
96059fede7f200350b6131fc131f76248085485722Miao Wang     */
97059fede7f200350b6131fc131f76248085485722Miao Wang    public void forEach(Allocation ain, Script.LaunchOptions opt) {
98059fede7f200350b6131fc131f76248085485722Miao Wang        if (ain.getType().getElement().getVectorSize() <
99059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement().getVectorSize()) {
100059fede7f200350b6131fc131f76248085485722Miao Wang
101059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException(
102059fede7f200350b6131fc131f76248085485722Miao Wang                "Input vector size must be >= output vector size.");
103059fede7f200350b6131fc131f76248085485722Miao Wang        }
104059fede7f200350b6131fc131f76248085485722Miao Wang        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
10513d123415d8286804cb025071b63083d05cc26d4Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
10613d123415d8286804cb025071b63083d05cc26d4Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
107059fede7f200350b6131fc131f76248085485722Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
10813d123415d8286804cb025071b63083d05cc26d4Miao Wang            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
109059fede7f200350b6131fc131f76248085485722Miao Wang        }
110059fede7f200350b6131fc131f76248085485722Miao Wang
111059fede7f200350b6131fc131f76248085485722Miao Wang        forEach(0, ain, null, null, opt);
112059fede7f200350b6131fc131f76248085485722Miao Wang    }
113059fede7f200350b6131fc131f76248085485722Miao Wang
114059fede7f200350b6131fc131f76248085485722Miao Wang
115059fede7f200350b6131fc131f76248085485722Miao Wang
116059fede7f200350b6131fc131f76248085485722Miao Wang    /**
117059fede7f200350b6131fc131f76248085485722Miao Wang     * Set the coefficients used for the RGBA to Luminocity
118059fede7f200350b6131fc131f76248085485722Miao Wang     * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
119059fede7f200350b6131fc131f76248085485722Miao Wang     *
120059fede7f200350b6131fc131f76248085485722Miao Wang     * Coefficients must be >= 0 and sum to 1.0 or less.
121059fede7f200350b6131fc131f76248085485722Miao Wang     *
122059fede7f200350b6131fc131f76248085485722Miao Wang     * @param r Red coefficient
123059fede7f200350b6131fc131f76248085485722Miao Wang     * @param g Green coefficient
124059fede7f200350b6131fc131f76248085485722Miao Wang     * @param b Blue coefficient
125059fede7f200350b6131fc131f76248085485722Miao Wang     * @param a Alpha coefficient
126059fede7f200350b6131fc131f76248085485722Miao Wang     */
127059fede7f200350b6131fc131f76248085485722Miao Wang    public void setDotCoefficients(float r, float g, float b, float a) {
128059fede7f200350b6131fc131f76248085485722Miao Wang        if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
129059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Coefficient may not be negative.");
130059fede7f200350b6131fc131f76248085485722Miao Wang        }
131059fede7f200350b6131fc131f76248085485722Miao Wang        if ((r + g + b + a) > 1.f) {
132059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
133059fede7f200350b6131fc131f76248085485722Miao Wang        }
134059fede7f200350b6131fc131f76248085485722Miao Wang
135059fede7f200350b6131fc131f76248085485722Miao Wang        FieldPacker fp = new FieldPacker(16);
136059fede7f200350b6131fc131f76248085485722Miao Wang        fp.addF32(r);
137059fede7f200350b6131fc131f76248085485722Miao Wang        fp.addF32(g);
138059fede7f200350b6131fc131f76248085485722Miao Wang        fp.addF32(b);
139059fede7f200350b6131fc131f76248085485722Miao Wang        fp.addF32(a);
140059fede7f200350b6131fc131f76248085485722Miao Wang        setVar(0, fp);
141059fede7f200350b6131fc131f76248085485722Miao Wang    }
142059fede7f200350b6131fc131f76248085485722Miao Wang
143059fede7f200350b6131fc131f76248085485722Miao Wang    /**
144059fede7f200350b6131fc131f76248085485722Miao Wang     * Set the output of the histogram.  32 bit integer types are
145059fede7f200350b6131fc131f76248085485722Miao Wang     * supported.
146059fede7f200350b6131fc131f76248085485722Miao Wang     *
147059fede7f200350b6131fc131f76248085485722Miao Wang     * @param aout The output allocation
148059fede7f200350b6131fc131f76248085485722Miao Wang     */
149059fede7f200350b6131fc131f76248085485722Miao Wang    public void setOutput(Allocation aout) {
150059fede7f200350b6131fc131f76248085485722Miao Wang        mOut = aout;
151059fede7f200350b6131fc131f76248085485722Miao Wang        if (mOut.getType().getElement() != Element.U32(mRS) &&
152059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.U32_2(mRS) &&
153059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.U32_3(mRS) &&
154059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.U32_4(mRS) &&
155059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.I32(mRS) &&
156059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.I32_2(mRS) &&
157059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.I32_3(mRS) &&
158059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().getElement() != Element.I32_4(mRS)) {
159059fede7f200350b6131fc131f76248085485722Miao Wang
160059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Output type must be U32 or I32.");
161059fede7f200350b6131fc131f76248085485722Miao Wang        }
162059fede7f200350b6131fc131f76248085485722Miao Wang        if ((mOut.getType().getX() != 256) ||
163059fede7f200350b6131fc131f76248085485722Miao Wang            (mOut.getType().getY() != 0) ||
164059fede7f200350b6131fc131f76248085485722Miao Wang            mOut.getType().hasMipmaps() ||
165059fede7f200350b6131fc131f76248085485722Miao Wang            (mOut.getType().getYuv() != 0)) {
166059fede7f200350b6131fc131f76248085485722Miao Wang
167059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
168059fede7f200350b6131fc131f76248085485722Miao Wang        }
169059fede7f200350b6131fc131f76248085485722Miao Wang        setVar(1, aout);
170059fede7f200350b6131fc131f76248085485722Miao Wang    }
171059fede7f200350b6131fc131f76248085485722Miao Wang
172059fede7f200350b6131fc131f76248085485722Miao Wang
173059fede7f200350b6131fc131f76248085485722Miao Wang    /**
174059fede7f200350b6131fc131f76248085485722Miao Wang     * Process an input buffer and place the histogram into the
175059fede7f200350b6131fc131f76248085485722Miao Wang     * output allocation. The dot product of the input channel and
176059fede7f200350b6131fc131f76248085485722Miao Wang     * the coefficients from 'setDotCoefficients' are used to
177059fede7f200350b6131fc131f76248085485722Miao Wang     * calculate the output values.
178059fede7f200350b6131fc131f76248085485722Miao Wang     *
179059fede7f200350b6131fc131f76248085485722Miao Wang     * 1D and 2D input allocations are supported.
180059fede7f200350b6131fc131f76248085485722Miao Wang     *
181059fede7f200350b6131fc131f76248085485722Miao Wang     * @param ain The input image
182059fede7f200350b6131fc131f76248085485722Miao Wang     */
183059fede7f200350b6131fc131f76248085485722Miao Wang    public void forEach_Dot(Allocation ain) {
184059fede7f200350b6131fc131f76248085485722Miao Wang        forEach_Dot(ain, null);
185059fede7f200350b6131fc131f76248085485722Miao Wang    }
186059fede7f200350b6131fc131f76248085485722Miao Wang
187059fede7f200350b6131fc131f76248085485722Miao Wang    /**
188059fede7f200350b6131fc131f76248085485722Miao Wang     * Process an input buffer and place the histogram into the
189059fede7f200350b6131fc131f76248085485722Miao Wang     * output allocation. The dot product of the input channel and
190059fede7f200350b6131fc131f76248085485722Miao Wang     * the coefficients from 'setDotCoefficients' are used to
191059fede7f200350b6131fc131f76248085485722Miao Wang     * calculate the output values.
192059fede7f200350b6131fc131f76248085485722Miao Wang     *
193059fede7f200350b6131fc131f76248085485722Miao Wang     * 1D and 2D input allocations are supported.
194059fede7f200350b6131fc131f76248085485722Miao Wang     *
195059fede7f200350b6131fc131f76248085485722Miao Wang     * @param ain The input image
196059fede7f200350b6131fc131f76248085485722Miao Wang     * @param opt LaunchOptions for clipping
197059fede7f200350b6131fc131f76248085485722Miao Wang     */
198059fede7f200350b6131fc131f76248085485722Miao Wang    public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
199059fede7f200350b6131fc131f76248085485722Miao Wang        if (mOut.getType().getElement().getVectorSize() != 1) {
200059fede7f200350b6131fc131f76248085485722Miao Wang            throw new RSIllegalArgumentException("Output vector size must be one.");
201059fede7f200350b6131fc131f76248085485722Miao Wang        }
202059fede7f200350b6131fc131f76248085485722Miao Wang        if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
20313d123415d8286804cb025071b63083d05cc26d4Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
20413d123415d8286804cb025071b63083d05cc26d4Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
205059fede7f200350b6131fc131f76248085485722Miao Wang            !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
20613d123415d8286804cb025071b63083d05cc26d4Miao Wang            throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
207059fede7f200350b6131fc131f76248085485722Miao Wang        }
208059fede7f200350b6131fc131f76248085485722Miao Wang
209059fede7f200350b6131fc131f76248085485722Miao Wang        forEach(1, ain, null, null, opt);
210059fede7f200350b6131fc131f76248085485722Miao Wang    }
211059fede7f200350b6131fc131f76248085485722Miao Wang
212059fede7f200350b6131fc131f76248085485722Miao Wang
213059fede7f200350b6131fc131f76248085485722Miao Wang
214059fede7f200350b6131fc131f76248085485722Miao Wang    /**
215059fede7f200350b6131fc131f76248085485722Miao Wang     * Get a KernelID for this intrinsic kernel.
216059fede7f200350b6131fc131f76248085485722Miao Wang     *
217059fede7f200350b6131fc131f76248085485722Miao Wang     * @return Script.KernelID The KernelID object.
218059fede7f200350b6131fc131f76248085485722Miao Wang     */
219059fede7f200350b6131fc131f76248085485722Miao Wang    public Script.KernelID getKernelID_Separate() {
220059fede7f200350b6131fc131f76248085485722Miao Wang        return createKernelID(0, 3, null, null);
221059fede7f200350b6131fc131f76248085485722Miao Wang    }
222059fede7f200350b6131fc131f76248085485722Miao Wang
223059fede7f200350b6131fc131f76248085485722Miao Wang    /**
224059fede7f200350b6131fc131f76248085485722Miao Wang     * Get a FieldID for the input field of this intrinsic.
225059fede7f200350b6131fc131f76248085485722Miao Wang     *
226059fede7f200350b6131fc131f76248085485722Miao Wang     * @return Script.FieldID The FieldID object.
227059fede7f200350b6131fc131f76248085485722Miao Wang     */
228059fede7f200350b6131fc131f76248085485722Miao Wang    public Script.FieldID getFieldID_Input() {
229059fede7f200350b6131fc131f76248085485722Miao Wang        return createFieldID(1, null);
230059fede7f200350b6131fc131f76248085485722Miao Wang    }
231059fede7f200350b6131fc131f76248085485722Miao Wang}
232059fede7f200350b6131fc131f76248085485722Miao Wang
233