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 ColorSpaceMatrix()27 public ColorSpaceMatrix() { 28 identity(); 29 } 30 31 /** 32 * Copy constructor 33 * 34 * @param matrix 35 */ ColorSpaceMatrix(ColorSpaceMatrix matrix)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 */ getMatrix()45 public float[] getMatrix() { 46 return mMatrix; 47 } 48 49 /** 50 * set matrix to identity 51 */ identity()52 public void identity() { 53 Arrays.fill(mMatrix, 0); 54 mMatrix[0] = mMatrix[5] = mMatrix[10] = mMatrix[15] = 1; 55 } 56 convertToLuminance()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 multiply(float[] a)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 xRotateMatrix(float rs, float rc)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 yRotateMatrix(float rs, float rc)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 zRotateMatrix(float rs, float rc)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 zShearMatrix(float dx, float dy)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 */ setHue(float rot)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 */ changeSaturation(float s)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 */ getRed(int r, int g, int b)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 */ getGreen(int r, int g, int b)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 */ getBlue(int r, int g, int b)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 getRedf(float r, float g, float b)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 getGreenf(float r, float g, float b)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 getBluef(float r, float g, float b)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