/*
* GeoTools - The Open Source Java GIS Toolkit
* http://geotools.org
*
* (C) 2006-2010, Open Source Geospatial Foundation (OSGeo)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation;
* version 2.1 of the License.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
*/
package org.geotools.image.crop;
import java.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.util.Map;
import javax.media.jai.ImageLayout;
import javax.media.jai.PointOpImage;
/**
* An alternative implementation of JAI Crop that respects the tile cache and tile scheduler
* specified in the rendering hints.
*
* This is a clean room implementation (there are no others ways in which a Crop can be implemented,
* so it looks a lot like the original one)
*
* @since 2.7.2
*/
final class GTCropOpImage extends PointOpImage {
private static ImageLayout layoutHelper(RenderedImage source, float originX, float originY,
float width, float height) {
Rectangle bounds = new Rectangle2D.Float(originX, originY, width, height).getBounds();
return new ImageLayout(bounds.x, bounds.y, bounds.width, bounds.height, source
.getTileGridXOffset(), source.getTileGridYOffset(), source.getTileWidth(), source
.getTileHeight(), source.getSampleModel(), source.getColorModel());
}
/**
* Construct an GTCropOpImage.
*/
public GTCropOpImage(RenderedImage source, float originX, float originY, float width,
float height, Map configuration) {
super(source, layoutHelper(source, originX, originY, width, height), configuration, false);
}
/**
* We just relay the original tiles, or return null
*/
public boolean computesUniqueTiles() {
return false;
}
/**
* Make sure the tile scheduler ends up calling getTile
*/
public Raster computeTile(int tileX, int tileY) {
return getTile(tileX, tileY);
}
/**
* Returns a tile. Either it's fully inside, and thus we relay the original tile (in-tile
* cutting will be performed by the image layout), or we return null
*/
public Raster getTile(int tileX, int tileY) {
if (tileX >= getMinTileX() && tileX <= getMaxTileX() //
&& tileY >= getMinTileY() && tileY <= getMaxTileY()) {
return getSourceImage(0).getTile(tileX, tileY);
} else {
return null;
}
}
}