Package org.geotools.arcsde.raster.jai

Source Code of org.geotools.arcsde.raster.jai.ArcSDEPlanarImage

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.DataBufferDouble;
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.io.IOException;
import java.math.BigInteger;
import java.util.Observable;
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.coverage.grid.io.imageio.RecyclingTileFactory;
import org.geotools.util.Utilities;
import org.geotools.util.logging.Logging;

import com.sun.media.jai.util.ImageUtil;

@SuppressWarnings("unchecked")
/**
*
*
* @source $URL$
*/
public class ArcSDEPlanarImage extends PlanarImage {

    private static final Logger LOGGER = Logging.getLogger(ArcSDEPlanarImage.class);

    private TileReader tileReader;

    private final SampleModel tileSampleModel;

    private final BigInteger UID;

    private final int hashCode;

    /**
     * We use an internal TileCache for each ArcSDEPlanarImage because RenderedOp's use to call
     * getTile(x,y) repeteadly for the same tile and since we're hitting a database it's not easy to
     * go fetch a tile from the stream that has already been fetch. Anyway, if a tile is requested
     * that's past the current tile index in the stream and it's not on this cache, NativeTileReader
     * will perform an extra database query to fetch that single tile, but this is to avoid that
     * situation to the maximum extent possible.
     */
    private final TileCache tileCache;

    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);

        int bytesPerPixel;
        switch (tileSampleModel.getDataType()) {
        case DataBuffer.TYPE_BYTE:
            bytesPerPixel = 1;
            break;
        case DataBuffer.TYPE_DOUBLE:
            bytesPerPixel = 8;
            break;
        case DataBuffer.TYPE_FLOAT:
        case DataBuffer.TYPE_INT:
            bytesPerPixel = 4;
            break;
        case DataBuffer.TYPE_SHORT:
        case DataBuffer.TYPE_USHORT:
            bytesPerPixel = 2;
            break;
        default:
            throw new IllegalArgumentException("Unknown DataBuffer type: "
                    + tileSampleModel.getDataType());
        }

        int numTilesInCache = 16;
        long memCapacity = numTilesInCache * bytesPerPixel * tileWidth * tileHeight
                * tileSampleModel.getNumBands();
        this.tileCache = JAI.createTileCache(memCapacity);

        final JAI jai = JAI.getDefaultInstance();
        TileFactory tileFactory = (TileFactory) jai.getRenderingHint(JAI.KEY_TILE_FACTORY);
        if (tileFactory == null) {
            if (tileCache instanceof Observable) {
                super.tileFactory = new RecyclingTileFactory((Observable) tileCache);
            } else {
                // not a SunTileCache?
                super.tileFactory = new javax.media.jai.RecyclingTileFactory();
            }
        } else {
            super.tileFactory = tileFactory;
        }
    }

    // @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;
    }

    /**
     * @see java.awt.image.RenderedImage#getTile(int, int)
     */
    @Override
    public synchronized Raster getTile(final int tileX, final int tileY) {
        Raster currentTile = tileCache.getTile(this, tileX, tileY);
        if (currentTile != null) {
            if (LOGGER.isLoggable(Level.FINER)) {
                LOGGER.finer("! GOT TILE FROM TileCache " + tileX + ", " + tileY + ", plevel "
                        + tileReader.getPyramidLevel());
            }
            return currentTile;
        }

        final int xOrigin = tileXToX(tileX);
        final int yOrigin = tileYToY(tileY);

        currentTile = tileFactory.createTile(tileSampleModel, 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 (tileX == tileReader.getMinTileX() || tileX == tileReader.getMaxTileX()
//                || tileY == tileReader.getMinTileY() || tileY == tileReader.getMaxTileY()) {
            tileCache.add(this, tileX, tileY, currentTile);
//        }

        return currentTile;
    }

    private boolean shallIgnoreTile(int tx, int ty) {
        int minTileX = tileReader.getMinTileX();
        int minTileY = tileReader.getMinTileY();
        int maxTileX = tileReader.getMaxTileX();
        int maxTileY = tileReader.getMaxTileY();

        boolean ignore = tx < minTileX || ty < minTileY || tx > maxTileX || ty > maxTileY;
        return ignore;
    }

    @Override
    public synchronized void dispose(){
        super.dispose();
        this.tileReader.dispose();
    }
   
    @Override
    protected void finalize(){
        dispose();
    }
}
TOP

Related Classes of org.geotools.arcsde.raster.jai.ArcSDEPlanarImage

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.