package org.geotools.arcsde.raster.jai; import java.awt.Point; import java.awt.image.ColorModel; import java.awt.image.DataBuffer; import java.awt.image.DataBufferByte; import java.awt.image.DataBufferFloat; import java.awt.image.DataBufferInt; import java.awt.image.DataBufferShort; import java.awt.image.DataBufferUShort; import java.awt.image.Raster; import java.awt.image.SampleModel; import java.awt.image.WritableRaster; import java.io.IOException; import java.math.BigInteger; import java.util.logging.Level; import java.util.logging.Logger; import javax.media.jai.JAI; import javax.media.jai.PlanarImage; import javax.media.jai.TileCache; import javax.media.jai.TileFactory; import org.geotools.arcsde.raster.io.TileReader; import org.geotools.util.Utilities; import org.geotools.util.logging.Logging; import com.sun.media.jai.codecimpl.util.DataBufferDouble; import com.sun.media.jai.util.ImageUtil; @SuppressWarnings("unchecked") public class ArcSDEPlanarImage extends PlanarImage { private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.raster.jai"); private TileReader tileReader; private final SampleModel tileSampleModel; private final BigInteger UID; private final int hashCode; public ArcSDEPlanarImage(TileReader tileReader, int minX, int minY, int width, int height, int tileGridXOffset, int tileGridYOffset, SampleModel tileSampleModel, ColorModel colorModel) { this.tileReader = tileReader; this.tileSampleModel = tileSampleModel; super.minX = minX; super.minY = minY; super.width = width; super.height = height; super.tileGridXOffset = tileGridXOffset; super.tileGridYOffset = tileGridYOffset; super.tileWidth = tileReader.getTileWidth(); super.tileHeight = tileReader.getTileHeight(); super.colorModel = colorModel; super.sampleModel = tileSampleModel; { int result = 17; // collect the contributions of various fields result = Utilities.hash(tileReader.getServerName(), result); result = Utilities.hash(tileReader.getRasterTableName(), result); result = Utilities.hash(tileReader.getRasterId(), result); result = Utilities.hash(tileReader.getPyramidLevel(), result); this.hashCode = result; } this.UID = (BigInteger) ImageUtil.generateID(this); } // @Override // public boolean equals(Object o) { // return super.equals(o); // } @Override public SampleModel getSampleModel() { return sampleModel; } @Override public int hashCode() { return hashCode; } @Override public BigInteger getImageID() { return UID; } private int lastTileX, lastTileY; private WritableRaster currentTile; /** * @see java.awt.image.RenderedImage#getTile(int, int) */ @Override public synchronized Raster getTile(final int tileX, final int tileY) { if (tileX == lastTileX && tileY == lastTileY && currentTile != null) { return currentTile; } // System.err.printf("getTile(%d, %d) %s\n", tileX, tileY, this.toString()); final boolean useCache = false; final JAI jai = JAI.getDefaultInstance(); final TileCache jaiCache = jai.getTileCache(); if (useCache && jaiCache != null) { Raster tile = jaiCache.getTile(this, tileX, tileY); if (tile != null) { if (LOGGER.isLoggable(Level.INFO)) { LOGGER.info("! GOT TILE FROM TileCache " + tileX + ", " + tileY + ", plevel " + tileReader.getPyramidLevel()); } return tile; } } if (super.tileFactory == null) { TileFactory tileFactory = (TileFactory) jai.getRenderingHint(JAI.KEY_TILE_FACTORY); if (tileFactory != null) { super.tileFactory = tileFactory; } } final int xOrigin = tileXToX(tileX); final int yOrigin = tileYToY(tileY); if (currentTile == null) { currentTile = Raster.createWritableRaster(tileSampleModel, new Point(xOrigin, yOrigin)); } else { DataBuffer db = currentTile.getDataBuffer(); currentTile = Raster.createWritableRaster(tileSampleModel, db, new Point(xOrigin, yOrigin)); } if (shallIgnoreTile(tileX, tileY)) { // not a requested tile return currentTile; } final int readerTileX = tileX - tileReader.getMinTileX(); final int readerTileY = tileY - tileReader.getMinTileY(); try { switch (tileSampleModel.getDataType()) { case DataBuffer.TYPE_BYTE: { DataBufferByte dataBuffer = (DataBufferByte) currentTile.getDataBuffer(); byte[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; case DataBuffer.TYPE_USHORT: { DataBufferUShort dataBuffer = (DataBufferUShort) currentTile.getDataBuffer(); short[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; case DataBuffer.TYPE_SHORT: { DataBufferShort dataBuffer = (DataBufferShort) currentTile.getDataBuffer(); short[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; case DataBuffer.TYPE_INT: { DataBufferInt dataBuffer = (DataBufferInt) currentTile.getDataBuffer(); int[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; case DataBuffer.TYPE_FLOAT: { DataBufferFloat dataBuffer = (DataBufferFloat) currentTile.getDataBuffer(); float[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; case DataBuffer.TYPE_DOUBLE: { DataBufferDouble dataBuffer = (DataBufferDouble) currentTile.getDataBuffer(); double[][] bankData = dataBuffer.getBankData(); tileReader.getTile(readerTileX, readerTileY, bankData); } break; default: throw new IllegalStateException("Unrecognized DataBuffer type: " + tileSampleModel.getDataType()); } } catch (IOException e) { e.printStackTrace(); throw new RuntimeException(e); } if (useCache && jaiCache != null) { jaiCache.add(this, tileX, tileY, currentTile); } lastTileX = tileX; lastTileY = tileY; return currentTile; } private boolean shallIgnoreTile(int tx, int ty) { int minTileX = tileReader.getMinTileX(); int minTileY = tileReader.getMinTileY(); int tilesWide = tileReader.getTilesWide(); int tilesHigh = tileReader.getTilesHigh(); return tx < minTileX || ty < minTileY || tx > minTileX + tilesWide || ty > minTileY + tilesHigh; } }