/*
* JAME 6.2.1
* http://jame.sourceforge.net
*
* Copyright 2001, 2016 Andrea Medeghini
*
* This file is part of JAME.
*
* JAME is an application for creating fractals and other graphics artifacts.
*
* JAME is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* JAME is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with JAME. If not, see <http://www.gnu.org/licenses/>.
*
*/
package net.sf.jame.core.util;
import java.awt.*;
/**
* Utility class for colors manipulation.
*
* @author Andrea Medeghini
*/
public class Colors {
/**
* Extracts the alpha component.
*
* @param rgb the color in rgb format.
* @return the alpha component.
*/
public static int getAlpha(final int argb) {
return (argb >> 24) & 0xFF;
}
/**
* Extracts the red component.
*
* @param argb the color in argb format.
* @return the red component.
*/
public static int getRed(final int argb) {
return (argb >> 16) & 0xFF;
}
/**
* Extracts the green component.
*
* @param argb the color in argb format.
* @return the green component.
*/
public static int getGreen(final int argb) {
return (argb >> 8) & 0xFF;
}
/**
* Extracts the blue component.
*
* @param argb the color in argb format.
* @return the blue component.
*/
public static int getBlue(final int argb) {
return (argb >> 0) & 0xFF;
}
/**
* @param rgb
* @param hsbvals
*/
public static void toHSB(int rgb, float[] hsbvals) {
Color.RGBtoHSB((rgb >> 16) & 0xFF, (rgb >> 8) & 0xFF, (rgb >> 0) & 0xFF, hsbvals);
}
/**
* @param alpha
* @param hsbvals
* @return
*/
public static int toRGB(int alpha, float[] hsbvals) {
return ((alpha & 0xFF) << 24) | Color.HSBtoRGB(hsbvals[0], hsbvals[1], hsbvals[2]);
}
/**
* @param hsbvals
* @return
*/
public static int toRGB(float[] hsbvals) {
return 0xFF000000 | Color.HSBtoRGB(hsbvals[0], hsbvals[1], hsbvals[2]);
}
/**
* Mixs two colors.
*
* @param color1 the first color in argb format.
* @param color2 the second color in argb format.
* @param alpha the alpha component.
* @return the mixed color.
*/
public static int mixColors(final int color1, final int color2, final int alpha) {
if (alpha == 0) {
return color1;
}
if (alpha == 255) {
return color2;
}
if (alpha == 127) {
return (((color1 & 0xFEFEFEFE) >> 1) + ((color2 & 0xFEFEFEFE) >> 1));
}
final int a = ((alpha * (((color2 >> 24) & 255) - ((color1 >> 24) & 255))) >> 8) + ((color1 >> 24) & 255);
final int r = ((alpha * (((color2 >> 16) & 255) - ((color1 >> 16) & 255))) >> 8) + ((color1 >> 16) & 255);
final int g = ((alpha * (((color2 >> 8) & 255) - ((color1 >> 8) & 255))) >> 8) + ((color1 >> 8) & 255);
final int b = ((alpha * ((color2 & 255) - (color1 & 255))) >> 8) + (color1 & 255);
return (a << 24) | (r << 16) | (g << 8) | b;
}
/**
* @param alpha
* @return
*/
public static int color(final int alpha, final int rgb) {
final int a = alpha & 255;
return (a << 24) | (rgb & 0xFFFFFF);
}
/**
* @param a
* @param r
* @param g
* @param b
* @return
*/
public static int color(final byte a, final byte r, final byte g, final byte b) {
return (0xFF000000 & ((a) << 24)) | (0xFF0000 & ((r) << 16)) | (0xFF00 & ((g) << 8)) | (0xFF & (b));
}
/**
* @param alpha
* @return
*/
public static int gray(final int alpha, final int level) {
final int a = alpha & 255;
final int l = level & 255;
return (a << 24) | (l << 16) | (l << 8) | l;
}
/**
* Fills the colors table.
*
* @param table the colors table to fill.
* @param offset the offset.
* @param length the length.
* @param color0 the first color.
* @param color1 the last color.
* @return the colors table.
*/
public static int[] fillTable(final int[] table, final int offset, final int length, final int color0, final int color1) {
final double[] delta = new double[4];
final int[] value = new int[4];
delta[0] = ((double) (Colors.getAlpha(color1) - Colors.getAlpha(color0))) / (double) length;
delta[1] = ((double) (Colors.getRed(color1) - Colors.getRed(color0))) / (double) length;
delta[2] = ((double) (Colors.getGreen(color1) - Colors.getGreen(color0))) / (double) length;
delta[3] = ((double) (Colors.getBlue(color1) - Colors.getBlue(color0))) / (double) length;
assert (table.length < offset + length);
for (int k = 0; k < length; k++) {
value[0] = (int) Math.round(delta[0] * k);
value[1] = (int) Math.round(delta[1] * k);
value[2] = (int) Math.round(delta[2] * k);
value[3] = (int) Math.round(delta[3] * k);
value[0] = (value[0] < 0) ? 0 : ((value[0] > 255) ? 255 : value[0]);
value[1] = (value[1] < 0) ? 0 : ((value[1] > 255) ? 255 : value[1]);
value[2] = (value[2] < 0) ? 0 : ((value[2] > 255) ? 255 : value[2]);
value[3] = (value[3] < 0) ? 0 : ((value[3] > 255) ? 255 : value[3]);
table[offset + k] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
}
return table;
}
/**
* Fills the colors table.
*
* @param table the colors table to fill.
* @param offset the offset.
* @param length the length.
* @param color0 the first color.
* @param color1 the last color.
* @param AV the alpha component modulation (same size as length parameter).
* @param RV the red component modulation (same size as length parameter).
* @param GV the green component modulation (same size as length parameter).
* @param BV the blue component modulation (same size as length parameter).
* @return the colors table.
*/
public static int[] fillTable(final int[] table, final int offset, final int length, final int color0, final int color1, final double[] AV, final double[] RV, final double[] GV, final double[] BV) {
final double[] delta = new double[4];
final int[] value = new int[4];
delta[0] = (Colors.getAlpha(color1) - Colors.getAlpha(color0));
delta[1] = (Colors.getRed(color1) - Colors.getRed(color0));
delta[2] = (Colors.getGreen(color1) - Colors.getGreen(color0));
delta[3] = (Colors.getBlue(color1) - Colors.getBlue(color0));
assert (AV.length == length);
assert (RV.length == length);
assert (GV.length == length);
assert (BV.length == length);
assert (table.length >= offset + length);
final int a = Colors.getAlpha(color0);
final int r = Colors.getRed(color0);
final int g = Colors.getGreen(color0);
final int b = Colors.getBlue(color0);
for (int k = 0; k < length; k++) {
value[0] = (int) Math.rint(a + delta[0] * AV[k]);
value[1] = (int) Math.rint(r + delta[1] * RV[k]);
value[2] = (int) Math.rint(g + delta[2] * GV[k]);
value[3] = (int) Math.rint(b + delta[3] * BV[k]);
value[0] = (value[0] < 0) ? 0 : ((value[0] > 255) ? 255 : value[0]);
value[1] = (value[1] < 0) ? 0 : ((value[1] > 255) ? 255 : value[1]);
value[2] = (value[2] < 0) ? 0 : ((value[2] > 255) ? 255 : value[2]);
value[3] = (value[3] < 0) ? 0 : ((value[3] > 255) ? 255 : value[3]);
table[offset + k] = (value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3];
}
return table;
}
}