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 import android.content.Context;
     20 import android.content.res.Resources;
     21 import android.util.Log;
     22 
     23 /**
     24  * Intrinsic Histogram filter.
     25  *
     26  *
     27  **/
     28 public 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
     40      * {@link Element#U8_4}, {@link Element#U8_3},
     41      * {@link Element#U8_2}, {@link Element#U8}
     42      *
     43      * @param rs The RenderScript context
     44      * @param e Element type for inputs
     45      *
     46      * @return ScriptIntrinsicHistogram
     47      */
     48     public static ScriptIntrinsicHistogram create(RenderScript rs, Element e) {
     49         if ((!e.isCompatible(Element.U8_4(rs))) &&
     50             (!e.isCompatible(Element.U8_3(rs))) &&
     51             (!e.isCompatible(Element.U8_2(rs))) &&
     52             (!e.isCompatible(Element.U8(rs)))) {
     53             throw new RSIllegalArgumentException("Unsuported element type.");
     54         }
     55         int id = rs.nScriptIntrinsicCreate(9, e.getID(rs));
     56         ScriptIntrinsicHistogram sib = new ScriptIntrinsicHistogram(id, rs);
     57         return sib;
     58     }
     59 
     60     /**
     61      * Process an input buffer and place the histogram into the
     62      * output allocation. The output allocation may be a narrower
     63      * vector size than the input. In this case the vector size of
     64      * the output is used to determine how many of the input
     65      * channels are used in the computation. This is useful if you
     66      * have an RGBA input buffer but only want the histogram for
     67      * RGB.
     68      *
     69      * 1D and 2D input allocations are supported.
     70      *
     71      * @param ain The input image
     72      */
     73     public void forEach(Allocation ain) {
     74         if (ain.getType().getElement().getVectorSize() <
     75             mOut.getType().getElement().getVectorSize()) {
     76 
     77             throw new RSIllegalArgumentException(
     78                 "Input vector size must be >= output vector size.");
     79         }
     80         if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
     81             ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
     82             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
     83         }
     84 
     85         forEach(0, ain, null, null);
     86     }
     87 
     88     /**
     89      * Set the coefficients used for the RGBA to Luminocity
     90      * calculation. The default is {0.299f, 0.587f, 0.114f, 0.f}.
     91      *
     92      * Coefficients must be >= 0 and sum to 1.0 or less.
     93      *
     94      * @param r Red coefficient
     95      * @param g Green coefficient
     96      * @param b Blue coefficient
     97      * @param a Alpha coefficient
     98      */
     99     public void setDotCoefficients(float r, float g, float b, float a) {
    100         if ((r < 0.f) || (g < 0.f) || (b < 0.f) || (a < 0.f)) {
    101             throw new RSIllegalArgumentException("Coefficient may not be negative.");
    102         }
    103         if ((r + g + b + a) > 1.f) {
    104             throw new RSIllegalArgumentException("Sum of coefficients must be 1.0 or less.");
    105         }
    106 
    107         FieldPacker fp = new FieldPacker(16);
    108         fp.addF32(r);
    109         fp.addF32(g);
    110         fp.addF32(b);
    111         fp.addF32(a);
    112         setVar(0, fp);
    113     }
    114 
    115     /**
    116      * Set the output of the histogram.  32 bit integer types are
    117      * supported.
    118      *
    119      * @param aout The output allocation
    120      */
    121     public void setOutput(Allocation aout) {
    122         mOut = aout;
    123         if (mOut.getType().getElement() != Element.U32(mRS) &&
    124             mOut.getType().getElement() != Element.U32_2(mRS) &&
    125             mOut.getType().getElement() != Element.U32_3(mRS) &&
    126             mOut.getType().getElement() != Element.U32_4(mRS) &&
    127             mOut.getType().getElement() != Element.I32(mRS) &&
    128             mOut.getType().getElement() != Element.I32_2(mRS) &&
    129             mOut.getType().getElement() != Element.I32_3(mRS) &&
    130             mOut.getType().getElement() != Element.I32_4(mRS)) {
    131 
    132             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
    133         }
    134         if ((mOut.getType().getX() != 256) ||
    135             (mOut.getType().getY() != 0) ||
    136             mOut.getType().hasMipmaps() ||
    137             (mOut.getType().getYuv() != 0)) {
    138 
    139             throw new RSIllegalArgumentException("Output must be 1D, 256 elements.");
    140         }
    141         setVar(1, aout);
    142     }
    143 
    144     /**
    145      * Process an input buffer and place the histogram into the
    146      * output allocation. The dot product of the input channel and
    147      * the coefficients from 'setDotCoefficients' are used to
    148      * calculate the output values.
    149      *
    150      * 1D and 2D input allocations are supported.
    151      *
    152      * @param ain The input image
    153      */
    154     public void forEach_Dot(Allocation ain) {
    155         if (mOut.getType().getElement().getVectorSize() != 1) {
    156             throw new RSIllegalArgumentException("Output vector size must be one.");
    157         }
    158         if (ain.getType().getElement().isCompatible(Element.U8(mRS)) &&
    159             ain.getType().getElement().isCompatible(Element.U8_4(mRS))) {
    160             throw new RSIllegalArgumentException("Output type must be U32 or I32.");
    161         }
    162 
    163         forEach(1, ain, null, null);
    164     }
    165 
    166 
    167 
    168     /**
    169      * Get a KernelID for this intrinsic kernel.
    170      *
    171      * @return Script.KernelID The KernelID object.
    172      */
    173     public Script.KernelID getKernelID_Separate() {
    174         return createKernelID(0, 3, null, null);
    175     }
    176 
    177     /**
    178      * Get a FieldID for the input field of this intrinsic.
    179      *
    180      * @return Script.FieldID The FieldID object.
    181      */
    182     public Script.FieldID getFieldID_Input() {
    183         return createFieldID(1, null);
    184     }
    185 }
    186 
    187