Home | History | Annotate | Download | only in renderscript
      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