/* * Copyright (C) 2012 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.gallery3d.filtershow.filters; import java.util.Arrays; public class ColorSpaceMatrix { private final float[] mMatrix = new float[16]; private static final float RLUM = 0.3086f; private static final float GLUM = 0.6094f; private static final float BLUM = 0.0820f; public ColorSpaceMatrix() { identity(); } /** * Copy constructor * * @param matrix */ public ColorSpaceMatrix(ColorSpaceMatrix matrix) { System.arraycopy(matrix.mMatrix, 0, mMatrix, 0, matrix.mMatrix.length); } /** * get the matrix * * @return the internal matrix */ public float[] getMatrix() { return mMatrix; } /** * set matrix to identity */ public void identity() { Arrays.fill(mMatrix, 0); mMatrix[0] = mMatrix[5] = mMatrix[10] = mMatrix[15] = 1; } public void convertToLuminance() { mMatrix[0] = mMatrix[1] = mMatrix[2] = 0.3086f; mMatrix[4] = mMatrix[5] = mMatrix[6] = 0.6094f; mMatrix[8] = mMatrix[9] = mMatrix[10] = 0.0820f; } private void multiply(float[] a) { int x, y; float[] temp = new float[16]; for (y = 0; y < 4; y++) { int y4 = y * 4; for (x = 0; x < 4; x++) { temp[y4 + x] = mMatrix[y4 + 0] * a[x] + mMatrix[y4 + 1] * a[4 + x] + mMatrix[y4 + 2] * a[8 + x] + mMatrix[y4 + 3] * a[12 + x]; } } for (int i = 0; i < 16; i++) mMatrix[i] = temp[i]; } private void xRotateMatrix(float rs, float rc) { ColorSpaceMatrix c = new ColorSpaceMatrix(); float[] tmp = c.mMatrix; tmp[5] = rc; tmp[6] = rs; tmp[9] = -rs; tmp[10] = rc; multiply(tmp); } private void yRotateMatrix(float rs, float rc) { ColorSpaceMatrix c = new ColorSpaceMatrix(); float[] tmp = c.mMatrix; tmp[0] = rc; tmp[2] = -rs; tmp[8] = rs; tmp[10] = rc; multiply(tmp); } private void zRotateMatrix(float rs, float rc) { ColorSpaceMatrix c = new ColorSpaceMatrix(); float[] tmp = c.mMatrix; tmp[0] = rc; tmp[1] = rs; tmp[4] = -rs; tmp[5] = rc; multiply(tmp); } private void zShearMatrix(float dx, float dy) { ColorSpaceMatrix c = new ColorSpaceMatrix(); float[] tmp = c.mMatrix; tmp[2] = dx; tmp[6] = dy; multiply(tmp); } /** * sets the transform to a shift in Hue * * @param rot rotation in degrees */ public void setHue(float rot) { float mag = (float) Math.sqrt(2.0); float xrs = 1 / mag; float xrc = 1 / mag; xRotateMatrix(xrs, xrc); mag = (float) Math.sqrt(3.0); float yrs = -1 / mag; float yrc = (float) Math.sqrt(2.0) / mag; yRotateMatrix(yrs, yrc); float lx = getRedf(RLUM, GLUM, BLUM); float ly = getGreenf(RLUM, GLUM, BLUM); float lz = getBluef(RLUM, GLUM, BLUM); float zsx = lx / lz; float zsy = ly / lz; zShearMatrix(zsx, zsy); float zrs = (float) Math.sin(rot * Math.PI / 180.0); float zrc = (float) Math.cos(rot * Math.PI / 180.0); zRotateMatrix(zrs, zrc); zShearMatrix(-zsx, -zsy); yRotateMatrix(-yrs, yrc); xRotateMatrix(-xrs, xrc); } /** * set it to a saturation matrix * * @param s */ public void changeSaturation(float s) { mMatrix[0] = (1 - s) * RLUM + s; mMatrix[1] = (1 - s) * RLUM; mMatrix[2] = (1 - s) * RLUM; mMatrix[4] = (1 - s) * GLUM; mMatrix[5] = (1 - s) * GLUM + s; mMatrix[6] = (1 - s) * GLUM; mMatrix[8] = (1 - s) * BLUM; mMatrix[9] = (1 - s) * BLUM; mMatrix[10] = (1 - s) * BLUM + s; } /** * Transform RGB value * * @param r red pixel value * @param g green pixel value * @param b blue pixel value * @return computed red pixel value */ public float getRed(int r, int g, int b) { return r * mMatrix[0] + g * mMatrix[4] + b * mMatrix[8] + mMatrix[12]; } /** * Transform RGB value * * @param r red pixel value * @param g green pixel value * @param b blue pixel value * @return computed green pixel value */ public float getGreen(int r, int g, int b) { return r * mMatrix[1] + g * mMatrix[5] + b * mMatrix[9] + mMatrix[13]; } /** * Transform RGB value * * @param r red pixel value * @param g green pixel value * @param b blue pixel value * @return computed blue pixel value */ public float getBlue(int r, int g, int b) { return r * mMatrix[2] + g * mMatrix[6] + b * mMatrix[10] + mMatrix[14]; } private float getRedf(float r, float g, float b) { return r * mMatrix[0] + g * mMatrix[4] + b * mMatrix[8] + mMatrix[12]; } private float getGreenf(float r, float g, float b) { return r * mMatrix[1] + g * mMatrix[5] + b * mMatrix[9] + mMatrix[13]; } private float getBluef(float r, float g, float b) { return r * mMatrix[2] + g * mMatrix[6] + b * mMatrix[10] + mMatrix[14]; } }