1 /* 2 * Copyright (C) 2012 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 for applying a color matrix to allocations. 21 * 22 * If the element type is {@link Element.DataType#UNSIGNED_8}, 23 * it is converted to {@link Element.DataType#FLOAT_32} and 24 * normalized from (0-255) to (0-1). If the incoming vector size 25 * is less than four, a {@link Element#F32_4} is created by 26 * filling the missing vector channels with zero. This value is 27 * then multiplied by the 4x4 color matrix as performed by 28 * rsMatrixMultiply(), adding a {@link Element#F32_4}, and then 29 * writing it to the output {@link Allocation}. 30 * 31 * If the ouptut type is unsigned, the value is normalized from 32 * (0-1) to (0-255) and converted. If the output vector size is 33 * less than four, the unused channels are discarded. 34 * 35 * Supported elements types are {@link Element#U8}, {@link 36 * Element#U8_2}, {@link Element#U8_3}, {@link Element#U8_4}, 37 * {@link Element#F32}, {@link Element#F32_2}, {@link 38 * Element#F32_3}, and {@link Element#F32_4}. 39 **/ 40 public final class ScriptIntrinsicColorMatrix extends ScriptIntrinsic { 41 private final Matrix4f mMatrix = new Matrix4f(); 42 private final Float4 mAdd = new Float4(); 43 44 private ScriptIntrinsicColorMatrix(long id, RenderScript rs) { 45 super(id, rs); 46 } 47 48 /** 49 * Create an intrinsic for applying a color matrix to an 50 * allocation. 51 * 52 * @param rs The RenderScript context 53 * @param e Element type for inputs and outputs, As of API 19, 54 * this parameter is ignored. The Element type check is 55 * performed in the kernel launch. 56 * 57 * @deprecated Use the single argument version as Element is now 58 * ignored. 59 * 60 * @return ScriptIntrinsicColorMatrix 61 */ 62 @Deprecated 63 public static ScriptIntrinsicColorMatrix create(RenderScript rs, Element e) { 64 return create(rs); 65 } 66 67 /** 68 * Create an intrinsic for applying a color matrix to an 69 * allocation. 70 * 71 * @param rs The RenderScript context 72 * 73 * @return ScriptIntrinsicColorMatrix 74 */ 75 public static ScriptIntrinsicColorMatrix create(RenderScript rs) { 76 long id = rs.nScriptIntrinsicCreate(2, 0); 77 return new ScriptIntrinsicColorMatrix(id, rs); 78 79 } 80 81 private void setMatrix() { 82 FieldPacker fp = new FieldPacker(16*4); 83 fp.addMatrix(mMatrix); 84 setVar(0, fp); 85 } 86 87 /** 88 * Set the color matrix which will be applied to each cell of 89 * the image. 90 * 91 * @param m The 4x4 matrix to set. 92 */ 93 public void setColorMatrix(Matrix4f m) { 94 mMatrix.load(m); 95 setMatrix(); 96 } 97 98 /** 99 * Set the color matrix which will be applied to each cell of the image. 100 * This will set the alpha channel to be a copy. 101 * 102 * @param m The 3x3 matrix to set. 103 */ 104 public void setColorMatrix(Matrix3f m) { 105 mMatrix.load(m); 106 setMatrix(); 107 } 108 109 /** 110 * Set the value to be added after the color matrix has been 111 * applied. The default value is {0, 0, 0, 0} 112 * 113 * @param f The float4 value to be added. 114 */ 115 public void setAdd(Float4 f) { 116 mAdd.x = f.x; 117 mAdd.y = f.y; 118 mAdd.z = f.z; 119 mAdd.w = f.w; 120 121 FieldPacker fp = new FieldPacker(4*4); 122 fp.addF32(f.x); 123 fp.addF32(f.y); 124 fp.addF32(f.z); 125 fp.addF32(f.w); 126 setVar(1, fp); 127 } 128 129 /** 130 * Set the value to be added after the color matrix has been 131 * applied. The default value is {0, 0, 0, 0} 132 * 133 * @param r The red add value. 134 * @param g The green add value. 135 * @param b The blue add value. 136 * @param a The alpha add value. 137 */ 138 public void setAdd(float r, float g, float b, float a) { 139 mAdd.x = r; 140 mAdd.y = g; 141 mAdd.z = b; 142 mAdd.w = a; 143 144 FieldPacker fp = new FieldPacker(4*4); 145 fp.addF32(mAdd.x); 146 fp.addF32(mAdd.y); 147 fp.addF32(mAdd.z); 148 fp.addF32(mAdd.w); 149 setVar(1, fp); 150 } 151 152 /** 153 * Set a color matrix to convert from RGB to luminance. The alpha channel 154 * will be a copy. 155 * 156 */ 157 public void setGreyscale() { 158 mMatrix.loadIdentity(); 159 mMatrix.set(0, 0, 0.299f); 160 mMatrix.set(1, 0, 0.587f); 161 mMatrix.set(2, 0, 0.114f); 162 mMatrix.set(0, 1, 0.299f); 163 mMatrix.set(1, 1, 0.587f); 164 mMatrix.set(2, 1, 0.114f); 165 mMatrix.set(0, 2, 0.299f); 166 mMatrix.set(1, 2, 0.587f); 167 mMatrix.set(2, 2, 0.114f); 168 setMatrix(); 169 } 170 171 /** 172 * Set the matrix to convert from YUV to RGB with a direct copy of the 4th 173 * channel. 174 * 175 */ 176 public void setYUVtoRGB() { 177 mMatrix.loadIdentity(); 178 mMatrix.set(0, 0, 1.f); 179 mMatrix.set(1, 0, 0.f); 180 mMatrix.set(2, 0, 1.13983f); 181 mMatrix.set(0, 1, 1.f); 182 mMatrix.set(1, 1, -0.39465f); 183 mMatrix.set(2, 1, -0.5806f); 184 mMatrix.set(0, 2, 1.f); 185 mMatrix.set(1, 2, 2.03211f); 186 mMatrix.set(2, 2, 0.f); 187 setMatrix(); 188 } 189 190 /** 191 * Set the matrix to convert from RGB to YUV with a direct copy of the 4th 192 * channel. 193 * 194 */ 195 public void setRGBtoYUV() { 196 mMatrix.loadIdentity(); 197 mMatrix.set(0, 0, 0.299f); 198 mMatrix.set(1, 0, 0.587f); 199 mMatrix.set(2, 0, 0.114f); 200 mMatrix.set(0, 1, -0.14713f); 201 mMatrix.set(1, 1, -0.28886f); 202 mMatrix.set(2, 1, 0.436f); 203 mMatrix.set(0, 2, 0.615f); 204 mMatrix.set(1, 2, -0.51499f); 205 mMatrix.set(2, 2, -0.10001f); 206 setMatrix(); 207 } 208 209 /** 210 * Invoke the kernel and apply the matrix to each cell of input 211 * {@link Allocation} and copy to the output {@link Allocation}. 212 * 213 * If the vector size of the input is less than four, the 214 * remaining components are treated as zero for the matrix 215 * multiply. 216 * 217 * If the output vector size is less than four, the unused 218 * vector components are discarded. 219 * 220 * 221 * @param ain Input allocation 222 * @param aout Output allocation 223 */ 224 public void forEach(Allocation ain, Allocation aout) { 225 forEach(ain, aout, null); 226 } 227 228 /** 229 * Invoke the kernel and apply the matrix to each cell of input 230 * {@link Allocation} and copy to the output {@link Allocation}. 231 * 232 * If the vector size of the input is less than four, the 233 * remaining components are treated as zero for the matrix 234 * multiply. 235 * 236 * If the output vector size is less than four, the unused 237 * vector components are discarded. 238 * 239 * 240 * @param ain Input allocation 241 * @param aout Output allocation 242 * @param opt LaunchOptions for clipping 243 */ 244 public void forEach(Allocation ain, Allocation aout, Script.LaunchOptions opt) { 245 if (!ain.getElement().isCompatible(Element.U8(mRS)) && 246 !ain.getElement().isCompatible(Element.U8_2(mRS)) && 247 !ain.getElement().isCompatible(Element.U8_3(mRS)) && 248 !ain.getElement().isCompatible(Element.U8_4(mRS)) && 249 !ain.getElement().isCompatible(Element.F32(mRS)) && 250 !ain.getElement().isCompatible(Element.F32_2(mRS)) && 251 !ain.getElement().isCompatible(Element.F32_3(mRS)) && 252 !ain.getElement().isCompatible(Element.F32_4(mRS))) { 253 254 throw new RSIllegalArgumentException("Unsuported element type."); 255 } 256 257 if (!aout.getElement().isCompatible(Element.U8(mRS)) && 258 !aout.getElement().isCompatible(Element.U8_2(mRS)) && 259 !aout.getElement().isCompatible(Element.U8_3(mRS)) && 260 !aout.getElement().isCompatible(Element.U8_4(mRS)) && 261 !aout.getElement().isCompatible(Element.F32(mRS)) && 262 !aout.getElement().isCompatible(Element.F32_2(mRS)) && 263 !aout.getElement().isCompatible(Element.F32_3(mRS)) && 264 !aout.getElement().isCompatible(Element.F32_4(mRS))) { 265 266 throw new RSIllegalArgumentException("Unsuported element type."); 267 } 268 269 forEach(0, ain, aout, null, opt); 270 } 271 272 /** 273 * Get a KernelID for this intrinsic kernel. 274 * 275 * @return Script.KernelID The KernelID object. 276 */ 277 public Script.KernelID getKernelID() { 278 return createKernelID(0, 3, null, null); 279 } 280 281 } 282 283