Home | History | Annotate | Download | only in renderscript
      1 /*
      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 
     17 package android.renderscript;
     18 
     19 /**
     20  * Intrinsic Histogram filter.
     21  *
     22  *
     23  **/
     24 public final class ScriptIntrinsicHistogram extends ScriptIntrinsic {
     25     private Allocation mOut;
     26 
     27     private ScriptIntrinsicHistogram(long id, RenderScript rs) {
     28         super(id, rs);
     29     }
     30 
     31     /**
     32      * Create an intrinsic for calculating the histogram of an uchar
     33      * or uchar4 image.
     34      *
     35      * Supported elements types are
     36      * {@link Element#U8_4}, {@link Element#U8_3},
     37      * {@link Element#U8_2}, {@link Element#U8}
     38      *
     39      * @param rs The RenderScript context
     40      * @param e Element type for inputs
     41      *
     42      * @return ScriptIntrinsicHistogram
     43      */
     44     public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
     45         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)))) {
     49             throw new RSIllegalArgumentException("Unsuported element type.");
     50         }
     51         long id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
     52         ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
     53         return sib;
     54     }
     55 
     56     /**
     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      */
     69     public void forEach(Allocation ain) {
     70         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) {
     88         if (ain.getType().getElement().getVectorSize() <
     89             mOut.getType().getElement().getVectorSize()) {
     90 
     91             throw new RSIllegalArgumentException(
     92                 "Input vector size must be >= output vector size.");
     93         }
     94         if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
     95             ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
     96             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
     97         }
     98 
     99         forEach(0, ain, null, null, opt);
    100     }
    101 
    102 
    103 
    104     /**
    105      * Set the coefficients used for the RGBA to Luminocity
    106      * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
    107      *
    108      * Coefficients must be >= 0 and sum to 1.0 or less.
    109      *
    110      * @param r Red coefficient
    111      * @param g Green coefficient
    112      * @param b Blue coefficient
    113      * @param a Alpha coefficient
    114      */
    115     public void setDotCoefficients(float r, float g, float b, float a) {
    116         if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
    117             throw new RSIllegalArgumentException("Coefficient may not be negative.");
    118         }
    119         if ((r + g + b + a) > 1.f) {
    120             throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
    121         }
    122 
    123         FieldPacker fp = new FieldPacker(16);
    124         fp.addF32(r);
    125         fp.addF32(g);
    126         fp.addF32(b);
    127         fp.addF32(a);
    128         setVar(0, fp);
    129     }
    130 
    131     /**
    132      * Set the output of the histogram.  32 bit integer types are
    133      * supported.
    134      *
    135      * @param aout The output allocation
    136      */
    137     public void setOutput(Allocation aout) {
    138         mOut = aout;
    139         if (mOut.getType().getElement() != Element.U32(mRS) &&
    140             mOut.getType().getElement() != Element.U32_2(mRS) &&
    141             mOut.getType().getElement() != Element.U32_3(mRS) &&
    142             mOut.getType().getElement() != Element.U32_4(mRS) &&
    143             mOut.getType().getElement() != Element.I32(mRS) &&
    144             mOut.getType().getElement() != Element.I32_2(mRS) &&
    145             mOut.getType().getElement() != Element.I32_3(mRS) &&
    146             mOut.getType().getElement() != Element.I32_4(mRS)) {
    147 
    148             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
    149         }
    150         if ((mOut.getType().getX() != 256) ||
    151             (mOut.getType().getY() != 0) ||
    152             mOut.getType().hasMipmaps() ||
    153             (mOut.getType().getYuv() != 0)) {
    154 
    155             throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
    156         }
    157         setVar(1, aout);
    158     }
    159 
    160 
    161     /**
    162      * Process an input buffer and place the histogram into the
    163      * output allocation. The dot product of the input channel and
    164      * the coefficients from 'setDotCoefficients' are used to
    165      * calculate the output values.
    166      *
    167      * 1D and 2D input allocations are supported.
    168      *
    169      * @param ain The input image
    170      */
    171     public void forEach_Dot(Allocation ain) {
    172         forEach_Dot(ain, null);
    173     }
    174 
    175     /**
    176      * Process an input buffer and place the histogram into the
    177      * output allocation. The dot product of the input channel and
    178      * the coefficients from 'setDotCoefficients' are used to
    179      * calculate the output values.
    180      *
    181      * 1D and 2D input allocations are supported.
    182      *
    183      * @param ain The input image
    184      * @param opt LaunchOptions for clipping
    185      */
    186     public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
    187         if (mOut.getType().getElement().getVectorSize() != 1) {
    188             throw new RSIllegalArgumentException("Output vector size must be one.");
    189         }
    190         if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
    191             ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
    192             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
    193         }
    194 
    195         forEach(1, ain, null, null, opt);
    196     }
    197 
    198 
    199 
    200     /**
    201      * Get a KernelID for this intrinsic kernel.
    202      *
    203      * @return Script.KernelID The KernelID object.
    204      */
    205     public Script.KernelID getKernelID_Separate() {
    206         return createKernelID(0, 3, null, null);
    207     }
    208 
    209     /**
    210      * Get a FieldID for the input field of this intrinsic.
    211      *
    212      * @return Script.FieldID The FieldID object.
    213      */
    214     public Script.FieldID getFieldID_Input() {
    215         return createFieldID(1, null);
    216     }
    217 }
    218 
    219