📄 matrixbasedtransformtosrgb.java
字号:
/***************************************************************************** * * $Id: MatrixBasedTransformTosRGB.java,v 1.1.1.1 2002/08/02 09:47:04 grosbois Exp $ * * Copyright Eastman Kodak Company, 343 State Street, Rochester, NY 14650 * $Date $ *****************************************************************************/package icc.lut;import colorspace .ColorSpace;import icc .ICCProfile;import icc .RestrictedICCProfile;import icc .tags.ICCXYZType;import icc .lut.LookUpTableFP;import jj2000.j2k.image.DataBlkInt;import jj2000.j2k.image.DataBlkFloat;/** * Transform for applying ICCProfiling to an input DataBlk * * @see jj2000.j2k.image.DataBlkInt * @see jj2000.j2k.image.DataBlkFloat * @version 1.0 * @author Bruce A. Kern */public class MatrixBasedTransformTosRGB { private static final String eol = System.getProperty ("line.separator"); // Start of contant definitions: private static final int // Convenience RED = ICCProfile.RED, GREEN = ICCProfile.GREEN, BLUE = ICCProfile.BLUE; private static final double // Define the PCS to linear sRGB matrix coefficients SRGB00 = 3.1337, SRGB01 = -1.6173, SRGB02 = -0.4907, SRGB10 = -0.9785, SRGB11 = 1.9162, SRGB12 = 0.0334, SRGB20 = 0.0720, SRGB21 = -0.2290, SRGB22 = 1.4056; // Define constants representing the indices into the matrix array private static final int M00 = 0; private static final int M01 = 1; private static final int M02 = 2; private static final int M10 = 3; private static final int M11 = 4; private static final int M12 = 5; private static final int M20 = 6; private static final int M21 = 7; private static final int M22 = 8; private static final double ksRGBExponent = (1.0 / 2.4); private static final double ksRGBScaleAfterExp = 1.055; private static final double ksRGBReduceAfterExp = 0.055; private static final double ksRGBShadowCutoff = 0.0031308; private static final double ksRGBShadowSlope = 12.92; // End of contant definitions: private final double [] matrix; // Matrix coefficients private LookUpTableFP [] fLut = new LookUpTableFP [3]; private LookUpTable32LinearSRGBtoSRGB lut; // Linear sRGB to sRGB LUT private final int [] dwMaxValue; private final int [] dwShiftValue; private int dwMaxCols = 0; // Maximum number of columns that can be processed private int dwMaxRows = 0; // Maximum number of rows that can be processed private float [][] fBuf = null; // Intermediate output of the first LUT operation. /** * String representation of class * @return suitable representation for class */ public String toString () { int i,j; StringBuffer rep = new StringBuffer ("[MatrixBasedTransformTosRGB: "); StringBuffer body = new StringBuffer (" "); body.append(eol).append("ksRGBExponent= ").append(String.valueOf(ksRGBExponent)); body.append(eol).append("ksRGBScaleAfterExp= ").append(String.valueOf(ksRGBScaleAfterExp)); body.append(eol).append("ksRGBReduceAfterExp= ").append(String.valueOf(ksRGBReduceAfterExp)); body.append(eol) .append("dwMaxValues= ") .append(String.valueOf(dwMaxValue[0])).append(", ") .append(String.valueOf(dwMaxValue[1])).append(", ") .append(String.valueOf(dwMaxValue[2])); body.append(eol) .append("dwShiftValues= ") .append(String.valueOf(dwShiftValue[0])).append(", ") .append(String.valueOf(dwShiftValue[1])).append(", ") .append(String.valueOf(dwShiftValue[2])); body.append(eol) .append(eol).append("fLut= ") .append(eol).append(ColorSpace.indent (" ", "fLut[RED]= "+ fLut[0].toString())) .append(eol).append(ColorSpace.indent (" ", "fLut[GRN]= "+ fLut[1].toString())) .append(eol).append(ColorSpace.indent (" ", "fLut[BLU]= "+ fLut[2].toString())); // Print the matrix body .append(eol).append(eol).append("[matrix "); for (i=0; i<3; ++i) { body .append(eol).append(" "); for (j=0; j<3; ++j) { body .append(matrix [3*i+j] + " "); }} body .append("]"); // Print the LinearSRGBtoSRGB lut. body.append(eol).append(eol).append(lut.toString()); rep.append(ColorSpace.indent(" ",body)).append("]"); return rep.append("]").toString(); } /** * Construct a 3 component transform based on an input RestricedICCProfile * This transform will pass the input throught a floating point lut (LookUpTableFP), * apply a matrix to the output and finally pass the intermediate buffer through * a 8-bit lut (LookUpTable8). This operation will be designated (LFP*M*L8) * Data * The operators (LFP*M*L8) are constructed here. Although the data for * only one component is returned, the transformation must be done for all * components, because the matrix application involves a linear combination of * component input to produce the output. * @param ricc input profile * @param dwMaxValue clipping value for output. * @param dwMaxCols number of columns to transform * @param dwMaxRows number of rows to transform */ public MatrixBasedTransformTosRGB (RestrictedICCProfile ricc, int dwMaxValue [], int dwShiftValue []) { // Assure the proper type profile for this xform. if (ricc.getType() != RestrictedICCProfile.kThreeCompInput) throw new IllegalArgumentException ("MatrixBasedTransformTosRGB: wrong type ICCProfile supplied"); int c; // component index. this .dwMaxValue = dwMaxValue; this .dwShiftValue = dwShiftValue; // Create the LUTFP from the input profile. for (c=0; c<3; ++c) { fLut[c] = LookUpTableFP.createInstance (ricc.trc[c], dwMaxValue[c]+1); } // Create the Input linear to PCS matrix matrix = createMatrix(ricc, dwMaxValue); // Create and matrix from the ICC profile. // Create the final LUT32 lut = LookUpTable32LinearSRGBtoSRGB.createInstance (dwMaxValue[0], dwMaxValue[0], ksRGBShadowCutoff, ksRGBShadowSlope, ksRGBScaleAfterExp, ksRGBExponent, ksRGBReduceAfterExp); } private double [] createMatrix (RestrictedICCProfile ricc, int [] maxValues) { // Coefficients from the input linear to PCS matrix double dfPCS00 = ICCXYZType.XYZToDouble(ricc.colorant[RED].x); double dfPCS01 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].x); double dfPCS02 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].x); double dfPCS10 = ICCXYZType.XYZToDouble(ricc.colorant[RED].y); double dfPCS11 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].y); double dfPCS12 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].y); double dfPCS20 = ICCXYZType.XYZToDouble(ricc.colorant[RED].z); double dfPCS21 = ICCXYZType.XYZToDouble(ricc.colorant[GREEN].z); double dfPCS22 = ICCXYZType.XYZToDouble(ricc.colorant[BLUE].z); double [] matrix = new double [9]; matrix[M00] = maxValues[0] * (SRGB00 * dfPCS00 + SRGB01 * dfPCS10 + SRGB02 * dfPCS20); matrix[M01] = maxValues[0] * (SRGB00 * dfPCS01 + SRGB01 * dfPCS11 + SRGB02 * dfPCS21); matrix[M02] = maxValues[0] * (SRGB00 * dfPCS02 + SRGB01 * dfPCS12 + SRGB02 * dfPCS22); matrix[M10] = maxValues[1] * (SRGB10 * dfPCS00 + SRGB11 * dfPCS10 + SRGB12 * dfPCS20); matrix[M11] = maxValues[1] * (SRGB10 * dfPCS01 + SRGB11 * dfPCS11 + SRGB12 * dfPCS21); matrix[M12] = maxValues[1] * (SRGB10 * dfPCS02 + SRGB11 * dfPCS12 + SRGB12 * dfPCS22); matrix[M20] = maxValues[2] * (SRGB20 * dfPCS00 + SRGB21 * dfPCS10 + SRGB22 * dfPCS20); matrix[M21] = maxValues[2] * (SRGB20 * dfPCS01 + SRGB21 * dfPCS11 + SRGB22 * dfPCS21); matrix[M22] = maxValues[2] * (SRGB20 * dfPCS02 + SRGB21 * dfPCS12 + SRGB22 * dfPCS22); return matrix; } /** * Performs the transform. Pass the input throught the LookUpTableFP, apply the * matrix to the output and finally pass the intermediate buffer through the * LookUpTable8. This operation is designated (LFP*M*L8) * Data are already * constructed. Although the data for only one component is returned, the * transformation must be done for all components, because the matrix application * involves a linear combination of component input to produce the output.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -