}
return;
}
LCMSImageLayout srcIL, dstIL;
Raster srcRas = src.getRaster();
WritableRaster dstRas = dst.getRaster();
ColorModel srcCM = src.getColorModel();
ColorModel dstCM = dst.getColorModel();
int w = src.getWidth();
int h = src.getHeight();
int srcNumComp = srcCM.getNumColorComponents();
int dstNumComp = dstCM.getNumColorComponents();
int precision = 8;
float maxNum = 255.0f;
for (int i = 0; i < srcNumComp; i++) {
if (srcCM.getComponentSize(i) > 8) {
precision = 16;
maxNum = 65535.0f;
}
}
for (int i = 0; i < dstNumComp; i++) {
if (dstCM.getComponentSize(i) > 8) {
precision = 16;
maxNum = 65535.0f;
}
}
float[] srcMinVal = new float[srcNumComp];
float[] srcInvDiffMinMax = new float[srcNumComp];
ColorSpace cs = srcCM.getColorSpace();
for (int i = 0; i < srcNumComp; i++) {
srcMinVal[i] = cs.getMinValue(i);
srcInvDiffMinMax[i] = maxNum / (cs.getMaxValue(i) - srcMinVal[i]);
}
cs = dstCM.getColorSpace();
float[] dstMinVal = new float[dstNumComp];
float[] dstDiffMinMax = new float[dstNumComp];
for (int i = 0; i < dstNumComp; i++) {
dstMinVal[i] = cs.getMinValue(i);
dstDiffMinMax[i] = (cs.getMaxValue(i) - dstMinVal[i]) / maxNum;
}
boolean dstHasAlpha = dstCM.hasAlpha();
boolean needSrcAlpha = srcCM.hasAlpha() && dstHasAlpha;
float[] dstColor;
if (dstHasAlpha) {
dstColor = new float[dstNumComp + 1];
} else {
dstColor = new float[dstNumComp];
}
if (precision == 8) {
byte[] srcLine = new byte[w * srcNumComp];
byte[] dstLine = new byte[w * dstNumComp];
Object pixel;
float[] color;
float[] alpha = null;
if (needSrcAlpha) {
alpha = new float[w];
}
int idx;
// TODO check for src npixels = dst npixels
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumInComponents());
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(1), getNumOutComponents());
// process each scanline
for (int y = 0; y < h; y++) {
// convert src scanline
pixel = null;
color = null;
idx = 0;
for (int x = 0; x < w; x++) {
pixel = srcRas.getDataElements(x, y, pixel);
color = srcCM.getNormalizedComponents(pixel, color, 0);
for (int i = 0; i < srcNumComp; i++) {
srcLine[idx++] = (byte)
((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
0.5f);
}
if (needSrcAlpha) {
alpha[x] = color[srcNumComp];
}
}
// color convert srcLine to dstLine
synchronized (this) {
LCMS.colorConvert(this, srcIL, dstIL);
}
// convert dst scanline
pixel = null;
idx = 0;
for (int x = 0; x < w; x++) {
for (int i = 0; i < dstNumComp; i++) {
dstColor[i] = ((float) (dstLine[idx++] & 0xff)) *
dstDiffMinMax[i] + dstMinVal[i];
}
if (needSrcAlpha) {
dstColor[dstNumComp] = alpha[x];
} else if (dstHasAlpha) {
dstColor[dstNumComp] = 1.0f;
}
pixel = dstCM.getDataElements(dstColor, 0, pixel);
dstRas.setDataElements(x, y, pixel);
}
}
} else {
short[] srcLine = new short[w * srcNumComp];
short[] dstLine = new short[w * dstNumComp];
Object pixel;
float[] color;
float[] alpha = null;
if (needSrcAlpha) {
alpha = new float[w];
}
int idx;
srcIL = new LCMSImageLayout(
srcLine, srcLine.length/getNumInComponents(),
LCMSImageLayout.CHANNELS_SH(getNumInComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumInComponents()*2);
dstIL = new LCMSImageLayout(
dstLine, dstLine.length/getNumOutComponents(),
LCMSImageLayout.CHANNELS_SH(getNumOutComponents()) |
LCMSImageLayout.BYTES_SH(2), getNumOutComponents()*2);
// process each scanline
for (int y = 0; y < h; y++) {
// convert src scanline
pixel = null;
color = null;
idx = 0;
for (int x = 0; x < w; x++) {
pixel = srcRas.getDataElements(x, y, pixel);
color = srcCM.getNormalizedComponents(pixel, color, 0);
for (int i = 0; i < srcNumComp; i++) {
srcLine[idx++] = (short)
((color[i] - srcMinVal[i]) * srcInvDiffMinMax[i] +
0.5f);
}
if (needSrcAlpha) {
alpha[x] = color[srcNumComp];
}
}
// color convert srcLine to dstLine
synchronized(this) {
LCMS.colorConvert(this, srcIL, dstIL);
}
// convert dst scanline
pixel = null;
idx = 0;
for (int x = 0; x < w; x++) {
for (int i = 0; i < dstNumComp; i++) {
dstColor[i] = ((float) (dstLine[idx++] & 0xffff)) *
dstDiffMinMax[i] + dstMinVal[i];
}
if (needSrcAlpha) {
dstColor[dstNumComp] = alpha[x];
} else if (dstHasAlpha) {
dstColor[dstNumComp] = 1.0f;
}
pixel = dstCM.getDataElements(dstColor, 0, pixel);
dstRas.setDataElements(x, y, pixel);
}
}
}
}