// Bands associated with each sources
int[] snbands = new int[nSrcs];
// PixelAccessor array for each source
PixelAccessor[] pas = new PixelAccessor[nSrcs];
for (int i = 0; i < nSrcs; i++) {
pas[i] = new PixelAccessor(sources[i].getSampleModel(), colorModels[i]);
if (colorModels[i] instanceof IndexColorModel) {
snbands[i] = colorModels[i].getNumComponents();
} else {
snbands[i] = sources[i].getNumBands();
}
}
// Destination bands
int dnbands = dest.getNumBands();
// Destination data type
int destType = dest.getTransferType();
// PixelAccessor associated with the destination raster
PixelAccessor d = new PixelAccessor(dest.getSampleModel(), null);
UnpackedImageData dimd = d.getPixels(dest, destRect, destType, true);
// Destination tile initial position
final int minX = destRect.x;
final int minY = destRect.y;
// Destination data values
byte[][] dstdata = (byte[][]) dimd.data;
// ONLY VALID DATA
if (caseA) {
// Cycle on all the sources
for (int sindex = 0, db = 0; sindex < nSrcs; sindex++) {
UnpackedImageData simd = colorModels[sindex] instanceof IndexColorModel ? pas[sindex]
.getComponents(sources[sindex], destRect, sources[sindex].getSampleModel()
.getTransferType()) : pas[sindex].getPixels(sources[sindex],
destRect, sources[sindex].getSampleModel().getTransferType(), false);
int srcPixelStride = simd.pixelStride;
int srcLineStride = simd.lineStride;
int dstPixelStride = dimd.pixelStride;
int dstLineStride = dimd.lineStride;
int dRectWidth = destRect.width;
// Cycle on each source bands
for (int sb = 0; sb < snbands[sindex]; sb++, db++) {
if (db >= dnbands) {
// exceeding destNumBands; should not have happened
break;
}
byte[] dstdatabandb = dstdata[db];
byte[][] srcdata = (byte[][]) simd.data;
byte[] srcdatabandsb = srcdata[sb];
int srcstart = simd.bandOffsets[sb];
int dststart = dimd.bandOffsets[db];
// Cycle on the y-axis
for (int y = 0; y < destRect.height; y++, srcstart += srcLineStride, dststart += dstLineStride) {
// Cycle on the x-axis
for (int i = 0, srcpos = srcstart, dstpos = dststart; i < dRectWidth; i++, srcpos += srcPixelStride, dstpos += dstPixelStride) {
dstdatabandb[dstpos] = srcdatabandsb[srcpos];
}
}
}
}
// ONLY ROI
} else if (caseB) {
// Cycle on all the sources
for (int sindex = 0, db = 0; sindex < nSrcs; sindex++) {
UnpackedImageData simd = colorModels[sindex] instanceof IndexColorModel ? pas[sindex]
.getComponents(sources[sindex], destRect, sources[sindex].getSampleModel()
.getTransferType()) : pas[sindex].getPixels(sources[sindex],
destRect, sources[sindex].getSampleModel().getTransferType(), false);
int srcPixelStride = simd.pixelStride;
int srcLineStride = simd.lineStride;
int dstPixelStride = dimd.pixelStride;
int dstLineStride = dimd.lineStride;
int dRectWidth = destRect.width;
int srcstart = 0;
int dststart = 0;
// Cycle on the y-axis
for (int y = 0; y < destRect.height; y++, srcstart += srcLineStride, dststart += dstLineStride) {
// Cycle on the x-axis
for (int i = 0, srcpos = srcstart, dstpos = dststart; i < dRectWidth; i++, srcpos += srcPixelStride, dstpos += dstPixelStride) {
// ROI Check
if (roi.contains(i + minX, y + minY)) {
// Cycle on each source bands
for (int sb = 0; sb < snbands[sindex]; sb++) {
int dbidx = db + sb;
byte[] dstdatabandb = dstdata[dbidx];
byte[][] srcdata = (byte[][]) simd.data;
byte[] srcdatabandsb = srcdata[sb];
if (db >= dnbands) {
// exceeding destNumBands; should not have happened
break;
}
dstdatabandb[dstpos + dimd.bandOffsets[dbidx]] = srcdatabandsb[srcpos
+ simd.bandOffsets[sb]];
}
} else {
for (int sb = 0; sb < snbands[sindex]; sb++) {
int dbidx = db + sb;
byte[] dstdatabandb = dstdata[dbidx];
dstdatabandb[dstpos + dimd.bandOffsets[dbidx]] = destNoDataByte;
}
}
}
}
db += snbands[sindex];
}
// ONLY NODATA
} else if (caseC) {
// Cycle on all the sources
for (int sindex = 0, db = 0; sindex < nSrcs; sindex++) {
// Source data
UnpackedImageData simd = colorModels[sindex] instanceof IndexColorModel ? pas[sindex]
.getComponents(sources[sindex], destRect, sources[sindex].getSampleModel()
.getTransferType()) : pas[sindex].getPixels(sources[sindex],
destRect, sources[sindex].getSampleModel().getTransferType(), false);
// Source and Destination parameters
int srcPixelStride = simd.pixelStride;
int srcLineStride = simd.lineStride;
int dstPixelStride = dimd.pixelStride;
int dstLineStride = dimd.lineStride;
int dRectWidth = destRect.width;
// Cycle on each source bands
for (int sb = 0; sb < snbands[sindex]; sb++, db++) {
if (db >= dnbands) {
// exceeding destNumBands; should not have happened
break;
}
// Source and destination data array
byte[] dstdatabandb = dstdata[db];
byte[][] srcdata = (byte[][]) simd.data;
byte[] srcdatabandsb = srcdata[sb];
int srcstart = simd.bandOffsets[sb];
int dststart = dimd.bandOffsets[db];
// Cycle on the y-axis
for (int y = 0; y < destRect.height; y++, srcstart += srcLineStride, dststart += dstLineStride) {
// Cycle on the x-axis
for (int i = 0, srcpos = srcstart, dstpos = dststart; i < dRectWidth; i++, srcpos += srcPixelStride, dstpos += dstPixelStride) {
// No Data control
if (noData[sindex].contains(srcdatabandsb[srcpos])) {
dstdatabandb[dstpos] = destNoDataByte;
} else {
dstdatabandb[dstpos] = srcdatabandsb[srcpos];
}
}
}
}
}
// NODATA AND ROI
} else {
// Cycle on all the sources
for (int sindex = 0, db = 0; sindex < nSrcs; sindex++) {
UnpackedImageData simd = colorModels[sindex] instanceof IndexColorModel ? pas[sindex]
.getComponents(sources[sindex], destRect, sources[sindex].getSampleModel()
.getTransferType()) : pas[sindex].getPixels(sources[sindex],
destRect, sources[sindex].getSampleModel().getTransferType(), false);
int srcPixelStride = simd.pixelStride;
int srcLineStride = simd.lineStride;
int dstPixelStride = dimd.pixelStride;
int dstLineStride = dimd.lineStride;
int dRectWidth = destRect.width;
int srcstart = 0;
int dststart = 0;
// Cycle on the y-axis
for (int y = 0; y < destRect.height; y++, srcstart += srcLineStride, dststart += dstLineStride) {
// Cycle on the x-axis
for (int i = 0, srcpos = srcstart, dstpos = dststart; i < dRectWidth; i++, srcpos += srcPixelStride, dstpos += dstPixelStride) {
// ROI Check
if (roi.contains(i + minX, y + minY)) {
// Cycle on each source bands
for (int sb = 0; sb < snbands[sindex]; sb++) {
int dbidx = db + sb;
byte[] dstdatabandb = dstdata[dbidx];
byte[][] srcdata = (byte[][]) simd.data;
byte[] srcdatabandsb = srcdata[sb];
if (db >= dnbands) {
// exceeding destNumBands; should not have happened
break;
}
// No Data control
if (noData[sindex].contains(srcdatabandsb[srcpos])) {
dstdatabandb[dstpos + dimd.bandOffsets[dbidx]] = destNoDataByte;
} else {
dstdatabandb[dstpos + dimd.bandOffsets[dbidx]] = srcdatabandsb[srcpos
+ simd.bandOffsets[sb]];
}
}
} else {
for (int sb = 0; sb < snbands[sindex]; sb++) {
int dbidx = db + sb;
byte[] dstdatabandb = dstdata[dbidx];
dstdatabandb[dstpos + dimd.bandOffsets[dbidx]] = destNoDataByte;
}
}
}
}
db += snbands[sindex];
}
}
d.setPixels(dimd);
}