int endTileY = YToTileY(xsect.y + xsect.height - 1);
if (startTileX == endTileX && startTileY == endTileY &&
getTileRect(startTileX, startTileY).contains(region)) {
// Requested region is within a single tile.
Raster tile = getTile(startTileX, startTileY);
if(this instanceof WritableRenderedImage) {
// Returned Raster must not change if the corresponding
// image data are modified so if this image is mutable
// a copy must be created.
SampleModel sm = tile.getSampleModel();
if(sm.getWidth() != region.width ||
sm.getHeight() != region.height) {
sm = sm.createCompatibleSampleModel(region.width,
region.height);
}
WritableRaster destinationRaster =
createWritableRaster(sm, region.getLocation());
Raster sourceRaster =
tile.getBounds().equals(region) ?
tile : tile.createChild(region.x, region.y,
region.width, region.height,
region.x, region.y,
null);
JDKWorkarounds.setRect(destinationRaster, sourceRaster);
return destinationRaster;
} else {
// Image is immutable so returning the tile or a child
// thereof is acceptable.
return tile.getBounds().equals(region) ?
tile : tile.createChild(region.x, region.y,
region.width, region.height,
region.x, region.y,
null);
}
} else {
// Extract a region crossing tiles into a new WritableRaster
WritableRaster dstRaster;
SampleModel srcSM = getSampleModel();
int dataType = srcSM.getDataType();
int nbands = srcSM.getNumBands();
boolean isBandChild = false;
ComponentSampleModel csm = null;
int[] bandOffs = null;
boolean fastCobblePossible = false;
if (srcSM instanceof ComponentSampleModel) {
csm = (ComponentSampleModel)srcSM;
int ps = csm.getPixelStride();
boolean isBandInt = (ps == 1 && nbands > 1);
isBandChild = (ps > 1 && nbands != ps);
if ( (!isBandChild) && (!isBandInt)) {
bandOffs = csm.getBandOffsets();
int i;
for (i=0; i<nbands; i++) {
if (bandOffs[i] >= nbands) {
break;
}
}
if (i == nbands) {
fastCobblePossible = true;
}
}
}
if (fastCobblePossible) {
// For acceptable cases of ComponentSampleModel,
// use an optimized cobbler which directly accesses the
// tile DataBuffers, using arraycopy whenever possible.
try {
SampleModel interleavedSM =
RasterFactory.createPixelInterleavedSampleModel(
dataType,
region.width,
region.height,
nbands,
region.width*nbands,
bandOffs);
dstRaster = createWritableRaster(interleavedSM,
region.getLocation());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(
JaiI18N.getString("PlanarImage2"));
}
switch (dataType) {
case DataBuffer.TYPE_BYTE:
cobbleByte(region, dstRaster);
break;
case DataBuffer.TYPE_SHORT:
cobbleShort(region, dstRaster);
break;
case DataBuffer.TYPE_USHORT:
cobbleUShort(region, dstRaster);
break;
case DataBuffer.TYPE_INT:
cobbleInt(region, dstRaster);
break;
case DataBuffer.TYPE_FLOAT:
cobbleFloat(region, dstRaster);
break;
case DataBuffer.TYPE_DOUBLE:
cobbleDouble(region, dstRaster);
break;
default:
break;
}
} else {
SampleModel sm = sampleModel;
if(sm.getWidth() != region.width ||
sm.getHeight() != region.height) {
sm = sm.createCompatibleSampleModel(region.width,
region.height);
}
try {
dstRaster = createWritableRaster(sm,
region.getLocation());
} catch (IllegalArgumentException e) {
throw new IllegalArgumentException(
JaiI18N.getString("PlanarImage2"));
}
for (int j = startTileY; j <= endTileY; j++) {
for (int i = startTileX; i <= endTileX; i++) {
Raster tile = getTile(i, j);
Rectangle subRegion = region.intersection(
tile.getBounds());
Raster subRaster =
tile.createChild(subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
subRegion.x,
subRegion.y,
null);
if (sm instanceof ComponentSampleModel &&
isBandChild) {
// Need to handle this case specially, since
// setDataElements will not copy band child images
switch (sm.getDataType()) {
case DataBuffer.TYPE_FLOAT:
dstRaster.setPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
subRaster.getPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
new float[nbands*subRegion.width*subRegion.height]));
break;
case DataBuffer.TYPE_DOUBLE:
dstRaster.setPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
subRaster.getPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
new double[nbands*subRegion.width*subRegion.height]));
break;
default:
dstRaster.setPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
subRaster.getPixels(
subRegion.x,
subRegion.y,
subRegion.width,
subRegion.height,
new int[nbands*subRegion.width*subRegion.height]));