RgbProfileConverter.java [plain text]
package gnu.java.awt.color;
import java.awt.color.ProfileDataException;
import java.awt.color.ICC_Profile;
import java.awt.color.ICC_ProfileRGB;
public class RgbProfileConverter implements ColorSpaceConverter
{
private float[][] matrix;
private float[][] inv_matrix;
private ToneReproductionCurve rTRC;
private ToneReproductionCurve gTRC;
private ToneReproductionCurve bTRC;
private ColorLookUpTable toPCS;
private ColorLookUpTable fromPCS;
private static float[] D50 = { 0.96422f, 1.00f, 0.82521f };
public RgbProfileConverter(ICC_ProfileRGB profile)
{
toPCS = fromPCS = null;
matrix = profile.getMatrix();
try
{
rTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.REDCOMPONENT));
}
catch (ProfileDataException e)
{
rTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.REDCOMPONENT));
}
try
{
gTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.GREENCOMPONENT));
}
catch (ProfileDataException e)
{
gTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.GREENCOMPONENT));
}
try
{
bTRC = new ToneReproductionCurve(profile.getGamma(ICC_ProfileRGB.BLUECOMPONENT));
}
catch (ProfileDataException e)
{
bTRC = new ToneReproductionCurve(profile.getTRC(ICC_ProfileRGB.BLUECOMPONENT));
}
try
{
toPCS = new ColorLookUpTable(profile, ICC_Profile.icSigAToB0Tag);
}
catch (Exception e)
{
toPCS = null;
}
try
{
fromPCS = new ColorLookUpTable(profile, ICC_Profile.icSigBToA0Tag);
}
catch (Exception e)
{
fromPCS = null;
}
if(fromPCS == null)
inv_matrix = invertMatrix(matrix);
else
{
inv_matrix = new float[3][3];
inv_matrix[0][0] = inv_matrix[1][1] = inv_matrix[2][2] = 1.0f;
}
}
public float[] toCIEXYZ(float[] in)
{
if (toPCS != null)
return toPCS.lookup(in);
float[] temp = new float[3];
float[] out = new float[3];
temp[0] = rTRC.lookup(in[0]);
temp[1] = gTRC.lookup(in[1]);
temp[2] = bTRC.lookup(in[2]);
out[0] = matrix[0][0] * temp[0] + matrix[0][1] * temp[1]
+ matrix[0][2] * temp[2];
out[1] = matrix[1][0] * temp[0] + matrix[1][1] * temp[1]
+ matrix[1][2] * temp[2];
out[2] = matrix[2][0] * temp[0] + matrix[2][1] * temp[1]
+ matrix[2][2] * temp[2];
return out;
}
public float[] toRGB(float[] in)
{
return SrgbConverter.XYZtoRGB(toCIEXYZ(in));
}
public float[] fromCIEXYZ(float[] in)
{
if (fromPCS != null)
return fromPCS.lookup(in);
float[] temp = new float[3];
float[] out = new float[3];
temp[0] = inv_matrix[0][0] * in[0] + inv_matrix[0][1] * in[1]
+ inv_matrix[0][2] * in[2];
temp[1] = inv_matrix[1][0] * in[0] + inv_matrix[1][1] * in[1]
+ inv_matrix[1][2] * in[2];
temp[2] = inv_matrix[2][0] * in[0] + inv_matrix[2][1] * in[1]
+ inv_matrix[2][2] * in[2];
out[0] = rTRC.reverseLookup(temp[0]);
out[1] = gTRC.reverseLookup(temp[1]);
out[2] = bTRC.reverseLookup(temp[2]);
return out;
}
public float[] fromRGB(float[] in)
{
return fromCIEXYZ(SrgbConverter.RGBtoXYZ(in));
}
private float[][] invertMatrix(float[][] matrix)
{
float[][] out = new float[3][3];
double determinant = matrix[0][0] * (matrix[1][1] * matrix[2][2]
- matrix[2][1] * matrix[1][2])
- matrix[0][1] * (matrix[1][0] * matrix[2][2]
- matrix[2][0] * matrix[1][2])
+ matrix[0][2] * (matrix[1][0] * matrix[2][1]
- matrix[2][0] * matrix[1][1]);
if (determinant == 0.0)
throw new IllegalArgumentException("Can't invert conversion matrix.");
float invdet = (float) (1.0 / determinant);
out[0][0] = invdet * (matrix[1][1] * matrix[2][2]
- matrix[1][2] * matrix[2][1]);
out[0][1] = invdet * (matrix[0][2] * matrix[2][1]
- matrix[0][1] * matrix[2][2]);
out[0][2] = invdet * (matrix[0][1] * matrix[1][2]
- matrix[0][2] * matrix[1][1]);
out[1][0] = invdet * (matrix[1][2] * matrix[2][0]
- matrix[1][0] * matrix[2][2]);
out[1][1] = invdet * (matrix[0][0] * matrix[2][2]
- matrix[0][2] * matrix[2][0]);
out[1][2] = invdet * (matrix[0][2] * matrix[1][0]
- matrix[0][0] * matrix[1][2]);
out[2][0] = invdet * (matrix[1][0] * matrix[2][1]
- matrix[1][1] * matrix[2][0]);
out[2][1] = invdet * (matrix[0][1] * matrix[2][0]
- matrix[0][0] * matrix[2][1]);
out[2][2] = invdet * (matrix[0][0] * matrix[1][1]
- matrix[0][1] * matrix[1][0]);
return out;
}
}