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