int dTagID = RasterAccessor.findCompatibleTag(null, dstSampleModel);
RasterFormatTag sTag = new RasterFormatTag(srcSampleModel,sTagID);
RasterFormatTag dTag = new RasterFormatTag(dstSampleModel,dTagID);
RasterAccessor s = new RasterAccessor(src, rect, sTag, null);
RasterAccessor d = new RasterAccessor(dst, rect, dTag, null);
/*int srcNumBands = s.getNumBands();
int srcDataType = s.getDataType();
int tblNumBands = getNumBands();
int tblDataType = getDataType();*/
int width = d.getWidth();
int height = d.getHeight();
int bands = d.getNumBands();
// int dstDataType = d.getDataType();
// Source information.
int srcLineStride = s.getScanlineStride();
int srcPixelStride = s.getPixelStride();
int[] srcBandOffsets = s.getBandOffsets();
short[][] srcData = s.getShortDataArrays();
// Table information.
int[] tblOffsets = getOffsets();
short[][] tblData = getShortData();
// Destination information.
int dstLineStride = d.getScanlineStride();
int dstPixelStride = d.getPixelStride();
int[] dstBandOffsets = d.getBandOffsets();
short[][] dstData = d.getShortDataArrays();
int lowBandOffset = 0;
for (int b = 0; b < bands; b++)
if (srcBandOffsets[b] < srcBandOffsets[lowBandOffset])
lowBandOffset = b;
short[] sd = srcData[lowBandOffset];
short[] dd = dstData[lowBandOffset];
short[] td = tblData[0];
int srcLineOffset = srcBandOffsets[lowBandOffset];
int dstLineOffset = dstBandOffsets[lowBandOffset];
int tblOffset = tblOffsets[0];
for (int h = 0; h < height; h++) {
int srcPixelOffset = srcLineOffset;
int dstPixelOffset = dstLineOffset;
srcLineOffset += srcLineStride;
dstLineOffset += dstLineStride;
final int scale = 0x4000;
int minOffset = Math.min(srcBandOffsets[0], Math.min(srcBandOffsets[1], srcBandOffsets[2]));
int wr = (int) (ColorScience.W[srcBandOffsets[0] - minOffset] * scale);
int wg = (int) (ColorScience.W[srcBandOffsets[1] - minOffset] * scale);
int wb = (int) (ColorScience.W[srcBandOffsets[2] - minOffset] * scale);
for (int w = 0; w < width; w++) {
int sr = sd[srcPixelOffset + 0] & 0xFFFF;
int sg = sd[srcPixelOffset + 1] & 0xFFFF;
int sb = sd[srcPixelOffset + 2] & 0xFFFF;
int lum = (wr * sr + wg * sg + wb * sb) / scale;
// prevent index out of bounds exceptions
int index = lum - tblOffset;
int val = td[index < 0 ? 0 : index >= 0xFFFF ? 0xFFFF : index] & 0xFFFF;
// int mul = sg > 0 ? (scale * val) / sg : scale;
int mul = lum > 0 ? (scale * val) / lum : scale;
int prod = (mul * sr) / scale;
dd[dstPixelOffset + 0] = prod > 0xFFFF ? (short) 0xFFFF : (short) prod;
prod = (mul * sg) / scale;
dd[dstPixelOffset + 1] = prod > 0xFFFF ? (short) 0xFFFF : (short) prod;
prod = (mul * sb) / scale;
dd[dstPixelOffset + 2] = prod > 0xFFFF ? (short) 0xFFFF : (short) prod;
srcPixelOffset += srcPixelStride;
dstPixelOffset += dstPixelStride;
}
}
d.copyDataToRaster();
return dst;
}