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("Unsupported 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_2(mRS)) &&
     96             !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
     97             !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
     98             throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
     99         }
    100 
    101         forEach(0, ain, null, null, opt);
    102     }
    103 
    104 
    105 
    106     /**
    107      * Set the coefficients used for the RGBA to Luminocity
    108      * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
    109      *
    110      * Coefficients must be >= 0 and sum to 1.0 or less.
    111      *
    112      * @param r Red coefficient
    113      * @param g Green coefficient
    114      * @param b Blue coefficient
    115      * @param a Alpha coefficient
    116      */
    117     public void setDotCoefficients(float r, float g, float b, float a) {
    118         if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
    119             throw new RSIllegalArgumentException("Coefficient may not be negative.");
    120         }
    121         if ((r + g + b + a) > 1.f) {
    122             throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
    123         }
    124 
    125         FieldPacker fp = new FieldPacker(16);
    126         fp.addF32(r);
    127         fp.addF32(g);
    128         fp.addF32(b);
    129         fp.addF32(a);
    130         setVar(0, fp);
    131     }
    132 
    133     /**
    134      * Set the output of the histogram.  32 bit integer types are
    135      * supported.
    136      *
    137      * @param aout The output allocation
    138      */
    139     public void setOutput(Allocation aout) {
    140         mOut = aout;
    141         if (mOut.getType().getElement() != Element.U32(mRS) &&
    142             mOut.getType().getElement() != Element.U32_2(mRS) &&
    143             mOut.getType().getElement() != Element.U32_3(mRS) &&
    144             mOut.getType().getElement() != Element.U32_4(mRS) &&
    145             mOut.getType().getElement() != Element.I32(mRS) &&
    146             mOut.getType().getElement() != Element.I32_2(mRS) &&
    147             mOut.getType().getElement() != Element.I32_3(mRS) &&
    148             mOut.getType().getElement() != Element.I32_4(mRS)) {
    149 
    150             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
    151         }
    152         if ((mOut.getType().getX() != 256) ||
    153             (mOut.getType().getY() != 0) ||
    154             mOut.getType().hasMipmaps() ||
    155             (mOut.getType().getYuv() != 0)) {
    156 
    157             throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
    158         }
    159         setVar(1, aout);
    160     }
    161 
    162 
    163     /**
    164      * Process an input buffer and place the histogram into the
    165      * output allocation. The dot product of the input channel and
    166      * the coefficients from 'setDotCoefficients' are used to
    167      * calculate the output values.
    168      *
    169      * 1D and 2D input allocations are supported.
    170      *
    171      * @param ain The input image
    172      */
    173     public void forEach_Dot(Allocation ain) {
    174         forEach_Dot(ain, null);
    175     }
    176 
    177     /**
    178      * Process an input buffer and place the histogram into the
    179      * output allocation. The dot product of the input channel and
    180      * the coefficients from 'setDotCoefficients' are used to
    181      * calculate the output values.
    182      *
    183      * 1D and 2D input allocations are supported.
    184      *
    185      * @param ain The input image
    186      * @param opt LaunchOptions for clipping
    187      */
    188     public void forEach_Dot(Allocation ain, Script.LaunchOptions opt) {
    189         if (mOut.getType().getElement().getVectorSize() != 1) {
    190             throw new RSIllegalArgumentException("Output vector size must be one.");
    191         }
    192         if (!ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
    193             !ain.getType().getElement().isCompatible(Element.U8_2(mRS)) &&
    194             !ain.getType().getElement().isCompatible(Element.U8_3(mRS)) &&
    195             !ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
    196             throw new RSIllegalArgumentException("Input type must be U8, U8_1, U8_2 or U8_4.");
    197         }
    198 
    199         forEach(1, ain, null, null, opt);
    200     }
    201 
    202 
    203 
    204     /**
    205      * Get a KernelID for this intrinsic kernel.
    206      *
    207      * @return Script.KernelID The KernelID object.
    208      */
    209     public Script.KernelID getKernelID_Separate() {
    210         return createKernelID(0, 3, null, null);
    211     }
    212 
    213     /**
    214      * Get a FieldID for the input field of this intrinsic.
    215      *
    216      * @return Script.FieldID The FieldID object.
    217      */
    218     public Script.FieldID getFieldID_Input() {
    219         return createFieldID(1, null);
    220     }
    221 }
    222 
    223