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