summaryrefslogtreecommitdiffstats
path: root/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java
diff options
context:
space:
mode:
Diffstat (limited to 'src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java')
-rw-r--r--src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java225
1 files changed, 225 insertions, 0 deletions
diff --git a/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java b/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java
new file mode 100644
index 000000000..7c307a9e7
--- /dev/null
+++ b/src/com/android/gallery3d/filtershow/filters/ColorSpaceMatrix.java
@@ -0,0 +1,225 @@
+/*
+ * 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];
+ }
+
+}