Home | History | Annotate | Download | only in filters
      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 com.android.gallery3d.filtershow.filters;
     18 
     19 import java.util.Arrays;
     20 
     21 public class ColorSpaceMatrix {
     22     private final float[] mMatrix = new float[16];
     23     private static final float RLUM = 0.3086f;
     24     private static final float GLUM = 0.6094f;
     25     private static final float BLUM = 0.0820f;
     26 
     27     public ColorSpaceMatrix() {
     28         identity();
     29     }
     30 
     31     /**
     32      * Copy constructor
     33      *
     34      * @param matrix
     35      */
     36     public ColorSpaceMatrix(ColorSpaceMatrix matrix) {
     37         System.arraycopy(matrix.mMatrix, 0, mMatrix, 0, matrix.mMatrix.length);
     38     }
     39 
     40     /**
     41      * get the matrix
     42      *
     43      * @return the internal matrix
     44      */
     45     public float[] getMatrix() {
     46         return mMatrix;
     47     }
     48 
     49     /**
     50      * set matrix to identity
     51      */
     52     public void identity() {
     53         Arrays.fill(mMatrix, 0);
     54         mMatrix[0] = mMatrix[5] = mMatrix[10] = mMatrix[15] = 1;
     55     }
     56 
     57     public void convertToLuminance() {
     58         mMatrix[0] = mMatrix[1] = mMatrix[2] = 0.3086f;
     59         mMatrix[4] = mMatrix[5] = mMatrix[6] = 0.6094f;
     60         mMatrix[8] = mMatrix[9] = mMatrix[10] = 0.0820f;
     61     }
     62 
     63     private void multiply(float[] a)
     64     {
     65         int x, y;
     66         float[] temp = new float[16];
     67 
     68         for (y = 0; y < 4; y++) {
     69             int y4 = y * 4;
     70             for (x = 0; x < 4; x++) {
     71                 temp[y4 + x] = mMatrix[y4 + 0] * a[x]
     72                         + mMatrix[y4 + 1] * a[4 + x]
     73                         + mMatrix[y4 + 2] * a[8 + x]
     74                         + mMatrix[y4 + 3] * a[12 + x];
     75             }
     76         }
     77         for (int i = 0; i < 16; i++)
     78             mMatrix[i] = temp[i];
     79     }
     80 
     81     private void xRotateMatrix(float rs, float rc)
     82     {
     83         ColorSpaceMatrix c = new ColorSpaceMatrix();
     84         float[] tmp = c.mMatrix;
     85 
     86         tmp[5] = rc;
     87         tmp[6] = rs;
     88         tmp[9] = -rs;
     89         tmp[10] = rc;
     90 
     91         multiply(tmp);
     92     }
     93 
     94     private void yRotateMatrix(float rs, float rc)
     95     {
     96         ColorSpaceMatrix c = new ColorSpaceMatrix();
     97         float[] tmp = c.mMatrix;
     98 
     99         tmp[0] = rc;
    100         tmp[2] = -rs;
    101         tmp[8] = rs;
    102         tmp[10] = rc;
    103 
    104         multiply(tmp);
    105     }
    106 
    107     private void zRotateMatrix(float rs, float rc)
    108     {
    109         ColorSpaceMatrix c = new ColorSpaceMatrix();
    110         float[] tmp = c.mMatrix;
    111 
    112         tmp[0] = rc;
    113         tmp[1] = rs;
    114         tmp[4] = -rs;
    115         tmp[5] = rc;
    116         multiply(tmp);
    117     }
    118 
    119     private void zShearMatrix(float dx, float dy)
    120     {
    121         ColorSpaceMatrix c = new ColorSpaceMatrix();
    122         float[] tmp = c.mMatrix;
    123 
    124         tmp[2] = dx;
    125         tmp[6] = dy;
    126         multiply(tmp);
    127     }
    128 
    129     /**
    130      * sets the transform to a shift in Hue
    131      *
    132      * @param rot rotation in degrees
    133      */
    134     public void setHue(float rot)
    135     {
    136         float mag = (float) Math.sqrt(2.0);
    137         float xrs = 1 / mag;
    138         float xrc = 1 / mag;
    139         xRotateMatrix(xrs, xrc);
    140         mag = (float) Math.sqrt(3.0);
    141         float yrs = -1 / mag;
    142         float yrc = (float) Math.sqrt(2.0) / mag;
    143         yRotateMatrix(yrs, yrc);
    144 
    145         float lx = getRedf(RLUM, GLUM, BLUM);
    146         float ly = getGreenf(RLUM, GLUM, BLUM);
    147         float lz = getBluef(RLUM, GLUM, BLUM);
    148         float zsx = lx / lz;
    149         float zsy = ly / lz;
    150         zShearMatrix(zsx, zsy);
    151 
    152         float zrs = (float) Math.sin(rot * Math.PI / 180.0);
    153         float zrc = (float) Math.cos(rot * Math.PI / 180.0);
    154         zRotateMatrix(zrs, zrc);
    155         zShearMatrix(-zsx, -zsy);
    156         yRotateMatrix(-yrs, yrc);
    157         xRotateMatrix(-xrs, xrc);
    158     }
    159 
    160     /**
    161      * set it to a saturation matrix
    162      *
    163      * @param s
    164      */
    165     public void changeSaturation(float s) {
    166         mMatrix[0] = (1 - s) * RLUM + s;
    167         mMatrix[1] = (1 - s) * RLUM;
    168         mMatrix[2] = (1 - s) * RLUM;
    169         mMatrix[4] = (1 - s) * GLUM;
    170         mMatrix[5] = (1 - s) * GLUM + s;
    171         mMatrix[6] = (1 - s) * GLUM;
    172         mMatrix[8] = (1 - s) * BLUM;
    173         mMatrix[9] = (1 - s) * BLUM;
    174         mMatrix[10] = (1 - s) * BLUM + s;
    175     }
    176 
    177     /**
    178      * Transform RGB value
    179      *
    180      * @param r red pixel value
    181      * @param g green pixel value
    182      * @param b blue pixel value
    183      * @return computed red pixel value
    184      */
    185     public float getRed(int r, int g, int b) {
    186         return r * mMatrix[0] + g * mMatrix[4] + b * mMatrix[8] + mMatrix[12];
    187     }
    188 
    189     /**
    190      * Transform RGB value
    191      *
    192      * @param r red pixel value
    193      * @param g green pixel value
    194      * @param b blue pixel value
    195      * @return computed green pixel value
    196      */
    197     public float getGreen(int r, int g, int b) {
    198         return r * mMatrix[1] + g * mMatrix[5] + b * mMatrix[9] + mMatrix[13];
    199     }
    200 
    201     /**
    202      * Transform RGB value
    203      *
    204      * @param r red pixel value
    205      * @param g green pixel value
    206      * @param b blue pixel value
    207      * @return computed blue pixel value
    208      */
    209     public float getBlue(int r, int g, int b) {
    210         return r * mMatrix[2] + g * mMatrix[6] + b * mMatrix[10] + mMatrix[14];
    211     }
    212 
    213     private float getRedf(float r, float g, float b) {
    214         return r * mMatrix[0] + g * mMatrix[4] + b * mMatrix[8] + mMatrix[12];
    215     }
    216 
    217     private float getGreenf(float r, float g, float b) {
    218         return r * mMatrix[1] + g * mMatrix[5] + b * mMatrix[9] + mMatrix[13];
    219     }
    220 
    221     private float getBluef(float r, float g, float b) {
    222         return r * mMatrix[2] + g * mMatrix[6] + b * mMatrix[10] + mMatrix[14];
    223     }
    224 
    225 }
    226