svn - r34354 - in branches/2.5.x/modules/plugin/arcsde: common common/src common/src/main/java/org/geotools/arcsde/jndi common/src/main/java/org/geotools/arcsde/session common/src/test/java/org/geotools/arcsde/jndi datastore datastore/src datastore/src/main/java/org/geotools/arcsde datastore/src/main/java/org/geotools/arcsde/data datastore/src/main/java/org/geotools/arcsde/filter datastore/src/main/java/org/geotools/arcsde/gce datastore/src/main/java/org/geotools/arcsde/raster datastore/src/main/java/org/geotools/arcsde/raster/gce datastore/src/main/java/org/geotools/arcsde/raster/info datastore/src/main/java/org/geotools/arcsde/raster/io datastore/src/main/java/org/geotools/arcsde/raster/jai datastore/src/main/java/org/geotools/arcsde/session datastore/src/main/java/org/geotools/arcsde/util datastore/src/main/resources datastore/src/main/resources/org datastore/src/main/resources/org/geotools datastore/src/test/java/org/geotools/arcsde datastore/src/test/java/org/ge otools/arcsde/data datastore/src/test/java/org/geotools/arcsde/gce datastore/src/test/java/org/geotools/arcsde/raster datastore/src/test/java/org/geotools/arcsde/raster/gce datastore/src/test/java/org/geotools/arcsde/raster/info datastore/src/test/java/org/geotools/arcsde/raster/io datastore/src/test/java/org/geotools/arcsde/session datastore/src/test/java/org/geotools/arcsde/util

1 message Options
Embed this post
Permalink
svn_geotools

svn - r34354 - in branches/2.5.x/modules/plugin/arcsde: common common/src common/src/main/java/org/geotools/arcsde/jndi common/src/main/java/org/geotools/arcsde/session common/src/test/java/org/geotools/arcsde/jndi datastore datastore/src datastore/src/main/java/org/geotools/arcsde datastore/src/main/java/org/geotools/arcsde/data datastore/src/main/java/org/geotools/arcsde/filter datastore/src/main/java/org/geotools/arcsde/gce datastore/src/main/java/org/geotools/arcsde/raster datastore/src/main/java/org/geotools/arcsde/raster/gce datastore/src/main/java/org/geotools/arcsde/raster/info datastore/src/main/java/org/geotools/arcsde/raster/io datastore/src/main/java/org/geotools/arcsde/raster/jai datastore/src/main/java/org/geotools/arcsde/session datastore/src/main/java/org/geotools/arcsde/util datastore/src/main/resources datastore/src/main/resources/org datastore/src/main/resources/org/geotools datastore/src/test/java/org/geotools/arcsde datastore/src/test/java/org/ge otools/arcsde/data datastore/src/test/java/org/geotools/arcsde/gce datastore/src/test/java/org/geotools/arcsde/raster datastore/src/test/java/org/geotools/arcsde/raster/gce datastore/src/test/java/org/geotools/arcsde/raster/info datastore/src/test/java/org/geotools/arcsde/raster/io datastore/src/test/java/org/geotools/arcsde/session datastore/src/test/java/org/geotools/arcsde/util

Reply Threaded More More options
Print post
Permalink
Author: groldan
Date: 2009-11-09 13:53:16 -0500 (Mon, 09 Nov 2009)
New Revision: 34354

Added:
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/BitmaskToNoDataConverter.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/DefaultTiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/RasterReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/org/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/org/geotools/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/org/geotools/arcsde/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/RasterTestData.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/RasterInfoTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/RasterUtilsTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/io/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/io/BitmaskToNoDataConverterTest.java
Removed:
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDETiledImageInputStream.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/BitmaskToNoDataConverter.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/CompressionType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/DefaultTiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterleaveType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterpolationType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/NativeTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PromotingTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PyramidLevelInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterBandInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterCellType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterDatasetInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterQueryInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterUtils.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/BitmaskToNoDataConverter.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/DefaultTiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/NativeTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/PromotingTileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/RasterReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileFetchCommand.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileInfo.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TileReaderFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/io/TiledRasterReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDEImageReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/jai/ArcSDETiledRenderedImage.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPool.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionPoolFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/session/ArcSDEPooledConnection.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/org/geotools/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/resources/org/geotools/arcsde/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/BitmaskToNoDataConverterTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterInfoTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterTestData.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/gce/RasterUtilsTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAILegacyOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAIOnlineTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/gce/RasterTestData.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/RasterInfoTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/info/RasterUtilsTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/io/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/raster/io/BitmaskToNoDataConverterTest.java
Modified:
   branches/2.5.x/modules/plugin/arcsde/common/
   branches/2.5.x/modules/plugin/arcsde/common/src/
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java
   branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java
   branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/
   branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml
   branches/2.5.x/modules/plugin/arcsde/datastore/src/
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDERasterFormatFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEGeometryBuilder.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SeToJTSGeometryFactory.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/FilterToSQLSDE.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/GeometryEncoderSDE.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/util/ArcSDEUtils.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEDataStoreFactoryTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactoryTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreNonSpatialTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEDataStoreTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ArcSDEJavaApiTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/ClobTestData.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/FIDReaderTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/GeometryBuilderTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/SDEJavaApiJoinTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestFeatureListener.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/data/TestProgressListener.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/session/SessionPoolTest.java
   branches/2.5.x/modules/plugin/arcsde/datastore/src/test/java/org/geotools/arcsde/util/ArcSDEUtilsTest.java
Log:
backport improvements for arcsde rasters from trunk


Property changes on: branches/2.5.x/modules/plugin/arcsde/common
___________________________________________________________________
Modified: svn:ignore
   - bin
target

   + bin
target
.settings
.classpath
.project

Added: svn:mergeinfo
   + /trunk/modules/plugin/arcsde/common:33503-34351


Property changes on: branches/2.5.x/modules/plugin/arcsde/common/src
___________________________________________________________________
Deleted: svn:mergeinfo
   - /trunk/modules/plugin/arcsde/common/src:33503-33585

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -75,6 +75,8 @@
  * </p>
  *
  * @author Gabriel Roldan (OpenGeo)
+ *
+ * @source $URL$
  * @version $Id$
  * @since 2.5.7
  */
@@ -121,6 +123,10 @@
 
     public ISessionPool getInstance(Map<String, String> properties) throws IOException {
         ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(properties);
+        return getInstance(config);
+    }
+
+    public ISessionPool getInstance(ArcSDEConnectionConfig config) throws IOException {
         validate(config);
         ISessionPool sharedPool = getSharedPool(config);
         return sharedPool;


Property changes on: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactory.java
___________________________________________________________________
Added: svn:keywords
   + Id URL

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/jndi/SharedSessionPool.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -39,7 +39,7 @@
  * @since 2.5.7
  *
  */
-final class SharedSessionPool implements ISessionPool {
+public final class SharedSessionPool implements ISessionPool {
 
     private static final Logger LOGGER = Logger.getLogger("org.geotools.arcsde.session");
 
@@ -120,13 +120,20 @@
     }
 
     /**
-     * @see ISessionPool#getSession()
+     * @see org.geotools.arcsde.session.ISessionPool#getSession()
      */
     public ISession getSession() throws IOException, UnavailableConnectionException {
-        return delegate.getSession();
+        return getSession(true);
     }
 
     /**
+     * @see ISessionPool#getSession(boolean)
+     */
+    public ISession getSession(final boolean transactional) throws IOException, UnavailableConnectionException {
+        return delegate.getSession(transactional);
+    }
+
+    /**
      * @see ISessionPool#isClosed()
      */
     public boolean isClosed() {

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionConfig.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -23,6 +23,8 @@
  * Represents a set of ArcSDE database connection parameters.
  *
  * @author Gabriel Roldan
+ *
+ * @source $URL$
  * @version $Id$
  */
 public class ArcSDEConnectionConfig {

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ArcSDEConnectionReference.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -50,9 +50,9 @@
     }
 
     @Override
-    public ISession getSession() throws IOException, UnavailableConnectionException {
+    public ISession getSession(final boolean transactional) throws IOException, UnavailableConnectionException {
         if (cached == null) {
-            ISession session = super.getSession(); // this will block if session is already in use
+            ISession session = super.getSession(transactional); // this will block if session is already in use
             this.cached = new SessionWrapper(session) {
                 @Override
                 public void dispose() {

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Command.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -30,6 +30,8 @@
  * to prevent a series of complicated locks and try/catch/finally code.
  *
  * @author Jody Garnett
+ *
+ * @source $URL$
  */
 public abstract class Command<R> {
     /**

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISession.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -73,6 +73,8 @@
 
     public abstract SeRasterColumn getRasterColumn(final String rasterName) throws IOException;
 
+    public abstract List<String> getRasterColumns() throws IOException;
+
     public abstract SeTable getTable(final String tableName) throws IOException;
 
     /**

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPool.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -18,6 +18,10 @@
  * </p>
  *
  * @author Gabriel Roldan
+ *
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/common/src/main/java/org/geotools
+ *         /arcsde/session/ISessionPool.java $
  * @version $Id$
  */
 public interface ISessionPool {
@@ -58,6 +62,9 @@
      * Grab a session from the pool, this session is the responsibility of the calling code and must
      * be closed after use.
      *
+     * @param transactional
+     *            whether the session is intended to be used on a transaction, so the pool may
+     *            choose to reuse or not a connection.
      * @return A Session, when close() is called it will be recycled into the pool
      * @throws IOException
      *             If we could not get a connection
@@ -66,8 +73,16 @@
      * @throws IllegalStateException
      *             If pool has been closed.
      */
+    ISession getSession(final boolean transactional) throws IOException,
+            UnavailableConnectionException;
+
+    /**
+     * Shortcut for {@code getSession(true)}
+     *
+     * @see #getSession(boolean)
+     */
     ISession getSession() throws IOException, UnavailableConnectionException;
 
     ArcSDEConnectionConfig getConfig();
 
-}
\ No newline at end of file
+}

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/ISessionPoolFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -29,6 +29,8 @@
  * </p>
  *
  * @author Gabriel Roldan (OpenGeo)
+ *
+ * @source $URL$
  * @version $Id$
  * @since 2.5.7
  */
@@ -46,4 +48,4 @@
      */
     ISessionPool createPool(ArcSDEConnectionConfig config) throws IOException;
 
-}
\ No newline at end of file
+}

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/Session.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -18,7 +18,7 @@
 package org.geotools.arcsde.session;
 
 import java.io.IOException;
-import java.util.HashMap;
+import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
 import java.util.NoSuchElementException;
@@ -32,7 +32,6 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.apache.commons.pool.ObjectPool;
 import org.geotools.arcsde.ArcSdeException;
 import org.geotools.arcsde.session.Commands.GetVersionCommand;
 
@@ -84,9 +83,9 @@
     private final SeConnection connection;
 
     /**
-     * ObjectPool used to manage open connections (shared).
+     * SessionPool used to manage open connections (shared).
      */
-    private final ObjectPool pool;
+    private final SessionPool pool;
 
     private final ArcSDEConnectionConfig config;
 
@@ -102,8 +101,6 @@
 
     private Map<String, SeLayer> cachedLayers = new WeakHashMap<String, SeLayer>();
 
-    private Map<String, SeRasterColumn> cachedRasters = new HashMap<String, SeRasterColumn>();
-
     /**
      * The SeConnection bound task executor, ensures all operations against a given connection are
      * performed in the same thread regardless of the thread the {@link #issue(Command)} is being
@@ -116,17 +113,19 @@
      */
     private Thread commandThread;
 
+    private int referenceCount;
+
     /**
      * Provides safe access to an SeConnection.
      *
      * @param pool
-     *            ObjectPool used to manage SeConnection
+     *            SessionPool used to manage SeConnection
      * @param config
      *            Used to set up a SeConnection
      * @throws SeException
      *             If we cannot connect
      */
-    Session(final ObjectPool pool, final ArcSDEConnectionConfig config) throws IOException {
+    Session(final SessionPool pool, final ArcSDEConnectionConfig config) throws IOException {
         this.config = config;
         this.pool = pool;
         this.taskExecutor = Executors.newSingleThreadExecutor();
@@ -292,11 +291,13 @@
      * Shall be called just before being returned from the connection pool
      * </p>
      *
-     * @see #markInactive()
      * @see #isPassivated
      * @see #checkActive()
      */
     void markActive() {
+        synchronized (this) {
+            referenceCount = referenceCount + 1;
+        }
         this.isPassivated = false;
     }
 
@@ -311,6 +312,9 @@
      * @see #checkActive()
      */
     void markInactive() {
+        if (referenceCount != 0) {
+            throw new IllegalStateException("referenceCount = " + referenceCount);
+        }
         this.isPassivated = true;
     }
 
@@ -360,7 +364,7 @@
                 }
             });
         }
-        
+
         SeLayer seLayer = cachedLayers.get(layerName);
         if (seLayer == null) {
             throw new NoSuchElementException("Layer '" + layerName + "' not found");
@@ -386,20 +390,30 @@
      * @see ISession#getRasterColumn(java.lang.String)
      */
     public synchronized SeRasterColumn getRasterColumn(final String rasterName) throws IOException {
+        throw new UnsupportedOperationException("Waiting for a proper implementation");
+    }
+
+    /**
+     * @see org.geotools.arcsde.session.ISession#getRasterColumns()
+     */
+    public List<String> getRasterColumns() throws IOException {
         checkActive();
-        if (!cachedRasters.containsKey(rasterName)) {
-            try {
-                cacheRasters();
-            } catch (SeException e) {
-                throw (IOException) new IOException("Can't obtain raster " + rasterName)
-                        .initCause(e);
+        List<String> rasterNames = issue(new Command<List<String>>() {
+            @SuppressWarnings("unchecked")
+            @Override
+            public List<String> execute(final ISession session, final SeConnection connection)
+                    throws SeException, IOException {
+
+                final Vector<SeRasterColumn> rasterColumns = connection.getRasterColumns();
+                List<String> names = new ArrayList<String>(rasterColumns.size());
+
+                for (SeRasterColumn col : rasterColumns) {
+                    names.add(col.getQualifiedTableName());
+                }
+                return names;
             }
-        }
-        SeRasterColumn raster = cachedRasters.get(rasterName);
-        if (raster == null) {
-            throw new NoSuchElementException("Raster '" + rasterName + "' not found");
-        }
-        return raster;
+        });
+        return rasterNames;
     }
 
     /**
@@ -436,15 +450,6 @@
         return seTable;
     }
 
-    @SuppressWarnings("unchecked")
-    private void cacheRasters() throws SeException {
-        Vector<SeRasterColumn> rasters = this.connection.getRasterColumns();
-        cachedRasters.clear();
-        for (SeRasterColumn raster : rasters) {
-            cachedRasters.put(raster.getQualifiedTableName(), raster);
-        }
-    }
-
     /**
      * @see ISession#startTransaction()
      */
@@ -510,17 +515,28 @@
      */
     public void dispose() throws IllegalStateException {
         checkActive();
+        final int refCount;
+        synchronized (this) {
+            refCount = referenceCount = referenceCount - 1;
+        }
+        if (refCount > 0) {
+            // ignore
+            if (LOGGER.isLoggable(Level.FINEST)) {
+                LOGGER.finest("---------> Ignoring disposal, ref count is still " + refCount
+                        + " for " + this);
+            }
+            return;
+        }
+
+        if (LOGGER.isLoggable(Level.FINEST)) {
+            LOGGER.finest("  -> RefCount is " + refCount + ". Disposing " + this);
+        }
         if (transactionInProgress) {
             throw new IllegalStateException(
                     "Transaction is in progress, should commit or rollback before closing");
         }
-
         try {
             this.pool.returnObject(this);
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("<-- " + toString() + " retured to pool. Active: "
-                        + pool.getNumActive() + ", idle: " + pool.getNumIdle());
-            }
         } catch (Exception e) {
             LOGGER.log(Level.SEVERE, e.getMessage(), e);
         }
@@ -548,6 +564,8 @@
             });
         } catch (Exception e) {
             LOGGER.log(Level.FINE, "closing connection " + toString(), e);
+        } finally {
+            taskExecutor.shutdown();
         }
     }
 
@@ -952,22 +970,46 @@
         @Override
         public SeConnection execute(final ISession session, final SeConnection connection)
                 throws SeException, IOException {
-            String serverName = config.getServerName();
-            int portNumber = config.getPortNumber().intValue();
-            String databaseName = config.getDatabaseName();
-            String userName = config.getUserName();
-            String userPassword = config.getPassword();
+            final String serverName = config.getServerName();
+            final int portNumber = config.getPortNumber().intValue();
+            final String databaseName = config.getDatabaseName();
+            final String userName = config.getUserName();
+            final String userPassword = config.getPassword();
 
-            SeConnection conn;
+            NegativeArraySizeException cause = null;
+            SeConnection conn = null;
             try {
-                conn = new SeConnection(serverName, portNumber, databaseName, userName,
-                        userPassword);
+                for (int i = 0; i < 3; i++) {
+                    try {
+                        conn = new SeConnection(serverName, portNumber, databaseName, userName,
+                                userPassword);
+                    } catch (NegativeArraySizeException nase) {
+                        LOGGER.warning("Strange failed ArcSDE connection error.  "
+                                + "Trying again (try " + (i + 1) + " of 3)");
+                        try {
+                            /*
+                             * This usually happen under high load, lets wait a little bit and see
+                             * if we can connect
+                             */
+                            Thread.sleep(100);
+                        } catch (InterruptedException e) {
+                            e.printStackTrace();
+                            // ignore
+                        }
+                        cause = nase;
+                    }
+                }
             } catch (SeException e) {
                 throw new ArcSdeException("Can't create connection to " + serverName, e);
             } catch (RuntimeException e) {
                 throw (IOException) new IOException("Can't create connection to " + serverName)
                         .initCause(e);
             }
+            if (cause != null) {
+                throw (IOException) new IOException(
+                        "Couldn't create ArcSDE Session because of strange SDE internal exception. "
+                                + " Tried 3 times, giving up.").initCause(cause);
+            }
             conn.setConcurrency(SeConnection.SE_ONE_THREAD_POLICY);
             return conn;
         }

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionPool.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -19,6 +19,10 @@
 
 import java.io.IOException;
 import java.util.NoSuchElementException;
+import java.util.Queue;
+import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -69,8 +73,10 @@
     protected ArcSDEConnectionConfig config;
 
     /** Apache commons-pool used to pool arcsde connections */
-    protected GenericObjectPool pool;
+    private GenericObjectPool pool;
 
+    private final Queue<Session> openSessionsNonTransactional = new ConcurrentLinkedQueue<Session>();
+
     /**
      * Creates a new SdeConnectionPool object with the connection parameters holded by
      * <code>config</code>
@@ -117,7 +123,11 @@
             // When reached the pool upper limit, block and wait for an idle connection for maxWait
             // milliseconds before failing
             poolCfg.maxWait = config.getConnTimeOut().longValue();
-            poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
+            if (poolCfg.maxWait > 0) {
+                poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_BLOCK;
+            } else {
+                poolCfg.whenExhaustedAction = GenericObjectPool.WHEN_EXHAUSTED_FAIL;
+            }
 
             // check connection health at borrowObject()?
             poolCfg.testOnBorrow = true;
@@ -158,11 +168,7 @@
                 pool.returnObject(preload[i]);
             }
         } catch (Exception e) {
-            try {
-                pool.close();
-            } catch (Exception closeEx) {
-                // ignore
-            }
+            close();
             if (e instanceof IOException) {
                 throw (IOException) e;
             }
@@ -189,9 +195,7 @@
      */
     public int getPoolSize() {
         checkOpen();
-        synchronized (this.pool) {
-            return this.pool.getNumActive() + this.pool.getNumIdle();
-        }
+        return pool.getMaxActive();
     }
 
     /*
@@ -202,7 +206,7 @@
     public void close() {
         if (pool != null) {
             try {
-                this.pool.close();
+                pool.close();
                 pool = null;
                 LOGGER.fine("SDE connection pool closed. ");
             } catch (Exception e) {
@@ -234,47 +238,79 @@
         close();
     }
 
-    /*
-     * (non-Javadoc)
-     *
+    /**
      * @see org.geotools.arcsde.session.ISessionPool#getAvailableCount()
      */
     public synchronized int getAvailableCount() {
         checkOpen();
-        return this.pool.getNumIdle();
+        return pool.getMaxActive() - pool.getNumActive();
     }
 
-    /*
-     * (non-Javadoc)
-     *
+    /**
      * @see org.geotools.arcsde.session.ISessionPool#getInUseCount()
      */
-    public synchronized int getInUseCount() {
+    public int getInUseCount() {
         checkOpen();
-        return this.pool.getNumActive();
+        return pool.getNumActive();
     }
 
-    /*
-     * (non-Javadoc)
-     *
+    /**
      * @see org.geotools.arcsde.session.ISessionPool#getSession()
      */
     public ISession getSession() throws IOException, UnavailableConnectionException {
+        return getSession(true);
+    }
+
+    private Lock poolLock = new ReentrantLock();
+
+    public void returnObject(Session session) throws Exception {
+        openSessionsNonTransactional.remove(session);
+        pool.returnObject(session);
+    }
+
+    /**
+     * @see org.geotools.arcsde.session.ISessionPool#getSession(boolean)
+     */
+    public ISession getSession(final boolean transactional) throws IOException,
+            UnavailableConnectionException {
         checkOpen();
         try {
-            Session connection = (Session) this.pool.borrowObject();
-
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("-->" + connection + " out of connection pool. Active: "
-                        + pool.getNumActive() + ", idle: " + pool.getNumIdle());
+            Session connection;
+            if (transactional) {
+                connection = (Session) pool.borrowObject();
+                connection.markActive();
+                return connection;
+            } else {
+                final int limit = config.getMaxConnections();
+                poolLock.lock();
+                final int used = pool.getNumActive();
+                if (used < limit) {
+                    try {
+                        connection = (Session) pool.borrowObject();
+                    } catch (NoSuchElementException e) {
+                        if (LOGGER.isLoggable(Level.FINEST)) {
+                            LOGGER.finest("Falling back to queued session");
+                        }
+                        connection = openSessionsNonTransactional.remove();
+                    }
+                    openSessionsNonTransactional.add(connection);
+                } else {
+                    connection = openSessionsNonTransactional.remove();
+                    openSessionsNonTransactional.add(connection);
+                }
+                poolLock.unlock();
+                connection.markActive();
+                return connection;
             }
 
-            connection.markActive();
-            return connection;
+            // if (LOGGER.isLoggable(Level.FINER)) {
+            // LOGGER.finer("-->" + connection + " out of connection pool. Active: "
+            // + pool.getNumActive() + ", idle: " + pool.getNumIdle());
+            // }
         } catch (NoSuchElementException e) {
             LOGGER.log(Level.WARNING, "Out of connections: " + e.getMessage() + ". Config: "
                     + this.config);
-            throw new UnavailableConnectionException(this.pool.getNumActive(), this.config);
+            throw new UnavailableConnectionException(config.getMaxConnections(), this.config);
         } catch (SeException se) {
             ArcSdeException sdee = new ArcSdeException(se);
             LOGGER.log(Level.WARNING, "ArcSDE error getting connection for " + config, sdee);
@@ -325,35 +361,25 @@
          */
         @Override
         public Object makeObject() throws IOException {
-            NegativeArraySizeException cause = null;
-            for (int i = 0; i < 3; i++) {
-                try {
-                    ISession seConn = new Session(SessionPool.this.pool, config);
-                    return seConn;
-                } catch (NegativeArraySizeException nase) {
-                    LOGGER.warning("Strange failed ArcSDE connection error.  Trying again (try "
-                            + (i + 1) + " of 3)");
-                    cause = nase;
-                }
+            ISession seConn;
+            /*
+             * When running on a server environment, if the server needs to serve multiple
+             * concurrent requests at a time this method might end up being called by multiple
+             * concurrent threads. If you try to create multiple SeConnection object at the same
+             * time they fail often, presumably by some bad concurrency code in the ArcSDE Java API.
+             * By synchronizing the creation of SeConnections this way we make sure a single
+             * SeConnection is created at a time, eliminating the error condition. Though the
+             * creation of a connection is quite slow, the performance penalty of this
+             * synchronization is minimal in the long run since once created they're in the pool and
+             * reused until the pool decides they've been idle enough to discard them.
+             */
+            synchronized (this) {
+                seConn = new Session(SessionPool.this, config);
             }
-            throw (IOException) new IOException(
-                    "Couldn't create ArcSDE Session because of strange SDE internal exception. "
-                            + " Tried 3 times, giving up.").initCause(cause);
+            return seConn;
         }
 
-        /**
-         * is invoked on every instance before it is returned from the pool.
-         *
-         * @param obj
-         */
         @Override
-        public void activateObject(Object obj) {
-            final Session conn = (Session) obj;
-            conn.markActive();
-            LOGGER.finest("    activating connection " + obj);
-        }
-
-        @Override
         public void passivateObject(Object obj) {
             LOGGER.finest("    passivating connection " + obj);
             final Session conn = (Session) obj;
@@ -423,5 +449,4 @@
         ret.append("]");
         return ret.toString();
     }
-
 }

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/main/java/org/geotools/arcsde/session/SessionWrapper.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -241,6 +241,13 @@
     }
 
     /**
+     * @see org.geotools.arcsde.session.ISession#getRasterColumns()
+     */
+    public List<String> getRasterColumns() throws IOException {
+        return wrapped.getRasterColumns();
+    }
+
+    /**
      * @see org.geotools.arcsde.session.ISession#getRelease()
      */
     public SeRelease getRelease() throws IOException {

Modified: branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/common/src/test/java/org/geotools/arcsde/jndi/ArcSDEConnectionFactoryTest.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -45,6 +45,8 @@
  * Unit test suite for {@link ArcSDEConnectionFactory}
  *
  * @author Gabriel Roldan (OpenGeo)
+ *
+ * @source $URL$
  * @version $Id$
  * @since 2.5.7
  */
@@ -223,31 +225,29 @@
         }
 
         public void close() {
-            // TODO Auto-generated method stub
         }
 
         public int getAvailableCount() {
-            // TODO Auto-generated method stub
             return 0;
         }
 
         public int getInUseCount() {
-            // TODO Auto-generated method stub
             return 0;
         }
 
         public int getPoolSize() {
-            // TODO Auto-generated method stub
             return 0;
         }
 
         public ISession getSession() throws IOException, UnavailableConnectionException {
-            // TODO Auto-generated method stub
             return null;
         }
 
+        public ISession getSession(boolean transactional) throws IOException, UnavailableConnectionException {
+            return null;
+        }
+
         public boolean isClosed() {
-            // TODO Auto-generated method stub
             return false;
         }
     }


Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore
___________________________________________________________________
Added: svn:mergeinfo
   + /trunk/modules/plugin/arcsde/datastore:31091-34351

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/pom.xml 2009-11-09 18:53:16 UTC (rev 34354)
@@ -120,7 +120,13 @@
  <artifactId>gt-coverage</artifactId>
  <version>${project.version}</version>
  </dependency>
- <dependency>
+    <dependency>
+      <groupId>org.geotools</groupId>
+      <artifactId>gt-epsg-hsql</artifactId>
+      <version>${project.version}</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
  <groupId>javax.media</groupId>
  <artifactId>jai_core</artifactId>
  <scope>provided</scope>


Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore/src
___________________________________________________________________
Deleted: svn:mergeinfo
   - /trunk/modules/plugin/arcsde/datastore/src:31091-33685

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEDataStoreFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -195,7 +195,7 @@
      */
     public ArcSDEDataStoreFactory() {
         if (!isAvailable()) {
-            LOGGER.warning("The ESRI ArcSDE Java API seems to not be on your classpath. Please"
+            LOGGER.finest("The ESRI ArcSDE Java API seems to not be on your classpath. Please"
                     + " verify that all needed jars are. ArcSDE data stores"
                     + " will not be available.");
         }
@@ -270,7 +270,7 @@
         ArcSDEDataStore sdeDStore;
         ISession session;
         try {
-            session = connPool.getSession();
+            session = connPool.getSession(false);
         } catch (UnavailableConnectionException e) {
             throw new RuntimeException(e);
         }

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -64,6 +64,10 @@
  * </p>
  *
  * @author Gabriel Roldan (OpenGeo)
+ *
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/ArcSDEJNDIDataStoreFactory.java $
  * @version $Id$
  * @since 2.5.7
  */


Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java
___________________________________________________________________
Deleted: svn:mergeinfo
   - /trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDEJNDIDataStoreFactory.java:31091-33805

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDERasterFormatFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDERasterFormatFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/ArcSDERasterFormatFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -22,7 +22,7 @@
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-import org.geotools.arcsde.gce.ArcSDERasterFormat;
+import org.geotools.arcsde.raster.gce.ArcSDERasterFormat;
 import org.geotools.coverage.grid.io.GridFormatFactorySpi;
 import org.geotools.util.logging.Logging;
 

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEAttributeReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -100,23 +100,28 @@
 
     private ISession session;
 
+    private GeometryFactory geometryFactory;
+
     /**
      * The query that defines this readers interaction with an ArcSDE instance.
      *
      * @param query
      *            the {@link SeQuery} wrapper where to fetch rows from. Must NOT be already
      *            {@link ArcSDEQuery#execute() executed}.
+     * @param geometryFactory
+     *            the JTS GeometryFactory to use when creating Feature geometries
      * @param session
      *            the session the <code>query</code> is being ran over. This attribute reader will
      *            close it only if it does not have a transaction in progress.
      * @throws IOException
      */
-    public ArcSDEAttributeReader(final ArcSDEQuery query, final ISession session)
-            throws IOException {
+    public ArcSDEAttributeReader(final ArcSDEQuery query, final GeometryFactory geometryFactory,
+            final ISession session) throws IOException {
         this.query = query;
         this.session = session;
         this.fidReader = query.getFidReader();
         this.schema = query.getSchema();
+        this.geometryFactory = geometryFactory;
 
         String typeName = schema.getTypeName();
 
@@ -231,7 +236,7 @@
      * @throws ArrayIndexOutOfBoundsException
      *             if <code>index</code> is outside the bounds of the schema attribute's count
      */
-    public Object read(int index) throws IOException, ArrayIndexOutOfBoundsException {
+    public Object read(final int index) throws IOException, ArrayIndexOutOfBoundsException {
         Object value = currentRow.getObject(index);
         if (value instanceof SeShape) {
             try {
@@ -244,7 +249,7 @@
                     actualGeomtryClass = ArcSDEAdapter.getGeometryTypeFromSeShape(shape);
                     final ArcSDEGeometryBuilder geometryBuilder;
                     geometryBuilder = ArcSDEGeometryBuilder.builderFor(actualGeomtryClass);
-                    value = geometryBuilder.construct(shape);
+                    value = geometryBuilder.construct(shape, geometryFactory);
                     if (!this.schemaGeometryClass.isAssignableFrom(actualGeomtryClass)) {
                         value = adaptGeometry((Geometry) value, schemaGeometryClass);
                     }

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEDataStore.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -58,8 +58,11 @@
 import org.geotools.data.ServiceInfo;
 import org.geotools.data.Transaction;
 import org.geotools.data.view.DefaultView;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
 import org.geotools.feature.FeatureTypes;
 import org.geotools.feature.SchemaException;
+import org.geotools.geometry.jts.LiteCoordinateSequenceFactory;
 import org.geotools.util.logging.Logging;
 import org.opengis.feature.simple.SimpleFeature;
 import org.opengis.feature.simple.SimpleFeatureType;
@@ -73,6 +76,10 @@
 import com.esri.sde.sdk.client.SeQueryInfo;
 import com.esri.sde.sdk.client.SeTable;
 import com.esri.sde.sdk.client.SeVersion;
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
+import com.vividsolutions.jts.geom.GeometryFactory;
+import com.vividsolutions.jts.geom.PrecisionModel;
+import com.vividsolutions.jts.geom.impl.CoordinateArraySequenceFactory;
 
 /**
  * DataStore implementation to work upon an ArcSDE spatial database gateway.
@@ -167,7 +174,7 @@
         final ISession session;
         if (Transaction.AUTO_COMMIT.equals(transaction)) {
             try {
-                session = connectionPool.getSession();
+                session = connectionPool.getSession(false);
             } catch (UnavailableConnectionException e) {
                 throw new RuntimeException("Session pool exhausted", e);
             }
@@ -366,11 +373,12 @@
                     versionHandler);
         }
 
-        // /sdeQuery.execute();
+        final GeometryFactory geometryFactory = getGeometryFactory(query.getHints());
 
         // this is the one which's gonna close the connection when done
         final ArcSDEAttributeReader attReader;
-        attReader = new ArcSDEAttributeReader(sdeQuery, session);
+        attReader = new ArcSDEAttributeReader(sdeQuery, geometryFactory, session);
+
         FeatureReader<SimpleFeatureType, SimpleFeature> reader;
         try {
             reader = new ArcSDEFeatureReader(attReader);
@@ -397,6 +405,39 @@
         return reader;
     }
 
+    private GeometryFactory getGeometryFactory(final Hints queryHints) {
+        // setup the geometry factory according to the hints
+        final Hints hints;
+        if (queryHints == null) {
+            hints = GeoTools.getDefaultHints();
+        } else {
+            hints = queryHints;
+        }
+
+        GeometryFactory gf = (GeometryFactory) hints.get(Hints.JTS_GEOMETRY_FACTORY);
+
+        if (gf == null) {
+            PrecisionModel pm = (PrecisionModel) hints.get(Hints.JTS_PRECISION_MODEL);
+            if (pm == null) {
+                pm = new PrecisionModel();
+            }
+            Integer SRID = (Integer) hints.get(Hints.JTS_SRID);
+            int srid = SRID == null ? 0 : SRID.intValue();
+            Integer dimension = (Integer) hints.get(Hints.COORDINATE_DIMENSION);
+            CoordinateSequenceFactory csFactory = (CoordinateSequenceFactory) hints
+                    .get(Hints.JTS_COORDINATE_SEQUENCE_FACTORY);
+            if (csFactory == null) {
+                if (dimension == null || dimension <= 3) {
+                    csFactory = CoordinateArraySequenceFactory.instance();
+                } else {
+                    csFactory = new LiteCoordinateSequenceFactory();
+                }
+            }
+            gf = new GeometryFactory(pm, srid, csFactory);
+        }
+        return gf;
+    }
+
     public SimpleFeatureType getQueryType(Query query) throws IOException {
         final String typeName = query.getTypeName();
         final String propertyNames[] = query.getPropertyNames();

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEGeometryBuilder.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEGeometryBuilder.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEGeometryBuilder.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -26,6 +26,7 @@
 
 import org.geotools.arcsde.ArcSdeException;
 import org.geotools.data.DataSourceException;
+import org.geotools.geometry.jts.LiteCoordinateSequenceFactory;
 import org.geotools.util.logging.Logging;
 
 import com.esri.sde.sdk.client.SDEPoint;
@@ -33,6 +34,8 @@
 import com.esri.sde.sdk.client.SeException;
 import com.esri.sde.sdk.client.SeShape;
 import com.vividsolutions.jts.geom.Coordinate;
+import com.vividsolutions.jts.geom.CoordinateSequence;
+import com.vividsolutions.jts.geom.CoordinateSequenceFactory;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.GeometryCollection;
 import com.vividsolutions.jts.geom.GeometryFactory;
@@ -80,7 +83,7 @@
  * @version $Id$
  */
 public abstract class ArcSDEGeometryBuilder {
-    /** DOCUMENT ME! */
+
     private static final Logger LOGGER = Logging.getLogger(ArcSDEGeometryBuilder.class.getName());
 
     /** lookup specialized geometry builders classes by it's geometry type */
@@ -108,9 +111,6 @@
         nullGeometries.put(MultiPolygon.class, new MultiPolygonBuilder().getEmpty());
     }
 
-    /** JTS geometry factory subclasses use to map SeShapes to JTS ones */
-    protected GeometryFactory factory = new GeometryFactory();
-
     /**
      * Private empty constructor to obligate using this class as factory.
      */
@@ -124,6 +124,7 @@
      *
      * @param shape
      *            the ESRI's ArcSDE java api shape upon wich to create the new JTS geometry
+     * @param geometryFactory
      * @return the type of JTS Geometry this subclass instance is specialized for or an empty
      *         geometry of the same class if <code>shape.isNil()</code>
      * @throws SeException
@@ -134,12 +135,13 @@
      *             the <code>com.vividsolutions.jts.geom.Coordinate[]</code> provided by
      *             <code>newGeometry</code>
      */
-    public Geometry construct(SeShape shape) throws SeException, DataSourceException {
+    public Geometry construct(final SeShape shape, final GeometryFactory geometryFactory)
+            throws SeException, DataSourceException {
         if (shape == null || shape.isNil()) {
             return getEmpty();
         }
         double[][][] allCoords = shape.getAllCoords();
-        return newGeometry(allCoords);
+        return newGeometry(allCoords, geometryFactory);
     }
 
     /**
@@ -153,7 +155,6 @@
      *            the <code>SeShape</code> is constructed.
      * @return the <code>SeShape</code> representation of passed <code>Geometry</code>
      * @throws ArcSDEGeometryBuildingException
-     *             DOCUMENT ME!
      */
     public final SeShape constructShape(final Geometry geometry, SeCoordinateReference seSrs)
             throws ArcSdeException {
@@ -237,100 +238,18 @@
     }
 
     /**
-     * utility method that <code>ArcSDEGeometryBuilder</code> subclasses use to obtain the three
-     * dimensional array of double's that forms the body of the <code>SeShape</code> structure.
-     *
-     * @param jtsGeom
-     *            the source JTS geometry
-     * @return the array of <code>double</code> primitives that represents <code>jtsGeom</code> in
-     *         <code>SeShape</code> format
-     */
-    // private double[][][] geometryToSdeCoords(Geometry jtsGeom) {
-    // int numParts;
-    // int numSubParts = 1;
-    // double[][][] sdeCoords;
-    //
-    // GeometryCollection gcol = null;
-    //
-    // // to simplify the algorithm, allways use GeometryCollections
-    // // as input geometries
-    // if (jtsGeom instanceof MultiPolygon) {
-    // gcol = (GeometryCollection) jtsGeom;
-    // } else {
-    // Geometry[] geoms = { jtsGeom };
-    //
-    // gcol = new GeometryFactory().createGeometryCollection(geoms);
-    // }
-    //
-    // numParts = gcol.getNumGeometries();
-    //
-    // sdeCoords = new double[numParts][0][0];
-    //
-    // for (int i = 0; i < numParts; i++) {
-    // Geometry geom = gcol.getGeometryN(i);
-    //
-    // numSubParts = (geom instanceof Polygon) ? (((Polygon)
-    // geom).getNumInteriorRing() + 1)
-    // : ((geom instanceof GeometryCollection) ? ((GeometryCollection) geom)
-    // .getNumGeometries() : 1);
-    //
-    // sdeCoords[i] = new double[numSubParts][0];
-    //
-    // Coordinate[] partCoords = null;
-    //
-    // for (int j = 0; j < numSubParts; j++) {
-    // if (geom instanceof Polygon) {
-    // if (j == 0) {
-    // partCoords = ((Polygon) geom).getExteriorRing().getCoordinates();
-    // } else {
-    // partCoords = ((Polygon) geom).getInteriorRingN(j - 1).getCoordinates();
-    // }
-    // } else if (geom instanceof GeometryCollection) {
-    // partCoords = ((GeometryCollection)
-    // geom).getGeometryN(j).getCoordinates();
-    // } else {
-    // partCoords = geom.getCoordinates();
-    // }
-    //
-    // sdeCoords[i][j] = toSdeCoords(partCoords);
-    // }
-    // }
-    //
-    // return sdeCoords;
-    // }
-    /**
-     * Creates an array of linear coordinates as <code>SeShape</code> use from an array of JTS
-     * <code>Coordinate</code> objects
-     *
-     * @param coords
-     *            wich coordinate to generate the linear array from
-     * @return the <code>SeShape</code> style coordinate array of a single geometry given by its
-     *         <code>Coordinate</code> array
-     */
-    // private double[] toSdeCoords(Coordinate[] coords) {
-    // int nCoords = coords.length;
-    // double[] sdeCoords = new double[2 * nCoords];
-    // Coordinate c;
-    //
-    // for (int i = 0, j = 1; i < nCoords; i++, j += 2) {
-    // c = coords[i];
-    // sdeCoords[j - 1] = c.x;
-    // sdeCoords[j] = c.y;
-    // }
-    //
-    // return sdeCoords;
-    // }
-    /**
      * Builds a JTS Geometry who't type is given by the <code>ArcSDEGeometryBuilder</code> subclass
      * instance specialization that implements it
      *
      * @param coords
      *            <code>SeShape</code>'s coordinate array to build the geometry from
+     * @param geometryFactory
      * @return the JST form of the passed geometry coordinates
      * @throws DataSourceException
      *             if an error occurs while creating the JTS Geometry
      */
-    protected abstract Geometry newGeometry(double[][][] coords) throws DataSourceException;
+    protected abstract Geometry newGeometry(final double[][][] coords,
+            final GeometryFactory geometryFactory) throws DataSourceException;
 
     /**
      * returns an empty JTS geometry who's type is given by the <code>ArcSDEGeometryBuilder</code>
@@ -341,7 +260,6 @@
      *
      * @return an empty JTS geometry
      * @throws UnsupportedOperationException
-     *             DOCUMENT ME!
      */
     protected Geometry getEmpty() {
         throw new UnsupportedOperationException(
@@ -360,24 +278,26 @@
      * @return a geometrically equal to <code>coordList</code> array of <code>Coordinate</code>
      *         instances
      */
-    protected Coordinate[] toCoords(double[] coordList) {
-        int nCoords = coordList.length / 2;
+    protected final CoordinateSequence toCoords(double[] coordList,
+            final CoordinateSequenceFactory csFact) {
 
-        Coordinate[] coords = new Coordinate[nCoords];
+        final int dimension = 2;
 
-        for (int i = 0, j = 0; i < nCoords; i++, j++)
-            coords[i] = new Coordinate(coordList[j], coordList[++j]);
+        CoordinateSequence cs;
 
-        return coords;
+        if (csFact instanceof LiteCoordinateSequenceFactory) {
+            cs = ((LiteCoordinateSequenceFactory) csFact).create(coordList, dimension);
+        } else {
+            final int nCoords = coordList.length / dimension;
+            cs = csFact.create(nCoords, dimension);
+            for (int coordN = 0; coordN < nCoords; coordN++) {
+                cs.setOrdinate(coordN, 0, coordList[dimension * coordN]);
+                cs.setOrdinate(coordN, 1, coordList[dimension * coordN + 1]);
+            }
+        }
+        return cs;
     }
 
-    /**
-     * DOCUMENT ME!
-     *
-     * @param coords
-     *            DOCUMENT ME!
-     * @return DOCUMENT ME!
-     */
     protected SDEPoint[] toPointsArray(Coordinate[] coords) {
         int nCoords = coords.length;
 
@@ -420,11 +340,6 @@
     /**
      * Create an empty geometry for the indicated class
      *
-     * @param geoClass
-     *            DOCUMENT ME!
-     * @return DOCUMENT ME!
-     * @throws NullPointerException
-     *             DOCUMENT ME!
      */
     public static Geometry defaultValueFor(Class<?> geoClass) {
         if (geoClass == null) {
@@ -460,11 +375,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -479,7 +389,8 @@
          * @see ArcSDEGeometryBuilder#construct(SeShape)
          */
         @Override
-        public Geometry construct(SeShape shape) throws SeException, DataSourceException {
+        public Geometry construct(SeShape shape, final GeometryFactory geometryFactory)
+                throws SeException, DataSourceException {
             if (shape == null || shape.isNil()) {
                 return getEmpty();
             }
@@ -490,22 +401,12 @@
             }
             ArcSDEGeometryBuilder realBuilder = builderFor(realGeomClass);
 
-            return realBuilder.construct(shape);
+            return realBuilder.construct(shape, geometryFactory);
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @throws DataSourceException
-         *             DOCUMENT ME!
-         * @throws UnsupportedOperationException
-         *             DOCUMENT ME!
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             throw new UnsupportedOperationException("This method should not "
                     + "be called for this builder. It should be mapped to the "
                     + "one capable of constructing the actual geometry type");
@@ -536,11 +437,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -550,20 +446,12 @@
             return EMPTY;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @throws DataSourceException
-         *             DOCUMENT ME!
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             final double x = coords[0][0][0];
             final double y = coords[0][0][1];
-            return super.factory.createPoint(new Coordinate(x, y));
+            return geometryFactory.createPoint(new Coordinate(x, y));
         }
     }
 
@@ -591,11 +479,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -605,17 +488,9 @@
             return EMPTY;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @throws DataSourceException
-         *             DOCUMENT ME!
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             int nPoints = coords.length;
 
             Coordinate[] points = new Coordinate[nPoints];
@@ -626,7 +501,7 @@
                 points[i] = new Coordinate(x, y);
             }
 
-            return super.factory.createMultiPoint(points);
+            return geometryFactory.createMultiPoint(points);
         }
     }
 
@@ -654,11 +529,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -668,27 +538,20 @@
             return EMPTY;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @throws DataSourceException
-         *             DOCUMENT ME!
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
-            return constructLineString(coords[0][0]);
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
+            return constructLineString(coords[0][0], geometryFactory);
         }
 
-        //
-        protected LineString constructLineString(double[] linearCoords) throws DataSourceException {
+        protected final LineString constructLineString(final double[] linearCoords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             LineString ls = null;
 
-            Coordinate[] coords = toCoords(linearCoords);
+            CoordinateSequence coords = toCoords(linearCoords, geometryFactory
+                    .getCoordinateSequenceFactory());
 
-            ls = super.factory.createLineString(coords);
+            ls = geometryFactory.createLineString(coords);
 
             return ls;
         }
@@ -718,11 +581,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -732,17 +590,9 @@
             return EMPTY;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @throws DataSourceException
-         *             DOCUMENT ME!
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             MultiLineString mls = null;
 
             LineString[] lineStrings = null;
@@ -751,10 +601,11 @@
 
             lineStrings = new LineString[nLines];
 
-            for (int i = 0; i < nLines; i++)
-                lineStrings[i] = constructLineString(coords[i][0]);
+            for (int i = 0; i < nLines; i++) {
+                lineStrings[i] = constructLineString(coords[i][0], geometryFactory);
+            }
 
-            mls = super.factory.createMultiLineString(lineStrings);
+            mls = geometryFactory.createMultiLineString(lineStrings);
 
             return mls;
         }
@@ -784,11 +635,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return DOCUMENT ME!
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -798,14 +644,9 @@
             return EMPTY;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param coords
-         * @throws DataSourceException
-         */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             // /////
             /*
              * for (int i = 0; i < coords.length; i++) { for (int j = 0; j < coords[i].length; j++)
@@ -820,13 +661,17 @@
             for (int i = 0; i < nHoles; i++) {
                 holes[i] = coords[0][i + 1];
             }
-            return buildPolygon(shell, holes);
+            return buildPolygon(shell, holes, geometryFactory);
         }
 
-        protected Polygon buildPolygon(final double[] shellCoords, final double[][] holes) {
+        protected final Polygon buildPolygon(final double[] shellCoords, final double[][] holes,
+                final GeometryFactory geometryFactory) {
             Polygon p = null;
 
-            final LinearRing shell = super.factory.createLinearRing(toCoords(shellCoords));
+            final CoordinateSequenceFactory sequenceFactory = geometryFactory
+                    .getCoordinateSequenceFactory();
+            final CoordinateSequence coords = toCoords(shellCoords, sequenceFactory);
+            final LinearRing shell = geometryFactory.createLinearRing(coords);
             final int nHoles = holes.length;
 
             LinearRing[] polygonHoles = new LinearRing[nHoles];
@@ -834,32 +679,28 @@
             if (nHoles > 0) {
                 for (int i = 0; i < nHoles; i++) {
                     double hole[] = holes[i];
-                    polygonHoles[i] = super.factory.createLinearRing(toCoords(hole));
+                    polygonHoles[i] = geometryFactory.createLinearRing(toCoords(hole,
+                            sequenceFactory));
                 }
             }
 
-            p = super.factory.createPolygon(shell, polygonHoles);
+            p = geometryFactory.createPolygon(shell, polygonHoles);
 
             return p;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param parts
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @deprecated
-         */
         @Deprecated
-        protected Polygon buildPolygon(double[][] parts) {
+        protected Polygon buildPolygon(final double[][] parts, final GeometryFactory geometryFactory) {
             Polygon p = null;
 
             double[] linearCoordArray = parts[0];
 
             int nHoles = parts.length - 1;
 
-            LinearRing shell = super.factory.createLinearRing(toCoords(linearCoordArray));
+            final CoordinateSequenceFactory coordinateSequenceFactory = geometryFactory
+                    .getCoordinateSequenceFactory();
+            LinearRing shell = geometryFactory.createLinearRing(toCoords(linearCoordArray,
+                    coordinateSequenceFactory));
 
             LinearRing[] holes = new LinearRing[nHoles];
 
@@ -867,32 +708,29 @@
                 for (int i = 0; i < nHoles; i++) {
                     linearCoordArray = parts[i + 1];
 
-                    holes[i] = super.factory.createLinearRing(toCoords(linearCoordArray));
+                    holes[i] = geometryFactory.createLinearRing(toCoords(linearCoordArray,
+                            coordinateSequenceFactory));
                 }
             }
 
-            p = super.factory.createPolygon(shell, holes);
+            p = geometryFactory.createPolygon(shell, holes);
 
             return p;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @param parts
-         *            DOCUMENT ME!
-         * @return DOCUMENT ME!
-         * @deprecated
-         */
         @Deprecated
-        protected Polygon buildPolygon(double[][][] parts) {
+        protected Polygon buildPolygon(final double[][][] parts,
+                final GeometryFactory geometryFactory) {
             Polygon p = null;
 
             double[] linearCoordArray = parts[0][0];
 
             int nHoles = parts.length - 1;
 
-            LinearRing shell = super.factory.createLinearRing(toCoords(linearCoordArray));
+            CoordinateSequenceFactory sequenceFactory = geometryFactory
+                    .getCoordinateSequenceFactory();
+            LinearRing shell = geometryFactory.createLinearRing(toCoords(linearCoordArray,
+                    sequenceFactory));
 
             LinearRing[] holes = new LinearRing[nHoles];
 
@@ -900,11 +738,12 @@
                 for (int i = 0; i < nHoles; i++) {
                     linearCoordArray = parts[i + 1][0];
 
-                    holes[i] = super.factory.createLinearRing(toCoords(linearCoordArray));
+                    holes[i] = geometryFactory.createLinearRing(toCoords(linearCoordArray,
+                            sequenceFactory));
                 }
             }
 
-            p = super.factory.createPolygon(shell, holes);
+            p = geometryFactory.createPolygon(shell, holes);
 
             return p;
         }
@@ -934,11 +773,6 @@
             return instance;
         }
 
-        /**
-         * DOCUMENT ME!
-         *
-         * @return an empty multipolygon
-         */
         @Override
         protected Geometry getEmpty() {
             if (EMPTY == null) {
@@ -949,7 +783,6 @@
         }
 
         /**
-         * DOCUMENT ME!
          *
          * @param coords
          *            the SeShape's multipolygon coordinates array
@@ -961,7 +794,8 @@
          *             occurs while building the Geometry
          */
         @Override
-        protected Geometry newGeometry(double[][][] coords) throws DataSourceException {
+        protected Geometry newGeometry(final double[][][] coords,
+                final GeometryFactory geometryFactory) throws DataSourceException {
             Polygon[] polys = null;
 
             int numPolys = coords.length;
@@ -970,13 +804,13 @@
 
             for (int i = 0; i < numPolys; i++) {
                 try {
-                    polys[i] = buildPolygon(coords[i]);
+                    polys[i] = buildPolygon(coords[i], geometryFactory);
                 } catch (Exception ex) {
                     throw new DataSourceException(ex.getMessage(), ex);
                 }
             }
 
-            MultiPolygon multiPoly = super.factory.createMultiPolygon(polys);
+            MultiPolygon multiPoly = geometryFactory.createMultiPolygon(polys);
 
             return multiPoly;
         }

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSDEQuery.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -810,20 +810,20 @@
 
         final SeQuery seQuery = getSeQuery();
         // commented out while SeToJTSGeometryFactory is in development
-        // if(currentRow == null){
+        // if (currentRow == null) {
         // GeometryFactory geomFac = new SeToJTSGeometryFactory();
         // currentRow = new SdeRow(geomFac);
         // int geometryIndex = -1;
-        // for(int i = 0; i < schema.getAttributeCount(); i++){
-        // if(schema.getDescriptor(i) instanceof GeometryDescriptor){
+        // for (int i = 0; i < schema.getAttributeCount(); i++) {
+        // if (schema.getDescriptor(i) instanceof GeometryDescriptor) {
         // geometryIndex = i;
         // break;
         // }
         // }
         // currentRow.setGeometryIndex(geometryIndex);
         // }
-        // try {
         // currentRow = session.fetch(seQuery, currentRow);
+
         try {
             currentRow = session.fetch(seQuery);
         } catch (IOException e) {
@@ -880,6 +880,10 @@
      * DOCUMENT ME!
      *
      * @author $author$
+     *
+     * @source $URL:
+     *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java
+     *         /org/geotools/arcsde/data/ArcSDEQuery.java $
      * @version $Revision: 1.9 $
      */
     public static class FilterSet {

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureSource.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -16,8 +16,10 @@
  */
 package org.geotools.arcsde.data;
 
+import java.awt.RenderingHints;
+import java.awt.RenderingHints.Key;
 import java.io.IOException;
-import java.util.Collections;
+import java.util.HashSet;
 import java.util.Set;
 import java.util.logging.Level;
 import java.util.logging.Logger;
@@ -45,11 +47,27 @@
 import org.opengis.filter.sort.SortBy;
 
 import com.vividsolutions.jts.geom.Envelope;
+import com.vividsolutions.jts.geom.GeometryFactory;
 
 public class ArcSdeFeatureSource implements FeatureSource<SimpleFeatureType, SimpleFeature> {
 
     private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.data");
 
+    /**
+     * {@link Hints#FEATURE_DETACHED} and the ones supported by
+     * {@link ArcSDEDataStore#getGeometryFactory}
+     *
+     * @see #getSupportedHints()
+     */
+    private static final Set<Key> supportedHints = new HashSet<Key>();
+    static {
+        supportedHints.add(Hints.FEATURE_DETACHED);
+        supportedHints.add(Hints.JTS_GEOMETRY_FACTORY);
+        supportedHints.add(Hints.JTS_COORDINATE_SEQUENCE_FACTORY);
+        supportedHints.add(Hints.JTS_PRECISION_MODEL);
+        supportedHints.add(Hints.JTS_SRID);
+    };
+
     protected Transaction transaction = Transaction.AUTO_COMMIT;
 
     protected FeatureTypeInfo typeInfo;
@@ -286,14 +304,30 @@
     }
 
     /**
-     * ArcSDE features are always "detached", so we return the FEATURE_DETACHED hint here.
+     * ArcSDE features are always "detached", so we return the FEATURE_DETACHED hint here, as well
+     * as the JTS related ones.
+     * <p>
+     * The JTS related hints supported are:
+     * <ul>
+     * <li>JTS_GEOMETRY_FACTORY
+     * <li>JTS_COORDINATE_SEQUENCE_FACTORY
+     * <li>JTS_PRECISION_MODEL
+     * <li>JTS_SRID
+     * </ul>
+     * Note, however, that if a {@link GeometryFactory} is provided through the {@code
+     * JTS_GEOMETRY_FACTORY} hint, that very factory is used and takes precedence over all the other
+     * ones.
+     * </p>
      *
-     * @return singleton with {@link Hints#FEATURE_DETACHED}
      * @see FeatureSource#getSupportedHints()
+     * @see Hints#FEATURE_DETACHED
+     * @see Hints#JTS_GEOMETRY_FACTORY
+     * @see Hints#JTS_COORDINATE_SEQUENCE_FACTORY
+     * @see Hints#JTS_PRECISION_MODEL
+     * @see Hints#JTS_SRID
      */
-    @SuppressWarnings("unchecked")
-    public final Set getSupportedHints() {
-        return Collections.singleton(Hints.FEATURE_DETACHED);
+    public final Set<RenderingHints.Key> getSupportedHints() {
+        return supportedHints;
     }
 
     public ArcSdeVersionHandler getVersionHandler() throws IOException {

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/ArcSdeFeatureWriter.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -40,7 +40,6 @@
 import org.geotools.data.jdbc.MutableFIDFeature;
 import org.geotools.factory.CommonFactoryFinder;
 import org.geotools.feature.simple.SimpleFeatureBuilder;
-import org.geotools.feature.type.Types;
 import org.geotools.geometry.jts.ReferencedEnvelope;
 import org.geotools.util.Converters;
 import org.geotools.util.logging.Logging;
@@ -365,10 +364,10 @@
      * @see FeatureWriter#write()
      */
     public void write() throws IOException {
-        
-        //make the feature validate against its schema before inserting/updating
+
+        // make the feature validate against its schema before inserting/updating
         feature.validate();
-        
+
         if (isNewlyCreated(feature)) {
             Number newId;
             try {

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/FeatureTypeInfoCache.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -223,7 +223,7 @@
 
         ISession session;
         try {
-            session = sessionPool.getSession();
+            session = sessionPool.getSession(false);
         } catch (UnavailableConnectionException e) {
             throw new RuntimeException("Can't get type info for " + typeName
                     + ". Connection pool exhausted", e);
@@ -346,7 +346,7 @@
 
         private List<String> fetchRegistrations() throws Exception {
             final List<String> typeNames;
-            final ISession session = sessionPool.getSession();
+            final ISession session = sessionPool.getSession(false);
             try {
                 typeNames = session.issue(new FetchRegistrationsCommand(allowNonSpatialTables));
             } finally {

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SeToJTSGeometryFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SeToJTSGeometryFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SeToJTSGeometryFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -19,6 +19,10 @@
  * creates JTS geometries directly by calling {@link SeRow#getGeometry(GeometryFactory, int)},
  * instead of fetching an {@link SeShape} through {@link SeRow#getShape(int)} and then converting it
  * to a JTS geometry. This is work in progress and _experimental_, though.
+ *
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/data/SeToJTSGeometryFactory.java $
  */
 public class SeToJTSGeometryFactory implements GeometryFactory {
 
@@ -27,15 +31,12 @@
 
     private SeToJTSGeometryFactory delegate;
 
-    private int lastGeomType = Integer.MIN_VALUE;
-
-    public void init(int type, int numParts, int numPoints) {
-        if (type != lastGeomType) {
-            if (type == SeShape.TYPE_POLYGON) {
-                delegate = new PolygonFactory();
-            } else if (type == SeShape.TYPE_MULTI_POLYGON) {
-                delegate = new MultiPolygonFactory();
-            }
+    public void init(final int type, final int numParts, final int numPoints) {
+        if (type == SeShape.TYPE_POLYGON) {
+            delegate = new PolygonFactory();
+        } else if (type == SeShape.TYPE_MULTI_POLYGON) {
+            delegate = new MultiPolygonFactory();
+        } else {
             throw new IllegalArgumentException("Unhandled geometry type: " + type);
         }
         delegate.init(numParts, numPoints);
@@ -74,7 +75,7 @@
     }
 
     public void partOffsets(int[] partOffsets) {
-        // System.out.println(Arrays.asList(partOffsets));
+        // System.out.println(Arrays.toString(partOffsets));
     }
 
     /**
@@ -186,4 +187,4 @@
             polygonFactory.newPoint(x, y);
         }
     }
-}
\ No newline at end of file
+}


Property changes on: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SeToJTSGeometryFactory.java
___________________________________________________________________
Added: svn:keywords
   + Id URL

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/data/SessionTransactionState.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -264,7 +264,7 @@
                 // start a transaction
                 ISession session;
                 try {
-                    session = pool.getSession();
+                    session = pool.getSession(true);
                 } catch (UnavailableConnectionException e) {
                     throw new RuntimeException(
                             "Can't create a transaction state, connection pool exhausted", e);

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/FilterToSQLSDE.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/FilterToSQLSDE.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/FilterToSQLSDE.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -228,12 +228,12 @@
         String fidField = layerFidFieldName;
 
         try {
-            String sql = buildFilter(fids, fidField+" IN(", ")", ",", 1000, " OR ");
+            String sql = buildFilter(fids, fidField + " IN(", ")", ",", 1000, " OR ");
 
             if (LOGGER.isLoggable(Level.FINER)) {
                 LOGGER.finer("added fid filter: " + sql);
             }
-
+
             this.out.write(sql);
         } catch (Exception ex) {
             throw new RuntimeException(ex.getMessage(), ex);
@@ -242,43 +242,37 @@
     }
 
     // return a string
-    private String buildFilter(long[] fids, String prefix, String suffix, String separator, int groupSize, String groupSeparator)
-    {
+    private String buildFilter(long[] fids, String prefix, String suffix, String separator,
+            int groupSize, String groupSeparator) {
         final int count = fids.length;
         final int groups = count / groupSize;
         final int remainder = count % groupSize;
         final StringBuilder sql = new StringBuilder();
-        for (int i=0; i<groups; i++)
-        {
-            if ( i > 0 )
-            {
+        for (int i = 0; i < groups; i++) {
+            if (i > 0) {
                 sql.append(groupSeparator);
             }
             sql.append(prefix);
-            addSubList(sql, fids, i*groupSize, (i+1)*groupSize, separator);
+            addSubList(sql, fids, i * groupSize, (i + 1) * groupSize, separator);
             sql.append(suffix);
         }
-        if ( remainder > 0 )
-        {
-            if ( groups > 0 )
-            {
+        if (remainder > 0) {
+            if (groups > 0) {
                 sql.append(groupSeparator);
-            }
+            }
             sql.append(prefix);
-            addSubList(sql, fids, count-remainder, count, separator);
+            addSubList(sql, fids, count - remainder, count, separator);
             sql.append(suffix);
         }
         return sql.toString();
     }
-
-    private void addSubList(StringBuilder sql, long[] fids, int start, int end, String separator)
-    {
-        for (int i=start; i<end; i++)
-        {
+
+    private void addSubList(StringBuilder sql, long[] fids, int start, int end, String separator) {
+        for (int i = start; i < end; i++) {
             sql.append(fids[i]);
             sql.append(separator);
         }
-        sql.setLength(sql.length()-separator.length());
+        sql.setLength(sql.length() - separator.length());
     }
 
     /**

Modified: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/GeometryEncoderSDE.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/GeometryEncoderSDE.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/filter/GeometryEncoderSDE.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -65,6 +65,7 @@
 import com.esri.sde.sdk.client.SeShapeFilter;
 import com.vividsolutions.jts.geom.Geometry;
 import com.vividsolutions.jts.geom.GeometryCollection;
+import com.vividsolutions.jts.geom.GeometryFactory;
 import com.vividsolutions.jts.geom.Polygon;
 
 /**
@@ -262,7 +263,7 @@
             SeShape extent = new SeShape(this.sdeLayer.getCoordRef());
             extent.generateRectangle(seExtent);
 
-            Geometry layerEnv = gb.construct(extent);
+            Geometry layerEnv = gb.construct(extent, new GeometryFactory());
             geom = geom.intersection(layerEnv); // does the work
 
             // Now make an SeShape

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,646 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-import java.awt.image.renderable.ParameterBlock;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageTypeSpecifier;
-import javax.media.jai.InterpolationNearest;
-import javax.media.jai.JAI;
-import javax.media.jai.operator.FormatDescriptor;
-import javax.media.jai.operator.MosaicDescriptor;
-
-import org.geotools.coverage.CoverageFactoryFinder;
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.TypeMap;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.GeneralGridRange;
-import org.geotools.coverage.grid.GridCoverage2D;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.data.DefaultServiceInfo;
-import org.geotools.data.ServiceInfo;
-import org.geotools.factory.Hints;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.util.logging.Logging;
-import org.opengis.coverage.ColorInterpretation;
-import org.opengis.coverage.grid.Format;
-import org.opengis.coverage.grid.GridCoverage;
-import org.opengis.coverage.grid.GridCoverageReader;
-import org.opengis.parameter.GeneralParameterValue;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-@SuppressWarnings( { "deprecation", "nls" })
-final class ArcSDEGridCoverage2DReaderJAI extends AbstractGridCoverage2DReader {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    /**
-     * @see LoggingHelper#log(RenderedImage, Long, String)
-     */
-    private static final boolean DEBUG_TO_DISK = Boolean
-            .getBoolean("org.geotools.arcsde.gce.debug");
-
-    private final ArcSDERasterFormat parent;
-
-    private final RasterDatasetInfo rasterInfo;
-
-    private DefaultServiceInfo serviceInfo;
-
-    private RasterReaderFactory rasterReaderFactory;
-
-    public ArcSDEGridCoverage2DReaderJAI(final ArcSDERasterFormat parent,
-            final RasterReaderFactory rasterReaderFactory, final RasterDatasetInfo rasterInfo,
-            final Hints hints) throws IOException {
-        // check it's a supported format
-        {
-            final int bitsPerSample = rasterInfo.getBand(0, 0).getCellType().getBitsPerSample();
-            if (rasterInfo.getNumBands() > 1 && (bitsPerSample == 1 || bitsPerSample == 4)) {
-                throw new IllegalArgumentException(bitsPerSample
-                        + "-bit rasters with more than one band are not supported");
-            }
-        }
-        this.parent = parent;
-        this.rasterReaderFactory = rasterReaderFactory;
-        this.rasterInfo = rasterInfo;
-
-        super.hints = hints;
-        super.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
-        super.crs = rasterInfo.getCoverageCrs();
-        super.originalEnvelope = rasterInfo.getOriginalEnvelope();
-
-        GeneralGridEnvelope gridRange = rasterInfo.getOriginalGridRange();
-        super.originalGridRange = new GeneralGridRange(gridRange.toRectangle());
-
-        super.coverageName = rasterInfo.getRasterTable();
-        final int numLevels = rasterInfo.getNumPyramidLevels(0);
-
-        // level 0 is not an overview, but the raster itself
-        super.numOverviews = numLevels - 1;
-
-        // ///
-        //
-        // setting the higher resolution avalaible for this coverage
-        //
-        // ///
-        highestRes = super.getResolution(originalEnvelope, originalGridRange.toRectangle(), crs);
-        // //
-        //
-        // get information for the successive images
-        //
-        // //
-        // REVISIT may the different rasters in the raster dataset have different pyramid levels? I
-        // guess so
-        if (numOverviews > 0) {
-            overViewResolutions = new double[numOverviews][2];
-            for (int pyramidLevel = 1; pyramidLevel <= numOverviews; pyramidLevel++) {
-                Rectangle levelGridRange = rasterInfo.getGridRange(0, pyramidLevel);
-                GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(0, pyramidLevel);
-                overViewResolutions[pyramidLevel - 1] = super.getResolution(levelEnvelope,
-                        levelGridRange, crs);
-            }
-        } else {
-            overViewResolutions = null;
-        }
-    }
-
-    /**
-     * @see GridCoverageReader#getFormat()
-     */
-    public Format getFormat() {
-        return parent;
-    }
-
-    @Override
-    public ServiceInfo getInfo() {
-        if (serviceInfo == null) {
-            serviceInfo = new DefaultServiceInfo();
-            serviceInfo.setTitle(rasterInfo.getRasterTable());
-            serviceInfo.setDescription(rasterInfo.toString());
-            Set<String> keywords = new HashSet<String>();
-            keywords.add("ArcSDE");
-            serviceInfo.setKeywords(keywords);
-        }
-        return serviceInfo;
-    }
-
-    /**
-     * @see GridCoverageReader#read(GeneralParameterValue[])
-     */
-    public GridCoverage read(GeneralParameterValue[] params) throws IOException {
-
-        final GeneralEnvelope requestedEnvelope;
-        final Rectangle requestedDim;
-        final OverviewPolicy overviewPolicy;
-        {
-            final ReadParameters opParams = RasterUtils.parseReadParams(getOriginalEnvelope(),
-                    params);
-            overviewPolicy = opParams.overviewPolicy;
-            requestedEnvelope = opParams.requestedEnvelope;
-            requestedDim = opParams.dim;
-        }
-
-        /*
-         * For each raster in the raster dataset, obtain the tiles, pixel range, and resulting
-         * envelope
-         */
-        final List<RasterQueryInfo> queries;
-        queries = findMatchingRasters(requestedEnvelope, requestedDim, overviewPolicy);
-        if (queries.isEmpty()) {
-            /*
-             * none of the rasters match the requested envelope. This may happen by the tiled nature
-             * of the raster dataset
-             */
-            return createFakeCoverage(requestedEnvelope, requestedDim);
-        }
-
-        final GeneralEnvelope resultEnvelope = getResultEnvelope(queries);
-
-        final LoggingHelper log = new LoggingHelper();
-        log.appendLoggingGeometries(LoggingHelper.REQ_ENV, requestedEnvelope);
-        log.appendLoggingGeometries(LoggingHelper.RES_ENV, resultEnvelope);
-
-        /*
-         * Once we collected the matching rasters and their image subsets, find out where in the
-         * overall resulting mosaic they fit. If the rasters does not share the spatial resolution,
-         * the QueryInfo.resultDimension and QueryInfo.mosaicLocation width or height won't match
-         */
-        final Rectangle mosaicGeometry;
-        mosaicGeometry = RasterUtils.setMosaicLocations(rasterInfo, resultEnvelope, queries);
-
-        /*
-         * Gather the rendered images for each of the rasters that match the requested envelope
-         */
-        final Map<Long, RasterQueryInfo> byRasterIdQueries = new HashMap<Long, RasterQueryInfo>();
-        for (RasterQueryInfo queryInfo : queries) {
-            byRasterIdQueries.put(queryInfo.getRasterId(), queryInfo);
-        }
-
-        final TiledRasterReader rasterReader = rasterReaderFactory.create(rasterInfo);
-
-        try {
-            readAllTiledRasters(byRasterIdQueries, rasterReader, log);
-        } finally {
-            rasterReader.dispose();
-        }
-
-        log.log(LoggingHelper.REQ_ENV);
-        log.log(LoggingHelper.RES_ENV);
-        log.log(LoggingHelper.MOSAIC_ENV);
-        log.log(LoggingHelper.MOSAIC_EXPECTED);
-
-        final RenderedImage coverageRaster = createMosaic(queries, log);
-        assert mosaicGeometry.getWidth() == coverageRaster.getWidth();
-        assert mosaicGeometry.getHeight() == coverageRaster.getHeight();
-
-        /*
-         * BUILDING COVERAGE
-         */
-        GridSampleDimension[] bands = getSampleDimensions(coverageRaster);
-
-        GridCoverage2D resultCoverage = coverageFactory.create(coverageName, coverageRaster,
-                resultEnvelope, bands, null, null);
-
-        return resultCoverage;
-    }
-
-    private GridSampleDimension[] getSampleDimensions(final RenderedImage coverageRaster)
-            throws IOException {
-
-        GridSampleDimension[] bands = rasterInfo.getGridSampleDimensions();
-
-        // may the image have been promoted? build the correct band info then
-        final int imageBands = coverageRaster.getSampleModel().getNumBands();
-        if (bands.length == 1 && imageBands > 1) {
-            LOGGER.fine(coverageName + " was promoted from 1 to "
-                    + coverageRaster.getSampleModel().getNumBands()
-                    + " bands, returning an appropriate set of GridSampleDimension");
-            // stolen from super.createCoverage:
-            final ColorModel cm = coverageRaster.getColorModel();
-            bands = new GridSampleDimension[imageBands];
-
-            // setting bands names.
-            for (int i = 0; i < imageBands; i++) {
-                final ColorInterpretation colorInterpretation;
-                colorInterpretation = TypeMap.getColorInterpretation(cm, i);
-                if (colorInterpretation == null) {
-                    throw new IOException("Unrecognized sample dimension type");
-                }
-                bands[i] = new GridSampleDimension(colorInterpretation.name()).geophysics(true);
-            }
-        }
-
-        return bands;
-    }
-
-    private void readAllTiledRasters(final Map<Long, RasterQueryInfo> byRasterIdQueries,
-            final TiledRasterReader rasterReader, final LoggingHelper log) throws IOException {
-
-        Long currentRasterId;
-
-        while ((currentRasterId = rasterReader.nextRaster()) != null) {
-            if (!byRasterIdQueries.containsKey(currentRasterId)) {
-                continue;
-            }
-            final RasterQueryInfo queryInfo = byRasterIdQueries.get(currentRasterId);
-            final RenderedImage rasterImage;
-
-            try {
-                final int pyramidLevel = queryInfo.getPyramidLevel();
-                final Rectangle matchingTiles = queryInfo.getMatchingTiles();
-                // final Point imageLocation = queryInfo.getTiledImageSize().getLocation();
-                rasterImage = rasterReader.read(pyramidLevel, matchingTiles);
-            } catch (IOException e) {
-                LOGGER.log(Level.SEVERE, "Fetching data for " + queryInfo.toString(), e);
-                throw e;
-            }
-
-            queryInfo.setResultImage(rasterImage);
-
-            {
-                LOGGER.finer(queryInfo.toString());
-                log.appendLoggingGeometries(LoggingHelper.MOSAIC_EXPECTED, queryInfo
-                        .getMosaicLocation());
-                log
-                        .appendLoggingGeometries(LoggingHelper.MOSAIC_ENV, queryInfo
-                                .getResultEnvelope());
-
-                final Rectangle tiledImageSize = queryInfo.getTiledImageSize();
-                int width = rasterImage.getWidth();
-                int height = rasterImage.getHeight();
-                if (tiledImageSize.width != width || tiledImageSize.height != height) {
-                    throw new IllegalStateException(
-                            "Read image is not of the expected size. Image=" + width + "x" + height
-                                    + ", expected: " + tiledImageSize.width + "x"
-                                    + tiledImageSize.height);
-                }
-                if (tiledImageSize.x != rasterImage.getMinX()
-                        || tiledImageSize.y != rasterImage.getMinY()) {
-                    throw new IllegalStateException("Read image is not at the expected location "
-                            + tiledImageSize.x + "," + tiledImageSize.y + ": "
-                            + rasterImage.getMinX() + "," + rasterImage.getMinY());
-                }
-            }
-        }
-    }
-
-    /**
-     * Called when the requested envelope do overlap the coverage envelope but none of the rasters
-     * in the dataset do
-     *
-     * @param requestedEnvelope
-     * @param requestedDim
-     * @return
-     */
-    private GridCoverage createFakeCoverage(GeneralEnvelope requestedEnvelope,
-            Rectangle requestedDim) {
-
-        ImageTypeSpecifier its = rasterInfo.getRenderedImageSpec(0);
-        SampleModel sampleModel = its.getSampleModel(requestedDim.width, requestedDim.height);
-        ColorModel colorModel = its.getColorModel();
-
-        WritableRaster raster = Raster.createWritableRaster(sampleModel, null);
-        BufferedImage image = new BufferedImage(colorModel, raster, false, null);
-        return coverageFactory.create(coverageName, image, requestedEnvelope);
-    }
-
-    private List<RasterQueryInfo> findMatchingRasters(final GeneralEnvelope requestedEnvelope,
-            final Rectangle requestedDim, final OverviewPolicy overviewPolicy) {
-
-        final List<RasterQueryInfo> matchingQueries;
-        matchingQueries = RasterUtils.findMatchingRasters(rasterInfo, requestedEnvelope,
-                requestedDim, overviewPolicy);
-
-        if (matchingQueries.isEmpty()) {
-            return matchingQueries;
-        }
-
-        for (RasterQueryInfo match : matchingQueries) {
-            RasterUtils.fitRequestToRaster(requestedEnvelope, rasterInfo, match);
-        }
-        return matchingQueries;
-    }
-
-    private GeneralEnvelope getResultEnvelope(final List<RasterQueryInfo> queryInfos) {
-
-        GeneralEnvelope finalEnvelope = null;
-
-        for (RasterQueryInfo rasterQueryInfo : queryInfos) {
-            // gather resulting envelope
-            if (finalEnvelope == null) {
-                finalEnvelope = new GeneralEnvelope(rasterQueryInfo.getResultEnvelope());
-            } else {
-                finalEnvelope.add(rasterQueryInfo.getResultEnvelope());
-            }
-        }
-        if (finalEnvelope == null) {
-            throw new IllegalStateException("Restult envelope is null, this shouldn't happen!! "
-                    + "we checked the request overlaps the coverage envelope before!");
-        }
-        return finalEnvelope;
-    }
-
-    /**
-     * For each raster: crop->scale->translate->add to mosaic
-     *
-     * @param queries
-     * @return
-     * @throws IOException
-     */
-    private RenderedImage createMosaic(final List<RasterQueryInfo> queries, final LoggingHelper log)
-            throws IOException {
-        List<RenderedImage> transformed = new ArrayList<RenderedImage>(queries.size());
-
-        /*
-         * Do we need to expand to RGB color space and then create a new colormapped image with the
-         * whole mosaic?
-         */
-        boolean expandThenContractCM = queries.size() > 1 && rasterInfo.isColorMapped();
-        if (expandThenContractCM) {
-            LOGGER.info("Creating mosaic out of " + queries.size()
-                    + " colormapped rasters. The mosaic tiles will be expanded to "
-                    + "\nRGB space and the resulting mosaic reduced to a new IndexColorModel");
-        }
-        for (RasterQueryInfo query : queries) {
-            RenderedImage image = query.getResultImage();
-            log.log(image, query.getRasterId(), "01_original");
-
-            image = cropToRequiredDimension(image, query.getResultDimensionInsideTiledImage());
-            log.log(image, query.getRasterId(), "02_crop");
-
-            final Rectangle mosaicLocation = query.getMosaicLocation();
-            // scale
-            Float scaleX = Float.valueOf((float) (mosaicLocation.getWidth() / image.getWidth()));
-            Float scaleY = Float.valueOf((float) (mosaicLocation.getHeight() / image.getHeight()));
-            Float translateX = null;
-            Float translateY = null;
-
-            ParameterBlock pb = new ParameterBlock();
-            pb.addSource(image);
-            pb.add(scaleX);
-            pb.add(scaleY);
-            pb.add(translateX);
-            pb.add(translateY);
-            pb.add(new InterpolationNearest());
-
-            image = JAI.create("scale", pb);
-            log.log(image, query.getRasterId(), "03_scale");
-
-            int width = image.getWidth();
-            int height = image.getHeight();
-
-            assert mosaicLocation.width == width;
-            assert mosaicLocation.height == height;
-
-            // translate
-            pb = new ParameterBlock();
-            pb.addSource(image);
-            pb.add(Float.valueOf(mosaicLocation.x - image.getMinX()));
-            pb.add(Float.valueOf(mosaicLocation.y - image.getMinY()));
-            pb.add(null);
-
-            image = JAI.create("translate", pb);
-            log.log(image, query.getRasterId(), "04_translate");
-
-            assert image.getMinX() == mosaicLocation.x : image.getMinX() + " != "
-                    + mosaicLocation.x;
-            assert image.getMinY() == mosaicLocation.y : image.getMinY() + " != "
-                    + mosaicLocation.y;
-            assert image.getWidth() == mosaicLocation.width : image.getWidth() + " != "
-                    + mosaicLocation.width;
-            assert image.getHeight() == mosaicLocation.height : image.getHeight() + " != "
-                    + mosaicLocation.height;
-
-            if (expandThenContractCM) {
-                if (LOGGER.isLoggable(Level.FINER)) {
-                    LOGGER.finer("Creating color expanded version of tile for raster #"
-                            + query.getRasterId());
-                }
-
-                /*
-                 * reformat the image as a 4 band rgba backed by byte data
-                 */
-                image = FormatDescriptor.create(image, Integer.valueOf(DataBuffer.TYPE_BYTE), null);
-
-                log.log(image, query.getRasterId(), "04_1_colorExpanded");
-            }
-
-            transformed.add(image);
-        }
-
-        final RenderedImage mosaic;
-        if (queries.size() == 1) {
-            /*
-             * This is besides a very slight perf improvement needed because the JAI mosaic
-             * operation truncates floating point raster values to 0 and 1. REVISIT: If there's no
-             * workaround for that we should prevent raster catalogs made of floating point rasters
-             * and throw an exception as we could not really support that.
-             */
-            mosaic = transformed.get(0);
-        } else {
-            ParameterBlock mosaicParams = new ParameterBlock();
-
-            for (RenderedImage img : transformed) {
-                mosaicParams.addSource(img);
-                log.appendLoggingGeometries(LoggingHelper.MOSAIC_RESULT, img);
-            }
-            log.log(LoggingHelper.MOSAIC_RESULT);
-
-            mosaicParams.add(MosaicDescriptor.MOSAIC_TYPE_OVERLAY); // mosaic type
-            mosaicParams.add(null); // alpha mask
-            mosaicParams.add(null); // source ROI mask
-            mosaicParams.add(null); // source threshold
-            mosaicParams.add(null); // destination background value
-
-            LOGGER.fine("Creating mosaic out of " + queries.size() + " raster tiles");
-            mosaic = JAI.create("Mosaic", mosaicParams);
-            log.log(mosaic, 0L, "05_mosaic_result");
-        }
-        return mosaic;
-    }
-
-    private RenderedImage cropToRequiredDimension(final RenderedImage fullTilesRaster,
-            final Rectangle cropTo) {
-
-        int minX = fullTilesRaster.getMinX();
-        int minY = fullTilesRaster.getMinY();
-        int width = fullTilesRaster.getWidth();
-        int height = fullTilesRaster.getHeight();
-
-        Rectangle origDim = new Rectangle(minX, minY, width, height);
-        if (!origDim.contains(cropTo)) {
-            throw new IllegalArgumentException("Original image (" + origDim
-                    + ") does not contain desired dimension (" + cropTo + ")");
-        } else if (origDim.equals(cropTo)) {
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("No need to crop image, full tiled dimension and target one "
-                        + "do match: original: " + width + "x" + height + ", target: "
-                        + cropTo.width + "x" + cropTo.height);
-            }
-            return fullTilesRaster;
-        }
-
-        ParameterBlock cropParams = new ParameterBlock();
-
-        cropParams.addSource(fullTilesRaster);// Source
-        cropParams.add(Float.valueOf(cropTo.x)); // x origin for each band
-        cropParams.add(Float.valueOf(cropTo.y)); // y origin for each band
-        cropParams.add(Float.valueOf(cropTo.width));// width for each band
-        cropParams.add(Float.valueOf(cropTo.height));// height for each band
-
-        final RenderingHints hints = null;
-        RenderedImage image = JAI.create("Crop", cropParams, hints);
-
-        assert cropTo.x == image.getMinX();
-        assert cropTo.y == image.getMinY();
-        assert cropTo.width == image.getWidth();
-        assert cropTo.height == image.getHeight();
-        return image;
-    }
-
-    static class ReadParameters {
-        GeneralEnvelope requestedEnvelope;
-
-        Rectangle dim;
-
-        OverviewPolicy overviewPolicy;
-    }
-
-    /**
-     * A simple helper class to guard and easy logging the mosaic geometries in both geographical
-     * and pixel ranges
-     */
-    private static class LoggingHelper {
-
-        private static final File debugDir = new File(System.getProperty("user.home")
-                + File.separator + "arcsde_test");
-
-        static {
-            if (DEBUG_TO_DISK) {
-                debugDir.mkdir();
-            }
-        }
-
-        public Level GEOM_LEVEL = Level.FINER;
-
-        public static String REQ_ENV = "Requested envelope";
-
-        public static String RES_ENV = "Resulting envelope";
-
-        public static String MOSAIC_ENV = "Resulting mosaiced envelopes";
-
-        public static String MOSAIC_EXPECTED = "Expected mosaic layout (in pixels)";
-
-        public static String MOSAIC_RESULT = "Resulting image mosaic layout (in pixels)";
-
-        private Map<String, StringBuilder> geoms = null;
-
-        LoggingHelper() {
-            // not much to to
-        }
-
-        private StringBuilder getGeom(String geomName) {
-            if (geoms == null) {
-                geoms = new HashMap<String, StringBuilder>();
-            }
-            StringBuilder sb = geoms.get(geomName);
-            if (sb == null) {
-                sb = new StringBuilder("MULTIPOLYGON(\n");
-                geoms.put(geomName, sb);
-            }
-            return sb;
-        }
-
-        public void appendLoggingGeometries(String geomName, RenderedImage img) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                appendLoggingGeometries(geomName, new Rectangle(img.getMinX(), img.getMinY(), img
-                        .getWidth(), img.getHeight()));
-            }
-        }
-
-        public void appendLoggingGeometries(String geomName, Rectangle env) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                appendLoggingGeometries(geomName, new GeneralEnvelope(env));
-            }
-        }
-
-        public void appendLoggingGeometries(String geomName, GeneralEnvelope env) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                StringBuilder sb = getGeom(geomName);
-                sb.append("  ((" + env.getMinimum(0) + " " + env.getMinimum(1) + ", "
-                        + env.getMaximum(0) + " " + env.getMinimum(1) + ", " + env.getMaximum(0)
-                        + " " + env.getMaximum(1) + ", " + env.getMinimum(0) + " "
-                        + env.getMaximum(1) + ", " + env.getMinimum(0) + " " + env.getMinimum(1)
-                        + ")),");
-            }
-        }
-
-        public void log(String geomName) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                StringBuilder sb = getGeom(geomName);
-                sb.setLength(sb.length() - 1);
-                sb.append("\n)");
-                LOGGER.log(GEOM_LEVEL, geomName + ":\n" + sb.toString());
-            }
-        }
-
-        public void log(RenderedImage image, Long rasterId, String fileName) {
-            if (DEBUG_TO_DISK) {
-                LOGGER.warning("BEWARE THE DEBUG FLAG IS TURNED ON! "
-                        + "IF IN PRODUCTION THIS IS A SEVERE MISTAKE!!!");
-                // ImageIO.write(FormatDescriptor.create(image,
-                // Integer.valueOf(DataBuffer.TYPE_BYTE),
-                // null), "TIFF", new File(debugDir, rasterId.longValue() + fileName + ".tiff"));
-
-                try {
-                    ImageIO.write(image, "TIFF", new File(debugDir, rasterId.longValue() + fileName
-                            + ".tiff"));
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-
-        }
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDERasterFormat.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,914 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.DBTYPE_PARAM_NAME;
-import static org.geotools.arcsde.data.ArcSDEDataStoreConfig.DBTYPE_PARAM_VALUE;
-import static org.geotools.arcsde.session.ArcSDEConnectionConfig.*;
-import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PASSWORD_PARAM_NAME;
-import static org.geotools.arcsde.session.ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME;
-import static org.geotools.arcsde.session.ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME;
-import static org.geotools.arcsde.session.ArcSDEConnectionConfig.USER_NAME_PARAM_NAME;
-
-import java.awt.geom.Point2D;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferUShort;
-import java.awt.image.IndexColorModel;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.geotools.arcsde.ArcSdeException;
-import org.geotools.arcsde.data.ArcSDEDataStoreConfig;
-import org.geotools.arcsde.session.ArcSDEConnectionConfig;
-import org.geotools.arcsde.session.ArcSDEConnectionPool;
-import org.geotools.arcsde.session.ArcSDEConnectionPoolFactory;
-import org.geotools.arcsde.session.ArcSDEPooledConnection;
-import org.geotools.arcsde.session.UnavailableConnectionException;
-import org.geotools.arcsde.util.ArcSDEUtils;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.coverage.grid.io.AbstractGridFormat;
-import org.geotools.coverage.grid.io.imageio.GeoToolsWriteParams;
-import org.geotools.data.DataSourceException;
-import org.geotools.factory.GeoTools;
-import org.geotools.factory.Hints;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.parameter.DefaultParameterDescriptorGroup;
-import org.geotools.parameter.ParameterGroup;
-import org.geotools.referencing.crs.DefaultEngineeringCRS;
-import org.geotools.util.logging.Logging;
-import org.opengis.coverage.grid.Format;
-import org.opengis.coverage.grid.GridCoverageWriter;
-import org.opengis.parameter.GeneralParameterDescriptor;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.esri.sde.sdk.client.SDEPoint;
-import com.esri.sde.sdk.client.SeColumnDefinition;
-import com.esri.sde.sdk.client.SeCoordinateReference;
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeExtent;
-import com.esri.sde.sdk.client.SeQuery;
-import com.esri.sde.sdk.client.SeRaster;
-import com.esri.sde.sdk.client.SeRasterAttr;
-import com.esri.sde.sdk.client.SeRasterBand;
-import com.esri.sde.sdk.client.SeRasterColumn;
-import com.esri.sde.sdk.client.SeRow;
-import com.esri.sde.sdk.client.SeSqlConstruct;
-import com.esri.sde.sdk.client.SeTable;
-
-/**
- * An implementation of the ArcSDE Raster Format. Based on the ArcGrid module.
- *
- * @author Saul Farber (saul.farber)
- * @author jeichar
- * @author Simone Giannecchini (simboss)
- * @author Gabriel Roldan (OpenGeo)
- * @source $URL:
- *         http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java
- *         /org/geotools/arcsde/gce/ArcSDERasterFormat.java $
- */
-@SuppressWarnings( { "nls", "deprecation" })
-public final class ArcSDERasterFormat extends AbstractGridFormat implements Format {
-
-    protected static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    /**
-     * Cache of raster metadata objects, where the keys are the URL's representing the full
-     * connection properties to a given ArcSDE raster, and the value the
-     * {@link ArcSDERasterGridCoverage2DReader}'s externalized state, so it is not needed to gather
-     * the raster properties each time.
-     */
-    private final Map<String, RasterDatasetInfo> rasterInfos = new WeakHashMap<String, RasterDatasetInfo>();
-
-    private final Map<String, ArcSDEDataStoreConfig> connectionConfigs = new WeakHashMap<String, ArcSDEDataStoreConfig>();
-
-    private static final ArcSDERasterFormat instance = new ArcSDERasterFormat();
-
-    private boolean statisticsMandatory = true;
-
-    /**
-     * Creates an instance and sets the metadata.
-     */
-    private ArcSDERasterFormat() {
-        setInfo();
-    }
-
-    public static ArcSDERasterFormat getInstance() {
-        return instance;
-    }
-
-    /**
-     * Sets the metadata information.
-     */
-    private void setInfo() {
-        Map<String, String> info = new HashMap<String, String>();
-
-        info.put("name", "ArcSDE Raster");
-        info.put("description", "ArcSDE Raster Format");
-        info.put("vendor", "Geotools");
-        info.put("docURL", "");
-        info.put("version", GeoTools.getVersion().toString());
-        mInfo = info;
-
-        readParameters = new ParameterGroup(new DefaultParameterDescriptorGroup(mInfo,
-                new GeneralParameterDescriptor[] { READ_GRIDGEOMETRY2D, OVERVIEW_POLICY }));
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#getReader(Object source)
-     */
-    @Override
-    public AbstractGridCoverage2DReader getReader(Object source) {
-        return getReader(source, null);
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#getReader(Object, Hints)
-     */
-    @Override
-    public AbstractGridCoverage2DReader getReader(final Object source, final Hints hints) {
-        try {
-            if (source == null) {
-                throw new DataSourceException("No source set to read this coverage.");
-            }
-
-            // this will be our connection string
-            final String coverageUrl = parseCoverageUrl(source);
-
-            final ArcSDEConnectionConfig connectionConfig = getConnectionConfig(coverageUrl);
-
-            ArcSDEConnectionPool connectionPool = setupConnectionPool(connectionConfig);
-
-            RasterDatasetInfo rasterInfo = getRasterInfo(coverageUrl, connectionPool);
-
-            RasterReaderFactory rasterReaderFactory = new RasterReaderFactory(connectionPool);
-
-            return new ArcSDEGridCoverage2DReaderJAI(this, rasterReaderFactory, rasterInfo, hints);
-        } catch (IOException dse) {
-            LOGGER
-                    .log(Level.SEVERE, "Unable to creata ArcSDERasterReader for " + source + ".",
-                            dse);
-            throw new RuntimeException(dse);
-        }
-    }
-
-    private RasterDatasetInfo getRasterInfo(final String coverageUrl,
-            ArcSDEConnectionPool connectionPool) throws IOException {
-
-        RasterDatasetInfo rasterInfo = rasterInfos.get(coverageUrl);
-        if (rasterInfo == null) {
-            synchronized (rasterInfos) {
-                rasterInfo = rasterInfos.get(coverageUrl);
-                if (rasterInfo == null) {
-                    ArcSDEPooledConnection scon;
-                    try {
-                        scon = connectionPool.getConnection();
-                    } catch (UnavailableConnectionException e) {
-                        throw new DataSourceException(e);
-                    }
-                    try {
-                        rasterInfo = gatherCoverageMetadata(scon, coverageUrl);
-                        rasterInfos.put(coverageUrl, rasterInfo);
-                    } finally {
-                        if (!scon.isPassivated())
-                            scon.close();
-                    }
-                }
-            }
-        }
-        return rasterInfo;
-    }
-
-    private ArcSDEConnectionConfig getConnectionConfig(final String coverageUrl) {
-        ArcSDEDataStoreConfig sdeConfig;
-        sdeConfig = connectionConfigs.get(coverageUrl);
-        if (sdeConfig == null) {
-            synchronized (connectionConfigs) {
-                sdeConfig = connectionConfigs.get(coverageUrl);
-                if (sdeConfig == null) {
-                    sdeConfig = sdeURLToConnectionConfig(new StringBuffer(coverageUrl));
-                    connectionConfigs.put(coverageUrl, sdeConfig);
-                }
-            }
-        }
-        return sdeConfig.getSessionConfig();
-    }
-
-    /**
-     * @see AbstractGridFormat#getWriter(Object)
-     */
-    @Override
-    public GridCoverageWriter getWriter(Object destination) {
-        // return new ArcGridWriter(destination);
-        return null;
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#accepts(Object input)
-     */
-    @Override
-    public boolean accepts(Object input) {
-        StringBuffer url;
-        if (input instanceof File) {
-            url = new StringBuffer(((File) input).getPath());
-        } else if (input instanceof String) {
-            url = new StringBuffer((String) input);
-        } else {
-            return false;
-        }
-        try {
-            sdeURLToConnectionConfig(url);
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * @see Format#getName()
-     */
-    @Override
-    public String getName() {
-        return this.mInfo.get("name");
-    }
-
-    /**
-     * @see Format#getDescription()
-     */
-    @Override
-    public String getDescription() {
-        return this.mInfo.get("description");
-    }
-
-    /**
-     * @see Format#getVendor()
-     */
-    @Override
-    public String getVendor() {
-        return this.mInfo.get("vendor");
-    }
-
-    /**
-     * @see Format#getDocURL()
-     */
-    @Override
-    public String getDocURL() {
-        return this.mInfo.get("docURL");
-    }
-
-    /**
-     * @see Format#getVersion()
-     */
-    @Override
-    public String getVersion() {
-        return this.mInfo.get("version");
-    }
-
-    /**
-     * Retrieves the default instance for the {@link ArcSDERasterFormat} of the
-     * {@link GeoToolsWriteParams} to control the writing process.
-     *
-     * @return a default instance for the {@link ArcSDERasterFormat} of the
-     *         {@link GeoToolsWriteParams} to control the writing process.
-     * @see AbstractGridFormat#getDefaultImageIOWriteParameters()
-     */
-    @Override
-    public GeoToolsWriteParams getDefaultImageIOWriteParameters() {
-        throw new UnsupportedOperationException("ArcSDE Rasters are read only for now.");
-    }
-
-    // ////////////////
-
-    /**
-     * @param input
-     *            either a {@link String} or a {@link File} instance representing the connection URL
-     *            to a given coverage
-     * @return the connection URL as a string
-     */
-    private String parseCoverageUrl(Object input) {
-        String coverageUrl;
-        if (input instanceof String) {
-            coverageUrl = (String) input;
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("connecting to ArcSDE Raster: " + coverageUrl);
-            }
-        } else if (input instanceof File) {
-            coverageUrl = ((File) input).getPath();
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("connectiong via file-hack to ArcSDE Raster: " + coverageUrl);
-            }
-        } else {
-            throw new IllegalArgumentException("Unsupported input type: " + input.getClass());
-        }
-        return coverageUrl;
-    }
-
-    /**
-     * Checks the input provided to this {@link ArcSDERasterGridCoverage2DReader} and sets all the
-     * other objects and flags accordingly.
-     *
-     * @param sdeUrl
-     *            a url representing the connection parameters to an arcsde server instance provied
-     *            to this {@link ArcSDERasterGridCoverage2DReader}.
-     * @throws IOException
-     */
-    private ArcSDEConnectionPool setupConnectionPool(ArcSDEConnectionConfig sdeConfig)
-            throws IOException {
-
-        if (LOGGER.isLoggable(Level.FINE)) {
-            LOGGER.fine("Getting ArcSDE connection pool for " + sdeConfig);
-        }
-
-        ArcSDEConnectionPool connectionPool;
-        connectionPool = ArcSDEConnectionPoolFactory.getInstance().createPool(sdeConfig);
-        return connectionPool;
-    }
-
-    /**
-     * @param sdeUrl
-     *            - A StringBuffer containing a string of form
-     *            'sde://user:pass@sdehost:[port]/[dbname]
-     * @return a ConnectionConfig object representing these parameters
-     */
-    public static ArcSDEDataStoreConfig sdeURLToConnectionConfig(StringBuffer sdeUrl) {
-        // annoyingly, geoserver currently stores the user-entered SDE string as
-        // a File, and passes us the
-        // File object. The File object strips the 'sde://user...' into a
-        // 'sde:/user..'. So we need to check
-        // for both forms of the url.
-        String sdeHost, sdeUser, sdePass, sdeDBName;
-        int sdePort;
-        if (sdeUrl.indexOf("sde:/") == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName -- Got "
-                            + sdeUrl);
-        }
-        if (sdeUrl.indexOf("sde://") == -1) {
-            sdeUrl.delete(0, 5);
-        } else {
-            sdeUrl.delete(0, 6);
-        }
-
-        int idx = sdeUrl.indexOf(":");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdeUser = sdeUrl.substring(0, idx);
-        sdeUrl.delete(0, idx);
-
-        idx = sdeUrl.indexOf("@");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdePass = sdeUrl.substring(1, idx);
-        sdeUrl.delete(0, idx);
-
-        idx = sdeUrl.indexOf(":");
-        if (idx == -1) {
-            // there's no "port" specification. Assume 5151;
-            sdePort = 5151;
-
-            idx = sdeUrl.indexOf("/");
-            if (idx == -1) {
-                throw new IllegalArgumentException(
-                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-            }
-            sdeHost = sdeUrl.substring(1, idx).toString();
-            sdeUrl.delete(0, idx);
-        } else {
-            sdeHost = sdeUrl.substring(1, idx).toString();
-            sdeUrl.delete(0, idx);
-
-            idx = sdeUrl.indexOf("/");
-            if (idx == -1) {
-                throw new IllegalArgumentException(
-                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-            }
-            sdePort = Integer.parseInt(sdeUrl.substring(1, idx).toString());
-            sdeUrl.delete(0, idx);
-        }
-
-        idx = sdeUrl.indexOf("#");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdeDBName = sdeUrl.substring(1, idx).toString();
-        sdeUrl.delete(0, idx);
-
-        Map<String, String> params = new HashMap<String, String>();
-        params.put(DBTYPE_PARAM_NAME, DBTYPE_PARAM_VALUE);
-        params.put(SERVER_NAME_PARAM_NAME, sdeHost);
-        params.put(PORT_NUMBER_PARAM_NAME, String.valueOf(sdePort));
-        params.put(INSTANCE_NAME_PARAM_NAME, sdeDBName);
-        params.put(USER_NAME_PARAM_NAME, sdeUser);
-        params.put(PASSWORD_PARAM_NAME, sdePass);
-        params.put(MIN_CONNECTIONS_PARAM_NAME, String.valueOf(ArcSDEConnectionPool.DEFAULT_CONNECTIONS));
-        params.put(MAX_CONNECTIONS_PARAM_NAME, String.valueOf(ArcSDEConnectionPool.DEFAULT_MAX_CONNECTIONS));
-        params.put(CONNECTION_TIMEOUT_PARAM_NAME, String.valueOf(ArcSDEConnectionPool.DEFAULT_MAX_WAIT_TIME));
-
-        return new ArcSDEDataStoreConfig(params);
-    }
-
-    /**
-     *
-     * @param scon
-     * @param coverageUrl
-     * @return
-     * @throws IOException
-     *             if an exception occurs accessing the raster metadata
-     * @throws IllegalArgumentException
-     *             if the raster has no CRS, contains no raster attributes, has no pyramids, no
-     *             bands or no statistics
-     */
-    private RasterDatasetInfo gatherCoverageMetadata(final ArcSDEPooledConnection scon,
-            final String coverageUrl) throws IOException {
-        LOGGER.fine("Gathering raster dataset metadata for " + coverageUrl);
-        String rasterTable;
-        {
-            String sdeUrl = coverageUrl;
-            if (sdeUrl.indexOf(";") != -1) {
-                /*
-                 * We're not using any extra param anymore. Yet, be cautious cause a client may
-                 * still be using urls with some old extra param, so just strip it
-                 */
-                sdeUrl = sdeUrl.substring(0, sdeUrl.indexOf(";"));
-            }
-            rasterTable = sdeUrl.substring(sdeUrl.indexOf("#") + 1);
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("Building ArcSDEGridCoverageReader2D for " + rasterTable);
-            }
-        }
-
-        final String[] rasterColumns = getRasterColumns(scon, rasterTable);
-        final List<RasterInfo> rastersLayoutInfo = new ArrayList<RasterInfo>();
-        {
-            final List<SeRasterAttr> rasterAttributes;
-            rasterAttributes = getSeRasterAttr(scon, rasterTable, rasterColumns);
-
-            if (rasterAttributes.size() == 0) {
-                throw new IllegalArgumentException("Table " + rasterTable
-                        + " contains no raster datasets");
-            }
-
-            final CoordinateReferenceSystem coverageCrs;
-
-            /*
-             * by bandId map of colormaps. The dataset may be composed of more than one raster so we
-             * gather all the colormaps once and held them here by rasterband id
-             */
-            final Map<Long, IndexColorModel> rastersColorMaps;
-            {
-                final SeRasterColumn rasterColumn;
-                final SeRasterBand sampleBand;
-                final long rasterColumnId;
-                final int bitsPerSample;
-                try {
-                    SeRasterAttr ratt = rasterAttributes.get(0);
-                    rasterColumn = new SeRasterColumn(scon, ratt.getRasterColumnId());
-                    rasterColumnId = rasterColumn.getID().longValue();
-                    sampleBand = ratt.getBands()[0];
-                    bitsPerSample = RasterCellType.valueOf(ratt.getPixelType()).getBitsPerSample();
-                } catch (SeException e) {
-                    throw new ArcSdeException(e);
-                }
-                final SeCoordinateReference seCoordRef = rasterColumn.getCoordRef();
-                if (seCoordRef == null) {
-                    throw new IllegalArgumentException(rasterTable
-                            + " has no coordinate reference system set");
-                }
-                LOGGER.finer("Looking CRS for raster column " + rasterTable);
-                coverageCrs = ArcSDEUtils.findCompatibleCRS(seCoordRef);
-                if (DefaultEngineeringCRS.CARTESIAN_2D == coverageCrs) {
-                    LOGGER.warning("Raster " + rasterTable
-                            + " has not CRS set, using DefaultEngineeringCRS.CARTESIAN_2D");
-                }
-                if (sampleBand.hasColorMap()) {
-                    rastersColorMaps = loadColorMaps(rasterColumnId, bitsPerSample, scon);
-                } else {
-                    rastersColorMaps = Collections.emptyMap();
-                }
-
-            }
-            try {
-                for (SeRasterAttr rAtt : rasterAttributes) {
-                    LOGGER.fine("Gathering raster metadata for " + rasterTable + " raster "
-                            + rAtt.getRasterId().longValue());
-
-                    if (rAtt.getMaxLevel() == 0) {
-                        throw new IllegalArgumentException(
-                                "Raster cotains no pyramid levels, we don't support non pyramid rasters");
-                    }
-                    if (rAtt.getNumBands() == 0) {
-                        throw new IllegalArgumentException("Raster "
-                                + rAtt.getRasterId().longValue() + " in " + rasterTable
-                                + " contains no raster attribtues");
-                    }
-                    if (this.statisticsMandatory && !rAtt.getBandInfo(1).hasStats()) {
-                        throw new IllegalArgumentException(rasterTable
-                                + " has no statistics generated (or not all it's rasters have). "
-                                + "Please use sderaster -o stats to create them before use");
-                    }
-
-                    RasterInfo rasterInfo = new RasterInfo(rAtt, coverageCrs);
-                    rastersLayoutInfo.add(rasterInfo);
-
-                    final GeneralEnvelope originalEnvelope;
-                    originalEnvelope = calculateOriginalEnvelope(rAtt, coverageCrs);
-                    rasterInfo.setOriginalEnvelope(originalEnvelope);
-                    final List<RasterBandInfo> bands;
-                    bands = setUpBandInfo(scon, rAtt, rastersColorMaps);
-                    rasterInfo.setBands(bands);
-                    if (LOGGER.isLoggable(Level.FINER)) {
-                        LOGGER.finer("Gathered metadata for " + rasterTable + "#"
-                                + rAtt.getRasterId().longValue() + ":\n" + rasterInfo.toString());
-                    }
-                }
-            } catch (SeException e) {
-                throw new ArcSdeException("Gathering raster dataset information", e);
-            }
-        }
-
-        RasterDatasetInfo rasterInfo = new RasterDatasetInfo();
-        rasterInfo.setRasterTable(rasterTable);
-        rasterInfo.setRasterColumns(rasterColumns);
-        rasterInfo.setPyramidInfo(rastersLayoutInfo);
-
-        return rasterInfo;
-    }
-
-    private GeneralEnvelope calculateOriginalEnvelope(final SeRasterAttr rasterAttributes,
-            CoordinateReferenceSystem coverageCrs) throws IOException {
-        SeExtent sdeExtent;
-        try {
-            sdeExtent = rasterAttributes.getExtent();
-        } catch (SeException e) {
-            throw new ArcSdeException("Exception getting the raster extent", e);
-        }
-        GeneralEnvelope originalEnvelope = new GeneralEnvelope(coverageCrs);
-        originalEnvelope.setRange(0, sdeExtent.getMinX(), sdeExtent.getMaxX());
-        originalEnvelope.setRange(1, sdeExtent.getMinY(), sdeExtent.getMaxY());
-        return originalEnvelope;
-    }
-
-    private String[] getRasterColumns(final ArcSDEPooledConnection scon, final String rasterTable)
-            throws IOException {
-
-        String[] rasterColumns;
-        SeTable sTable = scon.getTable(rasterTable);
-        SeColumnDefinition[] cols;
-        try {
-            cols = sTable.describe();
-        } catch (SeException e) {
-            throw new ArcSdeException("Exception fetching the list of columns for table "
-                    + rasterTable, e);
-        }
-        List<String> fetchColumns = new ArrayList<String>(cols.length / 2);
-        for (int i = 0; i < cols.length; i++) {
-            if (cols[i].getType() == SeColumnDefinition.TYPE_RASTER)
-                fetchColumns.add(cols[i].getName());
-        }
-        if (fetchColumns.size() == 0) {
-            throw new DataSourceException("Couldn't find any TYPE_RASTER columns in ArcSDE table "
-                    + rasterTable);
-        }
-
-        rasterColumns = fetchColumns.toArray(new String[fetchColumns.size()]);
-        return rasterColumns;
-    }
-
-    private List<SeRasterAttr> getSeRasterAttr(ArcSDEPooledConnection scon, String rasterTable,
-            String[] rasterColumns) throws IOException {
-
-        LOGGER.fine("Gathering raster attributes for " + rasterTable);
-        SeRasterAttr rasterAttributes;
-        LinkedList<SeRasterAttr> rasterAttList = new LinkedList<SeRasterAttr>();
-        SeQuery query = null;
-        try {
-            query = new SeQuery(scon, rasterColumns, new SeSqlConstruct(rasterTable));
-            query.prepareQuery();
-            query.execute();
-
-            SeRow row = query.fetch();
-            while (row != null) {
-                rasterAttributes = row.getRaster(0);
-                rasterAttList.addFirst(rasterAttributes);
-                row = query.fetch();
-            }
-        } catch (SeException se) {
-            throw new ArcSdeException("Error fetching raster attributes for " + rasterTable, se);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    throw new ArcSdeException(e);
-                }
-            }
-        }
-        LOGGER.fine("Found " + rasterAttList.size() + " raster attributes for " + rasterTable);
-        return rasterAttList;
-    }
-
-    private List<RasterBandInfo> setUpBandInfo(ArcSDEPooledConnection scon,
-            SeRasterAttr rasterAttributes, Map<Long, IndexColorModel> rastersColorMaps)
-            throws IOException {
-        final int numBands;
-        final SeRasterBand[] seBands;
-        final RasterCellType cellType;
-        try {
-            numBands = rasterAttributes.getNumBands();
-            seBands = rasterAttributes.getBands();
-            cellType = RasterCellType.valueOf(rasterAttributes.getPixelType());
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-
-        List<RasterBandInfo> detachedBandInfo = new ArrayList<RasterBandInfo>(numBands);
-
-        RasterBandInfo bandInfo;
-        SeRasterBand band;
-        for (int bandN = 0; bandN < numBands; bandN++) {
-            band = seBands[bandN];
-            bandInfo = new RasterBandInfo();
-            final int bitsPerSample = cellType.getBitsPerSample();
-            setBandInfo(numBands, bandInfo, band, scon, bitsPerSample, rastersColorMaps);
-            detachedBandInfo.add(bandInfo);
-        }
-        return detachedBandInfo;
-    }
-
-    /**
-     *
-     * @param numBands
-     * @param bandInfo
-     * @param band
-     * @param scon
-     * @param bitsPerSample
-     *            only used if the band is colormapped to create the IndexColorModel
-     * @throws IOException
-     */
-    private void setBandInfo(final int numBands, final RasterBandInfo bandInfo,
-            final SeRasterBand band, final ArcSDEPooledConnection scon, int bitsPerSample,
-            final Map<Long, IndexColorModel> colorMaps) throws IOException {
-
-        bandInfo.bandId = band.getId().longValue();
-        bandInfo.bandNumber = band.getBandNumber();
-        bandInfo.bandName = "Band " + bandInfo.bandNumber;
-
-        final boolean hasColorMap = band.hasColorMap();
-        if (hasColorMap) {
-            IndexColorModel colorMap = colorMaps.get(Long.valueOf(bandInfo.bandId));
-            LOGGER.finest("Setting band's color map: " + colorMap);
-            bandInfo.nativeColorMap = colorMap;
-            bandInfo.colorMap = RasterUtils.ensureNoDataPixelIsAvailable(colorMap);
-        } else {
-            bandInfo.nativeColorMap = null;
-        }
-
-        bandInfo.compressionType = CompressionType.valueOf(band.getCompressionType());
-        bandInfo.cellType = RasterCellType.valueOf(band.getPixelType());
-        bandInfo.interleaveType = InterleaveType.valueOf(band.getInterleave());
-        bandInfo.interpolationType = InterpolationType.valueOf(band.getInterpolation());
-        bandInfo.hasStats = band.hasStats();
-        if (bandInfo.hasStats) {
-            try {
-                bandInfo.statsMin = band.getStatsMin();
-                bandInfo.statsMax = band.getStatsMax();
-                bandInfo.statsMean = band.getStatsMean();
-                bandInfo.statsStdDev = band.getStatsStdDev();
-            } catch (SeException e) {
-                throw new ArcSdeException(e);
-            }
-            // double noDataValue = 0;
-            // bandInfo.noDataValue = noDataValue;
-        } else {
-            bandInfo.statsMin = java.lang.Double.NaN;
-            bandInfo.statsMax = java.lang.Double.NaN;
-            bandInfo.statsMean = java.lang.Double.NaN;
-            bandInfo.statsStdDev = java.lang.Double.NaN;
-        }
-        if (bandInfo.getColorMap() != null) {
-            bandInfo.noDataValue = RasterUtils.determineNoDataValue(bandInfo.getColorMap());
-        } else {
-            double statsMin = bandInfo.getStatsMin();
-            double statsMax = bandInfo.getStatsMax();
-            RasterCellType nativeCellType = bandInfo.getCellType();
-            bandInfo.noDataValue = RasterUtils.determineNoDataValue(numBands, statsMin, statsMax,
-                    nativeCellType);
-        }
-        SDEPoint tOrigin;
-        try {
-            tOrigin = band.getTileOrigin();
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-        bandInfo.tileOrigin = new Point2D.Double(tOrigin.getX(), tOrigin.getY());
-    }
-
-    /**
-     *
-     * @param band
-     * @param scon
-     * @return
-     * @throws ArcSdeException
-     */
-    private Map<Long, IndexColorModel> loadColorMaps(final long rasterColumnId,
-            final int bitsPerSample, ArcSDEPooledConnection scon) throws IOException {
-        LOGGER.fine("Reading colormap for raster column " + rasterColumnId);
-
-        final String auxTableName = getAuxTableName(rasterColumnId, scon);
-        LOGGER.fine("Quering auxiliary table " + auxTableName + " for color map data");
-
-        Map<Long, IndexColorModel> colorMaps = new HashMap<Long, IndexColorModel>();
-        SeQuery query = null;
-        try {
-            SeSqlConstruct sqlConstruct = new SeSqlConstruct();
-            sqlConstruct.setTables(new String[] { auxTableName });
-            String whereClause = "TYPE = 3";
-            sqlConstruct.setWhere(whereClause);
-
-            query = new SeQuery(scon, new String[] { "RASTERBAND_ID", "OBJECT" }, sqlConstruct);
-            query.prepareQuery();
-            query.execute();
-
-            long bandId;
-            ByteArrayInputStream colorMapIS;
-            DataBuffer colorMapData;
-            IndexColorModel colorModel;
-
-            SeRow row = query.fetch();
-            while (row != null) {
-                bandId = ((Number) row.getObject(0)).longValue();
-                colorMapIS = row.getBlob(1);
-
-                colorMapData = readColorMap(colorMapIS);
-                colorModel = RasterUtils.sdeColorMapToJavaColorModel(colorMapData, bitsPerSample);
-
-                colorMaps.put(Long.valueOf(bandId), colorModel);
-
-                row = query.fetch();
-            }
-        } catch (SeException e) {
-            throw new ArcSdeException("Error fetching colormap data for column " + rasterColumnId
-                    + " from table " + auxTableName, e);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
-                            + "fetch colormap data", e);
-                }
-            }
-        }
-        LOGGER.fine("Read color map data for " + colorMaps.size() + " rasters");
-        return colorMaps;
-    }
-
-    private String getAuxTableName(long rasterColumnId, ArcSDEPooledConnection scon)
-            throws IOException {
-
-        final String owner;
-        SeQuery query = null;
-        try {
-            final String dbaName = scon.getSdeDbaName();
-            String rastersColumnsTable = dbaName + ".SDE_RASTER_COLUMNS";
-
-            SeSqlConstruct sqlCons = new SeSqlConstruct(rastersColumnsTable);
-            sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
-
-            try {
-                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
-                query.prepareQuery();
-            } catch (SeException e) {
-                // sde 9.3 calls it raster_columns, not sde_raster_columns...
-                rastersColumnsTable = dbaName + ".RASTER_COLUMNS";
-                sqlCons = new SeSqlConstruct(rastersColumnsTable);
-                sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
-                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
-                query.prepareQuery();
-            }
-            query.execute();
-
-            SeRow row = query.fetch();
-            if (row == null) {
-                throw new IllegalArgumentException("No raster column registered with id "
-                        + rasterColumnId);
-            }
-            owner = row.getString(0);
-            query.close();
-        } catch (SeException e) {
-            throw new ArcSdeException("Error getting auxiliary table for raster column "
-                    + rasterColumnId, e);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
-                            + "fetch colormap data", e);
-                }
-            }
-        }
-
-        final String auxTableName = owner + ".SDE_AUX_" + rasterColumnId;
-
-        return auxTableName;
-    }
-
-    private DataBuffer readColorMap(final ByteArrayInputStream colorMapIS) throws IOException {
-
-        final DataInputStream dataIn = new DataInputStream(colorMapIS);
-        // discard unneeded data
-        dataIn.readInt();
-
-        final int colorSpaceType = dataIn.readInt();
-        final int numBanks;
-        if (colorSpaceType == SeRaster.SE_COLORMAP_RGB) {
-            numBanks = 3;
-        } else if (colorSpaceType == SeRaster.SE_COLORMAP_RGBA) {
-            numBanks = 4;
-        } else {
-            throw new IllegalStateException("Got unknown colormap type: " + colorSpaceType);
-        }
-        LOGGER.finest("Colormap has " + numBanks + " color components");
-
-        final int buffType = dataIn.readInt();
-        final int numElems = dataIn.readInt();
-        LOGGER.finest("ColorMap length: " + numElems);
-
-        final DataBuffer buff;
-        if (buffType == SeRaster.SE_COLORMAP_DATA_BYTE) {
-            LOGGER.finest("Creating Byte data buffer for " + numBanks + " banks and " + numElems
-                    + " elements per bank");
-            buff = new DataBufferByte(numElems, numBanks);
-            for (int elem = 0; elem < numElems; elem++) {
-                for (int bank = 0; bank < numBanks; bank++) {
-                    int val = dataIn.readUnsignedByte();
-                    buff.setElem(bank, elem, val);
-                }
-            }
-        } else if (buffType == SeRaster.SE_COLORMAP_DATA_SHORT) {
-            LOGGER.finest("Creating Short data buffer for " + numBanks + " banks and " + numElems
-                    + " elements per bank");
-            buff = new DataBufferUShort(numElems, numBanks);
-            for (int elem = 0; elem < numElems; elem++) {
-                for (int bank = 0; bank < numBanks; bank++) {
-                    int val = dataIn.readUnsignedShort();
-                    buff.setElem(bank, elem, val);
-                }
-            }
-        } else {
-            throw new IllegalStateException("Unknown databuffer type from colormap header: "
-                    + buffType + " expected one of TYPE_BYTE, TYPE_SHORT");
-        }
-
-        assert dataIn.read() == -1 : "color map data should have been exausted";
-        return buff;
-    }
-
-    /**
-     * Used by test code to indicate wether to fail when a raster lacks statistics, since we can't
-     * create statistics with the ArcSDE Java API
-     *
-     * @param statisticsMandatory
-     */
-    void setStatisticsMandatory(final boolean statisticsMandatory) {
-        this.statisticsMandatory = statisticsMandatory;
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDETiledImageInputStream.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDETiledImageInputStream.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/ArcSDETiledImageInputStream.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,122 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.io.IOException;
-
-import javax.imageio.stream.ImageInputStream;
-import javax.imageio.stream.ImageInputStreamImpl;
-
-/**
- * An {@link ImageInputStream} that reads ArcSDE raster tiles in a band interleaved order.
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-final class ArcSDETiledImageInputStream extends ImageInputStreamImpl implements ImageInputStream {
-
-    private final TileReader tileReader;
-
-    private final int tileDataLength;
-
-    private final byte[] currTileData;
-
-    private int currTileDataIndex;
-
-    public ArcSDETiledImageInputStream(final TileReader tileReader) {
-        super();
-        this.tileReader = tileReader;
-        final int bytesPerTile = tileReader.getBytesPerTile();
-        this.tileDataLength = bytesPerTile;
-        this.currTileData = new byte[bytesPerTile];
-        // force load at the first read invocation
-        this.currTileDataIndex = tileDataLength;
-    }
-
-    /**
-     * Returns the computed lenght of the stream based on the tile dimensions, number of tiles,
-     * number of bands, and bits per sample
-     */
-    @Override
-    public long length() {
-        final int bytesPerTile = tileReader.getBytesPerTile();
-        final int tilesWide = tileReader.getTilesWide();
-        final int tilesHigh = tileReader.getTilesHigh();
-        final int numberOfBands = tileReader.getNumberOfBands();
-        // final int bitsPerSample = tileReader.getBitsPerSample();
-
-        int length = bytesPerTile * tilesWide * tilesHigh * numberOfBands;
-
-        return length;
-    }
-
-    @Override
-    public int read() throws IOException {
-        final byte[] data = getTileData();
-        if (data == null) {
-            return -1;
-        }
-        byte b = data[currTileDataIndex];
-        currTileDataIndex++;
-        return b;
-    }
-
-    @Override
-    public int read(byte[] buff, int off, int len) throws IOException {
-        final byte[] data = getTileData();
-        if (data == null) {
-            return -1;
-        }
-        final int available = data.length - currTileDataIndex;
-        final int count = Math.min(available, len);
-        System.arraycopy(data, currTileDataIndex, buff, off, count);
-        currTileDataIndex += count;
-        return count;
-    }
-
-    /**
-     * Fetches a tile from the {@code tileReader} if necessary and returns the current tile data.
-     * <p>
-     * It is needed to fetch a new tile if {@link #currTileDataIndex} indicates all the current tile
-     * data has been already read. If so, {@code currTileDataIndex} is reset to 0. The {@code read}
-     * operations are responsible of incrementing {@code currTileDataIndex} depending on how many
-     * bytes have been consumed from the tile data returned by this method.
-     * </p>
-     *
-     * @return {@code null} if there's no more tiles to fetch, the current tile data otherwise
-     * @throws IOException
-     */
-    private byte[] getTileData() throws IOException {
-        if (currTileDataIndex == tileDataLength) {
-            if (!tileReader.hasNext()) {
-                return null;
-            }
-
-            currTileDataIndex = 0;
-            tileReader.next(currTileData);
-        }
-        return currTileData;
-    }
-
-    @Override
-    public void close() throws IOException {
-        super.close();
-    }
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/BitmaskToNoDataConverter.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/BitmaskToNoDataConverter.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/BitmaskToNoDataConverter.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,233 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_8BIT_U;
-
-import java.awt.Dimension;
-import java.io.ByteArrayOutputStream;
-import java.io.DataOutputStream;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.Map;
-
-/**
- * A helper class to set nodata values directly onto the arcsde tile's returned {@code byte[]}
- *
- * @author Gabriel Roldan
- * @since 2.5.6
- * @version $Id$
- *
- */
-class BitmaskToNoDataConverter {
-
-    public static final BitmaskToNoDataConverter NO_ACTION_CONVERTER = new BitmaskToNoDataConverter(
-            0, 0, null) {
-
-        @Override
-        public void setNoData(Long bandId, byte[] tileData, byte[] bitMaskData) {
-            // no action
-        }
-
-        @Override
-        public void setAll(Long bandId, byte[] tileData) {
-            // no action
-        }
-
-        @Override
-        public void setNoData(Long bandId, int sampleN, byte[] tileData) {
-            // no action
-        }
-
-    };
-
-    protected final int pixelsPerTile;
-
-    protected final Map<Long, byte[]> byBandIdNoDataValues;
-
-    protected final int bitsPerSample;
-
-    /**
-     *
-     * @param pixelsPerTile
-     * @param bitsPerSample
-     * @param byBandIdNoDataValues
-     */
-    private BitmaskToNoDataConverter(final int pixelsPerTile, final int bitsPerSample,
-            final Map<Long, byte[]> byBandIdNoDataValues) {
-
-        this.pixelsPerTile = pixelsPerTile;
-        this.bitsPerSample = bitsPerSample;
-        this.byBandIdNoDataValues = byBandIdNoDataValues;
-
-    }
-
-    /**
-     * Creates a "nodata setter" for the given raster determined by the raster dataset and the
-     * raster index inside the dataset
-     *
-     * @param rasterInfo
-     * @param rasterIndex
-     * @return
-     */
-    public static BitmaskToNoDataConverter getInstance(final RasterDatasetInfo rasterInfo,
-            final int rasterIndex) {
-
-        final int numBands = rasterInfo.getNumBands();
-        final RasterCellType targetType = rasterInfo.getTargetCellType(rasterIndex);
-
-        Map<Long, byte[]> byBandIdNoDataValues = new HashMap<Long, byte[]>();
-
-        Dimension tileDimension = rasterInfo.getTileDimension(rasterIndex);
-        final int samplesPerTile = tileDimension.width * tileDimension.height;
-
-        for (int bandN = 0; bandN < numBands; bandN++) {
-            long bandId = rasterInfo.getBand(rasterIndex, bandN).getBandId();
-            Number noDataValue = rasterInfo.getNoDataValue(rasterIndex, bandN);
-            byte[] noDataValueBytes = toBytes(noDataValue, targetType);
-            byBandIdNoDataValues.put(Long.valueOf(bandId), noDataValueBytes);
-        }
-
-        final int bitsPerSample = targetType.getBitsPerSample();
-        BitmaskToNoDataConverter noDataSetter;
-        if (targetType == TYPE_8BIT_U) {
-            noDataSetter = new Unsigned8bitConverter(samplesPerTile, bitsPerSample,
-                    byBandIdNoDataValues);
-        } else {
-            noDataSetter = new BitmaskToNoDataConverter(samplesPerTile, bitsPerSample,
-                    byBandIdNoDataValues);
-        }
-
-        return noDataSetter;
-    }
-
-    static byte[] toBytes(final Number noDataValue, final RasterCellType targetType) {
-
-        ByteArrayOutputStream out = new ByteArrayOutputStream();
-        DataOutputStream writer = new DataOutputStream(out);
-
-        try {
-            switch (targetType) {
-            case TYPE_16BIT_S:
-                writer.writeShort(noDataValue.intValue());
-                break;
-            case TYPE_16BIT_U:
-                writer.writeShort(noDataValue.intValue());
-                break;
-            case TYPE_32BIT_REAL:
-                writer.writeFloat(noDataValue.floatValue());
-                break;
-            case TYPE_32BIT_S:
-                writer.writeInt(noDataValue.intValue());
-                break;
-            case TYPE_32BIT_U:
-                writer.writeInt(noDataValue.intValue());
-                break;
-            case TYPE_64BIT_REAL:
-                writer.writeDouble(noDataValue.doubleValue());
-                break;
-            case TYPE_8BIT_S:
-                writer.writeByte(noDataValue.byteValue());
-                break;
-            case TYPE_8BIT_U:
-                writer.writeByte(noDataValue.intValue());
-                break;
-            default:
-                throw new UnsupportedOperationException(
-                        "No no-data converter exists for sample type " + targetType);
-            }
-        } catch (IOException e) {
-            throw new RuntimeException("Can't happen!", e);
-        }
-
-        byte[] no_data_bytes = out.toByteArray();
-        return no_data_bytes;
-    }
-
-    /**
-     * Returns whether the sample N in the bitmask byte array is marked as a no-data pixel
-     */
-    public final boolean isNoData(int sampleN, byte[] bitmaskData) {
-        boolean isNoData = ((bitmaskData[sampleN / 8] >> (7 - (sampleN % 8))) & 0x01) == 0x00;
-        return isNoData;
-    }
-
-    /**
-     * Sets all the samples of {@code tileData} marked as no-data pixel in {@code bitmaskData} to
-     * the no-data value for band {@code bandId}
-     */
-    public void setNoData(final Long bandId, final byte[] tileData, final byte[] bitmaskData) {
-        for (int sampleN = 0; sampleN < pixelsPerTile; sampleN++) {
-            if (isNoData(sampleN, bitmaskData)) {
-                setNoData(bandId, sampleN, tileData);
-            }
-        }
-    }
-
-    /**
-     * Sets all the samples in {@code tileData} to the no-data value for the band {@code bandId}
-     * <p>
-     * Default implementation is to call {@link #setNoData(Long, int, byte[])} as many times as
-     * number of samples in a tile. Subclasses may override to optimize.
-     * </p>
-     */
-    public void setAll(final Long bandId, final byte[] tileData) {
-        for (int sampleN = 0; sampleN < pixelsPerTile; sampleN++) {
-            setNoData(bandId, sampleN, tileData);
-        }
-    }
-
-    /**
-     * Sets the sample N for the band {@code bandId} on {@code tileData} to the no-data value
-     */
-    public void setNoData(final Long bandId, final int sampleN, final byte[] tileData) {
-        byte[] noData = byBandIdNoDataValues.get(bandId);
-        int pixArrayOffset = (sampleN * bitsPerSample) / 8;
-        System.arraycopy(noData, 0, tileData, pixArrayOffset, noData.length);
-    }
-
-    /**
-     * A subclass that provides some optimization for the case where the target cell type is
-     * {@link RasterCellType#TYPE_8BIT_U}
-     */
-    static final class Unsigned8bitConverter extends BitmaskToNoDataConverter {
-
-        public Unsigned8bitConverter(final int samplesPerTile, final int bitsPerSample,
-                final Map<Long, byte[]> byBandIdNoDataValues) {
-            super(samplesPerTile, bitsPerSample, byBandIdNoDataValues);
-        }
-
-        /**
-         * Overrides to use the faster {@link Arrays#fill(byte[], byte)} method rather than calling
-         * {@link #setNoData(Long, int, byte[])} {@code samplesPerTile} times
-         */
-        @Override
-        public void setAll(Long bandId, byte[] tileData) {
-            byte noDataValue = byBandIdNoDataValues.get(bandId)[0];
-            Arrays.fill(tileData, noDataValue);
-        }
-
-        @Override
-        public void setNoData(Long bandId, int sampleN, byte[] tileData) {
-            byte noDataValue = byBandIdNoDataValues.get(bandId)[0];
-            tileData[sampleN] = noDataValue;
-        }
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/CompressionType.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/CompressionType.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/CompressionType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,61 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible raster compression types in Arcsde (ie,
- * {@code SeRaster#SE_COMPRESSION_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-enum CompressionType {
-    COMPRESSION_JP2, COMPRESSION_JPEG, COMPRESSION_LZ77, COMPRESSION_NONE;
-    static {
-        COMPRESSION_JP2.setSdeTypeId(SeRaster.SE_COMPRESSION_JP2);
-        COMPRESSION_JPEG.setSdeTypeId(SeRaster.SE_COMPRESSION_JPEG);
-        COMPRESSION_LZ77.setSdeTypeId(SeRaster.SE_COMPRESSION_LZ77);
-        COMPRESSION_NONE.setSdeTypeId(SeRaster.SE_COMPRESSION_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeCompressionType() {
-        return this.typeId;
-    }
-
-    public static CompressionType valueOf(final int seCompressionType) {
-        for (CompressionType type : CompressionType.values()) {
-            if (type.getSeCompressionType() == seCompressionType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Compression type " + seCompressionType
-                + " does not exist");
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/DefaultTiledRasterReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/DefaultTiledRasterReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/DefaultTiledRasterReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,339 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.image.ColorModel;
-import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.renderable.ParameterBlock;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageReadParam;
-import javax.imageio.ImageReader;
-import javax.imageio.ImageTypeSpecifier;
-import javax.imageio.stream.ImageInputStream;
-import javax.media.jai.ImageLayout;
-import javax.media.jai.JAI;
-import javax.media.jai.RenderedOp;
-
-import org.geotools.arcsde.ArcSdeException;
-import org.geotools.arcsde.session.ArcSDEPooledConnection;
-import org.geotools.data.DataSourceException;
-import org.geotools.util.logging.Logging;
-
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeQuery;
-import com.esri.sde.sdk.client.SeRaster;
-import com.esri.sde.sdk.client.SeRasterAttr;
-import com.esri.sde.sdk.client.SeRasterConstraint;
-import com.esri.sde.sdk.client.SeRow;
-import com.esri.sde.sdk.client.SeSqlConstruct;
-import com.sun.media.imageio.stream.RawImageInputStream;
-import com.sun.media.imageioimpl.plugins.raw.RawImageReaderSpi;
-
-/**
- * The default implementation for {@link TiledRasterReader}.
- * <p>
- * This implementation holds a connection and an open {@link SeQuery query} until the reader is
- * exhausted or {@link #dispose()} is called.
- * </p>
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.7
- */
-class DefaultTiledRasterReader implements TiledRasterReader {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private ArcSDEPooledConnection conn;
-
-    private RasterDatasetInfo rasterInfo;
-
-    private final SeQuery preparedQuery;
-
-    private SeRow row;
-
-    private SeRasterAttr rAttr;
-
-    private Long rasterId;
-
-    /**
-     * Creates an {@link DefaultTiledRasterReader} that uses the given connection to fetch raster
-     * data for the given {@link RasterDatasetInfo rasterInfo}.
-     * <p>
-     * </p>
-     *
-     * @param conn
-     * @param rasterInfo
-     * @throws IOException
-     */
-    public DefaultTiledRasterReader(final ArcSDEPooledConnection conn,
-            final RasterDatasetInfo rasterInfo) throws IOException {
-        this.conn = conn;
-        this.rasterInfo = rasterInfo;
-
-        preparedQuery = createSeQuery(conn);
-
-        try {
-            preparedQuery.execute();
-        } catch (SeException e) {
-            dispose();
-            throw new ArcSdeException(e);
-        }
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TiledRasterReader#dispose()
-     */
-    public void dispose() {
-        if (conn != null) {
-            try {
-                preparedQuery.close();
-            } catch (SeException e) {
-                e.printStackTrace();
-            }
-            conn.close();
-            conn = null;
-        }
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TiledRasterReader#nextRaster()
-     */
-    public Long nextRaster() throws IOException {
-        try {
-            this.row = preparedQuery.fetch();
-            if (row == null) {
-                dispose();
-                return null;
-            }
-
-            // we don't work with datasets with more than one raster column
-            final int rasterColumnIndex = 0;
-            this.rAttr = row.getRaster(rasterColumnIndex);
-            this.rasterId = Long.valueOf(rAttr.getRasterId().longValue());
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-        return this.rasterId;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TiledRasterReader#read(int, java.awt.Rectangle)
-     */
-    public RenderedImage read(final int pyramidLevel, final Rectangle tileRange) throws IOException {
-        final RenderedImage rasterImage;
-
-        // final Point imageLocation = rasterQueryInfo.getTiledImageSize().getLocation();
-
-        try {
-            rasterImage = getRasterMatchingTileRange(pyramidLevel, tileRange);
-        } catch (IOException e) {
-            dispose();
-            throw e;
-        } catch (RuntimeException e) {
-            dispose();
-            throw e;
-        }
-        return rasterImage;
-    }
-
-    /**
-     * Creates a prepared query for the coverage's table, does not set any constraint nor executes
-     * it.
-     */
-    private SeQuery createSeQuery(final ArcSDEPooledConnection conn) throws IOException {
-        final SeQuery seQuery;
-        final String[] rasterColumns = rasterInfo.getRasterColumns();
-        final String tableName = rasterInfo.getRasterTable();
-        try {
-            seQuery = new SeQuery(conn, rasterColumns, new SeSqlConstruct(tableName));
-            seQuery.prepareQuery();
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-        return seQuery;
-    }
-
-    private RenderedImage getRasterMatchingTileRange(int pyramidLevel, final Rectangle matchingTiles)
-            throws IOException {
-
-        /*
-         * Create the prepared query (not executed) stream to fetch the tiles from
-         */
-
-        // covers an area of full tiles
-        final RenderedImage fullTilesRaster;
-
-        /*
-         * Create the tiled raster covering the full area of the matching tiles
-         */
-
-        fullTilesRaster = createTiledRaster(pyramidLevel, matchingTiles);
-
-        /*
-         * REVISIT: This is odd, we need to force the data to be loaded so we're free to release the
-         * stream, which gives away the streamed, tiled nature of this rasters, but I don't see the
-         * GCE api having a very clear usage workflow that ensures close() is always being called to
-         * the underlying ImageInputStream so we could let it close the SeQuery when done.
-         */
-        try {
-            LOGGER.info("Forcing loading data for " + rasterInfo.getRasterTable() + "#" + rasterId);
-            fullTilesRaster.getData();
-        } catch (RuntimeException e) {
-            throw new DataSourceException("Error fetching arcsde raster", e);
-        }
-        return fullTilesRaster;
-    }
-
-    private RenderedOp createTiledRaster(final int pyramidLevel, final Rectangle matchingTiles)
-            throws IOException {
-
-        final int rasterIndex = rasterInfo.getRasterIndex(rasterId);
-
-        final int tileWidth;
-        final int tileHeight;
-        final int numberOfBands;
-        try {
-            numberOfBands = rAttr.getNumBands();
-            tileWidth = rAttr.getTileWidth();
-            tileHeight = rAttr.getTileHeight();
-
-            int[] bandsToQuery = new int[numberOfBands];
-            for (int bandN = 1; bandN <= numberOfBands; bandN++) {
-                bandsToQuery[bandN - 1] = bandN;
-            }
-
-            int minTileX = matchingTiles.x;
-            int minTileY = matchingTiles.y;
-            int maxTileX = minTileX + matchingTiles.width - 1;
-            int maxTileY = minTileY + matchingTiles.height - 1;
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("Requesting tiles [x=" + minTileX + "-" + maxTileX + ", y=" + minTileY
-                        + "-" + maxTileY + "] from tile range [x=0-"
-                        + (rAttr.getTilesPerRowByLevel(pyramidLevel) - 1) + ", y=0-"
-                        + (rAttr.getTilesPerColByLevel(pyramidLevel) - 1) + "]");
-            }
-            // SDEPoint tileOrigin = rAttr.getTileOrigin();
-
-            if (LOGGER.isLoggable(Level.FINE)) {
-                Rectangle tiledImageSize = new Rectangle(0, 0, tileWidth * matchingTiles.width,
-                        tileHeight * matchingTiles.height);
-
-                LOGGER.fine("Tiled image size: " + tiledImageSize);
-            }
-
-            final int interleaveType = SeRaster.SE_RASTER_INTERLEAVE_BIP;
-
-            SeRasterConstraint rConstraint = new SeRasterConstraint();
-            rConstraint.setBands(bandsToQuery);
-            rConstraint.setLevel(pyramidLevel);
-            rConstraint.setEnvelope(minTileX, minTileY, maxTileX, maxTileY);
-            rConstraint.setInterleave(interleaveType);
-
-            preparedQuery.queryRasterTile(rConstraint);
-
-        } catch (SeException se) {
-            throw new ArcSdeException(se);
-        }
-
-        final TileReader tileReader;
-        {
-            final Dimension tileSize = new Dimension(tileWidth, tileHeight);
-            tileReader = TileReaderFactory.getInstance(row, rasterInfo, rasterIndex, matchingTiles,
-                    tileSize);
-        }
-
-        // Prepare temporary colorModel and sample model, needed to build the final
-        // ArcSDEPyramidLevel level;
-        final Dimension tiledImageSize;
-        final ColorModel colorModel;
-        final SampleModel sampleModel;
-        {
-            final int tiledImageWidth = tileReader.getTilesWide() * tileReader.getTileWidth();
-            final int tiledImageHeight = tileReader.getTilesHigh() * tileReader.getTileHeight();
-            tiledImageSize = new Dimension(tiledImageWidth, tiledImageHeight);
-
-            final ImageTypeSpecifier fullImageSpec = rasterInfo.getRenderedImageSpec(rasterIndex);
-            colorModel = fullImageSpec.getColorModel();
-            sampleModel = fullImageSpec.getSampleModel(tiledImageWidth, tiledImageHeight);
-        }
-
-        // Finally, build the image input stream
-        final RawImageInputStream raw;
-        {
-            final long[] imageOffsets = new long[] { 0 };
-            final Dimension[] imageDimensions = new Dimension[] { tiledImageSize };
-
-            final ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-
-            final ImageInputStream tiledImageInputStream;
-            tiledImageInputStream = new ArcSDETiledImageInputStream(tileReader);
-
-            raw = new RawImageInputStream(tiledImageInputStream, its, imageOffsets, imageDimensions);
-        }
-
-        // building the final image layout
-        final ImageLayout imageLayout;
-        {
-            // the value for the resulting image.getMinX() and image.getMinY() reflecting its
-            // position in the whole image at the pyramid level
-            int minX = (matchingTiles.x * tileWidth);
-            int minY = (matchingTiles.y * tileHeight);
-
-            int width = tiledImageSize.width;
-            int height = tiledImageSize.height;
-
-            int tileGridXOffset = minX;
-            int tileGridYOffset = minY;
-
-            imageLayout = new ImageLayout(minX, minY, width, height, tileGridXOffset,
-                    tileGridYOffset, tileWidth, tileHeight, sampleModel, colorModel);
-        }
-
-        // First operator: read the image
-        final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, imageLayout);
-
-        ParameterBlock pb = new ParameterBlock();
-        pb.add(raw);// Input
-        /*
-         * image index, always 0 since we're already fetching the required pyramid level
-         */
-        pb.add(Integer.valueOf(0)); // Image index
-        pb.add(Boolean.TRUE); // Read metadata
-        pb.add(Boolean.TRUE);// Read thumbnails
-        pb.add(Boolean.TRUE);// Verify input
-        pb.add(null);// Listeners
-        pb.add(null);// Locale
-        final ImageReadParam rParam = new ImageReadParam();
-        pb.add(rParam);// ReadParam
-        RawImageReaderSpi imageIOSPI = new RawImageReaderSpi();
-        ImageReader readerInstance = imageIOSPI.createReaderInstance();
-        pb.add(readerInstance);// Reader
-
-        RenderedOp image = JAI.create("ImageRead", pb, hints);
-
-        return image;
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterleaveType.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterleaveType.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterleaveType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,64 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible band interleave types in Arcsde (ie, {@code
- * SeRaster#SE_RASTER_INTERLEAVE_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-enum InterleaveType {
-    INTERLEAVE_BIL, INTERLEAVE_BIL_91, INTERLEAVE_BIP, INTERLEAVE_BIP_91, INTERLEAVE_BSQ, INTERLEAVE_BSQ_91, INTERLEAVE_NONE;
-    static {
-        INTERLEAVE_BIL.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL);
-        INTERLEAVE_BIL_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL_91);
-        INTERLEAVE_BIP.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP);
-        INTERLEAVE_BIP_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP_91);
-        INTERLEAVE_BSQ.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ);
-        INTERLEAVE_BSQ_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ_91);
-        INTERLEAVE_NONE.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeRasterInterleaveType() {
-        return this.typeId;
-    }
-
-    public static InterleaveType valueOf(final int seRasterInterleaveType) {
-        for (InterleaveType type : InterleaveType.values()) {
-            if (type.getSeRasterInterleaveType() == seRasterInterleaveType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Raster interleave type " + seRasterInterleaveType
-                + " does not exist");
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterpolationType.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterpolationType.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/InterpolationType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,61 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible raster interpolation types in Arcsde (ie,
- * {@code SeRaster#SE_INTERPOLATION_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-enum InterpolationType {
-    INTERPOLATION_BICUBIC, INTERPOLATION_BILINEAR, INTERPOLATION_NEAREST, INTERPOLATION_NONE;
-    static {
-        INTERPOLATION_BICUBIC.setSdeTypeId(SeRaster.SE_INTERPOLATION_BICUBIC);
-        INTERPOLATION_BILINEAR.setSdeTypeId(SeRaster.SE_INTERPOLATION_BILINEAR);
-        INTERPOLATION_NEAREST.setSdeTypeId(SeRaster.SE_INTERPOLATION_NEAREST);
-        INTERPOLATION_NONE.setSdeTypeId(SeRaster.SE_INTERPOLATION_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeInterpolationType() {
-        return this.typeId;
-    }
-
-    public static InterpolationType valueOf(final int seInterpolationType) {
-        for (InterpolationType type : InterpolationType.values()) {
-            if (type.getSeInterpolationType() == seInterpolationType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Interpolation type " + seInterpolationType
-                + " does not exist");
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/NativeTileReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/NativeTileReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/NativeTileReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,242 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Dimension;
-import java.awt.Rectangle;
-import java.io.EOFException;
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.geotools.arcsde.ArcSdeException;
-import org.geotools.util.logging.Logging;
-
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeRasterTile;
-import com.esri.sde.sdk.client.SeRow;
-
-/**
- * Offers an iterator like interface to fetch ArcSDE raster tiles.
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-@SuppressWarnings( { "nls" })
-final class NativeTileReader implements TileReader {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private final int bitsPerSample;
-
-    private final Rectangle requestedTiles;
-
-    private final Dimension tileSize;
-
-    private final int tileDataLength;
-
-    private final SeRow row;
-
-    private final int pixelsPerTile;
-
-    private final int numberOfBands;
-
-    private SeRasterTile nextTile;
-
-    private boolean started;
-
-    private final int bitmaskDataLength;
-
-    private final BitmaskToNoDataConverter noData;
-
-    /**
-     *
-     * @param row
-     * @param imageDimensions
-     *            the image size, x and y are the offsets, width and height the actual width and
-     *            height, used to ignore incomming pixel data as appropriate to fit the image
-     *            dimensions
-     * @param bitsPerSample
-     * @param numberOfBands2
-     * @param requestedTiles
-     */
-    NativeTileReader(final SeRow row, final int bitsPerSample, int numberOfBands,
-            final Rectangle requestedTiles, Dimension tileSize,
-            final BitmaskToNoDataConverter noData) {
-        this.row = row;
-        this.bitsPerSample = bitsPerSample;
-        this.numberOfBands = numberOfBands;
-        this.requestedTiles = requestedTiles;
-        this.tileSize = tileSize;
-        this.pixelsPerTile = tileSize.width * tileSize.height;
-        this.tileDataLength = (int) Math
-                .ceil(((double) pixelsPerTile * (double) bitsPerSample) / 8D);
-        this.bitmaskDataLength = (int) Math.ceil(pixelsPerTile / 8D);
-        this.noData = noData;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getBitsPerSample()
-     */
-    public int getBitsPerSample() {
-        return bitsPerSample;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getPixelsPerTile()
-     */
-    public int getPixelsPerTile() {
-        return pixelsPerTile;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getNumberOfBands()
-     */
-    public int getNumberOfBands() {
-        return numberOfBands;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getTileWidth()
-     */
-    public int getTileWidth() {
-        return tileSize.width;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getTileHeight()
-     */
-    public int getTileHeight() {
-        return tileSize.height;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getTilesWide()
-     */
-    public int getTilesWide() {
-        return requestedTiles.width;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getTilesHigh()
-     */
-    public int getTilesHigh() {
-        return requestedTiles.height;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#getBytesPerTile()
-     */
-    public int getBytesPerTile() {
-        return tileDataLength;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#hasNext()
-     */
-    public boolean hasNext() throws IOException {
-        if (!started) {
-            try {
-                nextTile = row.getRasterTile();
-                started = true;
-                if (nextTile == null) {
-                    LOGGER.fine("No tiles to fetch at all, releasing connection");
-                }
-            } catch (SeException e) {
-                throw new ArcSdeException(e);
-            }
-        }
-        return nextTile != null;
-    }
-
-    /**
-     * @see org.geotools.arcsde.gce.TileReader#next(byte[])
-     */
-    public TileInfo next(byte[] tileData) throws IOException {
-        if (tileData == null) {
-            throw new IllegalArgumentException("tileData is null");
-        }
-
-        final SeRasterTile tile;
-
-        if (hasNext()) {
-            tile = nextTile();
-        } else {
-            throw new IllegalStateException("There're no more tiles to fetch");
-        }
-
-        final byte[] bitMaskData = tile.getBitMaskData();
-
-        if (LOGGER.isLoggable(Level.FINEST)) {
-            LOGGER.finest(" >> Fetching " + tile + " - bitmask: " + bitMaskData.length
-                    + " has more: " + hasNext());
-        }
-
-        assert bitMaskData.length == 0 ? true : bitmaskDataLength == bitMaskData.length;
-
-        final int numPixels = tile.getNumPixels();
-
-        final Long bandId = Long.valueOf(tile.getBandId().longValue());
-
-        if (0 == numPixels) {
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("tile contains no pixel data, skipping: " + tile);
-            }
-            noData.setAll(bandId, tileData);
-        } else if (pixelsPerTile == numPixels) {
-
-            final byte[] rawTileData = tile.getPixelData();
-
-            System.arraycopy(rawTileData, 0, tileData, 0, tileDataLength);
-
-            if (bitMaskData.length > 0) {
-                noData.setNoData(bandId, tileData, bitMaskData);
-            }
-
-            if (LOGGER.isLoggable(Level.FINEST)) {
-                LOGGER.finest("returning " + numPixels + " pixels data packaged into "
-                        + tileDataLength + " bytes for tile [" + tile.getColumnIndex() + ","
-                        + tile.getRowIndex() + "]");
-            }
-        } else {
-            throw new IllegalStateException("Expected pixels per tile == " + pixelsPerTile
-                    + " but got " + numPixels + ": " + tile);
-        }
-
-        return new TileInfo(bandId, bitMaskData, numPixels);
-    }
-
-    private SeRasterTile nextTile() throws IOException {
-        if (nextTile == null) {
-            throw new EOFException("No more tiles to read");
-        }
-        SeRasterTile curr = nextTile;
-        try {
-            nextTile = row.getRasterTile();
-            if (nextTile == null) {
-                LOGGER.finer("There're no more tiles to fetch");
-            }
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-        return curr;
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PromotingTileReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PromotingTileReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PromotingTileReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,189 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_16BIT_S;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_16BIT_U;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_1BIT;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_32BIT_S;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_8BIT_U;
-
-import java.io.IOException;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.geotools.util.logging.Logging;
-
-/**
- * A {@link TileReader} decorator
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.6
- */
-final class PromotingTileReader implements TileReader {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private final TileReader nativeReader;
-
-    private final RasterCellType targetType;
-
-    private final SampleDepthPromoter promoter;
-
-    private final BitmaskToNoDataConverter noData;
-
-    private final byte[] nativeTileData;
-
-    public PromotingTileReader(final TileReader nativeTileReader, final RasterCellType sourceType,
-            final RasterCellType targetType, final BitmaskToNoDataConverter noData) {
-
-        this.nativeReader = nativeTileReader;
-        this.targetType = targetType;
-        this.noData = noData;
-        this.nativeTileData = new byte[nativeTileReader.getBytesPerTile()];
-        this.promoter = SampleDepthPromoter.createFor(sourceType, targetType);
-        LOGGER.fine("Using sample depth promoting tile reader, from " + sourceType + " to "
-                + targetType);
-    }
-
-    public int getBitsPerSample() {
-        return targetType.getBitsPerSample();
-    }
-
-    public int getBytesPerTile() {
-        double pixelsPerTile = getPixelsPerTile();
-        double bitsPerSample = getBitsPerSample();
-        int bytesPerTile = (int) Math.floor((pixelsPerTile * bitsPerSample) / 8D);
-        return bytesPerTile;
-    }
-
-    public int getNumberOfBands() {
-        return nativeReader.getNumberOfBands();
-    }
-
-    public int getPixelsPerTile() {
-        return nativeReader.getPixelsPerTile();
-    }
-
-    public int getTileHeight() {
-        return nativeReader.getTileHeight();
-    }
-
-    public int getTileWidth() {
-        return nativeReader.getTileWidth();
-    }
-
-    public int getTilesHigh() {
-        return nativeReader.getTilesHigh();
-    }
-
-    public int getTilesWide() {
-        return nativeReader.getTilesWide();
-    }
-
-    public boolean hasNext() throws IOException {
-        return nativeReader.hasNext();
-    }
-
-    public TileInfo next(byte[] tileData) throws IOException {
-        final TileInfo tileInfo = nativeReader.next(nativeTileData);
-        final byte[] bitmaskData = tileInfo.getBitmaskData();
-        final boolean hasNoDataPixels = bitmaskData.length > 0;
-        final Long bandId = tileInfo.getBandId();
-
-        final int numPixelsRead = tileInfo.getNumPixelsRead();
-        if (numPixelsRead == 0) {
-            noData.setAll(bandId, tileData);
-        } else {
-            final int numSamples = getPixelsPerTile();
-            assert numPixelsRead == numSamples;
-
-            for (int sampleN = 0; sampleN < numSamples; sampleN++) {
-                if (hasNoDataPixels && noData.isNoData(sampleN, bitmaskData)) {
-                    noData.setNoData(bandId, sampleN, tileData);
-                } else {
-                    promoter.promote(sampleN, nativeTileData, tileData);
-                }
-            }
-        }
-
-        return tileInfo;
-    }
-
-    /**
-     *
-     * @author Gabriel Roldan
-     */
-    private static abstract class SampleDepthPromoter {
-
-        public abstract void promote(int sampleN, byte[] nativeTileData, byte[] tileData);
-
-        public static SampleDepthPromoter createFor(final RasterCellType source,
-                final RasterCellType target) {
-
-            if (source == TYPE_1BIT && target == RasterCellType.TYPE_8BIT_U) {
-                return new OneBitToUchar();
-            } else if (source == TYPE_8BIT_U && target == TYPE_16BIT_U) {
-                return new UcharToUshort();
-            } else if (source == TYPE_16BIT_S && target == TYPE_32BIT_S) {
-                return new ShortToInt();
-            }
-
-            UnsupportedOperationException exception = new UnsupportedOperationException(
-                    "Promoting from " + source + " to " + target + " not yet implemented");
-            LOGGER.log(Level.WARNING, "Can't promote", exception);
-            throw exception;
-        }
-    }
-
-    private static class UcharToUshort extends SampleDepthPromoter {
-
-        @Override
-        public void promote(int sampleN, byte[] nativeTileData, byte[] tileData) {
-            int pixArrayOffset = 2 * sampleN;
-            tileData[pixArrayOffset] = 0;
-            tileData[pixArrayOffset + 1] = (byte) ((nativeTileData[sampleN] >>> 0) & 0xFF);
-        }
-    }
-
-    private static class OneBitToUchar extends SampleDepthPromoter {
-
-        @Override
-        public void promote(int sampleN, byte[] nativeTileData, byte[] tileData) {
-            int pixArrayOffset = sampleN / 8;
-            int bit = sampleN % 8;
-            int _byte = nativeTileData[pixArrayOffset];
-            byte ucharvalue = (byte) ((_byte >> (7 - bit)) & 0x01);
-            tileData[sampleN] = ucharvalue;
-        }
-    }
-
-    private static class ShortToInt extends SampleDepthPromoter {
-
-        @Override
-        public void promote(int sampleN, byte[] nativeTileData, byte[] tileData) {
-            int pixArrayOffset = 4 * sampleN;
-
-            tileData[pixArrayOffset] = 0;
-            tileData[pixArrayOffset + 1] = 0;
-            tileData[pixArrayOffset + 1] = (byte) ((nativeTileData[sampleN] >>> 8) & 0xFF);
-            tileData[pixArrayOffset + 1] = (byte) ((nativeTileData[sampleN] >>> 0) & 0xFF);
-        }
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PyramidLevelInfo.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PyramidLevelInfo.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/PyramidLevelInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,178 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.geom.Point2D;
-
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-/**
- * Represents one level in an ArcSDE pyramid. Holds information about a given pyramid level, like
- * resolution, x/y offsets, number of tiles high/wide, total pixel size and total envelope covered
- * by this level.
- *
- * @author sfarber
- *
- */
-final class PyramidLevelInfo {
-    private int pyramidLevel, xTiles, yTiles;
-
-    Point2D extentOffset;
-
-    Point imageOffset;
-
-    private double xRes, yRes;
-
-    private ReferencedEnvelope envelope;
-
-    public Dimension size;
-
-    /**
-     *
-     * @param level
-     *            the level index
-     * @param extent
-     *            the geographical extent the level covers
-     * @param imgOffset
-     *            the offset of the image at this level
-     * @param extOffset
-     *            the offset of the image extent at this level
-     * @param numTilesWide
-     * @param numTilesHigh
-     * @param levelSize
-     *            the size of the actual image inside the tiled pixel range
-     */
-    PyramidLevelInfo(int level, ReferencedEnvelope extent, Point imgOffset, Point2D extOffset,
-            int numTilesWide, int numTilesHigh, Dimension levelSize) {
-        this.pyramidLevel = level;
-        this.xRes = extent.getWidth() / levelSize.width;
-        this.yRes = extent.getHeight() / levelSize.height;
-        this.envelope = extent;
-        this.imageOffset = imgOffset;
-        this.extentOffset = extOffset;
-        this.xTiles = numTilesWide;
-        this.yTiles = numTilesHigh;
-        this.size = levelSize;
-    }
-
-    /**
-     * @return Which level in the pyramid this object represents
-     */
-    public int getLevel() {
-        return pyramidLevel;
-    }
-
-    /**
-     * @return The X and Y resolution in units/pixel for pixels at this level
-     */
-    public double getXRes() {
-        return xRes;
-    }
-
-    /**
-     * @return The X and Y resolution in units/pixel for pixels at this level
-     */
-    public double getYRes() {
-        return yRes;
-    }
-
-    /**
-     * @return DOCUMENT ME!!!
-     */
-    public int getXOffset() {
-        return imageOffset.x;
-    }
-
-    /**
-     * @return DOCUMENT ME!!!
-     */
-    public int getYOffset() {
-        return imageOffset.y;
-    }
-
-    /**
-     * @return The total number of tiles covering the width of this level
-     */
-    public int getNumTilesWide() {
-        return xTiles;
-    }
-
-    /**
-     * @return The total number of tiles covering the height of this level
-     */
-    public int getNumTilesHigh() {
-        return yTiles;
-    }
-
-    /**
-     * The envelope covering the image grid range inside fully tiled image at this pyramid level
-     *
-     * @return The geographical area covered by the {@link #getImageRange() grid range} of the
-     *         raster at this pyramid level
-     */
-    public ReferencedEnvelope getImageEnvelope() {
-        final double deltaX = extentOffset.getX();
-        final double deltaY = extentOffset.getY();
-        double minx = this.envelope.getMinX() - deltaX;
-        double miny = this.envelope.getMinY() - deltaY;
-        double maxx = minx + this.envelope.getWidth();
-        double maxy = miny + this.envelope.getHeight();
-
-        CoordinateReferenceSystem crs = this.envelope.getCoordinateReferenceSystem();
-        ReferencedEnvelope imageExtent = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
-
-        return imageExtent;
-    }
-
-    /**
-     * @return The total number of pixels in the image at this level as whole tiles
-     */
-    public Dimension getSize() {
-        return size;
-    }
-
-    /**
-     * The rectangle covering the actual raster data inside the tiled space
-     *
-     * @return
-     */
-    public Rectangle getImageRange() {
-        final int offsetX = getXOffset();
-        final int offsetY = getYOffset();
-
-        /*
-         * get the range of actual data pixels in this pyramid level in pixel space, offset and
-         * trailing no data pixels to fill up the tile space do not count
-         */
-        final Rectangle levelRange = new Rectangle(offsetX, offsetY, size.width, size.height);
-        return levelRange;
-    }
-
-    @Override
-    public String toString() {
-        return "[level: " + pyramidLevel + " size: " + size.width + "x" + size.height + "  xRes: "
-                + xRes + "  yRes: " + yRes + "  xOffset: " + getXOffset() + "  yOffset: "
-                + getYOffset() + "  extent: " + envelope.getMinX() + "," + envelope.getMinY() + " "
-                + envelope.getMaxX() + "," + envelope.getMaxY() + "  tilesWide: " + xTiles
-                + "  tilesHigh: " + yTiles + "]";
-    }
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterBandInfo.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterBandInfo.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterBandInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,175 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.geom.Point2D;
-import java.awt.geom.Point2D.Double;
-import java.awt.image.IndexColorModel;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-final class RasterBandInfo {
-
-    long bandId;
-
-    String bandName;
-
-    int bandNumber;
-
-    /**
-     * the color map as it is on the database, except that we always create a color map with alpha
-     * channel regardless of whether the native on has alpha or not, to account for the no-data
-     * pixel to be a transparent one where appropriate
-     */
-    IndexColorModel nativeColorMap;
-
-    /**
-     * The color map as it is going to be used by this library. May differ from the native one
-     * either in the number of elements (when the native color map is not full and it has no
-     * transparent pixel to be used as no-data value), or in the pixel depth (when the native
-     * colormap is full, has no no-data pixel, and hence it needs to be promoted to a higher
-     * transfer type to make room for a no-data index)
-     */
-    IndexColorModel colorMap;
-
-    /**
-     * The band's no-data value.
-     */
-    Number noDataValue;
-
-    CompressionType compressionType;
-
-    RasterCellType cellType;
-
-    InterleaveType interleaveType;
-
-    InterpolationType interpolationType;
-
-    boolean hasStats;
-
-    Point2D.Double tileOrigin;
-
-    double statsMin;
-
-    double statsMax;
-
-    double statsMean;
-
-    double statsStdDev;
-
-    public RasterBandInfo() {
-        // do nothing
-    }
-
-    /**
-     * @return the ArcSDE identifier for the band
-     */
-    public long getBandId() {
-        return bandId;
-    }
-
-    public String getBandName() {
-        return bandName;
-    }
-
-    public int getBandNumber() {
-        return bandNumber;
-    }
-
-    public boolean isColorMapped() {
-        return nativeColorMap != null;
-    }
-
-    public CompressionType getCompressionType() {
-        return compressionType;
-    }
-
-    public RasterCellType getCellType() {
-        return cellType;
-    }
-
-    public InterleaveType getInterleaveType() {
-        return interleaveType;
-    }
-
-    public InterpolationType getInterpolationType() {
-        return interpolationType;
-    }
-
-    public boolean isHasStats() {
-        return hasStats;
-    }
-
-    public Double getTileOrigin() {
-        return tileOrigin;
-    }
-
-    public IndexColorModel getNativeColorMap() {
-        return nativeColorMap;
-    }
-
-    public IndexColorModel getColorMap() {
-        return colorMap;
-    }
-
-    public double getStatsMin() {
-        return statsMin;
-    }
-
-    public double getStatsMax() {
-        return statsMax;
-    }
-
-    public double getStatsMean() {
-        return statsMean;
-    }
-
-    public double getStatsStdDev() {
-        return statsStdDev;
-    }
-
-    public Number getNoDataValue() {
-        return noDataValue;
-    }
-
-    @SuppressWarnings("nls")
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getBandName());
-        sb.append("[ id:").append(getBandId());
-        sb.append(", type:").append(getCellType());
-        sb.append(", samples: nodata=").append(getNoDataValue()).append(" min=").append(
-                getStatsMin()).append(" max=").append(getStatsMax()).append(" mean=").append(
-                getStatsMean()).append(" stddev=").append(getStatsStdDev());
-        /*
-         * sb.append(", tile origin: ").append((int) getTileOrigin().x).append(",").append( (int)
-         * getTileOrigin().y);
-         */
-        sb.append(", compression:").append(getCompressionType());
-        sb.append(", interpolation:").append(getInterpolationType());
-        sb.append(", Color Map: ").append(isColorMapped() ? "YES" : "NO");
-        return sb.toString();
-    }
-
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterCellType.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterCellType.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterCellType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,119 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.image.DataBuffer;
-import java.util.NoSuchElementException;
-
-import org.geotools.util.NumberRange;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible cell resolutions in Arcsde (ie, {@code
- * SeRaster#SE_PIXEL_TYPE_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-enum RasterCellType {
-    TYPE_16BIT_S(16, DataBuffer.TYPE_SHORT, true, NumberRange.create(Short.MIN_VALUE,
-            Short.MAX_VALUE)), //
-    TYPE_16BIT_U(16, DataBuffer.TYPE_USHORT, false, NumberRange.create((int) 0, (int) 65535)), //
-    TYPE_1BIT(1, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0, (byte) 1)), //
-    TYPE_32BIT_REAL(32, DataBuffer.TYPE_FLOAT, true, NumberRange.create(Float.MIN_VALUE,
-            Float.MAX_VALUE)), //
-    TYPE_32BIT_S(32, DataBuffer.TYPE_INT, true, NumberRange.create(Integer.MIN_VALUE,
-            Integer.MAX_VALUE)), //
-    TYPE_32BIT_U(32, DataBuffer.TYPE_INT, false, NumberRange.create(0L, (long) Math.pow(2, 32) - 1)), //
-    TYPE_4BIT(4, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0,
-            (byte) Math.pow(2, 4) - 1)), //
-    TYPE_64BIT_REAL(64, DataBuffer.TYPE_DOUBLE, true, NumberRange.create(Double.MIN_VALUE,
-            Double.MAX_VALUE)), //
-    TYPE_8BIT_S(8, DataBuffer.TYPE_BYTE, true, NumberRange.create(Byte.MIN_VALUE, Byte.MAX_VALUE)), //
-    TYPE_8BIT_U(8, DataBuffer.TYPE_BYTE, false, NumberRange.create((int) 0, (int) 255));
-    static {
-        // Setting the se_pixel_type in a static initializer to avoid having them linked to the fake
-        // values in the dummy api
-        TYPE_16BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_S);
-        TYPE_16BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_U);
-        TYPE_1BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_1BIT);
-        TYPE_32BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_REAL);
-        TYPE_32BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_S);
-        TYPE_32BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_U);
-        TYPE_4BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_4BIT);
-        TYPE_64BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_64BIT_REAL);
-        TYPE_8BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_S);
-        TYPE_8BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_U);
-    }
-
-    private int typeId;
-
-    private final int bitsPerSample;
-
-    private final int dataBufferType;
-
-    private final boolean signed;
-
-    private final NumberRange<?> sampleValueRange;
-
-    private RasterCellType(final int bitsPerSample, final int dataBufferType, final boolean signed,
-            final NumberRange<?> sampleValueRange) {
-        this.bitsPerSample = bitsPerSample;
-        this.dataBufferType = dataBufferType;
-        this.signed = signed;
-        this.sampleValueRange = sampleValueRange;
-    }
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeRasterPixelType() {
-        return this.typeId;
-    }
-
-    public int getBitsPerSample() {
-        return bitsPerSample;
-    }
-
-    public int getDataBufferType() {
-        return dataBufferType;
-    }
-
-    public boolean isSigned() {
-        return signed;
-    }
-
-    public static RasterCellType valueOf(final int seRasterPixelType) {
-        for (RasterCellType type : RasterCellType.values()) {
-            if (type.getSeRasterPixelType() == seRasterPixelType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Raster pixel type " + seRasterPixelType
-                + " does not exist");
-    }
-
-    public NumberRange<?> getSampleValueRange() {
-        return sampleValueRange;
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterDatasetInfo.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterDatasetInfo.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterDatasetInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,477 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.IndexColorModel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.imageio.ImageTypeSpecifier;
-
-import org.geotools.coverage.Category;
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
-import org.geotools.referencing.operation.transform.LinearTransform1D;
-import org.geotools.resources.i18n.Vocabulary;
-import org.geotools.resources.i18n.VocabularyKeys;
-import org.geotools.util.NumberRange;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.datum.PixelInCell;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.opengis.referencing.operation.TransformException;
-
-/**
- * Wraps metadata information for a raster dataset, whether it is composed of a single raster, or
- * it's raster catalog, and provides some conveinent methods to get to the raster metadata of it's
- * rasters and pyramid levels.
- * <p>
- * This is the single entry point to the metadata of a raster dataset. The associated classes
- * {@link RasterInfo} and {@link PyramidLevelInfo} are to be considered private to this class.
- * </p>
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-@SuppressWarnings( { "nls" })
-final class RasterDatasetInfo {
-
-    /** TRasterDatasetInfo the raster table we're pulling images from in this reader * */
-    private String rasterTable = null;
-
-    /**
-     * raster column names on this raster. If there's more than one raster column (is this
-     * possible?) then we just use the first one.
-     */
-    private String[] rasterColumns;
-
-    /** Array holding information on each level of the pyramid in this raster. * */
-    private List<RasterInfo> subRasterInfo;
-
-    /**
-     * The original (ie, pyramid level zero) envelope for the whole raster dataset
-     */
-    private GeneralEnvelope originalEnvelope;
-
-    private GeneralGridEnvelope originalGridRange;
-
-    private List<GridSampleDimension> gridSampleDimensions;
-
-    private final Map<Integer, ImageTypeSpecifier> renderedImageSpec = new HashMap<Integer, ImageTypeSpecifier>();
-
-    /**
-     * @param rasterTable
-     *            the rasterTable to set
-     */
-    void setRasterTable(String rasterTable) {
-        this.rasterTable = rasterTable;
-    }
-
-    /**
-     * @return the raster table name
-     */
-    public String getRasterTable() {
-        return rasterTable;
-    }
-
-    /**
-     * @param rasterColumns
-     *            the rasterColumns to set
-     */
-    void setRasterColumns(String[] rasterColumns) {
-        this.rasterColumns = rasterColumns;
-    }
-
-    /**
-     * @return the raster column names
-     */
-    public String[] getRasterColumns() {
-        return rasterColumns;
-    }
-
-    /**
-     * @param pyramidInfo
-     *            the pyramidInfo to set
-     */
-    void setPyramidInfo(List<RasterInfo> pyramidInfo) {
-        this.subRasterInfo = pyramidInfo;
-    }
-
-    public GridSampleDimension[] getGridSampleDimensions() {
-        if (gridSampleDimensions == null) {
-            synchronized (this) {
-                if (gridSampleDimensions == null) {
-                    gridSampleDimensions = buildSampleDimensions();
-                }
-            }
-        }
-        return gridSampleDimensions.toArray(new GridSampleDimension[getNumBands()]);
-    }
-
-    @SuppressWarnings("unchecked")
-    private List<GridSampleDimension> buildSampleDimensions() {
-
-        final int numBands = getNumBands();
-        List<GridSampleDimension> dimensions = new ArrayList<GridSampleDimension>(numBands);
-
-        final Color transparent = new Color(0, 0, 0, 0);
-
-        List<RasterBandInfo> bands = subRasterInfo.get(0).getBands();
-
-        for (RasterBandInfo band : bands) {
-            final int bandNumber = band.getBandNumber();
-            // use native cell type, in case no-data value has been computed to account for
-            // sample depth promotion, we want to category to keep being the native range for
-            // the values category
-            final RasterCellType targetCellType = getNativeCellType();
-            String bandName = band.getBandName();
-
-            final double statsMin = band.getStatsMin();
-            final double statsMax = band.getStatsMax();
-
-            NumberRange<?> sampleValueRange;
-            if (Double.isNaN(statsMin) || Double.isNaN(statsMax)) {
-                sampleValueRange = targetCellType.getSampleValueRange();
-            } else {
-                sampleValueRange = NumberRange.create(statsMin, statsMax);
-                Class elementClass = targetCellType.getSampleValueRange().getElementClass();
-                sampleValueRange = sampleValueRange.castTo(elementClass);
-            }
-
-            final Color[] colorRange = null;
-
-            final boolean geophysics = isGeoPhysics();
-
-            Category valuesCat = new Category("values", colorRange, sampleValueRange,
-                    LinearTransform1D.IDENTITY).geophysics(geophysics);
-
-            Category[] categories;
-            if (geophysics) {
-                double noDataValue = band.getNoDataValue().doubleValue();
-                // same as Category.NODATA but for the actual nodata value instead of hardcoded to
-                // zero
-                Category nodataCat = new Category(Vocabulary
-                        .formatInternational(VocabularyKeys.NODATA), transparent, noDataValue);
-                categories = new Category[] { valuesCat, nodataCat };
-            } else {
-                // do not build a nodata category. A nodata value that doesn't overlap the value
-                // range couldn't be determined
-                categories = new Category[] { valuesCat };
-            }
-            /*
-             * if (band.isHasStats()) { //can't do this, get an exception telling categories
-             * overlap.. so no real way to express the statistics, uh? Category catMin = new
-             * Category("Min", null, band.getStatsMin()).geophysics(true); Category catMax = new
-             * Category("Max", null, band.getStatsMin()).geophysics(true); Category catMean = new
-             * Category("Mean", null, band.getStatsMin()).geophysics(true); Category catStdDev = new
-             * Category("StdDev", null, band.getStatsMin()) .geophysics(true); categories = new
-             * Category[] { valuesCat, nodataCat, catMin, catMax, catMean, catStdDev }; } else {
-             * categories = new Category[] { valuesCat, nodataCat }; }
-             */
-            
-            // .geophysics(false) because our sample model always corresponds to the packed view
-            // (whether it matches the underlying sample depth or we're promoting in order to make
-            // room for the nodata value).
-            GridSampleDimension sampleDim = new GridSampleDimension(bandName, categories, null)
-                    .geophysics(false);
-
-            dimensions.add(sampleDim);
-        }
-        return dimensions;
-    }
-
-    private boolean isGeoPhysics() {
-        if (isColorMapped()) {
-            return false;
-        }
-        return RasterUtils.isGeoPhysics(getNumBands(), getNativeCellType());
-    }
-
-    public int getNumBands() {
-        return subRasterInfo.get(0).getNumBands();
-    }
-
-    public int getImageWidth() {
-        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
-        final int width = originalGridRange.getSpan(0);
-        return width;
-    }
-
-    public int getImageHeight() {
-        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
-        final int height = originalGridRange.getSpan(1);
-        return height;
-    }
-
-    /**
-     * @return the coverageCrs
-     */
-    public CoordinateReferenceSystem getCoverageCrs() {
-        return subRasterInfo.get(0).getCoordinateReferenceSystem();
-    }
-
-    /**
-     * @return the originalGridRange for the whole raster dataset, based on the first raster in the
-     *         raster dataset
-     */
-    public GeneralGridEnvelope getOriginalGridRange() {
-        if (originalGridRange == null) {
-            final MathTransform modelToRaster;
-            try {
-                final MathTransform rasterToModel = getRasterToModel();
-                modelToRaster = rasterToModel.inverse();
-            } catch (NoninvertibleTransformException e) {
-                throw new IllegalStateException("Can't create transform from model to raster");
-            }
-
-            int minx = Integer.MAX_VALUE;
-            int miny = Integer.MAX_VALUE;
-            int maxx = Integer.MIN_VALUE;
-            int maxy = Integer.MIN_VALUE;
-
-            final int rasterCount = getNumRasters();
-            for (int rasterN = 0; rasterN < rasterCount; rasterN++) {
-                final GeneralEnvelope rasterEnvelope = getGridEnvelope(rasterN, 0);
-                GeneralEnvelope rasterGridRangeInDataSet;
-                try {
-                    rasterGridRangeInDataSet = CRS.transform(modelToRaster, rasterEnvelope);
-                } catch (NoninvertibleTransformException e) {
-                    throw new IllegalArgumentException(e);
-                } catch (TransformException e) {
-                    throw new IllegalArgumentException(e);
-                }
-
-                minx = Math.min(minx, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(0)));
-                miny = Math.min(miny, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(1)));
-                maxx = Math.max(maxx, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(0)));
-                maxy = Math.max(maxy, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(1)));
-            }
-            int width = maxx - minx;
-            int height = maxy - miny;
-            Rectangle range = new Rectangle(0, 0, width, height);
-            originalGridRange = new GeneralGridEnvelope(range, 2);
-        }
-        return originalGridRange;
-    }
-
-    public MathTransform getRasterToModel() {
-
-        GeneralEnvelope firstRasterEnvelope = getGridEnvelope(0, 0);
-        Rectangle firstRasterGridRange = getGridRange(0, 0);
-        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(firstRasterGridRange, 2);
-
-        // create a raster to model transform, from this tile pixel space to the tile's geographic
-        // extent
-        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, firstRasterEnvelope);
-        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
-
-        final MathTransform rasterToModel = geMapper.createTransform();
-        return rasterToModel;
-    }
-
-    /**
-     * @return the originalEnvelope
-     */
-    public GeneralEnvelope getOriginalEnvelope() {
-        if (originalEnvelope == null) {
-            GeneralEnvelope env = null;
-            for (RasterInfo raster : subRasterInfo) {
-                GeneralEnvelope rasterEnvelope = raster.getOriginalEnvelope();
-                if (env == null) {
-                    env = new GeneralEnvelope(rasterEnvelope);
-                } else {
-                    env.add(rasterEnvelope);
-                }
-            }
-            originalEnvelope = env;
-        }
-        return originalEnvelope;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("ArcSDE Raster: " + getRasterTable());
-        sb.append(", Raster columns: ").append(Arrays.asList(getRasterColumns()));
-        sb.append(", Num bands: ").append(getNumBands());
-        sb.append(", Dimension: ").append(getImageWidth()).append("x").append(getImageHeight());
-        sb.append(", Pixel type: ").append(getNativeCellType());
-        sb.append(", Has Color Map: ").append(isColorMapped());
-        for (int rasterIndex = 0; rasterIndex < getNumRasters(); rasterIndex++) {
-            RasterInfo raster = getRasterInfo(rasterIndex);
-            sb.append("\n ");
-            sb.append(raster.toString());
-        }
-        return sb.toString();
-    }
-
-    public int getNumRasters() {
-        return subRasterInfo.size();
-    }
-
-    public RasterBandInfo getBand(final int rasterIndex, final int bandIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getBand(bandIndex);
-    }
-
-    public int getNumPyramidLevels(final int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getNumLevels();
-    }
-
-    public GeneralEnvelope getGridEnvelope(final int rasterIndex, final int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return new GeneralEnvelope(level.getImageEnvelope());
-    }
-
-    public Rectangle getGridRange(final int rasterIndex, final int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        Rectangle levelRange = level.getImageRange();
-        return levelRange;
-    }
-
-    public int getNumTilesWide(int rasterIndex, int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return level.getNumTilesWide();
-    }
-
-    public int getNumTilesHigh(int rasterIndex, int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return level.getNumTilesHigh();
-    }
-
-    public Dimension getTileDimension(int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getTileDimension();
-    }
-
-    private PyramidLevelInfo getLevel(int rasterIndex, int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
-        return level;
-    }
-
-    private RasterInfo getRasterInfo(int rasterIndex) {
-        RasterInfo rasterInfo = subRasterInfo.get(rasterIndex);
-        return rasterInfo;
-    }
-
-    public ImageTypeSpecifier getRenderedImageSpec(final int rasterIndex) {
-        if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
-            synchronized (this) {
-                if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
-                    ImageTypeSpecifier imageTypeSpecifier;
-                    imageTypeSpecifier = RasterUtils
-                            .createFullImageTypeSpecifier(this, rasterIndex);
-                    renderedImageSpec.put(Integer.valueOf(rasterIndex), imageTypeSpecifier);
-                }
-            }
-        }
-        return this.renderedImageSpec.get(Integer.valueOf(rasterIndex));
-    }
-
-    public IndexColorModel getColorMap(final int rasterIndex) {
-        final RasterBandInfo bandOne = getBand(rasterIndex, 0);
-        return bandOne.getColorMap();
-    }
-
-    boolean isColorMapped() {
-        RasterInfo rasterInfo = getRasterInfo(0);
-        return rasterInfo.isColorMapped();
-    }
-
-    public RasterCellType getNativeCellType() {
-        RasterInfo rasterInfo = getRasterInfo(0);
-        return rasterInfo.getNativeCellType();
-    }
-
-    public RasterCellType getTargetCellType(final int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getTargetCellType();
-    }
-
-    public Long getRasterId(final int rasterIndex) {
-        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getRasterId();
-    }
-
-    public int getOptimalPyramidLevel(final int rasterIndex, final OverviewPolicy policy,
-            final GeneralEnvelope requestedEnvelope, final Rectangle requestedDim) {
-
-        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-
-        double[] requestedRes = new double[2];
-        double reqSpanX = requestedEnvelope.getSpan(0);
-        double reqSpanY = requestedEnvelope.getSpan(1);
-        requestedRes[0] = reqSpanX / requestedDim.getWidth();
-        requestedRes[1] = reqSpanY / requestedDim.getHeight();
-
-        return rasterInfo.getOptimalPyramidLevel(policy, requestedRes);
-    }
-
-    public int getRasterIndex(Long rasterId) {
-        int index = -1;
-        for (RasterInfo p : subRasterInfo) {
-            index++;
-            if (rasterId.equals(p.getRasterId())) {
-                return index;
-            }
-        }
-        throw new IllegalArgumentException("rasterId: " + rasterId);
-    }
-
-    public double[] getResolution(int rasterN, int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterN);
-        double[] resolution = rasterInfo.getResolution(pyramidLevel);
-        return resolution;
-    }
-
-    public Point getTileOffset(final int rasterIndex, final int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
-        return new Point(level.getXOffset(), level.getYOffset());
-    }
-
-    public Number getNoDataValue(final int rasterIndex, final int bandIndex) {
-        RasterBandInfo band = getBand(rasterIndex, bandIndex);
-        Number noDataValue = band.getNoDataValue();
-        return noDataValue;
-    }
-
-    /**
-     * @param rasterIndex
-     *            the raster for which bands to return the no data values
-     * @return the list of no data values, one per band for the raster at index {@code rasterIndex}
-     */
-    public List<Number> getNoDataValues(final int rasterIndex) {
-        return getRasterInfo(rasterIndex).getNoDataValues();
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterInfo.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterInfo.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,405 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.geom.Point2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.data.DataSourceException;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.referencing.CRS;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.esri.sde.sdk.client.SDEPoint;
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeExtent;
-import com.esri.sde.sdk.client.SeRasterAttr;
-
-/**
- * A RasterInfo gathers the metadata for a single raster in a raster dataset
- * <p>
- * Basically, it wraps the SeRasterAttr object and implements some convenience methods for doing
- * calculations with it.
- * </p>
- *
- * @author Saul Farber
- * @author Gabriel Roldan
- */
-final class RasterInfo {
-
-    /**
-     * Orders pyramid levels by their level index
-     */
-    private static final Comparator<PyramidLevelInfo> levelComparator = new Comparator<PyramidLevelInfo>() {
-        public int compare(PyramidLevelInfo p0, PyramidLevelInfo p1) {
-            return (p0.getLevel() - p1.getLevel());
-        }
-    };
-
-    ArrayList<PyramidLevelInfo> pyramidList;
-
-    private int tileWidth;
-
-    private int tileHeight;
-
-    private GeneralEnvelope originalEnvelope;
-
-    private ArrayList<RasterBandInfo> bands;
-
-    private CoordinateReferenceSystem crs;
-
-    private Long rasterId;
-
-    /**
-     * Creates an in-memory representation of an ArcSDE Raster Pyramid. Basically it wraps the
-     * supplide SeRasterAttr object and implements some convenience logic for extracting
-     * information/ doing calculations with it.
-     *
-     * @param rasterAttributes
-     *            the SeRasterAttr object for the raster of interest.
-     * @param crs
-     * @throws DataSourceException
-     */
-    public RasterInfo(final SeRasterAttr rasterAttributes, final CoordinateReferenceSystem crs)
-            throws DataSourceException {
-        this.crs = crs;
-        try {
-            this.rasterId = Long.valueOf(rasterAttributes.getRasterId().longValue());
-            // levels goes from 0 to N, maxLevel is the zero-based max index of levels
-            final int numLevels = rasterAttributes.getMaxLevel() + 1;
-
-            pyramidList = new ArrayList<PyramidLevelInfo>(numLevels);
-
-            tileWidth = rasterAttributes.getTileWidth();
-            tileHeight = rasterAttributes.getTileHeight();
-
-            for (int level = 0; level < numLevels; level++) {
-                if (level == 1 && rasterAttributes.skipLevelOne()) {
-                    continue;
-                }
-
-                /*
-                 * this extent corresponds to the actual image size inside the tiled grid. That is,
-                 * to getImageWidth/Height by level. The dimensions of this extent are correct, but
-                 * it needs to be shifted by SeRasterAttr.getExtentOffsetByLevel(level) the same way
-                 * the grid envelope does by SeRasterAttr.getImageOffsetByLevel(level)
-                 */
-                final SeExtent slExtent = rasterAttributes.getExtentByLevel(level);
-
-                final int levelWidth = rasterAttributes.getImageWidthByLevel(level);
-                final int levelHeight = rasterAttributes.getImageHeightByLevel(level);
-
-                Dimension levelImageSize = new Dimension(levelWidth, levelHeight);
-
-                Point imgOffset = new Point();
-                // extent offset equals imgOffset * pixel resolution (ie, if resx == 2 and offsetX =
-                // 10, extent offset x == 20)
-                Point2D extOffset = new Point2D.Double();
-                {
-                    SDEPoint imageOffset = rasterAttributes.getImageOffsetByLevel(level);
-                    int xOffset = (int) (imageOffset == null ? 0 : imageOffset.getX());
-                    int yOffset = (int) (imageOffset == null ? 0 : imageOffset.getY());
-                    imgOffset.setLocation(xOffset, yOffset);
-
-                    SDEPoint extentOffset = rasterAttributes.getExtentOffsetByLevel(level);
-                    double xOffsetExtent = extentOffset == null ? 0D : extentOffset.getX();
-                    double yOffsetExtent = extentOffset == null ? 0D : extentOffset.getY();
-                    extOffset.setLocation(xOffsetExtent, yOffsetExtent);
-                }
-
-                final int numTilesWide = rasterAttributes.getTilesPerRowByLevel(level);
-                final int numTileHigh = rasterAttributes.getTilesPerColByLevel(level);
-
-                ReferencedEnvelope levelExtent = new ReferencedEnvelope(slExtent.getMinX(),
-                        slExtent.getMaxX(), slExtent.getMinY(), slExtent.getMaxY(), crs);
-
-                addPyramidLevel(level, levelExtent, imgOffset, extOffset, numTilesWide,
-                        numTileHigh, levelImageSize);
-            }
-
-        } catch (SeException se) {
-            throw new DataSourceException(se);
-        }
-    }
-
-    public Long getRasterId() {
-        return rasterId;
-    }
-
-    public int getTileWidth() {
-        return tileWidth;
-    }
-
-    public int getTileHeight() {
-        return tileHeight;
-    }
-
-    /**
-     * Don't use this constructor. It only exists for unit testing purposes.
-     *
-     * @param tileWidth
-     *            DON'T USE
-     * @param tileHeight
-     *            DON'T USE
-     */
-    public RasterInfo(int tileWidth, int tileHeight) {
-        this.tileWidth = tileWidth;
-        this.tileHeight = tileHeight;
-        pyramidList = new ArrayList<PyramidLevelInfo>(4);
-    }
-
-    public Dimension getTileDimension() {
-        return new Dimension(tileWidth, tileHeight);
-    }
-
-    public PyramidLevelInfo getPyramidLevel(int level) {
-        return pyramidList.get(level);
-    }
-
-    public int getNumLevels() {
-        return pyramidList.size();
-    }
-
-    /**
-     * @param pyramidLevel
-     * @return resx, resy, scalefactor
-     */
-    double[] getResolution(final int pyramidLevel) {
-        final double highestRes = getPyramidLevel(0).getXRes();
-        PyramidLevelInfo level = getPyramidLevel(pyramidLevel);
-        double[] resolution = new double[3];
-        resolution[0] = level.getXRes();
-        resolution[1] = level.getYRes();
-        resolution[2] = level.getXRes() / highestRes;
-        return resolution;
-    }
-
-    /**
-     * <p>
-     * NOTE: logic stolen and adapted from {@code AbstractGridCoverage2DReader#getOverviewImage()}
-     * </p>
-     *
-     * @param policy
-     * @return
-     */
-    public int getOptimalPyramidLevel(final OverviewPolicy policy, final double[] requestedRes) {
-
-        int pyramidLevelChoice = 0;
-
-        // sort resolutions from smallest pixels (higher res) to biggest pixels (higher res)
-        // keeping a reference to the original image choice
-        final double[] highestRes = getResolution(0);
-
-        // Now search for the best matching resolution.
-        // Check also for the "perfect match"... unlikely in practice unless someone
-        // tunes the clients to request exactly the resolution embedded in
-        // the overviews, something a perf sensitive person might do in fact
-
-        // the requested resolutions
-        final double reqx = requestedRes[0];
-        final double reqy = requestedRes[1];
-
-        // requested scale factor for least reduced axis
-        final double requestedScaleFactorX = reqx / highestRes[0];
-        final double requestedScaleFactorY = reqy / highestRes[1];
-        final int leastReduceAxis = requestedScaleFactorX <= requestedScaleFactorY ? 0 : 1;
-        final double requestedScaleFactor = leastReduceAxis == 0 ? requestedScaleFactorX
-                : requestedScaleFactorY;
-
-        final int numLevels = getNumLevels();
-
-        // no pyramiding or are we looking for a resolution even higher than the native one?
-        if (0 == numLevels || requestedScaleFactor <= 1) {
-            pyramidLevelChoice = 0;
-        } else {
-            // are we looking for a resolution even lower than the smallest overview?
-            final double[] min = getResolution(numLevels - 1);
-            if (requestedScaleFactor >= min[2]) {
-                pyramidLevelChoice = numLevels - 1;
-            } else {
-                // Ok, so we know the overview is between min and max, skip the first
-                // and search for an overview with a resolution lower than the one requested,
-                // that one and the one from the previous step will bound the searched resolution
-                double[] prev = highestRes;
-                for (int levelN = 1; levelN < numLevels; levelN++) {
-                    final double[] curr = getResolution(levelN);
-                    // perfect match check
-                    if (curr[2] == requestedScaleFactor) {
-                        pyramidLevelChoice = levelN;
-                    } else {
-                        /*
-                         * middle check. The first part of the condition should be sufficient, but
-                         * there are cases where the x resolution is satisfied by the lowest
-                         * resolution, the y by the one before the lowest (so the aspect ratio of
-                         * the request is different than the one of the overviews), and we would end
-                         * up going out of the loop since not even the lowest can "top" the request
-                         * for one axis
-                         */
-                        if (curr[2] > requestedScaleFactor || levelN == numLevels - 1) {
-                            if (policy == OverviewPolicy.QUALITY) {
-                                pyramidLevelChoice = levelN - 1;
-                            } else if (policy == OverviewPolicy.SPEED) {
-                                return levelN;
-                            } else if (requestedScaleFactor - prev[2] < curr[2]
-                                    - requestedScaleFactor) {
-                                pyramidLevelChoice = levelN - 1;
-                            } else {
-                                pyramidLevelChoice = levelN;
-                            }
-                            break;
-                        }
-                        prev = curr;
-                    }
-                }
-            }
-        }
-        // fallback
-        return pyramidLevelChoice;
-    }
-
-    /**
-     * Don't use this method. It's only public for unit testing purposes.
-     *
-     * @param level
-     *            the zero-based level index for the new level
-     * @param extent
-     *            the geographical extent the level covers, may need to be offsetted by {@code
-     *            extOffset}
-     * @param imgOffset
-     *            the offset on the X and Y axes of the actual image inside the tile space for this
-     *            level
-     * @param extOffset
-     *            the offset on the X and Y axes of the actual image inside the tile space for this
-     *            level
-     * @param numTilesWide
-     *            the number of tiles that make up the level on the X axis
-     * @param numTilesHigh
-     *            the number of tiles that make up the level on the Y axis
-     * @param imageSize
-     *            the size of the actual image in pixels
-     */
-    void addPyramidLevel(int level, ReferencedEnvelope extent, Point imgOffset, Point2D extOffset,
-            int numTilesWide, int numTilesHigh, Dimension imageSize) {
-
-        PyramidLevelInfo pyramidLevel;
-        pyramidLevel = new PyramidLevelInfo(level, extent, imgOffset, extOffset, numTilesWide,
-                numTilesHigh, imageSize);
-
-        pyramidList.add(pyramidLevel);
-
-        Collections.sort(pyramidList, levelComparator);
-    }
-
-    void setOriginalEnvelope(GeneralEnvelope originalEnvelope) {
-        this.originalEnvelope = originalEnvelope;
-    }
-
-    public GeneralEnvelope getOriginalEnvelope() {
-        return originalEnvelope;
-    }
-
-    void setBands(List<RasterBandInfo> bands) {
-        this.bands = new ArrayList<RasterBandInfo>(bands);
-    }
-
-    public List<RasterBandInfo> getBands() {
-        return new ArrayList<RasterBandInfo>(bands);
-    }
-
-    public int getNumBands() {
-        return bands.size();
-    }
-
-    public RasterBandInfo getBand(final int index) {
-        return bands.get(index);
-    }
-
-    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
-        return crs;
-    }
-
-    public RasterCellType getTargetCellType() {
-//        if (isColorMapped()) {
-//            // color map is already promoted if needed
-//            return getNativeCellType();
-//        }
-        List<Number> noDataValues = getNoDataValues();
-        RasterCellType nativeCellType = getNativeCellType();
-        RasterCellType targetCellType = RasterUtils.determineTargetCellType(nativeCellType,
-                noDataValues);
-        return targetCellType;
-    }
-
-    public boolean isColorMapped() {
-        return getBand(0).isColorMapped();
-    }
-
-    public RasterCellType getNativeCellType() {
-        return getBand(0).getCellType();
-    }
-
-    public List<Number> getNoDataValues() {
-        final List<Number> noDataValues = new ArrayList<Number>();
-        for (RasterBandInfo band : getBands()) {
-            Number noDataValue = band.getNoDataValue();
-            noDataValues.add(noDataValue);
-        }
-        return noDataValues;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(getClass().getSimpleName());
-        sb.append("[Id: ").append(getRasterId());
-        String srs = null;
-        try {
-            srs = CRS.lookupIdentifier(getCoordinateReferenceSystem(), false);
-        } catch (FactoryException e) {
-            e.printStackTrace();
-        }
-        sb.append(", bands: ").append(getNumBands());
-        sb.append(", levels: ").append(getNumLevels());
-        sb.append(", tile size: ").append(getTileWidth()).append("x").append(getTileHeight());
-        sb.append(", crs: ").append(srs == null ? getCoordinateReferenceSystem().toWKT() : srs);
-        GeneralEnvelope env = getOriginalEnvelope();
-        sb.append(", Envelope: ").append(env.getMinimum(0)).append(",").append(env.getMinimum(1))
-                .append(" ").append(env.getMaximum(0)).append(",").append(env.getMaximum(1));
-
-        sb.append("]\n Bands[");
-        for (RasterBandInfo band : getBands()) {
-            sb.append("\n\t");
-            sb.append(band.toString());
-        }
-        sb.append("\n ]");
-        sb.append("\n Pyramid[");
-        for (int l = 0; l < getNumLevels(); l++) {
-            sb.append("\n\t").append(getPyramidLevel(l).toString());
-        }
-        sb.append("\n ]");
-        return sb.toString();
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterQueryInfo.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterQueryInfo.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterQueryInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,216 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Rectangle;
-import java.awt.image.RenderedImage;
-import java.util.logging.Logger;
-
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.util.logging.Logging;
-
-/**
- * Captures information about a query for a single raster in a raster dataset.
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.6
- * @see RasterUtils#findMatchingRasters
- * @see RasterUtils#fitRequestToRaster
- */
-final class RasterQueryInfo {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private GeneralEnvelope requestedEnvelope;
-
-    private Rectangle requestedDim;
-
-    private int pyramidLevel;
-
-    /**
-     * The two-dimensional range of tile indices whose envelope intersect the requested extent. Will
-     * have negative width and height if none of the tiles do.
-     */
-    private Rectangle matchingTiles;
-
-    private GeneralEnvelope resultEnvelope;
-
-    private Rectangle resultDimension;
-
-    private Long rasterId;
-
-    private Rectangle mosaicLocation;
-
-    private RenderedImage resultImage;
-
-    private Rectangle tiledImageSize;
-
-    private double[] resolution;
-
-    private int rasterIndex;
-
-    /**
-     * The full tile range for the matching pyramid level
-     */
-    private Rectangle levelTileRange;
-
-    public RasterQueryInfo() {
-        setResultDimensionInsideTiledImage(new Rectangle(0, 0, 0, 0));
-        setMatchingTiles(new Rectangle(0, 0, 0, 0));
-        setResultEnvelope(null);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder s = new StringBuilder("[Raster query info:");
-        s.append("\n\tRaster ID            : ").append(getRasterId());
-        s.append("\n\tPyramid level        : ").append(getPyramidLevel());
-        s.append("\n\tResolution           : ").append(
-                getResolution()[0] + "," + getResolution()[1]);
-        s.append("\n\tRequested envelope   : ").append(getRequestedEnvelope());
-        s.append("\n\tRequested dimension  : ").append(getRequestedDim());
-        Rectangle mt = getMatchingTiles();
-        Rectangle ltr = getLevelTileRange();
-        String matching = "x=" + mt.x + "-" + (mt.width - 1) + ", y=" + mt.y + "-"
-                + (mt.height - 1);
-        String level = "x=" + ltr.x + "-" + (ltr.width - 1) + ", y=" + ltr.y + "-"
-                + (ltr.height - 1);
-        s.append("\n\tMatching tiles       : ").append(matching).append(" out of ").append(level);
-        s.append("\n\tTiled image size     : ").append(getTiledImageSize());
-        s.append("\n\tResult dimension     : ").append(getResultDimensionInsideTiledImage());
-        s.append("\n\tMosaiced dimension   : ").append(getMosaicLocation());
-        s.append("\n\tResult envelope      : ").append(getResultEnvelope());
-        s.append("\n]");
-        return s.toString();
-    }
-
-    /**
-     * @return the rasterId (as in SeRaster.getId()) for the raster in the raster dataset this query
-     *         works upon
-     */
-    public Long getRasterId() {
-        return rasterId;
-    }
-
-    public GeneralEnvelope getRequestedEnvelope() {
-        return requestedEnvelope;
-    }
-
-    public Rectangle getRequestedDim() {
-        return requestedDim;
-    }
-
-    public int getPyramidLevel() {
-        return pyramidLevel;
-    }
-
-    public Rectangle getMatchingTiles() {
-        return matchingTiles;
-    }
-
-    public GeneralEnvelope getResultEnvelope() {
-        return resultEnvelope;
-    }
-
-    public Rectangle getResultDimensionInsideTiledImage() {
-        return resultDimension;
-    }
-
-    void setRasterId(Long rasterId) {
-        this.rasterId = rasterId;
-    }
-
-    void setPyramidLevel(int pyramidLevel) {
-        this.pyramidLevel = pyramidLevel;
-    }
-
-    void setRequestedEnvelope(GeneralEnvelope requestedEnvelope) {
-        this.requestedEnvelope = requestedEnvelope;
-    }
-
-    void setRequestedDim(Rectangle requestedDim) {
-        this.requestedDim = requestedDim;
-    }
-
-    void setResultEnvelope(GeneralEnvelope resultEnvelope) {
-        this.resultEnvelope = resultEnvelope;
-    }
-
-    void setMatchingTiles(Rectangle matchingTiles) {
-        this.matchingTiles = matchingTiles;
-    }
-
-    void setResultDimensionInsideTiledImage(Rectangle resultDimension) {
-        this.resultDimension = resultDimension;
-    }
-
-    void setMosaicLocation(Rectangle rasterMosaicLocation) {
-        this.mosaicLocation = rasterMosaicLocation;
-    }
-
-    public Rectangle getMosaicLocation() {
-        return mosaicLocation;
-    }
-
-    public void setResultImage(RenderedImage rasterImage) {
-        this.resultImage = rasterImage;
-        if (rasterImage.getWidth() != tiledImageSize.width
-                || rasterImage.getHeight() != tiledImageSize.height) {
-            LOGGER.warning("Result image and expected dimensions don't match: image="
-                    + resultImage.getWidth() + "x" + resultImage.getHeight() + ", expected="
-                    + tiledImageSize.width + "x" + tiledImageSize.height);
-        }
-    }
-
-    public RenderedImage getResultImage() {
-        return resultImage;
-    }
-
-    void setTiledImageSize(Rectangle tiledImageSize) {
-        this.tiledImageSize = tiledImageSize;
-    }
-
-    public Rectangle getTiledImageSize() {
-        return tiledImageSize;
-    }
-
-    void setResolution(double[] resolution) {
-        this.resolution = resolution;
-    }
-
-    public double[] getResolution() {
-        return resolution == null ? new double[] { -1, -1 } : resolution;
-    }
-
-    void setRasterIndex(int rasterN) {
-        this.rasterIndex = rasterN;
-    }
-
-    public int getRasterIndex() {
-        return rasterIndex;
-    }
-
-    void setLevelTileRange(Rectangle levelTileRange) {
-        this.levelTileRange = levelTileRange;
-    }
-
-    public Rectangle getLevelTileRange() {
-        return levelTileRange;
-    }
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterReaderFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterReaderFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterReaderFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,53 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.io.IOException;
-
-import org.geotools.arcsde.session.ArcSDEConnectionPool;
-import org.geotools.arcsde.session.ArcSDEPooledConnection;
-import org.geotools.arcsde.session.UnavailableConnectionException;
-
-/**
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.7
- */
-public class RasterReaderFactory {
-
-    private final ArcSDEConnectionPool connectionPool;
-
-    public RasterReaderFactory(final ArcSDEConnectionPool connectionPool) {
-        this.connectionPool = connectionPool;
-    }
-
-    public TiledRasterReader create(final RasterDatasetInfo rasterInfo) throws IOException {
-
-        ArcSDEPooledConnection conn;
-        try {
-            conn = connectionPool.getConnection();
-        } catch (UnavailableConnectionException e) {
-            throw new RuntimeException(e);
-        }
-
-        TiledRasterReader rasterReader = new DefaultTiledRasterReader(conn, rasterInfo);
-
-        return rasterReader;
-    }
-
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterUtils.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterUtils.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/RasterUtils.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,998 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_16BIT_S;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_16BIT_U;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_1BIT;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_32BIT_REAL;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_32BIT_S;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_32BIT_U;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_4BIT;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_64BIT_REAL;
-import static org.geotools.arcsde.gce.RasterCellType.TYPE_8BIT_U;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.awt.image.BandedSampleModel;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.IndexColorModel;
-import java.awt.image.SampleModel;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageTypeSpecifier;
-
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.GridGeometry2D;
-import org.geotools.coverage.grid.io.AbstractGridFormat;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
-import org.geotools.resources.image.ColorUtilities;
-import org.geotools.resources.image.ComponentColorModelJAI;
-import org.geotools.util.NumberRange;
-import org.geotools.util.logging.Logging;
-import org.opengis.geometry.Envelope;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.parameter.ParameterNotFoundException;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.datum.PixelInCell;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.opengis.referencing.operation.TransformException;
-
-import com.sun.imageio.plugins.common.BogusColorSpace;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-@SuppressWarnings( { "nls" })
-class RasterUtils {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private RasterUtils() {
-        // do nothing
-    }
-
-    public static ReferencedEnvelope toReferencedEnvelope(GeneralEnvelope envelope) {
-        double minx = envelope.getMinimum(0);
-        double maxx = envelope.getMaximum(0);
-        double miny = envelope.getMinimum(1);
-        double maxy = envelope.getMaximum(1);
-        CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
-
-        ReferencedEnvelope refEnv = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
-        return refEnv;
-    }
-
-    public static ReferencedEnvelope toNativeCrs(final GeneralEnvelope requestedEnvelope,
-            final CoordinateReferenceSystem nativeCRS) throws IllegalArgumentException {
-
-        ReferencedEnvelope reqEnv = toReferencedEnvelope(requestedEnvelope);
-
-        if (!CRS.equalsIgnoreMetadata(nativeCRS, reqEnv.getCoordinateReferenceSystem())) {
-            // we're being reprojected. We'll need to reproject reqEnv into
-            // our native coordsys
-            try {
-                // ReferencedEnvelope origReqEnv = reqEnv;
-                reqEnv = reqEnv.transform(nativeCRS, true);
-            } catch (FactoryException fe) {
-                // unable to reproject?
-                throw new IllegalArgumentException("Unable to find a reprojection from requested "
-                        + "coordsys to native coordsys for this request", fe);
-            } catch (TransformException te) {
-                throw new IllegalArgumentException("Unable to perform reprojection from requested "
-                        + "coordsys to native coordsys for this request", te);
-            }
-        }
-        return reqEnv;
-    }
-
-    public static MathTransform createRasterToModel(final Rectangle levelGridRange,
-            final GeneralEnvelope levelEnvelope) {
-        // create a raster to model transform, from this tile pixel space to the tile's geographic
-        // extent
-        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(levelGridRange, 2);
-        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, levelEnvelope);
-        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
-
-        final MathTransform rasterToModel = geMapper.createTransform();
-        return rasterToModel;
-    }
-
-    private static Rectangle getResultDimensionForTileRange(final Rectangle tiledImageGridRange,
-            final Rectangle matchingLevelRange) {
-
-        int minx = Math.max(tiledImageGridRange.x, matchingLevelRange.x);
-        int miny = Math.max(tiledImageGridRange.y, matchingLevelRange.y);
-        int maxx = (int) Math.min(tiledImageGridRange.getMaxX(), matchingLevelRange.getMaxX());
-        int maxy = (int) Math.min(tiledImageGridRange.getMaxY(), matchingLevelRange.getMaxY());
-
-        return new Rectangle(minx, miny, maxx - minx, maxy - miny);
-    }
-
-    /**
-     * Returns the rectangle specifying the matching tiles for a given pyramid level and rectangle
-     * specifying the overlapping area to request in the level's pixel space.
-     *
-     * @param pixelRange
-     * @param tilesHigh
-     * @param tilesWide
-     * @param tileSize
-     * @param numTilesHigh
-     * @param numTilesWide
-     *
-     * @param pixelRange
-     * @param level
-     *
-     * @return a rectangle holding the coordinates in tile space that fully covers the requested
-     *         pixel range for the given pyramid level, or a negative area rectangle
-     */
-    private static Rectangle findMatchingTiles(final Dimension tileSize, int numTilesWide,
-            int numTilesHigh, final Rectangle pixelRange) {
-
-        final int minPixelX = pixelRange.x;
-        final int minPixelY = pixelRange.y;
-
-        // TODO: WARNING, we're not considering the possible x/y offsets on the level range for the
-        // given pyramid level here!
-
-        int minTileX = (int) Math.floor(minPixelX / tileSize.getWidth());
-        int minTileY = (int) Math.floor(minPixelY / tileSize.getHeight());
-
-        int numTilesX = (int) Math.ceil(pixelRange.getWidth() / tileSize.getWidth());
-        int numTilesY = (int) Math.ceil(pixelRange.getHeight() / tileSize.getHeight());
-
-        int maxTiledX = (minTileX + numTilesX) * tileSize.width;
-        int maxTiledY = (minTileY + numTilesY) * tileSize.height;
-
-        if (maxTiledX < pixelRange.getMaxX() && (minTileX + numTilesX) < numTilesWide) {
-            numTilesX++;
-        }
-
-        if (maxTiledY < pixelRange.getMaxY() && (minTileY + numTilesY) < numTilesHigh) {
-            numTilesY++;
-        }
-
-        Rectangle matchingTiles = new Rectangle(minTileX, minTileY, numTilesX, numTilesY);
-        return matchingTiles;
-    }
-
-    private static Rectangle getTargetGridRange(final MathTransform modelToRaster,
-            final Envelope requestedEnvelope) {
-        Rectangle levelOverlappingPixels;
-        int levelMinPixelX;
-        int levelMaxPixelX;
-        int levelMinPixelY;
-        int levelMaxPixelY;
-        {
-            // use a model to raster transform to find out which pixel range at the specified level
-            // better match the requested extent
-            GeneralEnvelope requestedPixels;
-            try {
-                requestedPixels = CRS.transform(modelToRaster, requestedEnvelope);
-            } catch (NoninvertibleTransformException e) {
-                throw new IllegalArgumentException(e);
-            } catch (TransformException e) {
-                throw new IllegalArgumentException(e);
-            }
-
-            levelMinPixelX = (int) Math.floor(requestedPixels.getMinimum(0));
-            levelMaxPixelX = (int) Math.floor(requestedPixels.getMaximum(0));
-
-            levelMinPixelY = (int) Math.ceil(requestedPixels.getMinimum(1));
-            levelMaxPixelY = (int) Math.ceil(requestedPixels.getMaximum(1));
-
-            final int width = levelMaxPixelX - levelMinPixelX;
-            final int height = levelMaxPixelY - levelMinPixelY;
-            levelOverlappingPixels = new Rectangle(levelMinPixelX, levelMinPixelY, width, height);
-        }
-        return levelOverlappingPixels;
-    }
-
-    /**
-     * Creates an IndexColorModel out of a DataBuffer obtained from an ArcSDE's raster color map.
-     *
-     * @param colorMapData
-     * @return
-     */
-    public static IndexColorModel sdeColorMapToJavaColorModel(final DataBuffer colorMapData,
-            final int bitsPerSample) {
-        if (colorMapData == null) {
-            throw new NullPointerException("colorMapData");
-        }
-
-        if (colorMapData.getNumBanks() < 3 || colorMapData.getNumBanks() > 4) {
-            throw new IllegalArgumentException("colorMapData shall have 3 or 4 banks: "
-                    + colorMapData.getNumBanks());
-        }
-
-        if (bitsPerSample != 8 && bitsPerSample != 16) {
-            throw new IllegalAccessError("bits per sample shall be either 8 or 16. Got "
-                    + bitsPerSample);
-        }
-
-        final int numBanks = colorMapData.getNumBanks();
-        final int mapSize = colorMapData.getSize();
-
-        byte[] r = new byte[mapSize];
-        byte[] g = new byte[mapSize];
-        byte[] b = new byte[mapSize];
-        byte[] a = new byte[mapSize];
-
-        for (int i = 0; i < mapSize; i++) {
-            r[i] = (byte) (colorMapData.getElem(0, i) & 0xFF);
-            g[i] = (byte) (colorMapData.getElem(1, i) & 0xFF);
-            b[i] = (byte) (colorMapData.getElem(2, i) & 0xFF);
-            a[i] = (byte) ((numBanks == 3 ? 255 : colorMapData.getElem(3, i)) & 0xFF);
-        }
-
-        IndexColorModel colorModel = new IndexColorModel(bitsPerSample, mapSize, r, g, b, a);
-
-        return colorModel;
-    }
-
-    public static ImageTypeSpecifier createFullImageTypeSpecifier(
-            final RasterDatasetInfo rasterInfo, final int rasterIndex) {
-
-        final int numberOfBands = rasterInfo.getNumBands();
-        final RasterCellType nativePixelType = rasterInfo.getNativeCellType();
-        final RasterCellType pixelType = rasterInfo.getTargetCellType(rasterIndex);
-
-        // Prepare temporary colorModel and sample model, needed to build the final
-        // ArcSDEPyramidLevel level;
-        int sampleImageWidth = 1;// rasterInfo.getImageWidth();
-        int sampleImageHeight = 1;// rasterInfo.getImageHeight();
-
-        final ImageTypeSpecifier its;
-        // treat special cases...
-        final int bitsPerSample = pixelType.getBitsPerSample();
-        final int dataType = pixelType.getDataBufferType();
-        final boolean hasColorMap = rasterInfo.isColorMapped();
-
-        if (hasColorMap) {
-            // special case, a single band colormapped image
-            IndexColorModel colorMap = rasterInfo.getColorMap(rasterIndex);
-            its = createColorMappedImageSpec(colorMap, sampleImageWidth, sampleImageHeight);
-
-        } else if (nativePixelType == TYPE_1BIT && numberOfBands == 1) {
-            byte noDataValue = rasterInfo.getNoDataValue(rasterIndex, 0).byteValue();
-            // special case, a single band 1-bit
-            its = createOneBitColorMappedImageSpec(sampleImageWidth, sampleImageHeight, noDataValue);
-
-        } else if (nativePixelType == TYPE_4BIT && numberOfBands == 1) {
-            byte noDataValue = rasterInfo.getNoDataValue(rasterIndex, 0).byteValue();
-            // special case, a single band 4-bit
-            its = createFourBitColorMappedImageSpec(sampleImageWidth, sampleImageHeight,
-                    noDataValue);
-        } else if (numberOfBands == 1) {
-            // special case, a single band grayscale image, no matter the pixel depth
-            its = createGrayscaleImageSpec(sampleImageWidth, sampleImageHeight, dataType,
-                    bitsPerSample);
-
-        } else if (numberOfBands == 3 && pixelType == TYPE_8BIT_U) {
-            // special case, an optimizable RGB image
-            its = createRGBImageSpec(sampleImageWidth, sampleImageHeight, dataType);
-
-        } else if (numberOfBands == 4 && pixelType == TYPE_8BIT_U) {
-            // special case, an optimizable RGBA image
-            its = createRGBAImageSpec(sampleImageWidth, sampleImageHeight, dataType);
-
-        } else {
-            /*
-             * not an special case, go for a more generic sample model, potentially slower than the
-             * special case ones, but that'll work anyway
-             */
-
-            final ColorModel colorModel;
-            final SampleModel sampleModel;
-            {
-                final ColorSpace colorSpace;
-                colorSpace = new BogusColorSpace(numberOfBands);
-                int[] numBits = new int[numberOfBands];
-                for (int i = 0; i < numberOfBands; i++) {
-                    numBits[i] = bitsPerSample;
-                }
-                colorModel = new ComponentColorModelJAI(colorSpace, numBits, false, false,
-                        Transparency.OPAQUE, dataType);
-            }
-            {
-                int[] bankIndices = new int[numberOfBands];
-                int[] bandOffsets = new int[numberOfBands];
-                // int bandOffset = (tileWidth * tileHeight * pixelType.getBitsPerSample()) / 8;
-                for (int i = 0; i < numberOfBands; i++) {
-                    bankIndices[i] = i;
-                    bandOffsets[i] = 0;// (i * bandOffset);
-                }
-                sampleModel = new BandedSampleModel(dataType, sampleImageWidth, sampleImageHeight,
-                        sampleImageWidth, bankIndices, bandOffsets);
-            }
-            its = new ImageTypeSpecifier(colorModel, sampleModel);
-        }
-
-        return its;
-    }
-
-    private static ImageTypeSpecifier createFourBitColorMappedImageSpec(int sampleImageWidth,
-            int sampleImageHeight, byte noDataValue) {
-
-        int maxValue = (int) TYPE_4BIT.getSampleValueRange().getMaximum();
-
-        int mapSize = noDataValue > maxValue ? noDataValue : maxValue + 1;
-
-        int[] cmap = new int[mapSize];
-        ColorUtilities.expand(new Color[] { Color.BLACK, Color.WHITE }, cmap, 0, maxValue);
-
-        for (int i = maxValue; i < mapSize; i++) {
-            cmap[i] = ColorUtilities.getIntFromColor(0, 0, 0, 0);
-        }
-
-        int transparentPixel = noDataValue;
-        IndexColorModel colorModel = new IndexColorModel(8, mapSize, cmap, 0, true,
-                transparentPixel, DataBuffer.TYPE_BYTE);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createOneBitColorMappedImageSpec(int sampleImageWidth,
-            int sampleImageHeight, byte noDataValue) {
-
-        assert noDataValue == 2;
-
-        final int FALSE = ColorUtilities.getIntFromColor(255, 255, 255, 255);
-        final int TRUE = ColorUtilities.getIntFromColor(255, 0, 0, 255);
-        final int NODATA = ColorUtilities.getIntFromColor(0, 255, 0, 255);
-
-        final int mapSize = 3;
-        int[] cmap = new int[mapSize];
-        cmap[0] = FALSE;
-        cmap[1] = TRUE;
-        cmap[2] = NODATA;
-
-        int transparentPixel = noDataValue;
-        IndexColorModel colorModel = new IndexColorModel(8, mapSize, cmap, 0, false,
-                transparentPixel, DataBuffer.TYPE_BYTE);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createRGBAImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType) {
-
-        final ImageTypeSpecifier its;
-
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        boolean hasAlpha = true;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.TRANSLUCENT;
-        int transferType = dataType;
-
-        int[] nBits = { 8, 8, 8, 8 };
-        ColorModel colorModel = new ComponentColorModelJAI(colorSpace, nBits, hasAlpha,
-                isAlphaPremultiplied, transparency, transferType);
-
-        /*
-         * Do not use colorModel.createCompatibleSampleModel cause it creates a
-         * PixelInterleavedSampleModel and we need a BandedSampleModel so it matches how the data
-         * comes out of ArcSDE
-         */
-        SampleModel sampleModel = new BandedSampleModel(dataType, sampleImageWidth,
-                sampleImageHeight, 4);
-
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createRGBImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType) {
-
-        final ImageTypeSpecifier its;
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        boolean hasAlpha = false;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.OPAQUE;
-        int transferType = dataType;
-        ColorModel colorModel = new ComponentColorModel(colorSpace, new int[] { 8, 8, 8 },
-                hasAlpha, isAlphaPremultiplied, transparency, transferType);
-
-        SampleModel sampleModel = new BandedSampleModel(dataType, sampleImageWidth,
-                sampleImageHeight, 3);
-
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createGrayscaleImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType, int bitsPerPixel) {
-        final ImageTypeSpecifier its;
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
-        boolean hasAlpha = false;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.OPAQUE;
-        int transferType = dataType;
-        int[] nbits = { bitsPerPixel };
-        ColorModel colorModel = new ComponentColorModelJAI(colorSpace, nbits, hasAlpha,
-                isAlphaPremultiplied, transparency, transferType);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createOneBitImageSpec(final RasterDatasetInfo rasterInfo,
-            final int numberOfBands, int sampleImageWidth, int sampleImageHeight,
-            final int bitsPerSample, final int dataType) {
-        final ColorModel colorModel;
-        final SampleModel sampleModel;
-        if (numberOfBands != 1) {
-            throw new IllegalArgumentException(bitsPerSample
-                    + "-Bit rasters are only supported for one band");
-        }
-        int[] argb = new int[(int) Math.pow(2, bitsPerSample)];
-        ColorUtilities.expand(new Color[] { Color.WHITE, Color.BLACK }, argb, 0, argb.length);
-        GridSampleDimension gridSampleDimension = rasterInfo.getGridSampleDimensions()[0];
-        colorModel = gridSampleDimension.getColorModel(0, numberOfBands, dataType);
-        sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth, sampleImageHeight);
-
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createColorMappedImageSpec(final IndexColorModel colorModel,
-            int sampleImageWidth, int sampleImageHeight) {
-
-        final SampleModel sampleModel;
-        final ImageTypeSpecifier its;
-        LOGGER.fine("Found single-band colormapped raster, using its index color model");
-        sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth, sampleImageHeight);
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-
-    }
-
-    public static ArcSDEGridCoverage2DReaderJAI.ReadParameters parseReadParams(
-            final GeneralEnvelope coverageEnvelope, final GeneralParameterValue[] params)
-            throws IllegalArgumentException {
-        if (params == null) {
-            throw new IllegalArgumentException("No GeneralParameterValue given to read operation");
-        }
-
-        GeneralEnvelope reqEnvelope = null;
-        Rectangle dim = null;
-        OverviewPolicy overviewPolicy = null;
-
-        // /////////////////////////////////////////////////////////////////////
-        //
-        // Checking params
-        //
-        // /////////////////////////////////////////////////////////////////////
-        for (int i = 0; i < params.length; i++) {
-            final ParameterValue<?> param = (ParameterValue<?>) params[i];
-            final String name = param.getDescriptor().getName().getCode();
-            if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString())) {
-                final GridGeometry2D gg = (GridGeometry2D) param.getValue();
-                reqEnvelope = new GeneralEnvelope((Envelope) gg.getEnvelope2D());
-
-                CoordinateReferenceSystem nativeCrs = coverageEnvelope
-                        .getCoordinateReferenceSystem();
-                CoordinateReferenceSystem requestCrs = reqEnvelope.getCoordinateReferenceSystem();
-                if (!CRS.equalsIgnoreMetadata(nativeCrs, requestCrs)) {
-                    LOGGER.info("Request CRS and native CRS differ, "
-                            + "reprojecting request envelope to native CRS");
-                    ReferencedEnvelope nativeCrsEnv;
-                    nativeCrsEnv = toNativeCrs(reqEnvelope, nativeCrs);
-                    reqEnvelope = new GeneralEnvelope(nativeCrsEnv);
-                }
-
-                dim = gg.getGridRange2D().getBounds();
-                continue;
-            }
-            if (name.equals(AbstractGridFormat.OVERVIEW_POLICY.getName().toString())) {
-                overviewPolicy = (OverviewPolicy) param.getValue();
-                continue;
-            }
-        }
-
-        if (dim == null && reqEnvelope == null) {
-            throw new ParameterNotFoundException("Parameter is mandatory and shall provide "
-                    + "the extent and dimension to request", AbstractGridFormat.READ_GRIDGEOMETRY2D
-                    .getName().toString());
-        }
-
-        if (!reqEnvelope.intersects(coverageEnvelope, true)) {
-            throw new IllegalArgumentException(
-                    "The requested extend does not overlap the coverage extent: "
-                            + coverageEnvelope);
-        }
-
-        if (dim.width <= 0 || dim.height <= 0) {
-            throw new IllegalArgumentException("The requested coverage dimension can't be null: "
-                    + dim);
-        }
-
-        if (overviewPolicy == null) {
-            LOGGER.finer("No overview policy requested, defaulting to QUALITY");
-            overviewPolicy = OverviewPolicy.QUALITY;
-        }
-        LOGGER.fine("Overview policy is " + overviewPolicy);
-
-        LOGGER.info("Reading raster for " + dim.getWidth() + "x" + dim.getHeight()
-                + " requested dim and " + reqEnvelope.getMinimum(0) + ","
-                + reqEnvelope.getMaximum(0) + " - " + reqEnvelope.getMinimum(1)
-                + reqEnvelope.getMaximum(1) + " requested extent");
-
-        ArcSDEGridCoverage2DReaderJAI.ReadParameters parsedParams = new ArcSDEGridCoverage2DReaderJAI.ReadParameters();
-        parsedParams.requestedEnvelope = reqEnvelope;
-        parsedParams.dim = dim;
-        parsedParams.overviewPolicy = overviewPolicy;
-        return parsedParams;
-    }
-
-    /**
-     * Given a collection of {@link RasterQueryInfo} instances holding information about how a
-     * request fits for each individual raster composing a catalog, figure out where their resulting
-     * images fit into the overall mosaic that's gonna be the result of the request.
-     *
-     * @param rasterInfo
-     * @param resultEnvelope
-     * @param results
-     * @return
-     */
-    public static Rectangle setMosaicLocations(final RasterDatasetInfo rasterInfo,
-            final GeneralEnvelope resultEnvelope, final List<RasterQueryInfo> results) {
-        final Rectangle mosaicDimension;
-        final MathTransform modelToRaster;
-        final MathTransform rasterToModel;
-        {
-            /*
-             * Of all the rasters that match the requested envelope, chose the one with the lowest
-             * resolution as the base to compute the final mosaic layout, so we avoid JAI upsamples,
-             * which are buggy and produce repeated patterns over the x axis instead of just scaling
-             * up the image.
-             */
-            RasterQueryInfo dimensionChoice = findLowestResolution(results);
-            Long rasterId = dimensionChoice.getRasterId();
-            int pyramidLevel = dimensionChoice.getPyramidLevel();
-            int rasterIndex = rasterInfo.getRasterIndex(rasterId);
-            Rectangle levelRange = rasterInfo.getGridRange(rasterIndex, pyramidLevel);
-            GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(rasterIndex, pyramidLevel);
-            rasterToModel = createRasterToModel(levelRange, levelEnvelope);
-            try {
-                modelToRaster = rasterToModel.inverse();
-            } catch (NoninvertibleTransformException e) {
-                throw new RuntimeException(e);
-            }
-            mosaicDimension = getTargetGridRange(modelToRaster, resultEnvelope);
-        }
-
-        for (RasterQueryInfo rasterResultInfo : results) {
-            final GeneralEnvelope rasterResultEnvelope = rasterResultInfo.getResultEnvelope();
-
-            final Rectangle targetRasterGridRange;
-            targetRasterGridRange = getTargetGridRange(modelToRaster, rasterResultEnvelope);
-
-            rasterResultInfo.setMosaicLocation(targetRasterGridRange);
-        }
-
-        return mosaicDimension;
-    }
-
-    private static RasterQueryInfo findLowestResolution(List<RasterQueryInfo> results) {
-        double[] prev = { Double.MIN_VALUE, Double.MIN_VALUE };
-        RasterQueryInfo lowestResQuery = null;
-
-        double[] curr;
-        for (RasterQueryInfo query : results) {
-            curr = query.getResolution();
-            if (curr[0] > prev[0]) {
-                prev = curr;
-                lowestResQuery = query;
-            }
-        }
-        return lowestResQuery;
-    }
-
-    /**
-     * Find out the raster ids and their pyramid levels in the raster dataset for the rasters whose
-     * envelope overlaps the requested one
-     *
-     * @param rasterInfo
-     * @param requestedEnvelope
-     * @param requestedDim
-     * @param overviewPolicy
-     * @return
-     */
-    public static List<RasterQueryInfo> findMatchingRasters(final RasterDatasetInfo rasterInfo,
-            final GeneralEnvelope requestedEnvelope, final Rectangle requestedDim,
-            final OverviewPolicy overviewPolicy) {
-
-        final int numRasters = rasterInfo.getNumRasters();
-        List<RasterQueryInfo> matchingRasters = new ArrayList<RasterQueryInfo>(numRasters);
-
-        int optimalPyramidLevel;
-        GeneralEnvelope gridEnvelope;
-        for (int rasterN = 0; rasterN < numRasters; rasterN++) {
-            optimalPyramidLevel = rasterInfo.getOptimalPyramidLevel(rasterN, overviewPolicy,
-                    requestedEnvelope, requestedDim);
-            gridEnvelope = rasterInfo.getGridEnvelope(rasterN, optimalPyramidLevel);
-            final boolean edgesInclusive = true;
-            if (requestedEnvelope.intersects(gridEnvelope, edgesInclusive)) {
-                RasterQueryInfo match = new RasterQueryInfo();
-                match.setRequestedEnvelope(requestedEnvelope);
-                match.setRequestedDim(requestedDim);
-
-                match.setRasterId(rasterInfo.getRasterId(rasterN));
-                match.setRasterIndex(rasterN);
-                match.setPyramidLevel(optimalPyramidLevel);
-                match.setResolution(rasterInfo.getResolution(rasterN, optimalPyramidLevel));
-                matchingRasters.add(match);
-            }
-        }
-        return matchingRasters;
-    }
-
-    public static void fitRequestToRaster(final GeneralEnvelope requestedEnvelope,
-            final RasterDatasetInfo rasterInfo, final RasterQueryInfo query) {
-
-        final int rasterIndex = query.getRasterIndex();
-        final int pyramidLevel = query.getPyramidLevel();
-        final Rectangle rasterGridRange = rasterInfo.getGridRange(rasterIndex, pyramidLevel);
-        final GeneralEnvelope rasterEnvelope = rasterInfo
-                .getGridEnvelope(rasterIndex, pyramidLevel);
-
-        double delta = requestedEnvelope.getMinimum(0) - rasterEnvelope.getMinimum(0);
-        double resX = rasterInfo.getResolution(rasterIndex, pyramidLevel)[0];
-        int xMinPixel = (int) Math.floor(delta / resX);
-
-        delta = requestedEnvelope.getMaximum(0) - rasterEnvelope.getMinimum(0);
-        int xMaxPixel = (int) Math.ceil(delta / resX);
-
-        delta = rasterEnvelope.getMaximum(1) - requestedEnvelope.getMaximum(1);
-        double resY = rasterInfo.getResolution(rasterIndex, pyramidLevel)[1];
-        // Distance in pixels from the top of the whole pyramid image to the top
-        // of our AOI.
-        // If we're off the top, this number will be negative.
-        int yMinPixel = (int) Math.floor(delta / resY);
-
-        delta = rasterEnvelope.getMaximum(1) - requestedEnvelope.getMinimum(1);
-        int yMaxPixel = (int) Math.ceil(delta / resY);
-
-        xMinPixel = Math.max(xMinPixel, rasterGridRange.x);
-        yMinPixel = Math.max(yMinPixel, rasterGridRange.y);
-        xMaxPixel = Math.min(xMaxPixel, rasterGridRange.x + rasterGridRange.width);
-        yMaxPixel = Math.min(yMaxPixel, rasterGridRange.y + rasterGridRange.height);
-
-        final int widthPixel = xMaxPixel - xMinPixel;
-        final int heightPixel = yMaxPixel - yMinPixel;
-
-        final double xMinGeo = rasterEnvelope.getMinimum(0) + resX * xMinPixel;
-        final double yMinGeo = rasterEnvelope.getMaximum(1) - resY * (yMinPixel + heightPixel);
-        final double widthGeo = resX * widthPixel;
-        final double heightGeo = resY * heightPixel;
-
-        final Rectangle resultGridRange;
-        final GeneralEnvelope resultEnvelope;
-
-        resultEnvelope = new GeneralEnvelope(new double[] { xMinGeo, yMinGeo }, new double[] {
-                xMinGeo + widthGeo, yMinGeo + heightGeo });
-        resultEnvelope.setCoordinateReferenceSystem(rasterEnvelope.getCoordinateReferenceSystem());
-
-        resultGridRange = new Rectangle(xMinPixel, yMinPixel, widthPixel, heightPixel);
-
-        final Rectangle matchingTiles;
-        final Rectangle levelTileRange;
-        final Rectangle tiledImageGridRange;
-        {
-            final Dimension tileSize = rasterInfo.getTileDimension(rasterIndex);
-            final int numTilesWide = rasterInfo.getNumTilesWide(rasterIndex, pyramidLevel);
-            final int numTilesHigh = rasterInfo.getNumTilesHigh(rasterIndex, pyramidLevel);
-            final Point tileOffset = rasterInfo.getTileOffset(rasterIndex, pyramidLevel);
-            levelTileRange = new Rectangle(0, 0, numTilesWide, numTilesHigh);
-            matchingTiles = findMatchingTiles(tileSize, numTilesWide, numTilesHigh, resultGridRange);
-
-            int tiledImageMinX = (matchingTiles.x * tileSize.width);
-            int tiledImageMinY = (matchingTiles.y * tileSize.height);
-
-            int tiledWidth = (matchingTiles.width * tileSize.width);
-            int tiledHeight = (matchingTiles.height * tileSize.height);
-
-            tiledImageGridRange = new Rectangle(tiledImageMinX, tiledImageMinY, tiledWidth,
-                    tiledHeight);
-        }
-
-        /*
-         * What is the grid range inside the whole level grid range that fits into the matching
-         * tiles
-         */
-        Rectangle resultDimensionInsideTiledImage;
-        resultDimensionInsideTiledImage = getResultDimensionForTileRange(tiledImageGridRange,
-                resultGridRange);
-
-        query.setResultEnvelope(resultEnvelope);
-        query.setResultDimensionInsideTiledImage(resultDimensionInsideTiledImage);
-        query.setTiledImageSize(tiledImageGridRange);
-        query.setLevelTileRange(levelTileRange);
-        query.setMatchingTiles(matchingTiles);
-    }
-
-    /**
-     * Returns a color model based on {@code colorMap} that's guaranteed to have at least one
-     * transparent pixel whose index can be used as no-data value for colormapped rasters, even if
-     * the returned IndexColorModel needs to be of a higher sample depth (ie, 16 instead of 8 bit)
-     * to satisfy that.
-     *
-     * @param colorMap
-     *            the raster's native color map the returned one will be based on
-     * @return the same {@code colorMap} if it has a transparent pixel, another, possibly of a
-     *         higher depth one if not, containing all the colors from {@code colorMap} and a newly
-     *         allocated cell for the transparent pixel if necessary
-     */
-    public static IndexColorModel ensureNoDataPixelIsAvailable(final IndexColorModel colorMap) {
-        int transparentPixel = colorMap.getTransparentPixel();
-        if (transparentPixel > -1) {
-            return colorMap;
-        }
-
-        final int transferType = colorMap.getTransferType();
-        final int mapSize = colorMap.getMapSize();
-        final int maxSize = 65536;// true for either transfer type
-
-        if (mapSize == maxSize) {
-            LOGGER.fine("There's no room for a new transparent pixel, "
-                    + "returning the original colorMap as is");
-            return colorMap;
-        }
-
-        /*
-         * The original map size is lower than the maximum allowed by a UShort color map, so expand
-         * the colormap by one and make that new entry transparent
-         */
-        final int newMapSize = mapSize + 1;
-        final int[] argb = new int[newMapSize];
-        colorMap.getRGBs(argb);
-
-        // set the last entry as transparent
-        argb[newMapSize - 1] = ColorUtilities.getIntFromColor(0, 0, 0, 0);
-
-        IndexColorModel targetColorModel;
-        final int significantBits;
-        final int newTransferType;
-
-        {
-            if (DataBuffer.TYPE_BYTE == transferType && newMapSize <= 256) {
-                /*
-                 * REVISIT: check if this needs to be promoted depending on whether I decide to
-                 * treat 1 and 4 bit images as indexed with 1 and 4 significant bits respectively
-                 */
-                significantBits = colorMap.getPixelSize();
-                newTransferType = DataBuffer.TYPE_BYTE;
-            } else {
-                // it's either being promoted or was already 16-bit
-                significantBits = 16;
-                newTransferType = DataBuffer.TYPE_USHORT;
-            }
-        }
-
-        final int transparentPixelIndex = newMapSize - 1;
-        final boolean hasalpha = true;
-        final int startIndex = 0;
-
-        targetColorModel = new IndexColorModel(significantBits, newMapSize, argb, startIndex,
-                hasalpha, transparentPixelIndex, newTransferType);
-
-        return targetColorModel;
-    }
-
-    /**
-     * For a color-mapped raster, the no-data value is set to the
-     * {@link IndexColorModel#getTransparentPixel() transparent pixel}
-     *
-     * @param colorMap
-     * @return the index in the colorMap that's the transparent pixel as is to be used as no-data
-     *         value
-     */
-    public static Number determineNoDataValue(IndexColorModel colorMap) {
-        int noDataPixel = colorMap.getTransparentPixel();
-        if (-1 == noDataPixel) {
-            // there were no room for a transparent pixel, find out the closest match
-            noDataPixel = ColorUtilities.getTransparentPixel(colorMap);
-        }
-        return Integer.valueOf(noDataPixel);
-    }
-
-    /**
-     * @param numBands
-     *            number of bands in the raster dataset for the band whose nodata value is to be
-     *            determined. Might be useful to treat special cases where some assumptions are made
-     *            depending on the cell type and number of bands
-     * @param statsMin
-     *            the minimum sample value for the band as reported by the band's statistics, or
-     *            {@code NaN}
-     * @param statsMax
-     *            the maximum sample value for the band as reported by the band's statistics, or
-     *            {@code NaN}
-     * @param nativeCellType
-     *            the band's native cell type
-     * @return
-     */
-    public static Number determineNoDataValue(final int numBands, final double statsMin,
-            final double statsMax, final RasterCellType nativeCellType) {
-
-        final Number nodata;
-
-        if (nativeCellType == TYPE_32BIT_REAL) {
-            LOGGER.fine("no data value is Float.NaN");
-            return Float.valueOf(Float.NaN);
-        } else if (nativeCellType == TYPE_64BIT_REAL) {
-            LOGGER.fine("no data value is Double.NaN");
-            return Double.valueOf(Double.NaN);
-        } else if (nativeCellType == TYPE_1BIT) {
-            LOGGER.fine("1BIT images no-data value is set to 2,"
-                    + " regardless of the raster statistics");
-            return Double.valueOf(2);
-        } else if (nativeCellType == TYPE_4BIT) {
-            LOGGER.fine("4BIT images no-data value is set to 16,"
-                    + " regardless of the raster statistics");
-            return Double.valueOf(16);
-        } else if (!isGeoPhysics(numBands, nativeCellType)) {
-            LOGGER.fine("3 or 4 band, 8 bit unsigned image, assumed to be "
-                    + "RGB or RGBA respectively and nodata value hardcoded to 255");
-            return (Number) nativeCellType.getSampleValueRange().getMaxValue();
-        }
-
-        final NumberRange<?> sampleValueRange = nativeCellType.getSampleValueRange();
-
-        final double minimumSample = sampleValueRange.getMinimum(true);
-        final double maximumSample = sampleValueRange.getMaximum(true);
-
-        double lower;
-        double greater;
-        if (Double.isNaN(statsMin) || Double.isNaN(statsMax)) {
-            lower = Math.ceil(minimumSample - 1);
-            greater = Math.floor(maximumSample + 1);
-        } else {
-            lower = Math.ceil(statsMin - 1);
-            greater = Math.floor(statsMax + 1);
-        }
-
-        final boolean isUnsigned = minimumSample == 0;
-
-        if (sampleValueRange.contains((Number) Double.valueOf(lower))) {
-            // lower is ok
-            nodata = lower;
-        } else if (sampleValueRange.contains((Number) Double.valueOf(greater))) {
-            // upper is ok
-            nodata = greater;
-        } else if (isUnsigned) {
-            // need to set no-data to the higher value, floor is zero
-            nodata = greater;
-            // if (cellType == TYPE_1BIT || cellType == TYPE_4BIT) {
-            // nodata = greater;
-            // } else {
-            // // best guess without promoting. We don't actually want to promote a raster that is
-            // // non
-            // // colormapped and either has no statistics or it's range is full to preserve the
-            // // cases
-            // // were it may affect badly the visualization (for example, a 3 band 8bit raster
-            // // promoted to 3 band 16bit is gonna look almost black
-            // nodata = maximumSample;
-            // }
-        } else {
-            // no-data as the lower value is ok, floor is non zero (the celltype is signed)
-            nodata = lower;
-        }
-
-        return nodata;
-    }
-
-    public static boolean isGeoPhysics(final int numBands, final RasterCellType nativeCellType) {
-        boolean geophysics = true;
-        if (nativeCellType == TYPE_8BIT_U && (numBands == 3 || numBands == 4)) {
-            geophysics = false;
-        }
-        return geophysics;
-    }
-
-    public static RasterCellType determineTargetCellType(final RasterCellType nativeCellType,
-            final List<Number> noDataValues) {
-
-        if (TYPE_32BIT_REAL == nativeCellType || TYPE_64BIT_REAL == nativeCellType) {
-            // no data value is NaN, so no need to promote. For other types NaN is not available
-            for (Number nodata : noDataValues) {
-                if (!Double.isNaN(nodata.doubleValue())) {
-                    throw new IllegalArgumentException("no data values for float and "
-                            + "double cell types shall be NaN: " + nodata);
-                }
-            }
-            return nativeCellType;
-        }
-
-        // find a cell type that's deep enough for all the bands in the given raster
-        double noDataMin = Double.POSITIVE_INFINITY, noDataMax = Double.NEGATIVE_INFINITY;
-        {
-            for (Number noData : noDataValues) {
-                noDataMin = Math.min(noDataMin, noData.doubleValue());
-                noDataMax = Math.max(noDataMax, noData.doubleValue());
-            }
-        }
-        final NumberRange<Double> sampleValueRange;
-        sampleValueRange = nativeCellType.getSampleValueRange().castTo(Double.class);
-
-        final RasterCellType targetCellType;
-
-        if (sampleValueRange.contains((Number) Double.valueOf(noDataMin))
-                && sampleValueRange.contains((Number) Double.valueOf(noDataMax))) {
-            /*
-             * The native cell type can hold the no-data values for all bands in the raster
-             */
-            targetCellType = nativeCellType;
-        } else {
-            targetCellType = promote(nativeCellType);
-        }
-        return targetCellType;
-    }
-
-    private static RasterCellType promote(final RasterCellType nativeCellType) {
-        switch (nativeCellType) {
-        case TYPE_1BIT:
-        case TYPE_4BIT:
-            return TYPE_8BIT_U;
-        case TYPE_8BIT_U:
-            return TYPE_16BIT_U;
-        case TYPE_8BIT_S:
-            return TYPE_16BIT_S;
-        case TYPE_16BIT_U:
-            return TYPE_32BIT_U;
-        case TYPE_16BIT_S:
-            return TYPE_32BIT_S;
-        case TYPE_32BIT_S:
-        case TYPE_32BIT_REAL:
-        case TYPE_32BIT_U:
-            return TYPE_64BIT_REAL;
-        default:
-            throw new IllegalArgumentException(
-                    "Can't promote a raster of type 64-bit-real, there's "
-                            + "no higher pixel depth than that!");
-        }
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,120 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.io.IOException;
-
-/**
- * Offers an iterator like interface to read ArcSDE raster tiles into a {@code byte[]}
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL$
- */
-interface TileReader {
-
-    public class TileInfo {
-        private Long bandId;
-
-        private byte[] bitmaskData;
-
-        private int numPixelsRead;
-
-        public TileInfo(Long bandId, byte[] bitMaskData, int numPixelsRead) {
-            this.bandId = bandId;
-            this.bitmaskData = bitMaskData;
-            this.numPixelsRead = numPixelsRead;
-        }
-
-        public Long getBandId() {
-            return bandId;
-        }
-
-        public byte[] getBitmaskData() {
-            return bitmaskData;
-        }
-
-        public int getNumPixelsRead() {
-            return numPixelsRead;
-        }
-    }
-
-    /**
-     * @return number of bits per sample
-     */
-    public abstract int getBitsPerSample();
-
-    /**
-     * @return number of samples per tile
-     */
-    public abstract int getPixelsPerTile();
-
-    /**
-     * @return numbre of bands being fetched
-     */
-    public abstract int getNumberOfBands();
-
-    /**
-     * @return number of pixels per tile over the X axis
-     */
-    public abstract int getTileWidth();
-
-    /**
-     * @return number of pixels per tile over the Y axis
-     */
-    public abstract int getTileHeight();
-
-    /**
-     * @return number of tiles being fetched over the X axis
-     */
-    public abstract int getTilesWide();
-
-    /**
-     * @return number of tiles being fetched over the Y axis
-     */
-    public abstract int getTilesHigh();
-
-    /**
-     * @return number of bytes in the raw pixel content of a tile, not taking into account any
-     *         trailing bitmask data.
-     */
-    public abstract int getBytesPerTile();
-
-    /**
-     * @return whether there are more tiles to fetch
-     * @throws IOException
-     */
-    public abstract boolean hasNext() throws IOException;
-
-    /**
-     * Fetches a tile and fills {@code tileData} with its raw pixel data packaged as bytes according
-     * to the number of bits per sample
-     *
-     * @param tileData
-     *            a possibly {@code null} array where to store the next tile data. If {@code null} a
-     *            new byte[] of length {@link #getBytesPerTile()} will be allocated and filled up
-     *            with the raw tile pixel data.
-     * @return the bitmask data, or an empty array if the tile is full
-     * @throws IOException
-     * @throws {@link IllegalArgumentException} if tileData is not null and its size is less than
-     *         {@link #getBytesPerTile()}
-     */
-    public abstract TileInfo next(byte[] tileData) throws IOException;
-
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReaderFactory.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReaderFactory.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TileReaderFactory.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,54 +0,0 @@
-package org.geotools.arcsde.gce;
-
-import java.awt.Dimension;
-import java.awt.Rectangle;
-
-import com.esri.sde.sdk.client.SeRow;
-
-public class TileReaderFactory {
-
-    /**
-     *
-     * @param row
-     * @param nativeType
-     * @param targetType
-     * @param noDataValues
-     * @param numberOfBands
-     * @param requestedTiles
-     * @param tileSize
-     * @return
-     */
-    public static TileReader getInstance(final SeRow row, final RasterDatasetInfo rasterInfo,
-            final int rasterIndex, final Rectangle requestedTiles, Dimension tileSize) {
-
-        final TileReader tileReader;
-
-        final RasterCellType nativeType = rasterInfo.getNativeCellType();
-        final RasterCellType targetType = rasterInfo.getTargetCellType(rasterIndex);
-        final int numberOfBands = rasterInfo.getNumBands();
-
-        final BitmaskToNoDataConverter noData;
-        noData = BitmaskToNoDataConverter.getInstance(rasterInfo, rasterIndex);
-
-        final int nativeBitsPerPixel = nativeType.getBitsPerSample();
-
-        if (targetType == nativeType) {
-
-            TileReader nativeTileReader = new NativeTileReader(row, nativeBitsPerPixel,
-                    numberOfBands, requestedTiles, tileSize, noData);
-
-            tileReader = nativeTileReader;
-
-        } else {
-            // need to promote native to target sample depth
-            TileReader nativeTileReader;
-            nativeTileReader = new NativeTileReader(row, nativeBitsPerPixel, numberOfBands,
-                    requestedTiles, tileSize, BitmaskToNoDataConverter.NO_ACTION_CONVERTER);
-
-            TileReader promotingTileReader = new PromotingTileReader(nativeTileReader, nativeType,
-                    targetType, noData);
-            tileReader = promotingTileReader;
-        }
-        return tileReader;
-    }
-}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TiledRasterReader.java
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TiledRasterReader.java 2009-11-09 18:47:38 UTC (rev 34353)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/gce/TiledRasterReader.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,94 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.gce;
-
-import java.awt.Rectangle;
-import java.awt.image.RenderedImage;
-import java.io.IOException;
-
-import com.esri.sde.sdk.client.SeRasterAttr;
-
-/**
- * An Iterator like interface to read ArcSDE rasters for a given ArcSDE raster dataset (whether it
- * is a single raster or a raster catalog).
- * <p>
- * Sample usage: <code>
- * <pre>
- * RasterReaderFactory readerFactory = ....
- * RasterDatasetInfo raserInfo = ...
- * ArcSDERasterReader reader = readerFactory.create(rasterInfo);
- * try{
- *      Long nextRasterId;
- *      while((nextRasterId = reader.nextRaster()) != null){
- *          if(amIInterestedInThisRaster(nextRasterId)){
- *              int pyramidLevel = ...
- *              Rectangle tileRange = ...
- *              RenderedImage raster = reader.read(pyramidLevel, tileRange);
- *          }
- *      }
- * }finally{
- *      reader.dispose();
- * }
- * </pre>
- * </code>
- * </p>
- * <p>
- * So one has to call {@code nextRaster()} to get the id of the raster immediately available to be
- * read through {@link #read()}. This is so because there might be more than one raster on a raster
- * dataset and the order they are fetched from the ArcSDE server is non deterministic, and once you
- * opened a stream to a raster you can't open another one and then read the former.
- * </p>
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.7
- */
-interface TiledRasterReader {
-
-    /**
-     * Disposes any resource being held by this reader, whether it's a connection to the ArcSDE
-     * server, opened streams, etc.
-     */
-    void dispose();
-
-    /**
-     * Advances to the next available raster in the raster dataset this reader works upon and
-     * returns it's {@link SeRasterAttr#getRasterId() raster id}.
-     *
-     * @return the ID for the raster ready to be read from the queried raster column in the raster
-     *         dataset, or {@code null} if there are no more rasters to be read.
-     * @throws IOException
-     *             for any problem occurred retrieving the next {@link SeRasterAttr} in the request
-     */
-    Long nextRaster() throws IOException;
-
-    /**
-     * Reads the image subset determined by the given pyramid level and tile range for the currently
-     * available raster attribute in the requested raster column for the given raster dataset.
-     *
-     * @param pyramidLevel
-     *            the pyramid level to read
-     * @param tileRange
-     *            the range of tiles to read at the given pyramid level. The boundaries of the tile
-     *            range are inclusive and starts at {@code 0,0} for the upper left most tile.
-     * @return the rendered image determined by the requested pyramid level and tile range
-     * @throws IOException
-     *             for any exception occurred while reading the image
-     */
-    RenderedImage read(final int pyramidLevel, final Rectangle tileRange) throws IOException;
-
-}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,809 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.gce;
-
-import java.awt.Rectangle;
-import java.awt.RenderingHints;
-import java.awt.image.BufferedImage;
-import java.awt.image.ColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.Raster;
-import java.awt.image.RenderedImage;
-import java.awt.image.SampleModel;
-import java.awt.image.WritableRaster;
-import java.awt.image.renderable.ParameterBlock;
-import java.io.File;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageIO;
-import javax.imageio.ImageTypeSpecifier;
-import javax.media.jai.ImageLayout;
-import javax.media.jai.InterpolationNearest;
-import javax.media.jai.JAI;
-import javax.media.jai.ParameterBlockJAI;
-import javax.media.jai.operator.FormatDescriptor;
-import javax.media.jai.operator.MosaicDescriptor;
-
-import org.geotools.arcsde.raster.info.RasterDatasetInfo;
-import org.geotools.arcsde.raster.info.RasterQueryInfo;
-import org.geotools.arcsde.raster.info.RasterUtils;
-import org.geotools.arcsde.raster.io.RasterReaderFactory;
-import org.geotools.arcsde.raster.io.TiledRasterReader;
-import org.geotools.coverage.CoverageFactoryFinder;
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.TypeMap;
-//import org.geotools.coverage.grid.GeneralGridRange;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.GridCoverage2D;
-import org.geotools.coverage.grid.GridEnvelope2D;
-import org.geotools.coverage.grid.GridGeometry2D;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.coverage.grid.io.AbstractGridFormat;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.data.DefaultServiceInfo;
-import org.geotools.data.ServiceInfo;
-import org.geotools.factory.Hints;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.util.logging.Logging;
-import org.opengis.coverage.ColorInterpretation;
-import org.opengis.coverage.grid.Format;
-import org.opengis.coverage.grid.GridCoverageReader;
-import org.opengis.geometry.Envelope;
-import org.opengis.parameter.GeneralParameterValue;
-import org.opengis.parameter.ParameterNotFoundException;
-import org.opengis.parameter.ParameterValue;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.operation.TransformException;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java $
- */
-@SuppressWarnings( { "deprecation", "nls" })
-public final class ArcSDEGridCoverage2DReaderJAI extends AbstractGridCoverage2DReader {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    /**
-     * @see LoggingHelper#log(RenderedImage, Long, String)
-     */
-    private static final boolean DEBUG_TO_DISK = Boolean
-            .getBoolean("org.geotools.arcsde.gce.debug");
-
-    private final ArcSDERasterFormat parent;
-
-    private final RasterDatasetInfo rasterInfo;
-
-    private DefaultServiceInfo serviceInfo;
-
-    private RasterReaderFactory rasterReaderFactory;
-
-    public ArcSDEGridCoverage2DReaderJAI(final ArcSDERasterFormat parent,
-            final RasterReaderFactory rasterReaderFactory, final RasterDatasetInfo rasterInfo,
-            final Hints hints) throws IOException {
-        // check it's a supported format
-        {
-            final int bitsPerSample = rasterInfo.getBand(0, 0).getCellType().getBitsPerSample();
-            if (rasterInfo.getNumBands() > 1 && (bitsPerSample == 1 || bitsPerSample == 4)) {
-                throw new IllegalArgumentException(bitsPerSample
-                        + "-bit rasters with more than one band are not supported");
-            }
-        }
-        this.parent = parent;
-        this.rasterReaderFactory = rasterReaderFactory;
-        this.rasterInfo = rasterInfo;
-
-        super.hints = hints;
-        super.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
-        super.crs = rasterInfo.getCoverageCrs();
-        super.originalEnvelope = rasterInfo.getOriginalEnvelope();
-
-        GeneralGridEnvelope gridRange = rasterInfo.getOriginalGridRange();
-        //super.originalGridRange = new GeneralGridRange(gridRange.toRectangle());
-        super.originalGridRange = new GridEnvelope2D(gridRange.toRectangle());
-
-        super.coverageName = rasterInfo.getRasterTable();
-        final int numLevels = rasterInfo.getNumPyramidLevels(0);
-
-        // level 0 is not an overview, but the raster itself
-        super.numOverviews = numLevels - 1;
-
-        // ///
-        //
-        // setting the higher resolution avalaible for this coverage
-        //
-        // ///
-        highestRes = super.getResolution(originalEnvelope, (Rectangle) originalGridRange, crs);
-        // //
-        //
-        // get information for the successive images
-        //
-        // //
-        // REVISIT may the different rasters in the raster dataset have different pyramid levels? I
-        // guess so
-        if (numOverviews > 0) {
-            overViewResolutions = new double[numOverviews][2];
-            for (int pyramidLevel = 1; pyramidLevel <= numOverviews; pyramidLevel++) {
-                Rectangle levelGridRange = rasterInfo.getGridRange(0, pyramidLevel);
-                GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(0, pyramidLevel);
-                overViewResolutions[pyramidLevel - 1] = super.getResolution(levelEnvelope,
-                        levelGridRange, crs);
-            }
-        } else {
-            overViewResolutions = null;
-        }
-    }
-
-    /**
-     * @see GridCoverageReader#getFormat()
-     */
-    public Format getFormat() {
-        return parent;
-    }
-
-    @Override
-    public ServiceInfo getInfo() {
-        if (serviceInfo == null) {
-            serviceInfo = new DefaultServiceInfo();
-            serviceInfo.setTitle(rasterInfo.getRasterTable());
-            serviceInfo.setDescription(rasterInfo.toString());
-            Set<String> keywords = new HashSet<String>();
-            keywords.add("ArcSDE");
-            serviceInfo.setKeywords(keywords);
-        }
-        return serviceInfo;
-    }
-
-    /**
-     * @see GridCoverageReader#read(GeneralParameterValue[])
-     */
-    public GridCoverage2D read(GeneralParameterValue[] params) throws IOException {
-
-        final GeneralEnvelope requestedEnvelope;
-        final Rectangle requestedDim;
-        final OverviewPolicy overviewPolicy;
-        {
-            final ReadParameters opParams = parseReadParams(getOriginalEnvelope(), params);
-            overviewPolicy = opParams.overviewPolicy;
-            requestedEnvelope = opParams.requestedEnvelope;
-            requestedDim = opParams.dim;
-        }
-
-        /*
-         * For each raster in the raster dataset, obtain the tiles, pixel range, and resulting
-         * envelope
-         */
-        final List<RasterQueryInfo> queries;
-        queries = findMatchingRasters(requestedEnvelope, requestedDim, overviewPolicy);
-        if (queries.isEmpty()) {
-            /*
-             * none of the rasters match the requested envelope. This may happen by the tiled nature
-             * of the raster dataset
-             */
-            return createFakeCoverage(requestedEnvelope, requestedDim);
-        }
-
-        final GeneralEnvelope resultEnvelope = getResultEnvelope(queries);
-
-        final LoggingHelper log = new LoggingHelper();
-        log.appendLoggingGeometries(LoggingHelper.REQ_ENV, requestedEnvelope);
-        log.appendLoggingGeometries(LoggingHelper.RES_ENV, resultEnvelope);
-
-        /*
-         * Once we collected the matching rasters and their image subsets, find out where in the
-         * overall resulting mosaic they fit. If the rasters does not share the spatial resolution,
-         * the QueryInfo.resultDimension and QueryInfo.mosaicLocation width or height won't match
-         */
-        final Rectangle mosaicGeometry;
-        mosaicGeometry = RasterUtils.setMosaicLocations(rasterInfo, resultEnvelope, queries);
-
-        if (mosaicGeometry.width == 0 || mosaicGeometry.height == 0) {
-            LOGGER.finer("Mosaic geometry width or height is zero,"
-                    + " returning fake coverage for pixels " + mosaicGeometry);
-            return createFakeCoverage(requestedEnvelope, requestedDim);
-        }
-        /*
-         * Gather the rendered images for each of the rasters that match the requested envelope
-         */
-        final TiledRasterReader rasterReader = rasterReaderFactory.create(rasterInfo);
-
-        try {
-            readAllTiledRasters(queries, rasterReader, log);
-        } finally {
-            // rasterReader.dispose();
-        }
-
-        log.log(LoggingHelper.REQ_ENV);
-        log.log(LoggingHelper.RES_ENV);
-        log.log(LoggingHelper.MOSAIC_ENV);
-        log.log(LoggingHelper.MOSAIC_EXPECTED);
-
-        final RenderedImage coverageRaster = createMosaic(queries, mosaicGeometry, log);
-        assert mosaicGeometry.getWidth() == coverageRaster.getWidth();
-        assert mosaicGeometry.getHeight() == coverageRaster.getHeight();
-
-        /*
-         * BUILDING COVERAGE
-         */
-        GridSampleDimension[] bands = getSampleDimensions(coverageRaster);
-
-        GridCoverage2D resultCoverage = coverageFactory.create(coverageName, coverageRaster,
-                resultEnvelope, bands, null, null);
-
-        return resultCoverage;
-    }
-
-    private GridSampleDimension[] getSampleDimensions(final RenderedImage coverageRaster)
-            throws IOException {
-
-        GridSampleDimension[] bands = rasterInfo.getGridSampleDimensions();
-
-        // may the image have been promoted? build the correct band info then
-        final int imageBands = coverageRaster.getSampleModel().getNumBands();
-        if (bands.length == 1 && imageBands > 1) {
-            LOGGER.fine(coverageName + " was promoted from 1 to "
-                    + coverageRaster.getSampleModel().getNumBands()
-                    + " bands, returning an appropriate set of GridSampleDimension");
-            // stolen from super.createCoverage:
-            final ColorModel cm = coverageRaster.getColorModel();
-            bands = new GridSampleDimension[imageBands];
-
-            // setting bands names.
-            for (int i = 0; i < imageBands; i++) {
-                final ColorInterpretation colorInterpretation;
-                colorInterpretation = TypeMap.getColorInterpretation(cm, i);
-                if (colorInterpretation == null) {
-                    throw new IOException("Unrecognized sample dimension type");
-                }
-                bands[i] = new GridSampleDimension(colorInterpretation.name()).geophysics(true);
-            }
-        }
-
-        return bands;
-    }
-
-    private void readAllTiledRasters(final List<RasterQueryInfo> queries,
-            final TiledRasterReader rasterReader, final LoggingHelper log) throws IOException {
-
-        for (RasterQueryInfo queryInfo : queries) {
-
-            final Long rasterId = queryInfo.getRasterId();
-
-            final RenderedImage rasterImage;
-
-            try {
-                final int pyramidLevel = queryInfo.getPyramidLevel();
-                final Rectangle matchingTiles = queryInfo.getMatchingTiles();
-                // final Point imageLocation = queryInfo.getTiledImageSize().getLocation();
-                rasterImage = rasterReader.read(rasterId, pyramidLevel, matchingTiles);
-            } catch (IOException e) {
-                LOGGER.log(Level.SEVERE, "Fetching data for " + queryInfo.toString(), e);
-                throw e;
-            }
-
-            queryInfo.setResultImage(rasterImage);
-
-            {
-                LOGGER.finer(queryInfo.toString());
-                log.appendLoggingGeometries(LoggingHelper.MOSAIC_EXPECTED, queryInfo
-                        .getMosaicLocation());
-                log
-                        .appendLoggingGeometries(LoggingHelper.MOSAIC_ENV, queryInfo
-                                .getResultEnvelope());
-
-                final Rectangle tiledImageSize = queryInfo.getTiledImageSize();
-                int width = rasterImage.getWidth();
-                int height = rasterImage.getHeight();
-                if (tiledImageSize.width != width || tiledImageSize.height != height) {
-                    throw new IllegalStateException(
-                            "Read image is not of the expected size. Image=" + width + "x" + height
-                                    + ", expected: " + tiledImageSize.width + "x"
-                                    + tiledImageSize.height);
-                }
-                // if (tiledImageSize.x != rasterImage.getMinX()
-                // || tiledImageSize.y != rasterImage.getMinY()) {
-                // throw new IllegalStateException("Read image is not at the expected location "
-                // + tiledImageSize.x + "," + tiledImageSize.y + ": "
-                // + rasterImage.getMinX() + "," + rasterImage.getMinY());
-                // }
-            }
-        }
-    }
-
-    /**
-     * Called when the requested envelope do overlap the coverage envelope but none of the rasters
-     * in the dataset do
-     *
-     * @param requestedEnvelope
-     * @param requestedDim
-     * @return
-     */
-    private GridCoverage2D createFakeCoverage(GeneralEnvelope requestedEnvelope,
-            Rectangle requestedDim) {
-
-        ImageTypeSpecifier its = rasterInfo.getRenderedImageSpec(0);
-        SampleModel sampleModel = its.getSampleModel(requestedDim.width, requestedDim.height);
-        ColorModel colorModel = its.getColorModel();
-
-        WritableRaster raster = Raster.createWritableRaster(sampleModel, null);
-        BufferedImage image = new BufferedImage(colorModel, raster, false, null);
-        return coverageFactory.create(coverageName, image, requestedEnvelope);
-    }
-
-    private List<RasterQueryInfo> findMatchingRasters(final GeneralEnvelope requestedEnvelope,
-            final Rectangle requestedDim, final OverviewPolicy overviewPolicy) {
-
-        final List<RasterQueryInfo> matchingQueries;
-        matchingQueries = RasterUtils.findMatchingRasters(rasterInfo, requestedEnvelope,
-                requestedDim, overviewPolicy);
-
-        if (matchingQueries.isEmpty()) {
-            return matchingQueries;
-        }
-
-        for (RasterQueryInfo match : matchingQueries) {
-            RasterUtils.fitRequestToRaster(requestedEnvelope, rasterInfo, match);
-        }
-        return matchingQueries;
-    }
-
-    private GeneralEnvelope getResultEnvelope(final List<RasterQueryInfo> queryInfos) {
-
-        GeneralEnvelope finalEnvelope = null;
-
-        for (RasterQueryInfo rasterQueryInfo : queryInfos) {
-            // gather resulting envelope
-            if (finalEnvelope == null) {
-                finalEnvelope = new GeneralEnvelope(rasterQueryInfo.getResultEnvelope());
-            } else {
-                finalEnvelope.add(rasterQueryInfo.getResultEnvelope());
-            }
-        }
-        if (finalEnvelope == null) {
-            throw new IllegalStateException("Restult envelope is null, this shouldn't happen!! "
-                    + "we checked the request overlaps the coverage envelope before!");
-        }
-        return finalEnvelope;
-    }
-
-    /**
-     * For each raster: crop->scale->translate->add to mosaic
-     *
-     * @param queries
-     * @param mosaicGeometry
-     * @return
-     * @throws IOException
-     */
-    private RenderedImage createMosaic(final List<RasterQueryInfo> queries,
-            final Rectangle mosaicGeometry, final LoggingHelper log) throws IOException {
-
-        List<RenderedImage> transformed = new ArrayList<RenderedImage>(queries.size());
-
-        /*
-         * Do we need to expand to RGB color space and then create a new colormapped image with the
-         * whole mosaic?
-         */
-        boolean expandThenContractCM = queries.size() > 1 && rasterInfo.isColorMapped();
-        if (expandThenContractCM) {
-            LOGGER.info("Creating mosaic out of " + queries.size()
-                    + " colormapped rasters. The mosaic tiles will be expanded to "
-                    + "\nRGB space and the resulting mosaic reduced to a new IndexColorModel");
-        }
-
-        for (RasterQueryInfo query : queries) {
-            RenderedImage image = query.getResultImage();
-            log.log(image, query.getRasterId(), "01_original");
-
-            image = cropToRequiredDimension(image, query.getTiledImageSize(), query
-                    .getResultDimensionInsideTiledImage());
-            log.log(image, query.getRasterId(), "02_crop");
-
-            final Rectangle mosaicLocation = query.getMosaicLocation();
-            // scale
-            Float scaleX = Float.valueOf((float) (mosaicLocation.getWidth() / image.getWidth()));
-            Float scaleY = Float.valueOf((float) (mosaicLocation.getHeight() / image.getHeight()));
-            Float translateX = Float.valueOf(0);
-            Float translateY = Float.valueOf(0);
-            // image.getData();
-            if (!(Float.valueOf(1.0F).equals(scaleX) && Float.valueOf(1.0F).equals(scaleY))) {
-                ParameterBlock pb = new ParameterBlock();
-                pb.addSource(image);
-                pb.add(scaleX);
-                pb.add(scaleY);
-                pb.add(translateX);
-                pb.add(translateY);
-                pb.add(new InterpolationNearest());
-
-                image = JAI.create("scale", pb);
-                log.log(image, query.getRasterId(), "03_scale");
-
-                int width = image.getWidth();
-                int height = image.getHeight();
-
-                assert mosaicLocation.width == width;
-                assert mosaicLocation.height == height;
-            }
-            if (image.getMinX() != mosaicLocation.x || image.getMinY() != mosaicLocation.y) {
-                // translate
-                ParameterBlock pb = new ParameterBlock();
-                pb.addSource(image);
-                pb.add(Float.valueOf(mosaicLocation.x - image.getMinX()));
-                pb.add(Float.valueOf(mosaicLocation.y - image.getMinY()));
-                pb.add(null);
-
-                image = JAI.create("translate", pb);
-                log.log(image, query.getRasterId(), "04_translate");
-
-                assert image.getMinX() == mosaicLocation.x : image.getMinX() + " != "
-                        + mosaicLocation.x;
-                assert image.getMinY() == mosaicLocation.y : image.getMinY() + " != "
-                        + mosaicLocation.y;
-                assert image.getWidth() == mosaicLocation.width : image.getWidth() + " != "
-                        + mosaicLocation.width;
-                assert image.getHeight() == mosaicLocation.height : image.getHeight() + " != "
-                        + mosaicLocation.height;
-            }
-            if (expandThenContractCM) {
-                if (LOGGER.isLoggable(Level.FINER)) {
-                    LOGGER.finer("Creating color expanded version of tile for raster #"
-                            + query.getRasterId());
-                }
-
-                /*
-                 * reformat the image as a 4 band rgba backed by byte data
-                 */
-                image = FormatDescriptor.create(image, Integer.valueOf(DataBuffer.TYPE_BYTE), null);
-
-                log.log(image, query.getRasterId(), "04_1_colorExpanded");
-            }
-
-            transformed.add(image);
-        }
-
-        final RenderedImage mosaic;
-        if (queries.size() == 1) {
-            /*
-             * This is besides a very slight perf improvement needed because the JAI mosaic
-             * operation truncates floating point raster values to 0 and 1. REVISIT: If there's no
-             * workaround for that we should prevent raster catalogs made of floating point rasters
-             * and throw an exception as we could not really support that.
-             */
-            mosaic = transformed.get(0);
-        } else {
-            /*
-             * adapted from RasterLayerResponse.java in the imagemosaic module
-             */
-            ParameterBlockJAI mosaicParams = new ParameterBlockJAI("Mosaic");
-
-            // TODO: set background values to raster's no-data
-            // mosaicParams.setParameter("backgroundValues",backgroundValues);
-
-            mosaicParams.setParameter("mosaicType", MosaicDescriptor.MOSAIC_TYPE_OVERLAY);
-
-            final ImageLayout layout = new ImageLayout(mosaicGeometry.x, mosaicGeometry.y,
-                    mosaicGeometry.width, mosaicGeometry.height);
-            layout.setTileWidth(mosaicGeometry.width);
-            layout.setTileHeight(mosaicGeometry.height);
-            final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
-            // hints.put(JAI.KEY_SERIALIZE_DEEP_COPY, Boolean.TRUE);
-
-            for (RenderedImage img : transformed) {
-                mosaicParams.addSource(img);
-                log.appendLoggingGeometries(LoggingHelper.MOSAIC_RESULT, img);
-            }
-            log.log(LoggingHelper.MOSAIC_RESULT);
-
-            LOGGER.fine("Creating mosaic out of " + queries.size() + " raster tiles");
-            mosaic = JAI.create("Mosaic", mosaicParams, hints);
-
-            log.log(mosaic, 0L, "05_mosaic_result");
-        }
-        return mosaic;
-    }
-
-    /**
-     * Crops the image representing a full tile set to the required dimension and returns it, but
-     * keeps minx and miny being zero.
-     *
-     * @param fullTilesRaster
-     * @param tiledImageGridRagne
-     * @param cropTo
-     * @return
-     */
-    private RenderedImage cropToRequiredDimension(final RenderedImage fullTilesRaster,
-            final Rectangle tiledImageGridRagne, final Rectangle cropTo) {
-
-        // int minX = fullTilesRaster.getMinX();
-        // int minY = fullTilesRaster.getMinY();
-        // int width = fullTilesRaster.getWidth();
-        // int height = fullTilesRaster.getHeight();
-
-        int minX = tiledImageGridRagne.x;
-        int minY = tiledImageGridRagne.y;
-        int width = tiledImageGridRagne.width;
-        int height = tiledImageGridRagne.height;
-
-        Rectangle origDim = new Rectangle(minX, minY, width, height);
-        if (!origDim.contains(cropTo)) {
-            throw new IllegalArgumentException("Original image (" + origDim
-                    + ") does not contain desired dimension (" + cropTo + ")");
-        } else if (origDim.equals(cropTo)) {
-            if (LOGGER.isLoggable(Level.FINER)) {
-                LOGGER.finer("No need to crop image, full tiled dimension and target one "
-                        + "do match: original: " + width + "x" + height + ", target: "
-                        + cropTo.width + "x" + cropTo.height);
-            }
-            return fullTilesRaster;
-        }
-
-        ParameterBlock cropParams = new ParameterBlock();
-
-        cropParams.addSource(fullTilesRaster);// Source
-        cropParams.add(Float.valueOf(cropTo.x - tiledImageGridRagne.x)); // x origin for each band
-        cropParams.add(Float.valueOf(cropTo.y - tiledImageGridRagne.y)); // y origin for each band
-        cropParams.add(Float.valueOf(cropTo.width));// width for each band
-        cropParams.add(Float.valueOf(cropTo.height));// height for each band
-
-        final RenderingHints hints = null;
-        RenderedImage image = JAI.create("Crop", cropParams, hints);
-
-        assert cropTo.x - tiledImageGridRagne.x == image.getMinX();
-        assert cropTo.y - tiledImageGridRagne.y == image.getMinY();
-        assert cropTo.width == image.getWidth();
-        assert cropTo.height == image.getHeight();
-
-        // assert cropTo.x == image.getMinX();
-        // assert cropTo.y == image.getMinY();
-        // assert cropTo.width == image.getWidth();
-        // assert cropTo.height == image.getHeight();
-        return image;
-    }
-
-    static class ReadParameters {
-        GeneralEnvelope requestedEnvelope;
-
-        Rectangle dim;
-
-        OverviewPolicy overviewPolicy;
-    }
-
-    private static ArcSDEGridCoverage2DReaderJAI.ReadParameters parseReadParams(
-            final GeneralEnvelope coverageEnvelope, final GeneralParameterValue[] params)
-            throws IllegalArgumentException {
-        if (params == null) {
-            throw new IllegalArgumentException("No GeneralParameterValue given to read operation");
-        }
-
-        GeneralEnvelope reqEnvelope = null;
-        Rectangle dim = null;
-        OverviewPolicy overviewPolicy = null;
-
-        // /////////////////////////////////////////////////////////////////////
-        //
-        // Checking params
-        //
-        // /////////////////////////////////////////////////////////////////////
-        for (int i = 0; i < params.length; i++) {
-            final ParameterValue<?> param = (ParameterValue<?>) params[i];
-            final String name = param.getDescriptor().getName().getCode();
-            if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString())) {
-                final GridGeometry2D gg = (GridGeometry2D) param.getValue();
-                reqEnvelope = new GeneralEnvelope((Envelope) gg.getEnvelope2D());
-
-                CoordinateReferenceSystem nativeCrs = coverageEnvelope
-                        .getCoordinateReferenceSystem();
-                CoordinateReferenceSystem requestCrs = reqEnvelope.getCoordinateReferenceSystem();
-                if (!CRS.equalsIgnoreMetadata(nativeCrs, requestCrs)) {
-                    LOGGER.info("Request CRS and native CRS differ, "
-                            + "reprojecting request envelope to native CRS");
-                    ReferencedEnvelope nativeCrsEnv;
-                    nativeCrsEnv = toNativeCrs(reqEnvelope, nativeCrs);
-                    reqEnvelope = new GeneralEnvelope(nativeCrsEnv);
-                }
-
-                dim = gg.getGridRange2D().getBounds();
-                continue;
-            }
-            if (name.equals(AbstractGridFormat.OVERVIEW_POLICY.getName().toString())) {
-                overviewPolicy = (OverviewPolicy) param.getValue();
-                continue;
-            }
-        }
-
-        if (dim == null && reqEnvelope == null) {
-            throw new ParameterNotFoundException("Parameter is mandatory and shall provide "
-                    + "the extent and dimension to request", AbstractGridFormat.READ_GRIDGEOMETRY2D
-                    .getName().toString());
-        }
-
-        if (!reqEnvelope.intersects(coverageEnvelope, true)) {
-            throw new IllegalArgumentException(
-                    "The requested extend does not overlap the coverage extent: "
-                            + coverageEnvelope);
-        }
-
-        if (dim.width <= 0 || dim.height <= 0) {
-            throw new IllegalArgumentException("The requested coverage dimension can't be null: "
-                    + dim);
-        }
-
-        if (overviewPolicy == null) {
-            LOGGER.finer("No overview policy requested, defaulting to QUALITY");
-            overviewPolicy = OverviewPolicy.QUALITY;
-        }
-        LOGGER.fine("Overview policy is " + overviewPolicy);
-
-        LOGGER.info("Reading raster for " + dim.getWidth() + "x" + dim.getHeight()
-                + " requested dim and " + reqEnvelope.getMinimum(0) + ","
-                + reqEnvelope.getMaximum(0) + " - " + reqEnvelope.getMinimum(1)
-                + reqEnvelope.getMaximum(1) + " requested extent");
-
-        ArcSDEGridCoverage2DReaderJAI.ReadParameters parsedParams = new ArcSDEGridCoverage2DReaderJAI.ReadParameters();
-        parsedParams.requestedEnvelope = reqEnvelope;
-        parsedParams.dim = dim;
-        parsedParams.overviewPolicy = overviewPolicy;
-        return parsedParams;
-    }
-
-    private static ReferencedEnvelope toNativeCrs(final GeneralEnvelope requestedEnvelope,
-            final CoordinateReferenceSystem nativeCRS) throws IllegalArgumentException {
-
-        ReferencedEnvelope reqEnv = toReferencedEnvelope(requestedEnvelope);
-
-        if (!CRS.equalsIgnoreMetadata(nativeCRS, reqEnv.getCoordinateReferenceSystem())) {
-            // we're being reprojected. We'll need to reproject reqEnv into
-            // our native coordsys
-            try {
-                // ReferencedEnvelope origReqEnv = reqEnv;
-                reqEnv = reqEnv.transform(nativeCRS, true);
-            } catch (FactoryException fe) {
-                // unable to reproject?
-                throw new IllegalArgumentException("Unable to find a reprojection from requested "
-                        + "coordsys to native coordsys for this request", fe);
-            } catch (TransformException te) {
-                throw new IllegalArgumentException("Unable to perform reprojection from requested "
-                        + "coordsys to native coordsys for this request", te);
-            }
-        }
-        return reqEnv;
-    }
-
-    private static ReferencedEnvelope toReferencedEnvelope(GeneralEnvelope envelope) {
-        double minx = envelope.getMinimum(0);
-        double maxx = envelope.getMaximum(0);
-        double miny = envelope.getMinimum(1);
-        double maxy = envelope.getMaximum(1);
-        CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
-
-        ReferencedEnvelope refEnv = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
-        return refEnv;
-    }
-
-    /**
-     * A simple helper class to guard and easy logging the mosaic geometries in both geographical
-     * and pixel ranges
-     */
-    private static class LoggingHelper {
-
-        private static final File debugDir = new File(System.getProperty("user.home")
-                + File.separator + "arcsde_test");
-
-        static {
-            if (DEBUG_TO_DISK) {
-                debugDir.mkdir();
-            }
-        }
-
-        public Level GEOM_LEVEL = Level.FINER;
-
-        public static String REQ_ENV = "Requested envelope";
-
-        public static String RES_ENV = "Resulting envelope";
-
-        public static String MOSAIC_ENV = "Resulting mosaiced envelopes";
-
-        public static String MOSAIC_EXPECTED = "Expected mosaic layout (in pixels)";
-
-        public static String MOSAIC_RESULT = "Resulting image mosaic layout (in pixels)";
-
-        private Map<String, StringBuilder> geoms = null;
-
-        LoggingHelper() {
-            // not much to to
-        }
-
-        private StringBuilder getGeom(String geomName) {
-            if (geoms == null) {
-                geoms = new HashMap<String, StringBuilder>();
-            }
-            StringBuilder sb = geoms.get(geomName);
-            if (sb == null) {
-                sb = new StringBuilder("MULTIPOLYGON(\n");
-                geoms.put(geomName, sb);
-            }
-            return sb;
-        }
-
-        public void appendLoggingGeometries(String geomName, RenderedImage img) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                appendLoggingGeometries(geomName, new Rectangle(img.getMinX(), img.getMinY(), img
-                        .getWidth(), img.getHeight()));
-            }
-        }
-
-        public void appendLoggingGeometries(String geomName, Rectangle env) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                appendLoggingGeometries(geomName, new GeneralEnvelope(env));
-            }
-        }
-
-        public void appendLoggingGeometries(String geomName, GeneralEnvelope env) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                StringBuilder sb = getGeom(geomName);
-                sb.append("  ((" + env.getMinimum(0) + " " + env.getMinimum(1) + ", "
-                        + env.getMaximum(0) + " " + env.getMinimum(1) + ", " + env.getMaximum(0)
-                        + " " + env.getMaximum(1) + ", " + env.getMinimum(0) + " "
-                        + env.getMaximum(1) + ", " + env.getMinimum(0) + " " + env.getMinimum(1)
-                        + ")),");
-            }
-        }
-
-        public void log(String geomName) {
-            if (LOGGER.isLoggable(GEOM_LEVEL)) {
-                StringBuilder sb = getGeom(geomName);
-                sb.setLength(sb.length() - 1);
-                sb.append("\n)");
-                LOGGER.log(GEOM_LEVEL, geomName + ":\n" + sb.toString());
-            }
-        }
-
-        public void log(RenderedImage image, Long rasterId, String fileName) {
-            if (DEBUG_TO_DISK) {
-                LOGGER.warning("BEWARE THE DEBUG FLAG IS TURNED ON! "
-                        + "IF IN PRODUCTION THIS IS A SEVERE MISTAKE!!!");
-                // ImageIO.write(FormatDescriptor.create(image,
-                // Integer.valueOf(DataBuffer.TYPE_BYTE),
-                // null), "TIFF", new File(debugDir, rasterId.longValue() + fileName + ".tiff"));
-
-                try {
-                    ImageIO.write(image, "TIFF", new File(debugDir, rasterId.longValue() + fileName
-                            + ".tiff"));
-                } catch (IOException e) {
-                    e.printStackTrace();
-                }
-            }
-
-        }
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDEGridCoverage2DReaderJAI.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,809 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.gce;
+
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.image.BufferedImage;
+import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.Raster;
+import java.awt.image.RenderedImage;
+import java.awt.image.SampleModel;
+import java.awt.image.WritableRaster;
+import java.awt.image.renderable.ParameterBlock;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageIO;
+import javax.imageio.ImageTypeSpecifier;
+import javax.media.jai.ImageLayout;
+import javax.media.jai.InterpolationNearest;
+import javax.media.jai.JAI;
+import javax.media.jai.ParameterBlockJAI;
+import javax.media.jai.operator.FormatDescriptor;
+import javax.media.jai.operator.MosaicDescriptor;
+
+import org.geotools.arcsde.raster.info.RasterDatasetInfo;
+import org.geotools.arcsde.raster.info.RasterQueryInfo;
+import org.geotools.arcsde.raster.info.RasterUtils;
+import org.geotools.arcsde.raster.io.RasterReaderFactory;
+import org.geotools.arcsde.raster.io.TiledRasterReader;
+import org.geotools.coverage.CoverageFactoryFinder;
+import org.geotools.coverage.GridSampleDimension;
+import org.geotools.coverage.TypeMap;
+import org.geotools.coverage.grid.GeneralGridEnvelope;
+import org.geotools.coverage.grid.GeneralGridRange;
+import org.geotools.coverage.grid.GridCoverage2D;
+import org.geotools.coverage.grid.GridGeometry2D;
+import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.coverage.grid.io.AbstractGridFormat;
+import org.geotools.coverage.grid.io.OverviewPolicy;
+import org.geotools.data.DefaultServiceInfo;
+import org.geotools.data.ServiceInfo;
+import org.geotools.factory.Hints;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.geotools.util.logging.Logging;
+import org.opengis.coverage.ColorInterpretation;
+import org.opengis.coverage.grid.Format;
+import org.opengis.coverage.grid.GridCoverageReader;
+import org.opengis.geometry.Envelope;
+import org.opengis.parameter.GeneralParameterValue;
+import org.opengis.parameter.ParameterNotFoundException;
+import org.opengis.parameter.ParameterValue;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.TransformException;
+
+/**
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/gce/ArcSDEGridCoverage2DReaderJAI.java $
+ */
+@SuppressWarnings( { "deprecation", "nls" })
+public final class ArcSDEGridCoverage2DReaderJAI extends AbstractGridCoverage2DReader {
+
+    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
+
+    /**
+     * @see LoggingHelper#log(RenderedImage, Long, String)
+     */
+    private static final boolean DEBUG_TO_DISK = Boolean
+            .getBoolean("org.geotools.arcsde.gce.debug");
+
+    private final ArcSDERasterFormat parent;
+
+    private final RasterDatasetInfo rasterInfo;
+
+    private DefaultServiceInfo serviceInfo;
+
+    private RasterReaderFactory rasterReaderFactory;
+
+    public ArcSDEGridCoverage2DReaderJAI(final ArcSDERasterFormat parent,
+            final RasterReaderFactory rasterReaderFactory, final RasterDatasetInfo rasterInfo,
+            final Hints hints) throws IOException {
+        // check it's a supported format
+        {
+            final int bitsPerSample = rasterInfo.getBand(0, 0).getCellType().getBitsPerSample();
+            if (rasterInfo.getNumBands() > 1 && (bitsPerSample == 1 || bitsPerSample == 4)) {
+                throw new IllegalArgumentException(bitsPerSample
+                        + "-bit rasters with more than one band are not supported");
+            }
+        }
+        this.parent = parent;
+        this.rasterReaderFactory = rasterReaderFactory;
+        this.rasterInfo = rasterInfo;
+
+        super.hints = hints;
+        super.coverageFactory = CoverageFactoryFinder.getGridCoverageFactory(this.hints);
+        super.crs = rasterInfo.getCoverageCrs();
+        super.originalEnvelope = rasterInfo.getOriginalEnvelope();
+
+        GeneralGridEnvelope gridRange = rasterInfo.getOriginalGridRange();
+        super.originalGridRange = new GeneralGridRange(gridRange.toRectangle());
+        //super.originalGridRange = new GridEnvelope2D(gridRange.toRectangle());
+
+        super.coverageName = rasterInfo.getRasterTable();
+        final int numLevels = rasterInfo.getNumPyramidLevels(0);
+
+        // level 0 is not an overview, but the raster itself
+        super.numOverviews = numLevels - 1;
+
+        // ///
+        //
+        // setting the higher resolution avalaible for this coverage
+        //
+        // ///
+        //highestRes = super.getResolution(originalEnvelope, (Rectangle) originalGridRange, crs);
+        highestRes = super.getResolution(originalEnvelope, originalGridRange.toRectangle(), crs);
+        // //
+        //
+        // get information for the successive images
+        //
+        // //
+        // REVISIT may the different rasters in the raster dataset have different pyramid levels? I
+        // guess so
+        if (numOverviews > 0) {
+            overViewResolutions = new double[numOverviews][2];
+            for (int pyramidLevel = 1; pyramidLevel <= numOverviews; pyramidLevel++) {
+                Rectangle levelGridRange = rasterInfo.getGridRange(0, pyramidLevel);
+                GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(0, pyramidLevel);
+                overViewResolutions[pyramidLevel - 1] = super.getResolution(levelEnvelope,
+                        levelGridRange, crs);
+            }
+        } else {
+            overViewResolutions = null;
+        }
+    }
+
+    /**
+     * @see GridCoverageReader#getFormat()
+     */
+    public Format getFormat() {
+        return parent;
+    }
+
+    @Override
+    public ServiceInfo getInfo() {
+        if (serviceInfo == null) {
+            serviceInfo = new DefaultServiceInfo();
+            serviceInfo.setTitle(rasterInfo.getRasterTable());
+            serviceInfo.setDescription(rasterInfo.toString());
+            Set<String> keywords = new HashSet<String>();
+            keywords.add("ArcSDE");
+            serviceInfo.setKeywords(keywords);
+        }
+        return serviceInfo;
+    }
+
+    /**
+     * @see GridCoverageReader#read(GeneralParameterValue[])
+     */
+    public GridCoverage2D read(GeneralParameterValue[] params) throws IOException {
+
+        final GeneralEnvelope requestedEnvelope;
+        final Rectangle requestedDim;
+        final OverviewPolicy overviewPolicy;
+        {
+            final ReadParameters opParams = parseReadParams(getOriginalEnvelope(), params);
+            overviewPolicy = opParams.overviewPolicy;
+            requestedEnvelope = opParams.requestedEnvelope;
+            requestedDim = opParams.dim;
+        }
+
+        /*
+         * For each raster in the raster dataset, obtain the tiles, pixel range, and resulting
+         * envelope
+         */
+        final List<RasterQueryInfo> queries;
+        queries = findMatchingRasters(requestedEnvelope, requestedDim, overviewPolicy);
+        if (queries.isEmpty()) {
+            /*
+             * none of the rasters match the requested envelope. This may happen by the tiled nature
+             * of the raster dataset
+             */
+            return createFakeCoverage(requestedEnvelope, requestedDim);
+        }
+
+        final GeneralEnvelope resultEnvelope = getResultEnvelope(queries);
+
+        final LoggingHelper log = new LoggingHelper();
+        log.appendLoggingGeometries(LoggingHelper.REQ_ENV, requestedEnvelope);
+        log.appendLoggingGeometries(LoggingHelper.RES_ENV, resultEnvelope);
+
+        /*
+         * Once we collected the matching rasters and their image subsets, find out where in the
+         * overall resulting mosaic they fit. If the rasters does not share the spatial resolution,
+         * the QueryInfo.resultDimension and QueryInfo.mosaicLocation width or height won't match
+         */
+        final Rectangle mosaicGeometry;
+        mosaicGeometry = RasterUtils.setMosaicLocations(rasterInfo, resultEnvelope, queries);
+
+        if (mosaicGeometry.width == 0 || mosaicGeometry.height == 0) {
+            LOGGER.finer("Mosaic geometry width or height is zero,"
+                    + " returning fake coverage for pixels " + mosaicGeometry);
+            return createFakeCoverage(requestedEnvelope, requestedDim);
+        }
+        /*
+         * Gather the rendered images for each of the rasters that match the requested envelope
+         */
+        final TiledRasterReader rasterReader = rasterReaderFactory.create(rasterInfo);
+
+        try {
+            readAllTiledRasters(queries, rasterReader, log);
+        } finally {
+            // rasterReader.dispose();
+        }
+
+        log.log(LoggingHelper.REQ_ENV);
+        log.log(LoggingHelper.RES_ENV);
+        log.log(LoggingHelper.MOSAIC_ENV);
+        log.log(LoggingHelper.MOSAIC_EXPECTED);
+
+        final RenderedImage coverageRaster = createMosaic(queries, mosaicGeometry, log);
+        assert mosaicGeometry.getWidth() == coverageRaster.getWidth();
+        assert mosaicGeometry.getHeight() == coverageRaster.getHeight();
+
+        /*
+         * BUILDING COVERAGE
+         */
+        GridSampleDimension[] bands = getSampleDimensions(coverageRaster);
+
+        GridCoverage2D resultCoverage = coverageFactory.create(coverageName, coverageRaster,
+                resultEnvelope, bands, null, null);
+
+        return resultCoverage;
+    }
+
+    private GridSampleDimension[] getSampleDimensions(final RenderedImage coverageRaster)
+            throws IOException {
+
+        GridSampleDimension[] bands = rasterInfo.getGridSampleDimensions();
+
+        // may the image have been promoted? build the correct band info then
+        final int imageBands = coverageRaster.getSampleModel().getNumBands();
+        if (bands.length == 1 && imageBands > 1) {
+            LOGGER.fine(coverageName + " was promoted from 1 to "
+                    + coverageRaster.getSampleModel().getNumBands()
+                    + " bands, returning an appropriate set of GridSampleDimension");
+            // stolen from super.createCoverage:
+            final ColorModel cm = coverageRaster.getColorModel();
+            bands = new GridSampleDimension[imageBands];
+
+            // setting bands names.
+            for (int i = 0; i < imageBands; i++) {
+                final ColorInterpretation colorInterpretation;
+                colorInterpretation = TypeMap.getColorInterpretation(cm, i);
+                if (colorInterpretation == null) {
+                    throw new IOException("Unrecognized sample dimension type");
+                }
+                bands[i] = new GridSampleDimension(colorInterpretation.name()).geophysics(true);
+            }
+        }
+
+        return bands;
+    }
+
+    private void readAllTiledRasters(final List<RasterQueryInfo> queries,
+            final TiledRasterReader rasterReader, final LoggingHelper log) throws IOException {
+
+        for (RasterQueryInfo queryInfo : queries) {
+
+            final Long rasterId = queryInfo.getRasterId();
+
+            final RenderedImage rasterImage;
+
+            try {
+                final int pyramidLevel = queryInfo.getPyramidLevel();
+                final Rectangle matchingTiles = queryInfo.getMatchingTiles();
+                // final Point imageLocation = queryInfo.getTiledImageSize().getLocation();
+                rasterImage = rasterReader.read(rasterId, pyramidLevel, matchingTiles);
+            } catch (IOException e) {
+                LOGGER.log(Level.SEVERE, "Fetching data for " + queryInfo.toString(), e);
+                throw e;
+            }
+
+            queryInfo.setResultImage(rasterImage);
+
+            {
+                LOGGER.finer(queryInfo.toString());
+                log.appendLoggingGeometries(LoggingHelper.MOSAIC_EXPECTED, queryInfo
+                        .getMosaicLocation());
+                log
+                        .appendLoggingGeometries(LoggingHelper.MOSAIC_ENV, queryInfo
+                                .getResultEnvelope());
+
+                final Rectangle tiledImageSize = queryInfo.getTiledImageSize();
+                int width = rasterImage.getWidth();
+                int height = rasterImage.getHeight();
+                if (tiledImageSize.width != width || tiledImageSize.height != height) {
+                    throw new IllegalStateException(
+                            "Read image is not of the expected size. Image=" + width + "x" + height
+                                    + ", expected: " + tiledImageSize.width + "x"
+                                    + tiledImageSize.height);
+                }
+                // if (tiledImageSize.x != rasterImage.getMinX()
+                // || tiledImageSize.y != rasterImage.getMinY()) {
+                // throw new IllegalStateException("Read image is not at the expected location "
+                // + tiledImageSize.x + "," + tiledImageSize.y + ": "
+                // + rasterImage.getMinX() + "," + rasterImage.getMinY());
+                // }
+            }
+        }
+    }
+
+    /**
+     * Called when the requested envelope do overlap the coverage envelope but none of the rasters
+     * in the dataset do
+     *
+     * @param requestedEnvelope
+     * @param requestedDim
+     * @return
+     */
+    private GridCoverage2D createFakeCoverage(GeneralEnvelope requestedEnvelope,
+            Rectangle requestedDim) {
+
+        ImageTypeSpecifier its = rasterInfo.getRenderedImageSpec(0);
+        SampleModel sampleModel = its.getSampleModel(requestedDim.width, requestedDim.height);
+        ColorModel colorModel = its.getColorModel();
+
+        WritableRaster raster = Raster.createWritableRaster(sampleModel, null);
+        BufferedImage image = new BufferedImage(colorModel, raster, false, null);
+        return coverageFactory.create(coverageName, image, requestedEnvelope);
+    }
+
+    private List<RasterQueryInfo> findMatchingRasters(final GeneralEnvelope requestedEnvelope,
+            final Rectangle requestedDim, final OverviewPolicy overviewPolicy) {
+
+        final List<RasterQueryInfo> matchingQueries;
+        matchingQueries = RasterUtils.findMatchingRasters(rasterInfo, requestedEnvelope,
+                requestedDim, overviewPolicy);
+
+        if (matchingQueries.isEmpty()) {
+            return matchingQueries;
+        }
+
+        for (RasterQueryInfo match : matchingQueries) {
+            RasterUtils.fitRequestToRaster(requestedEnvelope, rasterInfo, match);
+        }
+        return matchingQueries;
+    }
+
+    private GeneralEnvelope getResultEnvelope(final List<RasterQueryInfo> queryInfos) {
+
+        GeneralEnvelope finalEnvelope = null;
+
+        for (RasterQueryInfo rasterQueryInfo : queryInfos) {
+            // gather resulting envelope
+            if (finalEnvelope == null) {
+                finalEnvelope = new GeneralEnvelope(rasterQueryInfo.getResultEnvelope());
+            } else {
+                finalEnvelope.add(rasterQueryInfo.getResultEnvelope());
+            }
+        }
+        if (finalEnvelope == null) {
+            throw new IllegalStateException("Restult envelope is null, this shouldn't happen!! "
+                    + "we checked the request overlaps the coverage envelope before!");
+        }
+        return finalEnvelope;
+    }
+
+    /**
+     * For each raster: crop->scale->translate->add to mosaic
+     *
+     * @param queries
+     * @param mosaicGeometry
+     * @return
+     * @throws IOException
+     */
+    private RenderedImage createMosaic(final List<RasterQueryInfo> queries,
+            final Rectangle mosaicGeometry, final LoggingHelper log) throws IOException {
+
+        List<RenderedImage> transformed = new ArrayList<RenderedImage>(queries.size());
+
+        /*
+         * Do we need to expand to RGB color space and then create a new colormapped image with the
+         * whole mosaic?
+         */
+        boolean expandThenContractCM = queries.size() > 1 && rasterInfo.isColorMapped();
+        if (expandThenContractCM) {
+            LOGGER.info("Creating mosaic out of " + queries.size()
+                    + " colormapped rasters. The mosaic tiles will be expanded to "
+                    + "\nRGB space and the resulting mosaic reduced to a new IndexColorModel");
+        }
+
+        for (RasterQueryInfo query : queries) {
+            RenderedImage image = query.getResultImage();
+            log.log(image, query.getRasterId(), "01_original");
+
+            image = cropToRequiredDimension(image, query.getTiledImageSize(), query
+                    .getResultDimensionInsideTiledImage());
+            log.log(image, query.getRasterId(), "02_crop");
+
+            final Rectangle mosaicLocation = query.getMosaicLocation();
+            // scale
+            Float scaleX = Float.valueOf((float) (mosaicLocation.getWidth() / image.getWidth()));
+            Float scaleY = Float.valueOf((float) (mosaicLocation.getHeight() / image.getHeight()));
+            Float translateX = Float.valueOf(0);
+            Float translateY = Float.valueOf(0);
+            // image.getData();
+            if (!(Float.valueOf(1.0F).equals(scaleX) && Float.valueOf(1.0F).equals(scaleY))) {
+                ParameterBlock pb = new ParameterBlock();
+                pb.addSource(image);
+                pb.add(scaleX);
+                pb.add(scaleY);
+                pb.add(translateX);
+                pb.add(translateY);
+                pb.add(new InterpolationNearest());
+
+                image = JAI.create("scale", pb);
+                log.log(image, query.getRasterId(), "03_scale");
+
+                int width = image.getWidth();
+                int height = image.getHeight();
+
+                assert mosaicLocation.width == width;
+                assert mosaicLocation.height == height;
+            }
+            if (image.getMinX() != mosaicLocation.x || image.getMinY() != mosaicLocation.y) {
+                // translate
+                ParameterBlock pb = new ParameterBlock();
+                pb.addSource(image);
+                pb.add(Float.valueOf(mosaicLocation.x - image.getMinX()));
+                pb.add(Float.valueOf(mosaicLocation.y - image.getMinY()));
+                pb.add(null);
+
+                image = JAI.create("translate", pb);
+                log.log(image, query.getRasterId(), "04_translate");
+
+                assert image.getMinX() == mosaicLocation.x : image.getMinX() + " != "
+                        + mosaicLocation.x;
+                assert image.getMinY() == mosaicLocation.y : image.getMinY() + " != "
+                        + mosaicLocation.y;
+                assert image.getWidth() == mosaicLocation.width : image.getWidth() + " != "
+                        + mosaicLocation.width;
+                assert image.getHeight() == mosaicLocation.height : image.getHeight() + " != "
+                        + mosaicLocation.height;
+            }
+            if (expandThenContractCM) {
+                if (LOGGER.isLoggable(Level.FINER)) {
+                    LOGGER.finer("Creating color expanded version of tile for raster #"
+                            + query.getRasterId());
+                }
+
+                /*
+                 * reformat the image as a 4 band rgba backed by byte data
+                 */
+                image = FormatDescriptor.create(image, Integer.valueOf(DataBuffer.TYPE_BYTE), null);
+
+                log.log(image, query.getRasterId(), "04_1_colorExpanded");
+            }
+
+            transformed.add(image);
+        }
+
+        final RenderedImage mosaic;
+        if (queries.size() == 1) {
+            /*
+             * This is besides a very slight perf improvement needed because the JAI mosaic
+             * operation truncates floating point raster values to 0 and 1. REVISIT: If there's no
+             * workaround for that we should prevent raster catalogs made of floating point rasters
+             * and throw an exception as we could not really support that.
+             */
+            mosaic = transformed.get(0);
+        } else {
+            /*
+             * adapted from RasterLayerResponse.java in the imagemosaic module
+             */
+            ParameterBlockJAI mosaicParams = new ParameterBlockJAI("Mosaic");
+
+            // TODO: set background values to raster's no-data
+            // mosaicParams.setParameter("backgroundValues",backgroundValues);
+
+            mosaicParams.setParameter("mosaicType", MosaicDescriptor.MOSAIC_TYPE_OVERLAY);
+
+            final ImageLayout layout = new ImageLayout(mosaicGeometry.x, mosaicGeometry.y,
+                    mosaicGeometry.width, mosaicGeometry.height);
+            layout.setTileWidth(mosaicGeometry.width);
+            layout.setTileHeight(mosaicGeometry.height);
+            final RenderingHints hints = new RenderingHints(JAI.KEY_IMAGE_LAYOUT, layout);
+            // hints.put(JAI.KEY_SERIALIZE_DEEP_COPY, Boolean.TRUE);
+
+            for (RenderedImage img : transformed) {
+                mosaicParams.addSource(img);
+                log.appendLoggingGeometries(LoggingHelper.MOSAIC_RESULT, img);
+            }
+            log.log(LoggingHelper.MOSAIC_RESULT);
+
+            LOGGER.fine("Creating mosaic out of " + queries.size() + " raster tiles");
+            mosaic = JAI.create("Mosaic", mosaicParams, hints);
+
+            log.log(mosaic, 0L, "05_mosaic_result");
+        }
+        return mosaic;
+    }
+
+    /**
+     * Crops the image representing a full tile set to the required dimension and returns it, but
+     * keeps minx and miny being zero.
+     *
+     * @param fullTilesRaster
+     * @param tiledImageGridRagne
+     * @param cropTo
+     * @return
+     */
+    private RenderedImage cropToRequiredDimension(final RenderedImage fullTilesRaster,
+            final Rectangle tiledImageGridRagne, final Rectangle cropTo) {
+
+        // int minX = fullTilesRaster.getMinX();
+        // int minY = fullTilesRaster.getMinY();
+        // int width = fullTilesRaster.getWidth();
+        // int height = fullTilesRaster.getHeight();
+
+        int minX = tiledImageGridRagne.x;
+        int minY = tiledImageGridRagne.y;
+        int width = tiledImageGridRagne.width;
+        int height = tiledImageGridRagne.height;
+
+        Rectangle origDim = new Rectangle(minX, minY, width, height);
+        if (!origDim.contains(cropTo)) {
+            throw new IllegalArgumentException("Original image (" + origDim
+                    + ") does not contain desired dimension (" + cropTo + ")");
+        } else if (origDim.equals(cropTo)) {
+            if (LOGGER.isLoggable(Level.FINER)) {
+                LOGGER.finer("No need to crop image, full tiled dimension and target one "
+                        + "do match: original: " + width + "x" + height + ", target: "
+                        + cropTo.width + "x" + cropTo.height);
+            }
+            return fullTilesRaster;
+        }
+
+        ParameterBlock cropParams = new ParameterBlock();
+
+        cropParams.addSource(fullTilesRaster);// Source
+        cropParams.add(Float.valueOf(cropTo.x - tiledImageGridRagne.x)); // x origin for each band
+        cropParams.add(Float.valueOf(cropTo.y - tiledImageGridRagne.y)); // y origin for each band
+        cropParams.add(Float.valueOf(cropTo.width));// width for each band
+        cropParams.add(Float.valueOf(cropTo.height));// height for each band
+
+        final RenderingHints hints = null;
+        RenderedImage image = JAI.create("Crop", cropParams, hints);
+
+        assert cropTo.x - tiledImageGridRagne.x == image.getMinX();
+        assert cropTo.y - tiledImageGridRagne.y == image.getMinY();
+        assert cropTo.width == image.getWidth();
+        assert cropTo.height == image.getHeight();
+
+        // assert cropTo.x == image.getMinX();
+        // assert cropTo.y == image.getMinY();
+        // assert cropTo.width == image.getWidth();
+        // assert cropTo.height == image.getHeight();
+        return image;
+    }
+
+    static class ReadParameters {
+        GeneralEnvelope requestedEnvelope;
+
+        Rectangle dim;
+
+        OverviewPolicy overviewPolicy;
+    }
+
+    private static ArcSDEGridCoverage2DReaderJAI.ReadParameters parseReadParams(
+            final GeneralEnvelope coverageEnvelope, final GeneralParameterValue[] params)
+            throws IllegalArgumentException {
+        if (params == null) {
+            throw new IllegalArgumentException("No GeneralParameterValue given to read operation");
+        }
+
+        GeneralEnvelope reqEnvelope = null;
+        Rectangle dim = null;
+        OverviewPolicy overviewPolicy = null;
+
+        // /////////////////////////////////////////////////////////////////////
+        //
+        // Checking params
+        //
+        // /////////////////////////////////////////////////////////////////////
+        for (int i = 0; i < params.length; i++) {
+            final ParameterValue<?> param = (ParameterValue<?>) params[i];
+            final String name = param.getDescriptor().getName().getCode();
+            if (name.equals(AbstractGridFormat.READ_GRIDGEOMETRY2D.getName().toString())) {
+                final GridGeometry2D gg = (GridGeometry2D) param.getValue();
+                reqEnvelope = new GeneralEnvelope((Envelope) gg.getEnvelope2D());
+
+                CoordinateReferenceSystem nativeCrs = coverageEnvelope
+                        .getCoordinateReferenceSystem();
+                CoordinateReferenceSystem requestCrs = reqEnvelope.getCoordinateReferenceSystem();
+                if (!CRS.equalsIgnoreMetadata(nativeCrs, requestCrs)) {
+                    LOGGER.info("Request CRS and native CRS differ, "
+                            + "reprojecting request envelope to native CRS");
+                    ReferencedEnvelope nativeCrsEnv;
+                    nativeCrsEnv = toNativeCrs(reqEnvelope, nativeCrs);
+                    reqEnvelope = new GeneralEnvelope(nativeCrsEnv);
+                }
+
+                dim = gg.getGridRange2D().getBounds();
+                continue;
+            }
+            if (name.equals(AbstractGridFormat.OVERVIEW_POLICY.getName().toString())) {
+                overviewPolicy = (OverviewPolicy) param.getValue();
+                continue;
+            }
+        }
+
+        if (dim == null && reqEnvelope == null) {
+            throw new ParameterNotFoundException("Parameter is mandatory and shall provide "
+                    + "the extent and dimension to request", AbstractGridFormat.READ_GRIDGEOMETRY2D
+                    .getName().toString());
+        }
+
+        if (!reqEnvelope.intersects(coverageEnvelope, true)) {
+            throw new IllegalArgumentException(
+                    "The requested extend does not overlap the coverage extent: "
+                            + coverageEnvelope);
+        }
+
+        if (dim.width <= 0 || dim.height <= 0) {
+            throw new IllegalArgumentException("The requested coverage dimension can't be null: "
+                    + dim);
+        }
+
+        if (overviewPolicy == null) {
+            LOGGER.finer("No overview policy requested, defaulting to QUALITY");
+            overviewPolicy = OverviewPolicy.QUALITY;
+        }
+        LOGGER.fine("Overview policy is " + overviewPolicy);
+
+        LOGGER.info("Reading raster for " + dim.getWidth() + "x" + dim.getHeight()
+                + " requested dim and " + reqEnvelope.getMinimum(0) + ","
+                + reqEnvelope.getMaximum(0) + " - " + reqEnvelope.getMinimum(1)
+                + reqEnvelope.getMaximum(1) + " requested extent");
+
+        ArcSDEGridCoverage2DReaderJAI.ReadParameters parsedParams = new ArcSDEGridCoverage2DReaderJAI.ReadParameters();
+        parsedParams.requestedEnvelope = reqEnvelope;
+        parsedParams.dim = dim;
+        parsedParams.overviewPolicy = overviewPolicy;
+        return parsedParams;
+    }
+
+    private static ReferencedEnvelope toNativeCrs(final GeneralEnvelope requestedEnvelope,
+            final CoordinateReferenceSystem nativeCRS) throws IllegalArgumentException {
+
+        ReferencedEnvelope reqEnv = toReferencedEnvelope(requestedEnvelope);
+
+        if (!CRS.equalsIgnoreMetadata(nativeCRS, reqEnv.getCoordinateReferenceSystem())) {
+            // we're being reprojected. We'll need to reproject reqEnv into
+            // our native coordsys
+            try {
+                // ReferencedEnvelope origReqEnv = reqEnv;
+                reqEnv = reqEnv.transform(nativeCRS, true);
+            } catch (FactoryException fe) {
+                // unable to reproject?
+                throw new IllegalArgumentException("Unable to find a reprojection from requested "
+                        + "coordsys to native coordsys for this request", fe);
+            } catch (TransformException te) {
+                throw new IllegalArgumentException("Unable to perform reprojection from requested "
+                        + "coordsys to native coordsys for this request", te);
+            }
+        }
+        return reqEnv;
+    }
+
+    private static ReferencedEnvelope toReferencedEnvelope(GeneralEnvelope envelope) {
+        double minx = envelope.getMinimum(0);
+        double maxx = envelope.getMaximum(0);
+        double miny = envelope.getMinimum(1);
+        double maxy = envelope.getMaximum(1);
+        CoordinateReferenceSystem crs = envelope.getCoordinateReferenceSystem();
+
+        ReferencedEnvelope refEnv = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
+        return refEnv;
+    }
+
+    /**
+     * A simple helper class to guard and easy logging the mosaic geometries in both geographical
+     * and pixel ranges
+     */
+    private static class LoggingHelper {
+
+        private static final File debugDir = new File(System.getProperty("user.home")
+                + File.separator + "arcsde_test");
+
+        static {
+            if (DEBUG_TO_DISK) {
+                debugDir.mkdir();
+            }
+        }
+
+        public Level GEOM_LEVEL = Level.FINER;
+
+        public static String REQ_ENV = "Requested envelope";
+
+        public static String RES_ENV = "Resulting envelope";
+
+        public static String MOSAIC_ENV = "Resulting mosaiced envelopes";
+
+        public static String MOSAIC_EXPECTED = "Expected mosaic layout (in pixels)";
+
+        public static String MOSAIC_RESULT = "Resulting image mosaic layout (in pixels)";
+
+        private Map<String, StringBuilder> geoms = null;
+
+        LoggingHelper() {
+            // not much to to
+        }
+
+        private StringBuilder getGeom(String geomName) {
+            if (geoms == null) {
+                geoms = new HashMap<String, StringBuilder>();
+            }
+            StringBuilder sb = geoms.get(geomName);
+            if (sb == null) {
+                sb = new StringBuilder("MULTIPOLYGON(\n");
+                geoms.put(geomName, sb);
+            }
+            return sb;
+        }
+
+        public void appendLoggingGeometries(String geomName, RenderedImage img) {
+            if (LOGGER.isLoggable(GEOM_LEVEL)) {
+                appendLoggingGeometries(geomName, new Rectangle(img.getMinX(), img.getMinY(), img
+                        .getWidth(), img.getHeight()));
+            }
+        }
+
+        public void appendLoggingGeometries(String geomName, Rectangle env) {
+            if (LOGGER.isLoggable(GEOM_LEVEL)) {
+                appendLoggingGeometries(geomName, new GeneralEnvelope(env));
+            }
+        }
+
+        public void appendLoggingGeometries(String geomName, GeneralEnvelope env) {
+            if (LOGGER.isLoggable(GEOM_LEVEL)) {
+                StringBuilder sb = getGeom(geomName);
+                sb.append("  ((" + env.getMinimum(0) + " " + env.getMinimum(1) + ", "
+                        + env.getMaximum(0) + " " + env.getMinimum(1) + ", " + env.getMaximum(0)
+                        + " " + env.getMaximum(1) + ", " + env.getMinimum(0) + " "
+                        + env.getMaximum(1) + ", " + env.getMinimum(0) + " " + env.getMinimum(1)
+                        + ")),");
+            }
+        }
+
+        public void log(String geomName) {
+            if (LOGGER.isLoggable(GEOM_LEVEL)) {
+                StringBuilder sb = getGeom(geomName);
+                sb.setLength(sb.length() - 1);
+                sb.append("\n)");
+                LOGGER.log(GEOM_LEVEL, geomName + ":\n" + sb.toString());
+            }
+        }
+
+        public void log(RenderedImage image, Long rasterId, String fileName) {
+            if (DEBUG_TO_DISK) {
+                LOGGER.warning("BEWARE THE DEBUG FLAG IS TURNED ON! "
+                        + "IF IN PRODUCTION THIS IS A SEVERE MISTAKE!!!");
+                // ImageIO.write(FormatDescriptor.create(image,
+                // Integer.valueOf(DataBuffer.TYPE_BYTE),
+                // null), "TIFF", new File(debugDir, rasterId.longValue() + fileName + ".tiff"));
+
+                try {
+                    ImageIO.write(image, "TIFF", new File(debugDir, rasterId.longValue() + fileName
+                            + ".tiff"));
+                } catch (IOException e) {
+                    e.printStackTrace();
+                }
+            }
+
+        }
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,452 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.gce;
-
-import java.io.File;
-import java.io.IOException;
-import java.net.URI;
-import java.net.URISyntaxException;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.WeakHashMap;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.geotools.arcsde.jndi.SharedSessionPool;
-import org.geotools.arcsde.raster.info.GatherCoverageMetadataCommand;
-import org.geotools.arcsde.raster.info.RasterDatasetInfo;
-import org.geotools.arcsde.raster.io.RasterReaderFactory;
-import org.geotools.arcsde.session.ArcSDEConnectionConfig;
-import org.geotools.arcsde.session.ISession;
-import org.geotools.arcsde.session.ISessionPool;
-import org.geotools.arcsde.session.SessionPoolFactory;
-import org.geotools.arcsde.session.UnavailableConnectionException;
-import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
-import org.geotools.coverage.grid.io.AbstractGridFormat;
-import org.geotools.coverage.grid.io.imageio.GeoToolsWriteParams;
-import org.geotools.data.DataSourceException;
-import org.geotools.factory.GeoTools;
-import org.geotools.factory.Hints;
-import org.geotools.parameter.DefaultParameterDescriptorGroup;
-import org.geotools.parameter.ParameterGroup;
-import org.geotools.util.logging.Logging;
-import org.opengis.coverage.grid.Format;
-import org.opengis.coverage.grid.GridCoverageWriter;
-import org.opengis.parameter.GeneralParameterDescriptor;
-
-/**
- * An implementation of the ArcSDE Raster Format. Based on the ArcGrid module.
- *
- * @author Saul Farber (saul.farber)
- * @author jeichar
- * @author Simone Giannecchini (simboss)
- * @author Gabriel Roldan (OpenGeo)
- * @source $URL:
- *         http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java
- *         /org/geotools/arcsde/gce/ArcSDERasterFormat.java $
- */
-@SuppressWarnings( { "nls", "deprecation" })
-public final class ArcSDERasterFormat extends AbstractGridFormat implements Format {
-
-    protected static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    /**
-     * Cache of raster metadata objects, where the keys are the URL's representing the full
-     * connection properties to a given ArcSDE raster, and the value the
-     * {@link ArcSDERasterGridCoverage2DReader}'s externalized state, so it is not needed to gather
-     * the raster properties each time.
-     */
-    private final Map<String, RasterDatasetInfo> rasterInfos = new WeakHashMap<String, RasterDatasetInfo>();
-
-    private final Map<String, ArcSDEConnectionConfig> connectionConfigs = new WeakHashMap<String, ArcSDEConnectionConfig>();
-
-    private static final ArcSDERasterFormat instance = new ArcSDERasterFormat();
-
-    private boolean statisticsMandatory = true;
-
-    /**
-     * Creates an instance and sets the metadata.
-     */
-    private ArcSDERasterFormat() {
-        setInfo();
-    }
-
-    public static ArcSDERasterFormat getInstance() {
-        return instance;
-    }
-
-    /**
-     * Sets the metadata information.
-     */
-    private void setInfo() {
-        Map<String, String> info = new HashMap<String, String>();
-
-        info.put("name", "ArcSDE Raster");
-        info.put("description", "ArcSDE Raster Format");
-        info.put("vendor", "Geotools");
-        info.put("docURL", "");
-        info.put("version", GeoTools.getVersion().toString());
-        mInfo = info;
-
-        readParameters = new ParameterGroup(new DefaultParameterDescriptorGroup(mInfo,
-                new GeneralParameterDescriptor[] { READ_GRIDGEOMETRY2D, OVERVIEW_POLICY }));
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#getReader(Object source)
-     */
-    @Override
-    public AbstractGridCoverage2DReader getReader(Object source) {
-        return getReader(source, null);
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#getReader(Object, Hints)
-     */
-    @Override
-    public AbstractGridCoverage2DReader getReader(final Object source, final Hints hints) {
-        try {
-            if (source == null) {
-                throw new DataSourceException("No source set to read this coverage.");
-            }
-
-            // this will be our connection string
-            final String coverageUrl = parseCoverageUrl(source);
-
-            final ArcSDEConnectionConfig connectionConfig = getConnectionConfig(coverageUrl);
-
-            final ISessionPool sessionPool = setupConnectionPool(connectionConfig);
-
-            final RasterDatasetInfo rasterInfo = getRasterInfo(coverageUrl, sessionPool);
-
-            final RasterReaderFactory rasterReaderFactory = new RasterReaderFactory(sessionPool);
-
-            return new ArcSDEGridCoverage2DReaderJAI(this, rasterReaderFactory, rasterInfo, hints);
-        } catch (IOException dse) {
-            LOGGER
-                    .log(Level.SEVERE, "Unable to creata ArcSDERasterReader for " + source + ".",
-                            dse);
-            throw new RuntimeException(dse);
-        }
-    }
-
-    private RasterDatasetInfo getRasterInfo(final String coverageUrl, ISessionPool connectionPool)
-            throws IOException {
-
-        RasterDatasetInfo rasterInfo = rasterInfos.get(coverageUrl);
-        if (rasterInfo == null) {
-            synchronized (rasterInfos) {
-                rasterInfo = rasterInfos.get(coverageUrl);
-                if (rasterInfo == null) {
-                    ISession scon;
-                    try {
-                        scon = connectionPool.getSession(false);
-                    } catch (UnavailableConnectionException e) {
-                        throw new RuntimeException(e);
-                    }
-                    try {
-                        final String rasterTable;
-                        {
-                            String sdeUrl = coverageUrl;
-                            if (sdeUrl.indexOf(";") != -1) {
-                                /*
-                                 * We're not using any extra param anymore. Yet, be cautious cause a
-                                 * client may still be using urls with some old extra param, so just
-                                 * strip it
-                                 */
-                                sdeUrl = sdeUrl.substring(0, sdeUrl.indexOf(";"));
-                            }
-                            rasterTable = sdeUrl.substring(sdeUrl.indexOf("#") + 1);
-                            if (LOGGER.isLoggable(Level.FINE)) {
-                                LOGGER.fine("Building ArcSDEGridCoverageReader2D for "
-                                        + rasterTable);
-                            }
-                        }
-
-                        GatherCoverageMetadataCommand command = new GatherCoverageMetadataCommand(
-                                rasterTable, statisticsMandatory);
-                        rasterInfo = scon.issue(command);
-                        rasterInfos.put(coverageUrl, rasterInfo);
-                    } finally {
-                        scon.dispose();
-                    }
-                }
-            }
-        }
-        return rasterInfo;
-    }
-
-    private ArcSDEConnectionConfig getConnectionConfig(final String coverageUrl) {
-        ArcSDEConnectionConfig sdeConfig;
-        sdeConfig = connectionConfigs.get(coverageUrl);
-        if (sdeConfig == null) {
-            synchronized (connectionConfigs) {
-                sdeConfig = connectionConfigs.get(coverageUrl);
-                if (sdeConfig == null) {
-                    sdeConfig = sdeURLToConnectionConfig(new StringBuffer(coverageUrl));
-                    connectionConfigs.put(coverageUrl, sdeConfig);
-                }
-            }
-        }
-        return sdeConfig;
-    }
-
-    /**
-     * @see AbstractGridFormat#getWriter(Object)
-     */
-    @Override
-    public GridCoverageWriter getWriter(Object destination) {
-        // return new ArcGridWriter(destination);
-        return null;
-    }
-
-    /**
-     * @param source
-     *            either a {@link String} or {@link File} instance representing the connection URL
-     * @see AbstractGridFormat#accepts(Object input)
-     */
-    @Override
-    public boolean accepts(Object input) {
-        StringBuffer url;
-        if (input instanceof File) {
-            url = new StringBuffer(((File) input).getPath());
-        } else if (input instanceof String) {
-            url = new StringBuffer((String) input);
-        } else {
-            return false;
-        }
-        try {
-            sdeURLToConnectionConfig(url);
-            return true;
-        } catch (Exception e) {
-            return false;
-        }
-    }
-
-    /**
-     * @see Format#getName()
-     */
-    @Override
-    public String getName() {
-        return this.mInfo.get("name");
-    }
-
-    /**
-     * @see Format#getDescription()
-     */
-    @Override
-    public String getDescription() {
-        return this.mInfo.get("description");
-    }
-
-    /**
-     * @see Format#getVendor()
-     */
-    @Override
-    public String getVendor() {
-        return this.mInfo.get("vendor");
-    }
-
-    /**
-     * @see Format#getDocURL()
-     */
-    @Override
-    public String getDocURL() {
-        return this.mInfo.get("docURL");
-    }
-
-    /**
-     * @see Format#getVersion()
-     */
-    @Override
-    public String getVersion() {
-        return this.mInfo.get("version");
-    }
-
-    /**
-     * Retrieves the default instance for the {@link ArcSDERasterFormat} of the
-     * {@link GeoToolsWriteParams} to control the writing process.
-     *
-     * @return a default instance for the {@link ArcSDERasterFormat} of the
-     *         {@link GeoToolsWriteParams} to control the writing process.
-     * @see AbstractGridFormat#getDefaultImageIOWriteParameters()
-     */
-    @Override
-    public GeoToolsWriteParams getDefaultImageIOWriteParameters() {
-        throw new UnsupportedOperationException("ArcSDE Rasters are read only for now.");
-    }
-
-    // ////////////////
-
-    /**
-     * @param input
-     *            either a {@link String} or a {@link File} instance representing the connection URL
-     *            to a given coverage
-     * @return the connection URL as a string
-     */
-    private String parseCoverageUrl(Object input) {
-        String coverageUrl;
-        if (input instanceof String) {
-            coverageUrl = (String) input;
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("connecting to ArcSDE Raster: " + coverageUrl);
-            }
-        } else if (input instanceof File) {
-            String path = ((File) input).getPath();
-            while (path.indexOf('\\') > -1) {
-                path = path.replace('\\', '/');
-            }
-            URI uri;
-            try {
-                uri = new URI(path);
-            } catch (URISyntaxException e) {
-                throw new IllegalArgumentException(path);
-            }
-            coverageUrl = uri.toString();
-            if (LOGGER.isLoggable(Level.FINE)) {
-                LOGGER.fine("connectiong via file-hack to ArcSDE Raster: " + coverageUrl);
-            }
-        } else {
-            throw new IllegalArgumentException("Unsupported input type: " + input.getClass());
-        }
-        return coverageUrl;
-    }
-
-    /**
-     * Checks the input provided to this {@link ArcSDERasterGridCoverage2DReader} and sets all the
-     * other objects and flags accordingly.
-     *
-     * @param sdeUrl
-     *            a url representing the connection parameters to an arcsde server instance provied
-     *            to this {@link ArcSDERasterGridCoverage2DReader}.
-     * @throws IOException
-     */
-    private ISessionPool setupConnectionPool(ArcSDEConnectionConfig sdeConfig) throws IOException {
-
-        if (LOGGER.isLoggable(Level.FINE)) {
-            LOGGER.fine("Getting ArcSDE connection pool for " + sdeConfig);
-        }
-
-        ISessionPool sessionPool;
-        sessionPool = SharedSessionPool.getInstance(sdeConfig, SessionPoolFactory.getInstance());
-
-        return sessionPool;
-    }
-
-    /**
-     * @param sdeUrl
-     *            - A StringBuffer containing a string of form
-     *            'sde://user:pass@sdehost:[port]/[dbname]
-     * @return a ConnectionConfig object representing these parameters
-     */
-    public static ArcSDEConnectionConfig sdeURLToConnectionConfig(StringBuffer sdeUrl) {
-        // annoyingly, geoserver currently stores the user-entered SDE string as
-        // a File, and passes us the
-        // File object. The File object strips the 'sde://user...' into a
-        // 'sde:/user..'. So we need to check
-        // for both forms of the url.
-        String sdeHost, sdeUser, sdePass, sdeDBName;
-        int sdePort;
-        if (sdeUrl.indexOf("sde:/") == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName -- Got "
-                            + sdeUrl);
-        }
-        if (sdeUrl.indexOf("sde://") == -1) {
-            sdeUrl.delete(0, 5);
-        } else {
-            sdeUrl.delete(0, 6);
-        }
-
-        int idx = sdeUrl.indexOf(":");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdeUser = sdeUrl.substring(0, idx);
-        sdeUrl.delete(0, idx);
-
-        idx = sdeUrl.indexOf("@");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdePass = sdeUrl.substring(1, idx);
-        sdeUrl.delete(0, idx);
-
-        idx = sdeUrl.indexOf(":");
-        if (idx == -1) {
-            // there's no "port" specification. Assume 5151;
-            sdePort = 5151;
-
-            idx = sdeUrl.indexOf("/");
-            if (idx == -1) {
-                throw new IllegalArgumentException(
-                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-            }
-            sdeHost = sdeUrl.substring(1, idx).toString();
-            sdeUrl.delete(0, idx);
-        } else {
-            sdeHost = sdeUrl.substring(1, idx).toString();
-            sdeUrl.delete(0, idx);
-
-            idx = sdeUrl.indexOf("/");
-            if (idx == -1) {
-                throw new IllegalArgumentException(
-                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-            }
-            sdePort = Integer.parseInt(sdeUrl.substring(1, idx).toString());
-            sdeUrl.delete(0, idx);
-        }
-
-        idx = sdeUrl.indexOf("#");
-        if (idx == -1) {
-            throw new IllegalArgumentException(
-                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
-        }
-        sdeDBName = sdeUrl.substring(1, idx).toString();
-        sdeUrl.delete(0, idx);
-
-        Map<String, String> params = new HashMap<String, String>();
-        params.put(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, sdeHost);
-        params.put(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, String.valueOf(sdePort));
-        params.put(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME, sdeDBName);
-        params.put(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, sdeUser);
-        params.put(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, sdePass);
-        params.put(ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME, "1");
-        params.put(ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME, "20");
-        params.put(ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME, "-1");// do not wait
-
-        ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(params);
-        return config;
-    }
-
-    /**
-     * Used by test code to indicate wether to fail when a raster lacks statistics, since we can't
-     * create statistics with the ArcSDE Java API
-     *
-     * @param statisticsMandatory
-     */
-    void setStatisticsMandatory(final boolean statisticsMandatory) {
-        this.statisticsMandatory = statisticsMandatory;
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/gce/ArcSDERasterFormat.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,452 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.gce;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.arcsde.jndi.SharedSessionPool;
+import org.geotools.arcsde.raster.info.GatherCoverageMetadataCommand;
+import org.geotools.arcsde.raster.info.RasterDatasetInfo;
+import org.geotools.arcsde.raster.io.RasterReaderFactory;
+import org.geotools.arcsde.session.ArcSDEConnectionConfig;
+import org.geotools.arcsde.session.ISession;
+import org.geotools.arcsde.session.ISessionPool;
+import org.geotools.arcsde.session.SessionPoolFactory;
+import org.geotools.arcsde.session.UnavailableConnectionException;
+import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
+import org.geotools.coverage.grid.io.AbstractGridFormat;
+import org.geotools.coverage.grid.io.imageio.GeoToolsWriteParams;
+import org.geotools.data.DataSourceException;
+import org.geotools.factory.GeoTools;
+import org.geotools.factory.Hints;
+import org.geotools.parameter.DefaultParameterDescriptorGroup;
+import org.geotools.parameter.ParameterGroup;
+import org.geotools.util.logging.Logging;
+import org.opengis.coverage.grid.Format;
+import org.opengis.coverage.grid.GridCoverageWriter;
+import org.opengis.parameter.GeneralParameterDescriptor;
+
+/**
+ * An implementation of the ArcSDE Raster Format. Based on the ArcGrid module.
+ *
+ * @author Saul Farber (saul.farber)
+ * @author jeichar
+ * @author Simone Giannecchini (simboss)
+ * @author Gabriel Roldan (OpenGeo)
+ * @source $URL:
+ *         http://svn.geotools.org/geotools/trunk/gt/modules/plugin/arcsde/datastore/src/main/java
+ *         /org/geotools/arcsde/gce/ArcSDERasterFormat.java $
+ */
+@SuppressWarnings( { "nls", "deprecation" })
+public final class ArcSDERasterFormat extends AbstractGridFormat implements Format {
+
+    protected static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
+
+    /**
+     * Cache of raster metadata objects, where the keys are the URL's representing the full
+     * connection properties to a given ArcSDE raster, and the value the
+     * {@link ArcSDERasterGridCoverage2DReader}'s externalized state, so it is not needed to gather
+     * the raster properties each time.
+     */
+    private final Map<String, RasterDatasetInfo> rasterInfos = new WeakHashMap<String, RasterDatasetInfo>();
+
+    private final Map<String, ArcSDEConnectionConfig> connectionConfigs = new WeakHashMap<String, ArcSDEConnectionConfig>();
+
+    private static final ArcSDERasterFormat instance = new ArcSDERasterFormat();
+
+    private boolean statisticsMandatory = true;
+
+    /**
+     * Creates an instance and sets the metadata.
+     */
+    private ArcSDERasterFormat() {
+        setInfo();
+    }
+
+    public static ArcSDERasterFormat getInstance() {
+        return instance;
+    }
+
+    /**
+     * Sets the metadata information.
+     */
+    private void setInfo() {
+        Map<String, String> info = new HashMap<String, String>();
+
+        info.put("name", "ArcSDE Raster");
+        info.put("description", "ArcSDE Raster Format");
+        info.put("vendor", "Geotools");
+        info.put("docURL", "");
+        info.put("version", GeoTools.getVersion().toString());
+        mInfo = info;
+
+        readParameters = new ParameterGroup(new DefaultParameterDescriptorGroup(mInfo,
+                new GeneralParameterDescriptor[] { READ_GRIDGEOMETRY2D, OVERVIEW_POLICY }));
+    }
+
+    /**
+     * @param source
+     *            either a {@link String} or {@link File} instance representing the connection URL
+     * @see AbstractGridFormat#getReader(Object source)
+     */
+    @Override
+    public AbstractGridCoverage2DReader getReader(Object source) {
+        return getReader(source, null);
+    }
+
+    /**
+     * @param source
+     *            either a {@link String} or {@link File} instance representing the connection URL
+     * @see AbstractGridFormat#getReader(Object, Hints)
+     */
+    @Override
+    public AbstractGridCoverage2DReader getReader(final Object source, final Hints hints) {
+        try {
+            if (source == null) {
+                throw new DataSourceException("No source set to read this coverage.");
+            }
+
+            // this will be our connection string
+            final String coverageUrl = parseCoverageUrl(source);
+
+            final ArcSDEConnectionConfig connectionConfig = getConnectionConfig(coverageUrl);
+
+            final ISessionPool sessionPool = setupConnectionPool(connectionConfig);
+
+            final RasterDatasetInfo rasterInfo = getRasterInfo(coverageUrl, sessionPool);
+
+            final RasterReaderFactory rasterReaderFactory = new RasterReaderFactory(sessionPool);
+
+            return new ArcSDEGridCoverage2DReaderJAI(this, rasterReaderFactory, rasterInfo, hints);
+        } catch (IOException dse) {
+            LOGGER
+                    .log(Level.SEVERE, "Unable to creata ArcSDERasterReader for " + source + ".",
+                            dse);
+            throw new RuntimeException(dse);
+        }
+    }
+
+    private RasterDatasetInfo getRasterInfo(final String coverageUrl, ISessionPool connectionPool)
+            throws IOException {
+
+        RasterDatasetInfo rasterInfo = rasterInfos.get(coverageUrl);
+        if (rasterInfo == null) {
+            synchronized (rasterInfos) {
+                rasterInfo = rasterInfos.get(coverageUrl);
+                if (rasterInfo == null) {
+                    ISession scon;
+                    try {
+                        scon = connectionPool.getSession(false);
+                    } catch (UnavailableConnectionException e) {
+                        throw new RuntimeException(e);
+                    }
+                    try {
+                        final String rasterTable;
+                        {
+                            String sdeUrl = coverageUrl;
+                            if (sdeUrl.indexOf(";") != -1) {
+                                /*
+                                 * We're not using any extra param anymore. Yet, be cautious cause a
+                                 * client may still be using urls with some old extra param, so just
+                                 * strip it
+                                 */
+                                sdeUrl = sdeUrl.substring(0, sdeUrl.indexOf(";"));
+                            }
+                            rasterTable = sdeUrl.substring(sdeUrl.indexOf("#") + 1);
+                            if (LOGGER.isLoggable(Level.FINE)) {
+                                LOGGER.fine("Building ArcSDEGridCoverageReader2D for "
+                                        + rasterTable);
+                            }
+                        }
+
+                        GatherCoverageMetadataCommand command = new GatherCoverageMetadataCommand(
+                                rasterTable, statisticsMandatory);
+                        rasterInfo = scon.issue(command);
+                        rasterInfos.put(coverageUrl, rasterInfo);
+                    } finally {
+                        scon.dispose();
+                    }
+                }
+            }
+        }
+        return rasterInfo;
+    }
+
+    private ArcSDEConnectionConfig getConnectionConfig(final String coverageUrl) {
+        ArcSDEConnectionConfig sdeConfig;
+        sdeConfig = connectionConfigs.get(coverageUrl);
+        if (sdeConfig == null) {
+            synchronized (connectionConfigs) {
+                sdeConfig = connectionConfigs.get(coverageUrl);
+                if (sdeConfig == null) {
+                    sdeConfig = sdeURLToConnectionConfig(new StringBuffer(coverageUrl));
+                    connectionConfigs.put(coverageUrl, sdeConfig);
+                }
+            }
+        }
+        return sdeConfig;
+    }
+
+    /**
+     * @see AbstractGridFormat#getWriter(Object)
+     */
+    @Override
+    public GridCoverageWriter getWriter(Object destination) {
+        // return new ArcGridWriter(destination);
+        return null;
+    }
+
+    /**
+     * @param source
+     *            either a {@link String} or {@link File} instance representing the connection URL
+     * @see AbstractGridFormat#accepts(Object input)
+     */
+    @Override
+    public boolean accepts(Object input) {
+        StringBuffer url;
+        if (input instanceof File) {
+            url = new StringBuffer(((File) input).getPath());
+        } else if (input instanceof String) {
+            url = new StringBuffer((String) input);
+        } else {
+            return false;
+        }
+        try {
+            sdeURLToConnectionConfig(url);
+            return true;
+        } catch (Exception e) {
+            return false;
+        }
+    }
+
+    /**
+     * @see Format#getName()
+     */
+    @Override
+    public String getName() {
+        return this.mInfo.get("name");
+    }
+
+    /**
+     * @see Format#getDescription()
+     */
+    @Override
+    public String getDescription() {
+        return this.mInfo.get("description");
+    }
+
+    /**
+     * @see Format#getVendor()
+     */
+    @Override
+    public String getVendor() {
+        return this.mInfo.get("vendor");
+    }
+
+    /**
+     * @see Format#getDocURL()
+     */
+    @Override
+    public String getDocURL() {
+        return this.mInfo.get("docURL");
+    }
+
+    /**
+     * @see Format#getVersion()
+     */
+    @Override
+    public String getVersion() {
+        return this.mInfo.get("version");
+    }
+
+    /**
+     * Retrieves the default instance for the {@link ArcSDERasterFormat} of the
+     * {@link GeoToolsWriteParams} to control the writing process.
+     *
+     * @return a default instance for the {@link ArcSDERasterFormat} of the
+     *         {@link GeoToolsWriteParams} to control the writing process.
+     * @see AbstractGridFormat#getDefaultImageIOWriteParameters()
+     */
+    @Override
+    public GeoToolsWriteParams getDefaultImageIOWriteParameters() {
+        throw new UnsupportedOperationException("ArcSDE Rasters are read only for now.");
+    }
+
+    // ////////////////
+
+    /**
+     * @param input
+     *            either a {@link String} or a {@link File} instance representing the connection URL
+     *            to a given coverage
+     * @return the connection URL as a string
+     */
+    private String parseCoverageUrl(Object input) {
+        String coverageUrl;
+        if (input instanceof String) {
+            coverageUrl = (String) input;
+            if (LOGGER.isLoggable(Level.FINE)) {
+                LOGGER.fine("connecting to ArcSDE Raster: " + coverageUrl);
+            }
+        } else if (input instanceof File) {
+            String path = ((File) input).getPath();
+            while (path.indexOf('\\') > -1) {
+                path = path.replace('\\', '/');
+            }
+            URI uri;
+            try {
+                uri = new URI(path);
+            } catch (URISyntaxException e) {
+                throw new IllegalArgumentException(path);
+            }
+            coverageUrl = uri.toString();
+            if (LOGGER.isLoggable(Level.FINE)) {
+                LOGGER.fine("connectiong via file-hack to ArcSDE Raster: " + coverageUrl);
+            }
+        } else {
+            throw new IllegalArgumentException("Unsupported input type: " + input.getClass());
+        }
+        return coverageUrl;
+    }
+
+    /**
+     * Checks the input provided to this {@link ArcSDERasterGridCoverage2DReader} and sets all the
+     * other objects and flags accordingly.
+     *
+     * @param sdeUrl
+     *            a url representing the connection parameters to an arcsde server instance provied
+     *            to this {@link ArcSDERasterGridCoverage2DReader}.
+     * @throws IOException
+     */
+    private ISessionPool setupConnectionPool(ArcSDEConnectionConfig sdeConfig) throws IOException {
+
+        if (LOGGER.isLoggable(Level.FINE)) {
+            LOGGER.fine("Getting ArcSDE connection pool for " + sdeConfig);
+        }
+
+        ISessionPool sessionPool;
+        sessionPool = SharedSessionPool.getInstance(sdeConfig, SessionPoolFactory.getInstance());
+
+        return sessionPool;
+    }
+
+    /**
+     * @param sdeUrl
+     *            - A StringBuffer containing a string of form
+     *            'sde://user:pass@sdehost:[port]/[dbname]
+     * @return a ConnectionConfig object representing these parameters
+     */
+    public static ArcSDEConnectionConfig sdeURLToConnectionConfig(StringBuffer sdeUrl) {
+        // annoyingly, geoserver currently stores the user-entered SDE string as
+        // a File, and passes us the
+        // File object. The File object strips the 'sde://user...' into a
+        // 'sde:/user..'. So we need to check
+        // for both forms of the url.
+        String sdeHost, sdeUser, sdePass, sdeDBName;
+        int sdePort;
+        if (sdeUrl.indexOf("sde:/") == -1) {
+            throw new IllegalArgumentException(
+                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName -- Got "
+                            + sdeUrl);
+        }
+        if (sdeUrl.indexOf("sde://") == -1) {
+            sdeUrl.delete(0, 5);
+        } else {
+            sdeUrl.delete(0, 6);
+        }
+
+        int idx = sdeUrl.indexOf(":");
+        if (idx == -1) {
+            throw new IllegalArgumentException(
+                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
+        }
+        sdeUser = sdeUrl.substring(0, idx);
+        sdeUrl.delete(0, idx);
+
+        idx = sdeUrl.indexOf("@");
+        if (idx == -1) {
+            throw new IllegalArgumentException(
+                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
+        }
+        sdePass = sdeUrl.substring(1, idx);
+        sdeUrl.delete(0, idx);
+
+        idx = sdeUrl.indexOf(":");
+        if (idx == -1) {
+            // there's no "port" specification. Assume 5151;
+            sdePort = 5151;
+
+            idx = sdeUrl.indexOf("/");
+            if (idx == -1) {
+                throw new IllegalArgumentException(
+                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
+            }
+            sdeHost = sdeUrl.substring(1, idx).toString();
+            sdeUrl.delete(0, idx);
+        } else {
+            sdeHost = sdeUrl.substring(1, idx).toString();
+            sdeUrl.delete(0, idx);
+
+            idx = sdeUrl.indexOf("/");
+            if (idx == -1) {
+                throw new IllegalArgumentException(
+                        "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
+            }
+            sdePort = Integer.parseInt(sdeUrl.substring(1, idx).toString());
+            sdeUrl.delete(0, idx);
+        }
+
+        idx = sdeUrl.indexOf("#");
+        if (idx == -1) {
+            throw new IllegalArgumentException(
+                    "ArcSDE Raster URL must be of the form sde://user:pass@sdehost:port/[dbname]#rasterTableName");
+        }
+        sdeDBName = sdeUrl.substring(1, idx).toString();
+        sdeUrl.delete(0, idx);
+
+        Map<String, String> params = new HashMap<String, String>();
+        params.put(ArcSDEConnectionConfig.SERVER_NAME_PARAM_NAME, sdeHost);
+        params.put(ArcSDEConnectionConfig.PORT_NUMBER_PARAM_NAME, String.valueOf(sdePort));
+        params.put(ArcSDEConnectionConfig.INSTANCE_NAME_PARAM_NAME, sdeDBName);
+        params.put(ArcSDEConnectionConfig.USER_NAME_PARAM_NAME, sdeUser);
+        params.put(ArcSDEConnectionConfig.PASSWORD_PARAM_NAME, sdePass);
+        params.put(ArcSDEConnectionConfig.MIN_CONNECTIONS_PARAM_NAME, "1");
+        params.put(ArcSDEConnectionConfig.MAX_CONNECTIONS_PARAM_NAME, "20");
+        params.put(ArcSDEConnectionConfig.CONNECTION_TIMEOUT_PARAM_NAME, "-1");// do not wait
+
+        ArcSDEConnectionConfig config = ArcSDEConnectionConfig.fromMap(params);
+        return config;
+    }
+
+    /**
+     * Used by test code to indicate wether to fail when a raster lacks statistics, since we can't
+     * create statistics with the ArcSDE Java API
+     *
+     * @param statisticsMandatory
+     */
+    void setStatisticsMandatory(final boolean statisticsMandatory) {
+        this.statisticsMandatory = statisticsMandatory;
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,63 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible raster compression types in Arcsde (ie,
- * {@code SeRaster#SE_COMPRESSION_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/CompressionType.java $
- */
-public enum CompressionType {
-    COMPRESSION_JP2, COMPRESSION_JPEG, COMPRESSION_LZ77, COMPRESSION_NONE;
-    static {
-        COMPRESSION_JP2.setSdeTypeId(SeRaster.SE_COMPRESSION_JP2);
-        COMPRESSION_JPEG.setSdeTypeId(SeRaster.SE_COMPRESSION_JPEG);
-        COMPRESSION_LZ77.setSdeTypeId(SeRaster.SE_COMPRESSION_LZ77);
-        COMPRESSION_NONE.setSdeTypeId(SeRaster.SE_COMPRESSION_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeCompressionType() {
-        return this.typeId;
-    }
-
-    public static CompressionType valueOf(final int seCompressionType) {
-        for (CompressionType type : CompressionType.values()) {
-            if (type.getSeCompressionType() == seCompressionType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Compression type " + seCompressionType
-                + " does not exist");
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/CompressionType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.util.NoSuchElementException;
+
+import com.esri.sde.sdk.client.SeRaster;
+
+/**
+ * An enumeration that mirrors the different possible raster compression types in Arcsde (ie,
+ * {@code SeRaster#SE_COMPRESSION_*})
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/CompressionType.java $
+ */
+public enum CompressionType {
+    COMPRESSION_JP2, COMPRESSION_JPEG, COMPRESSION_LZ77, COMPRESSION_NONE;
+    static {
+        COMPRESSION_JP2.setSdeTypeId(SeRaster.SE_COMPRESSION_JP2);
+        COMPRESSION_JPEG.setSdeTypeId(SeRaster.SE_COMPRESSION_JPEG);
+        COMPRESSION_LZ77.setSdeTypeId(SeRaster.SE_COMPRESSION_LZ77);
+        COMPRESSION_NONE.setSdeTypeId(SeRaster.SE_COMPRESSION_NONE);
+    }
+
+    private int typeId;
+
+    private void setSdeTypeId(int typeId) {
+        this.typeId = typeId;
+    }
+
+    public int getSeCompressionType() {
+        return this.typeId;
+    }
+
+    public static CompressionType valueOf(final int seCompressionType) {
+        for (CompressionType type : CompressionType.values()) {
+            if (type.getSeCompressionType() == seCompressionType) {
+                return type;
+            }
+        }
+        throw new NoSuchElementException("Compression type " + seCompressionType
+                + " does not exist");
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,521 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.geom.Point2D;
-import java.awt.image.DataBuffer;
-import java.awt.image.DataBufferByte;
-import java.awt.image.DataBufferUShort;
-import java.awt.image.IndexColorModel;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.geotools.arcsde.ArcSdeException;
-import org.geotools.arcsde.session.Command;
-import org.geotools.arcsde.session.ISession;
-import org.geotools.arcsde.util.ArcSDEUtils;
-import org.geotools.data.DataSourceException;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.referencing.crs.DefaultEngineeringCRS;
-import org.geotools.util.logging.Logging;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.esri.sde.sdk.client.SDEPoint;
-import com.esri.sde.sdk.client.SeColumnDefinition;
-import com.esri.sde.sdk.client.SeConnection;
-import com.esri.sde.sdk.client.SeCoordinateReference;
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeExtent;
-import com.esri.sde.sdk.client.SeQuery;
-import com.esri.sde.sdk.client.SeRaster;
-import com.esri.sde.sdk.client.SeRasterAttr;
-import com.esri.sde.sdk.client.SeRasterBand;
-import com.esri.sde.sdk.client.SeRasterColumn;
-import com.esri.sde.sdk.client.SeRow;
-import com.esri.sde.sdk.client.SeSqlConstruct;
-import com.esri.sde.sdk.client.SeTable;
-
-/**
- * Session command to gather information for an ArcSDE Raster, such as dimensions, spatial extent,
- * number of pyramid levels, etc; into a {@link RasterDatasetInfo}
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.8
- * @source $UR$
- */
-public class GatherCoverageMetadataCommand extends Command<RasterDatasetInfo> {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private final boolean statisticsMandatory;
-
-    private final String rasterTableName;
-
-    public GatherCoverageMetadataCommand(final String rasterTableName,
-            final boolean statisticsMandatory) {
-        this.rasterTableName = rasterTableName;
-        this.statisticsMandatory = statisticsMandatory;
-    }
-
-    /**
-     * @throws IOException
-     *             if an exception occurs accessing the raster metadata
-     * @throws SeException
-     * @throws IllegalArgumentException
-     *             if the raster has no CRS, contains no raster attributes, has no pyramids, no
-     *             bands or no statistics
-     */
-    @Override
-    public RasterDatasetInfo execute(ISession session, SeConnection connection) throws SeException,
-            IOException {
-        LOGGER.fine("Gathering raster dataset metadata for " + rasterTableName);
-        final String[] rasterColumns = getRasterColumns(connection, rasterTableName);
-        final List<RasterInfo> rastersLayoutInfo = new ArrayList<RasterInfo>();
-        {
-            final List<SeRasterAttr> rasterAttributes;
-            rasterAttributes = getSeRasterAttr(connection, rasterTableName, rasterColumns);
-
-            if (rasterAttributes.size() == 0) {
-                throw new IllegalArgumentException("Table " + rasterTableName
-                        + " contains no raster datasets");
-            }
-
-            final CoordinateReferenceSystem coverageCrs;
-
-            /*
-             * by bandId map of colormaps. The dataset may be composed of more than one raster so we
-             * gather all the colormaps once and held them here by rasterband id
-             */
-            final Map<Long, IndexColorModel> rastersColorMaps;
-            {
-                final SeRasterColumn rasterColumn;
-                final SeRasterBand sampleBand;
-                final long rasterColumnId;
-                final int bitsPerSample;
-                try {
-                    SeRasterAttr ratt = rasterAttributes.get(0);
-                    rasterColumn = new SeRasterColumn(connection, ratt.getRasterColumnId());
-                    rasterColumnId = rasterColumn.getID().longValue();
-                    sampleBand = ratt.getBands()[0];
-                    bitsPerSample = RasterCellType.valueOf(ratt.getPixelType()).getBitsPerSample();
-                } catch (SeException e) {
-                    throw new ArcSdeException(e);
-                }
-                final SeCoordinateReference seCoordRef = rasterColumn.getCoordRef();
-                if (seCoordRef == null) {
-                    throw new IllegalArgumentException(rasterTableName
-                            + " has no coordinate reference system set");
-                }
-                LOGGER.finer("Looking CRS for raster column " + rasterTableName);
-                coverageCrs = ArcSDEUtils.findCompatibleCRS(seCoordRef);
-                if (DefaultEngineeringCRS.CARTESIAN_2D == coverageCrs) {
-                    LOGGER.warning("Raster " + rasterTableName
-                            + " has not CRS set, using DefaultEngineeringCRS.CARTESIAN_2D");
-                }
-                if (sampleBand.hasColorMap()) {
-                    rastersColorMaps = loadColorMaps(rasterColumnId, bitsPerSample, connection);
-                } else {
-                    rastersColorMaps = Collections.emptyMap();
-                }
-
-            }
-            try {
-                for (SeRasterAttr rAtt : rasterAttributes) {
-                    LOGGER.fine("Gathering raster metadata for " + rasterTableName + " raster "
-                            + rAtt.getRasterId().longValue());
-
-                    if (rAtt.getMaxLevel() == 0) {
-                        throw new IllegalArgumentException(
-                                "Raster cotains no pyramid levels, we don't support non pyramid rasters");
-                    }
-                    if (rAtt.getNumBands() == 0) {
-                        throw new IllegalArgumentException("Raster "
-                                + rAtt.getRasterId().longValue() + " in " + rasterTableName
-                                + " contains no raster attribtues");
-                    }
-                    if (this.statisticsMandatory && !rAtt.getBandInfo(1).hasStats()) {
-                        throw new IllegalArgumentException(rasterTableName
-                                + " has no statistics generated (or not all it's rasters have). "
-                                + "Please use sderaster -o stats to create them before use");
-                    }
-
-                    RasterInfo rasterInfo = new RasterInfo(rAtt, coverageCrs);
-                    rastersLayoutInfo.add(rasterInfo);
-
-                    final GeneralEnvelope originalEnvelope;
-                    originalEnvelope = calculateOriginalEnvelope(rAtt, coverageCrs);
-                    rasterInfo.setOriginalEnvelope(originalEnvelope);
-                    final List<RasterBandInfo> bands;
-                    bands = setUpBandInfo(connection, rAtt, rastersColorMaps);
-                    rasterInfo.setBands(bands);
-                    if (LOGGER.isLoggable(Level.FINER)) {
-                        LOGGER.finer("Gathered metadata for " + rasterTableName + "#"
-                                + rAtt.getRasterId().longValue() + ":\n" + rasterInfo.toString());
-                    }
-                }
-            } catch (SeException e) {
-                throw new ArcSdeException("Gathering raster dataset information", e);
-            }
-        }
-
-        RasterDatasetInfo rasterInfo = new RasterDatasetInfo();
-        rasterInfo.setRasterTable(rasterTableName);
-        rasterInfo.setRasterColumns(rasterColumns);
-        rasterInfo.setPyramidInfo(rastersLayoutInfo);
-
-        return rasterInfo;
-    }
-
-    private String[] getRasterColumns(final SeConnection scon, final String rasterTable)
-            throws IOException, SeException {
-
-        String[] rasterColumns;
-        SeTable sTable = new SeTable(scon, rasterTable);
-        SeColumnDefinition[] cols;
-        try {
-            cols = sTable.describe();
-        } catch (SeException e) {
-            throw new ArcSdeException("Exception fetching the list of columns for table "
-                    + rasterTable, e);
-        }
-        List<String> fetchColumns = new ArrayList<String>(cols.length / 2);
-        for (int i = 0; i < cols.length; i++) {
-            if (cols[i].getType() == SeColumnDefinition.TYPE_RASTER)
-                fetchColumns.add(cols[i].getName());
-        }
-        if (fetchColumns.size() == 0) {
-            throw new DataSourceException("Couldn't find any TYPE_RASTER columns in ArcSDE table "
-                    + rasterTable);
-        }
-
-        rasterColumns = fetchColumns.toArray(new String[fetchColumns.size()]);
-        return rasterColumns;
-    }
-
-    private GeneralEnvelope calculateOriginalEnvelope(final SeRasterAttr rasterAttributes,
-            CoordinateReferenceSystem coverageCrs) throws IOException {
-        SeExtent sdeExtent;
-        try {
-            sdeExtent = rasterAttributes.getExtent();
-        } catch (SeException e) {
-            throw new ArcSdeException("Exception getting the raster extent", e);
-        }
-        GeneralEnvelope originalEnvelope = new GeneralEnvelope(coverageCrs);
-        originalEnvelope.setRange(0, sdeExtent.getMinX(), sdeExtent.getMaxX());
-        originalEnvelope.setRange(1, sdeExtent.getMinY(), sdeExtent.getMaxY());
-        return originalEnvelope;
-    }
-
-    private List<SeRasterAttr> getSeRasterAttr(SeConnection scon, String rasterTable,
-            String[] rasterColumns) throws IOException {
-
-        LOGGER.fine("Gathering raster attributes for " + rasterTable);
-        SeRasterAttr rasterAttributes;
-        LinkedList<SeRasterAttr> rasterAttList = new LinkedList<SeRasterAttr>();
-        SeQuery query = null;
-        try {
-            query = new SeQuery(scon, rasterColumns, new SeSqlConstruct(rasterTable));
-            query.prepareQuery();
-            query.execute();
-
-            SeRow row = query.fetch();
-            while (row != null) {
-                rasterAttributes = row.getRaster(0);
-                rasterAttList.addFirst(rasterAttributes);
-                row = query.fetch();
-            }
-        } catch (SeException se) {
-            throw new ArcSdeException("Error fetching raster attributes for " + rasterTable, se);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    throw new ArcSdeException(e);
-                }
-            }
-        }
-        LOGGER.fine("Found " + rasterAttList.size() + " raster attributes for " + rasterTable);
-        return rasterAttList;
-    }
-
-    /**
-     *
-     * @param band
-     * @param scon
-     * @return
-     * @throws ArcSdeException
-     */
-    private Map<Long, IndexColorModel> loadColorMaps(final long rasterColumnId,
-            final int bitsPerSample, SeConnection scon) throws IOException {
-        LOGGER.fine("Reading colormap for raster column " + rasterColumnId);
-
-        final String auxTableName = getAuxTableName(rasterColumnId, scon);
-        LOGGER.fine("Quering auxiliary table " + auxTableName + " for color map data");
-
-        Map<Long, IndexColorModel> colorMaps = new HashMap<Long, IndexColorModel>();
-        SeQuery query = null;
-        try {
-            SeSqlConstruct sqlConstruct = new SeSqlConstruct();
-            sqlConstruct.setTables(new String[] { auxTableName });
-            String whereClause = "TYPE = 3";
-            sqlConstruct.setWhere(whereClause);
-
-            query = new SeQuery(scon, new String[] { "RASTERBAND_ID", "OBJECT" }, sqlConstruct);
-            query.prepareQuery();
-            query.execute();
-
-            long bandId;
-            ByteArrayInputStream colorMapIS;
-            DataBuffer colorMapData;
-            IndexColorModel colorModel;
-
-            SeRow row = query.fetch();
-            while (row != null) {
-                bandId = ((Number) row.getObject(0)).longValue();
-                colorMapIS = row.getBlob(1);
-
-                colorMapData = readColorMap(colorMapIS);
-                colorModel = RasterUtils.sdeColorMapToJavaColorModel(colorMapData, bitsPerSample);
-
-                colorMaps.put(Long.valueOf(bandId), colorModel);
-
-                row = query.fetch();
-            }
-        } catch (SeException e) {
-            throw new ArcSdeException("Error fetching colormap data for column " + rasterColumnId
-                    + " from table " + auxTableName, e);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
-                            + "fetch colormap data", e);
-                }
-            }
-        }
-        LOGGER.fine("Read color map data for " + colorMaps.size() + " rasters");
-        return colorMaps;
-    }
-
-    private DataBuffer readColorMap(final ByteArrayInputStream colorMapIS) throws IOException {
-
-        final DataInputStream dataIn = new DataInputStream(colorMapIS);
-        // discard unneeded data
-        dataIn.readInt();
-
-        final int colorSpaceType = dataIn.readInt();
-        final int numBanks;
-        if (colorSpaceType == SeRaster.SE_COLORMAP_RGB) {
-            numBanks = 3;
-        } else if (colorSpaceType == SeRaster.SE_COLORMAP_RGBA) {
-            numBanks = 4;
-        } else {
-            throw new IllegalStateException("Got unknown colormap type: " + colorSpaceType);
-        }
-        LOGGER.finest("Colormap has " + numBanks + " color components");
-
-        final int buffType = dataIn.readInt();
-        final int numElems = dataIn.readInt();
-        LOGGER.finest("ColorMap length: " + numElems);
-
-        final DataBuffer buff;
-        if (buffType == SeRaster.SE_COLORMAP_DATA_BYTE) {
-            LOGGER.finest("Creating Byte data buffer for " + numBanks + " banks and " + numElems
-                    + " elements per bank");
-            buff = new DataBufferByte(numElems, numBanks);
-            for (int elem = 0; elem < numElems; elem++) {
-                for (int bank = 0; bank < numBanks; bank++) {
-                    int val = dataIn.readUnsignedByte();
-                    buff.setElem(bank, elem, val);
-                }
-            }
-        } else if (buffType == SeRaster.SE_COLORMAP_DATA_SHORT) {
-            LOGGER.finest("Creating Short data buffer for " + numBanks + " banks and " + numElems
-                    + " elements per bank");
-            buff = new DataBufferUShort(numElems, numBanks);
-            for (int elem = 0; elem < numElems; elem++) {
-                for (int bank = 0; bank < numBanks; bank++) {
-                    int val = dataIn.readUnsignedShort();
-                    buff.setElem(bank, elem, val);
-                }
-            }
-        } else {
-            throw new IllegalStateException("Unknown databuffer type from colormap header: "
-                    + buffType + " expected one of TYPE_BYTE, TYPE_SHORT");
-        }
-
-        assert dataIn.read() == -1 : "color map data should have been exausted";
-        return buff;
-    }
-
-    private String getAuxTableName(long rasterColumnId, SeConnection scon) throws IOException {
-
-        final String owner;
-        SeQuery query = null;
-        try {
-            final String dbaName = scon.getSdeDbaName();
-            String rastersColumnsTable = dbaName + ".SDE_RASTER_COLUMNS";
-
-            SeSqlConstruct sqlCons = new SeSqlConstruct(rastersColumnsTable);
-            sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
-
-            try {
-                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
-                query.prepareQuery();
-            } catch (SeException e) {
-                // sde 9.3 calls it raster_columns, not sde_raster_columns...
-                rastersColumnsTable = dbaName + ".RASTER_COLUMNS";
-                sqlCons = new SeSqlConstruct(rastersColumnsTable);
-                sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
-                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
-                query.prepareQuery();
-            }
-            query.execute();
-
-            SeRow row = query.fetch();
-            if (row == null) {
-                throw new IllegalArgumentException("No raster column registered with id "
-                        + rasterColumnId);
-            }
-            owner = row.getString(0);
-            query.close();
-        } catch (SeException e) {
-            throw new ArcSdeException("Error getting auxiliary table for raster column "
-                    + rasterColumnId, e);
-        } finally {
-            if (query != null) {
-                try {
-                    query.close();
-                } catch (SeException e) {
-                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
-                            + "fetch colormap data", e);
-                }
-            }
-        }
-
-        final String auxTableName = owner + ".SDE_AUX_" + rasterColumnId;
-
-        return auxTableName;
-    }
-
-    private List<RasterBandInfo> setUpBandInfo(SeConnection scon, SeRasterAttr rasterAttributes,
-            Map<Long, IndexColorModel> rastersColorMaps) throws IOException {
-        final int numBands;
-        final SeRasterBand[] seBands;
-        final RasterCellType cellType;
-        try {
-            numBands = rasterAttributes.getNumBands();
-            seBands = rasterAttributes.getBands();
-            cellType = RasterCellType.valueOf(rasterAttributes.getPixelType());
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-
-        List<RasterBandInfo> detachedBandInfo = new ArrayList<RasterBandInfo>(numBands);
-
-        RasterBandInfo bandInfo;
-        SeRasterBand band;
-        for (int bandN = 0; bandN < numBands; bandN++) {
-            band = seBands[bandN];
-            bandInfo = new RasterBandInfo();
-            final int bitsPerSample = cellType.getBitsPerSample();
-            setBandInfo(numBands, bandInfo, band, scon, bitsPerSample, rastersColorMaps);
-            detachedBandInfo.add(bandInfo);
-        }
-        return detachedBandInfo;
-    }
-
-    /**
-     *
-     * @param numBands
-     * @param bandInfo
-     * @param band
-     * @param scon
-     * @param bitsPerSample
-     *            only used if the band is colormapped to create the IndexColorModel
-     * @throws IOException
-     */
-    private void setBandInfo(final int numBands, final RasterBandInfo bandInfo,
-            final SeRasterBand band, final SeConnection scon, int bitsPerSample,
-            final Map<Long, IndexColorModel> colorMaps) throws IOException {
-
-        bandInfo.bandId = band.getId().longValue();
-        bandInfo.bandNumber = band.getBandNumber();
-        bandInfo.bandName = "Band " + bandInfo.bandNumber;
-
-        final boolean hasColorMap = band.hasColorMap();
-        if (hasColorMap) {
-            IndexColorModel colorMap = colorMaps.get(Long.valueOf(bandInfo.bandId));
-            LOGGER.finest("Setting band's color map: " + colorMap);
-            bandInfo.nativeColorMap = colorMap;
-            bandInfo.colorMap = RasterUtils.ensureNoDataPixelIsAvailable(colorMap);
-        } else {
-            bandInfo.nativeColorMap = null;
-        }
-
-        bandInfo.compressionType = CompressionType.valueOf(band.getCompressionType());
-        bandInfo.cellType = RasterCellType.valueOf(band.getPixelType());
-        bandInfo.interleaveType = InterleaveType.valueOf(band.getInterleave());
-        bandInfo.interpolationType = InterpolationType.valueOf(band.getInterpolation());
-        bandInfo.hasStats = band.hasStats();
-        if (bandInfo.hasStats) {
-            try {
-                bandInfo.statsMin = band.getStatsMin();
-                bandInfo.statsMax = band.getStatsMax();
-                bandInfo.statsMean = band.getStatsMean();
-                bandInfo.statsStdDev = band.getStatsStdDev();
-            } catch (SeException e) {
-                throw new ArcSdeException(e);
-            }
-            // double noDataValue = 0;
-            // bandInfo.noDataValue = noDataValue;
-        } else {
-            bandInfo.statsMin = java.lang.Double.NaN;
-            bandInfo.statsMax = java.lang.Double.NaN;
-            bandInfo.statsMean = java.lang.Double.NaN;
-            bandInfo.statsStdDev = java.lang.Double.NaN;
-        }
-        if (bandInfo.getColorMap() != null) {
-            bandInfo.noDataValue = RasterUtils.determineNoDataValue(bandInfo.getColorMap());
-        } else {
-            double statsMin = bandInfo.getStatsMin();
-            double statsMax = bandInfo.getStatsMax();
-            RasterCellType nativeCellType = bandInfo.getCellType();
-            bandInfo.noDataValue = RasterUtils.determineNoDataValue(numBands, statsMin, statsMax,
-                    nativeCellType);
-        }
-        SDEPoint tOrigin;
-        try {
-            tOrigin = band.getTileOrigin();
-        } catch (SeException e) {
-            throw new ArcSdeException(e);
-        }
-        bandInfo.tileOrigin = new Point2D.Double(tOrigin.getX(), tOrigin.getY());
-    }
-
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/GatherCoverageMetadataCommand.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,521 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.geom.Point2D;
+import java.awt.image.DataBuffer;
+import java.awt.image.DataBufferByte;
+import java.awt.image.DataBufferUShort;
+import java.awt.image.IndexColorModel;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.geotools.arcsde.ArcSdeException;
+import org.geotools.arcsde.session.Command;
+import org.geotools.arcsde.session.ISession;
+import org.geotools.arcsde.util.ArcSDEUtils;
+import org.geotools.data.DataSourceException;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.referencing.crs.DefaultEngineeringCRS;
+import org.geotools.util.logging.Logging;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.esri.sde.sdk.client.SDEPoint;
+import com.esri.sde.sdk.client.SeColumnDefinition;
+import com.esri.sde.sdk.client.SeConnection;
+import com.esri.sde.sdk.client.SeCoordinateReference;
+import com.esri.sde.sdk.client.SeException;
+import com.esri.sde.sdk.client.SeExtent;
+import com.esri.sde.sdk.client.SeQuery;
+import com.esri.sde.sdk.client.SeRaster;
+import com.esri.sde.sdk.client.SeRasterAttr;
+import com.esri.sde.sdk.client.SeRasterBand;
+import com.esri.sde.sdk.client.SeRasterColumn;
+import com.esri.sde.sdk.client.SeRow;
+import com.esri.sde.sdk.client.SeSqlConstruct;
+import com.esri.sde.sdk.client.SeTable;
+
+/**
+ * Session command to gather information for an ArcSDE Raster, such as dimensions, spatial extent,
+ * number of pyramid levels, etc; into a {@link RasterDatasetInfo}
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.8
+ * @source $UR$
+ */
+public class GatherCoverageMetadataCommand extends Command<RasterDatasetInfo> {
+
+    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
+
+    private final boolean statisticsMandatory;
+
+    private final String rasterTableName;
+
+    public GatherCoverageMetadataCommand(final String rasterTableName,
+            final boolean statisticsMandatory) {
+        this.rasterTableName = rasterTableName;
+        this.statisticsMandatory = statisticsMandatory;
+    }
+
+    /**
+     * @throws IOException
+     *             if an exception occurs accessing the raster metadata
+     * @throws SeException
+     * @throws IllegalArgumentException
+     *             if the raster has no CRS, contains no raster attributes, has no pyramids, no
+     *             bands or no statistics
+     */
+    @Override
+    public RasterDatasetInfo execute(ISession session, SeConnection connection) throws SeException,
+            IOException {
+        LOGGER.fine("Gathering raster dataset metadata for " + rasterTableName);
+        final String[] rasterColumns = getRasterColumns(connection, rasterTableName);
+        final List<RasterInfo> rastersLayoutInfo = new ArrayList<RasterInfo>();
+        {
+            final List<SeRasterAttr> rasterAttributes;
+            rasterAttributes = getSeRasterAttr(connection, rasterTableName, rasterColumns);
+
+            if (rasterAttributes.size() == 0) {
+                throw new IllegalArgumentException("Table " + rasterTableName
+                        + " contains no raster datasets");
+            }
+
+            final CoordinateReferenceSystem coverageCrs;
+
+            /*
+             * by bandId map of colormaps. The dataset may be composed of more than one raster so we
+             * gather all the colormaps once and held them here by rasterband id
+             */
+            final Map<Long, IndexColorModel> rastersColorMaps;
+            {
+                final SeRasterColumn rasterColumn;
+                final SeRasterBand sampleBand;
+                final long rasterColumnId;
+                final int bitsPerSample;
+                try {
+                    SeRasterAttr ratt = rasterAttributes.get(0);
+                    rasterColumn = new SeRasterColumn(connection, ratt.getRasterColumnId());
+                    rasterColumnId = rasterColumn.getID().longValue();
+                    sampleBand = ratt.getBands()[0];
+                    bitsPerSample = RasterCellType.valueOf(ratt.getPixelType()).getBitsPerSample();
+                } catch (SeException e) {
+                    throw new ArcSdeException(e);
+                }
+                final SeCoordinateReference seCoordRef = rasterColumn.getCoordRef();
+                if (seCoordRef == null) {
+                    throw new IllegalArgumentException(rasterTableName
+                            + " has no coordinate reference system set");
+                }
+                LOGGER.finer("Looking CRS for raster column " + rasterTableName);
+                coverageCrs = ArcSDEUtils.findCompatibleCRS(seCoordRef);
+                if (DefaultEngineeringCRS.CARTESIAN_2D == coverageCrs) {
+                    LOGGER.warning("Raster " + rasterTableName
+                            + " has not CRS set, using DefaultEngineeringCRS.CARTESIAN_2D");
+                }
+                if (sampleBand.hasColorMap()) {
+                    rastersColorMaps = loadColorMaps(rasterColumnId, bitsPerSample, connection);
+                } else {
+                    rastersColorMaps = Collections.emptyMap();
+                }
+
+            }
+            try {
+                for (SeRasterAttr rAtt : rasterAttributes) {
+                    LOGGER.fine("Gathering raster metadata for " + rasterTableName + " raster "
+                            + rAtt.getRasterId().longValue());
+
+                    if (rAtt.getMaxLevel() == 0) {
+                        throw new IllegalArgumentException(
+                                "Raster cotains no pyramid levels, we don't support non pyramid rasters");
+                    }
+                    if (rAtt.getNumBands() == 0) {
+                        throw new IllegalArgumentException("Raster "
+                                + rAtt.getRasterId().longValue() + " in " + rasterTableName
+                                + " contains no raster attribtues");
+                    }
+                    if (this.statisticsMandatory && !rAtt.getBandInfo(1).hasStats()) {
+                        throw new IllegalArgumentException(rasterTableName
+                                + " has no statistics generated (or not all it's rasters have). "
+                                + "Please use sderaster -o stats to create them before use");
+                    }
+
+                    RasterInfo rasterInfo = new RasterInfo(rAtt, coverageCrs);
+                    rastersLayoutInfo.add(rasterInfo);
+
+                    final GeneralEnvelope originalEnvelope;
+                    originalEnvelope = calculateOriginalEnvelope(rAtt, coverageCrs);
+                    rasterInfo.setOriginalEnvelope(originalEnvelope);
+                    final List<RasterBandInfo> bands;
+                    bands = setUpBandInfo(connection, rAtt, rastersColorMaps);
+                    rasterInfo.setBands(bands);
+                    if (LOGGER.isLoggable(Level.FINER)) {
+                        LOGGER.finer("Gathered metadata for " + rasterTableName + "#"
+                                + rAtt.getRasterId().longValue() + ":\n" + rasterInfo.toString());
+                    }
+                }
+            } catch (SeException e) {
+                throw new ArcSdeException("Gathering raster dataset information", e);
+            }
+        }
+
+        RasterDatasetInfo rasterInfo = new RasterDatasetInfo();
+        rasterInfo.setRasterTable(rasterTableName);
+        rasterInfo.setRasterColumns(rasterColumns);
+        rasterInfo.setPyramidInfo(rastersLayoutInfo);
+
+        return rasterInfo;
+    }
+
+    private String[] getRasterColumns(final SeConnection scon, final String rasterTable)
+            throws IOException, SeException {
+
+        String[] rasterColumns;
+        SeTable sTable = new SeTable(scon, rasterTable);
+        SeColumnDefinition[] cols;
+        try {
+            cols = sTable.describe();
+        } catch (SeException e) {
+            throw new ArcSdeException("Exception fetching the list of columns for table "
+                    + rasterTable, e);
+        }
+        List<String> fetchColumns = new ArrayList<String>(cols.length / 2);
+        for (int i = 0; i < cols.length; i++) {
+            if (cols[i].getType() == SeColumnDefinition.TYPE_RASTER)
+                fetchColumns.add(cols[i].getName());
+        }
+        if (fetchColumns.size() == 0) {
+            throw new DataSourceException("Couldn't find any TYPE_RASTER columns in ArcSDE table "
+                    + rasterTable);
+        }
+
+        rasterColumns = fetchColumns.toArray(new String[fetchColumns.size()]);
+        return rasterColumns;
+    }
+
+    private GeneralEnvelope calculateOriginalEnvelope(final SeRasterAttr rasterAttributes,
+            CoordinateReferenceSystem coverageCrs) throws IOException {
+        SeExtent sdeExtent;
+        try {
+            sdeExtent = rasterAttributes.getExtent();
+        } catch (SeException e) {
+            throw new ArcSdeException("Exception getting the raster extent", e);
+        }
+        GeneralEnvelope originalEnvelope = new GeneralEnvelope(coverageCrs);
+        originalEnvelope.setRange(0, sdeExtent.getMinX(), sdeExtent.getMaxX());
+        originalEnvelope.setRange(1, sdeExtent.getMinY(), sdeExtent.getMaxY());
+        return originalEnvelope;
+    }
+
+    private List<SeRasterAttr> getSeRasterAttr(SeConnection scon, String rasterTable,
+            String[] rasterColumns) throws IOException {
+
+        LOGGER.fine("Gathering raster attributes for " + rasterTable);
+        SeRasterAttr rasterAttributes;
+        LinkedList<SeRasterAttr> rasterAttList = new LinkedList<SeRasterAttr>();
+        SeQuery query = null;
+        try {
+            query = new SeQuery(scon, rasterColumns, new SeSqlConstruct(rasterTable));
+            query.prepareQuery();
+            query.execute();
+
+            SeRow row = query.fetch();
+            while (row != null) {
+                rasterAttributes = row.getRaster(0);
+                rasterAttList.addFirst(rasterAttributes);
+                row = query.fetch();
+            }
+        } catch (SeException se) {
+            throw new ArcSdeException("Error fetching raster attributes for " + rasterTable, se);
+        } finally {
+            if (query != null) {
+                try {
+                    query.close();
+                } catch (SeException e) {
+                    throw new ArcSdeException(e);
+                }
+            }
+        }
+        LOGGER.fine("Found " + rasterAttList.size() + " raster attributes for " + rasterTable);
+        return rasterAttList;
+    }
+
+    /**
+     *
+     * @param band
+     * @param scon
+     * @return
+     * @throws ArcSdeException
+     */
+    private Map<Long, IndexColorModel> loadColorMaps(final long rasterColumnId,
+            final int bitsPerSample, SeConnection scon) throws IOException {
+        LOGGER.fine("Reading colormap for raster column " + rasterColumnId);
+
+        final String auxTableName = getAuxTableName(rasterColumnId, scon);
+        LOGGER.fine("Quering auxiliary table " + auxTableName + " for color map data");
+
+        Map<Long, IndexColorModel> colorMaps = new HashMap<Long, IndexColorModel>();
+        SeQuery query = null;
+        try {
+            SeSqlConstruct sqlConstruct = new SeSqlConstruct();
+            sqlConstruct.setTables(new String[] { auxTableName });
+            String whereClause = "TYPE = 3";
+            sqlConstruct.setWhere(whereClause);
+
+            query = new SeQuery(scon, new String[] { "RASTERBAND_ID", "OBJECT" }, sqlConstruct);
+            query.prepareQuery();
+            query.execute();
+
+            long bandId;
+            ByteArrayInputStream colorMapIS;
+            DataBuffer colorMapData;
+            IndexColorModel colorModel;
+
+            SeRow row = query.fetch();
+            while (row != null) {
+                bandId = ((Number) row.getObject(0)).longValue();
+                colorMapIS = row.getBlob(1);
+
+                colorMapData = readColorMap(colorMapIS);
+                colorModel = RasterUtils.sdeColorMapToJavaColorModel(colorMapData, bitsPerSample);
+
+                colorMaps.put(Long.valueOf(bandId), colorModel);
+
+                row = query.fetch();
+            }
+        } catch (SeException e) {
+            throw new ArcSdeException("Error fetching colormap data for column " + rasterColumnId
+                    + " from table " + auxTableName, e);
+        } finally {
+            if (query != null) {
+                try {
+                    query.close();
+                } catch (SeException e) {
+                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
+                            + "fetch colormap data", e);
+                }
+            }
+        }
+        LOGGER.fine("Read color map data for " + colorMaps.size() + " rasters");
+        return colorMaps;
+    }
+
+    private DataBuffer readColorMap(final ByteArrayInputStream colorMapIS) throws IOException {
+
+        final DataInputStream dataIn = new DataInputStream(colorMapIS);
+        // discard unneeded data
+        dataIn.readInt();
+
+        final int colorSpaceType = dataIn.readInt();
+        final int numBanks;
+        if (colorSpaceType == SeRaster.SE_COLORMAP_RGB) {
+            numBanks = 3;
+        } else if (colorSpaceType == SeRaster.SE_COLORMAP_RGBA) {
+            numBanks = 4;
+        } else {
+            throw new IllegalStateException("Got unknown colormap type: " + colorSpaceType);
+        }
+        LOGGER.finest("Colormap has " + numBanks + " color components");
+
+        final int buffType = dataIn.readInt();
+        final int numElems = dataIn.readInt();
+        LOGGER.finest("ColorMap length: " + numElems);
+
+        final DataBuffer buff;
+        if (buffType == SeRaster.SE_COLORMAP_DATA_BYTE) {
+            LOGGER.finest("Creating Byte data buffer for " + numBanks + " banks and " + numElems
+                    + " elements per bank");
+            buff = new DataBufferByte(numElems, numBanks);
+            for (int elem = 0; elem < numElems; elem++) {
+                for (int bank = 0; bank < numBanks; bank++) {
+                    int val = dataIn.readUnsignedByte();
+                    buff.setElem(bank, elem, val);
+                }
+            }
+        } else if (buffType == SeRaster.SE_COLORMAP_DATA_SHORT) {
+            LOGGER.finest("Creating Short data buffer for " + numBanks + " banks and " + numElems
+                    + " elements per bank");
+            buff = new DataBufferUShort(numElems, numBanks);
+            for (int elem = 0; elem < numElems; elem++) {
+                for (int bank = 0; bank < numBanks; bank++) {
+                    int val = dataIn.readUnsignedShort();
+                    buff.setElem(bank, elem, val);
+                }
+            }
+        } else {
+            throw new IllegalStateException("Unknown databuffer type from colormap header: "
+                    + buffType + " expected one of TYPE_BYTE, TYPE_SHORT");
+        }
+
+        assert dataIn.read() == -1 : "color map data should have been exausted";
+        return buff;
+    }
+
+    private String getAuxTableName(long rasterColumnId, SeConnection scon) throws IOException {
+
+        final String owner;
+        SeQuery query = null;
+        try {
+            final String dbaName = scon.getSdeDbaName();
+            String rastersColumnsTable = dbaName + ".SDE_RASTER_COLUMNS";
+
+            SeSqlConstruct sqlCons = new SeSqlConstruct(rastersColumnsTable);
+            sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
+
+            try {
+                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
+                query.prepareQuery();
+            } catch (SeException e) {
+                // sde 9.3 calls it raster_columns, not sde_raster_columns...
+                rastersColumnsTable = dbaName + ".RASTER_COLUMNS";
+                sqlCons = new SeSqlConstruct(rastersColumnsTable);
+                sqlCons.setWhere("RASTERCOLUMN_ID = " + rasterColumnId);
+                query = new SeQuery(scon, new String[] { "OWNER" }, sqlCons);
+                query.prepareQuery();
+            }
+            query.execute();
+
+            SeRow row = query.fetch();
+            if (row == null) {
+                throw new IllegalArgumentException("No raster column registered with id "
+                        + rasterColumnId);
+            }
+            owner = row.getString(0);
+            query.close();
+        } catch (SeException e) {
+            throw new ArcSdeException("Error getting auxiliary table for raster column "
+                    + rasterColumnId, e);
+        } finally {
+            if (query != null) {
+                try {
+                    query.close();
+                } catch (SeException e) {
+                    LOGGER.log(Level.INFO, "ignoring exception when closing query to "
+                            + "fetch colormap data", e);
+                }
+            }
+        }
+
+        final String auxTableName = owner + ".SDE_AUX_" + rasterColumnId;
+
+        return auxTableName;
+    }
+
+    private List<RasterBandInfo> setUpBandInfo(SeConnection scon, SeRasterAttr rasterAttributes,
+            Map<Long, IndexColorModel> rastersColorMaps) throws IOException {
+        final int numBands;
+        final SeRasterBand[] seBands;
+        final RasterCellType cellType;
+        try {
+            numBands = rasterAttributes.getNumBands();
+            seBands = rasterAttributes.getBands();
+            cellType = RasterCellType.valueOf(rasterAttributes.getPixelType());
+        } catch (SeException e) {
+            throw new ArcSdeException(e);
+        }
+
+        List<RasterBandInfo> detachedBandInfo = new ArrayList<RasterBandInfo>(numBands);
+
+        RasterBandInfo bandInfo;
+        SeRasterBand band;
+        for (int bandN = 0; bandN < numBands; bandN++) {
+            band = seBands[bandN];
+            bandInfo = new RasterBandInfo();
+            final int bitsPerSample = cellType.getBitsPerSample();
+            setBandInfo(numBands, bandInfo, band, scon, bitsPerSample, rastersColorMaps);
+            detachedBandInfo.add(bandInfo);
+        }
+        return detachedBandInfo;
+    }
+
+    /**
+     *
+     * @param numBands
+     * @param bandInfo
+     * @param band
+     * @param scon
+     * @param bitsPerSample
+     *            only used if the band is colormapped to create the IndexColorModel
+     * @throws IOException
+     */
+    private void setBandInfo(final int numBands, final RasterBandInfo bandInfo,
+            final SeRasterBand band, final SeConnection scon, int bitsPerSample,
+            final Map<Long, IndexColorModel> colorMaps) throws IOException {
+
+        bandInfo.bandId = band.getId().longValue();
+        bandInfo.bandNumber = band.getBandNumber();
+        bandInfo.bandName = "Band " + bandInfo.bandNumber;
+
+        final boolean hasColorMap = band.hasColorMap();
+        if (hasColorMap) {
+            IndexColorModel colorMap = colorMaps.get(Long.valueOf(bandInfo.bandId));
+            LOGGER.finest("Setting band's color map: " + colorMap);
+            bandInfo.nativeColorMap = colorMap;
+            bandInfo.colorMap = RasterUtils.ensureNoDataPixelIsAvailable(colorMap);
+        } else {
+            bandInfo.nativeColorMap = null;
+        }
+
+        bandInfo.compressionType = CompressionType.valueOf(band.getCompressionType());
+        bandInfo.cellType = RasterCellType.valueOf(band.getPixelType());
+        bandInfo.interleaveType = InterleaveType.valueOf(band.getInterleave());
+        bandInfo.interpolationType = InterpolationType.valueOf(band.getInterpolation());
+        bandInfo.hasStats = band.hasStats();
+        if (bandInfo.hasStats) {
+            try {
+                bandInfo.statsMin = band.getStatsMin();
+                bandInfo.statsMax = band.getStatsMax();
+                bandInfo.statsMean = band.getStatsMean();
+                bandInfo.statsStdDev = band.getStatsStdDev();
+            } catch (SeException e) {
+                throw new ArcSdeException(e);
+            }
+            // double noDataValue = 0;
+            // bandInfo.noDataValue = noDataValue;
+        } else {
+            bandInfo.statsMin = java.lang.Double.NaN;
+            bandInfo.statsMax = java.lang.Double.NaN;
+            bandInfo.statsMean = java.lang.Double.NaN;
+            bandInfo.statsStdDev = java.lang.Double.NaN;
+        }
+        if (bandInfo.getColorMap() != null) {
+            bandInfo.noDataValue = RasterUtils.determineNoDataValue(bandInfo.getColorMap());
+        } else {
+            double statsMin = bandInfo.getStatsMin();
+            double statsMax = bandInfo.getStatsMax();
+            RasterCellType nativeCellType = bandInfo.getCellType();
+            bandInfo.noDataValue = RasterUtils.determineNoDataValue(numBands, statsMin, statsMax,
+                    nativeCellType);
+        }
+        SDEPoint tOrigin;
+        try {
+            tOrigin = band.getTileOrigin();
+        } catch (SeException e) {
+            throw new ArcSdeException(e);
+        }
+        bandInfo.tileOrigin = new Point2D.Double(tOrigin.getX(), tOrigin.getY());
+    }
+
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,66 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible band interleave types in Arcsde (ie, {@code
- * SeRaster#SE_RASTER_INTERLEAVE_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/InterleaveType.java $
- */
-public enum InterleaveType {
-    INTERLEAVE_BIL, INTERLEAVE_BIL_91, INTERLEAVE_BIP, INTERLEAVE_BIP_91, INTERLEAVE_BSQ, INTERLEAVE_BSQ_91, INTERLEAVE_NONE;
-    static {
-        INTERLEAVE_BIL.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL);
-        INTERLEAVE_BIL_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL_91);
-        INTERLEAVE_BIP.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP);
-        INTERLEAVE_BIP_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP_91);
-        INTERLEAVE_BSQ.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ);
-        INTERLEAVE_BSQ_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ_91);
-        INTERLEAVE_NONE.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeRasterInterleaveType() {
-        return this.typeId;
-    }
-
-    public static InterleaveType valueOf(final int seRasterInterleaveType) {
-        for (InterleaveType type : InterleaveType.values()) {
-            if (type.getSeRasterInterleaveType() == seRasterInterleaveType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Raster interleave type " + seRasterInterleaveType
-                + " does not exist");
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterleaveType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,66 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.util.NoSuchElementException;
+
+import com.esri.sde.sdk.client.SeRaster;
+
+/**
+ * An enumeration that mirrors the different possible band interleave types in Arcsde (ie, {@code
+ * SeRaster#SE_RASTER_INTERLEAVE_*})
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/InterleaveType.java $
+ */
+public enum InterleaveType {
+    INTERLEAVE_BIL, INTERLEAVE_BIL_91, INTERLEAVE_BIP, INTERLEAVE_BIP_91, INTERLEAVE_BSQ, INTERLEAVE_BSQ_91, INTERLEAVE_NONE;
+    static {
+        INTERLEAVE_BIL.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL);
+        INTERLEAVE_BIL_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIL_91);
+        INTERLEAVE_BIP.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP);
+        INTERLEAVE_BIP_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BIP_91);
+        INTERLEAVE_BSQ.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ);
+        INTERLEAVE_BSQ_91.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_BSQ_91);
+        INTERLEAVE_NONE.setSdeTypeId(SeRaster.SE_RASTER_INTERLEAVE_NONE);
+    }
+
+    private int typeId;
+
+    private void setSdeTypeId(int typeId) {
+        this.typeId = typeId;
+    }
+
+    public int getSeRasterInterleaveType() {
+        return this.typeId;
+    }
+
+    public static InterleaveType valueOf(final int seRasterInterleaveType) {
+        for (InterleaveType type : InterleaveType.values()) {
+            if (type.getSeRasterInterleaveType() == seRasterInterleaveType) {
+                return type;
+            }
+        }
+        throw new NoSuchElementException("Raster interleave type " + seRasterInterleaveType
+                + " does not exist");
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,63 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.util.NoSuchElementException;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible raster interpolation types in Arcsde (ie,
- * {@code SeRaster#SE_INTERPOLATION_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/InterpolationType.java $
- */
-public enum InterpolationType {
-    INTERPOLATION_BICUBIC, INTERPOLATION_BILINEAR, INTERPOLATION_NEAREST, INTERPOLATION_NONE;
-    static {
-        INTERPOLATION_BICUBIC.setSdeTypeId(SeRaster.SE_INTERPOLATION_BICUBIC);
-        INTERPOLATION_BILINEAR.setSdeTypeId(SeRaster.SE_INTERPOLATION_BILINEAR);
-        INTERPOLATION_NEAREST.setSdeTypeId(SeRaster.SE_INTERPOLATION_NEAREST);
-        INTERPOLATION_NONE.setSdeTypeId(SeRaster.SE_INTERPOLATION_NONE);
-    }
-
-    private int typeId;
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeInterpolationType() {
-        return this.typeId;
-    }
-
-    public static InterpolationType valueOf(final int seInterpolationType) {
-        for (InterpolationType type : InterpolationType.values()) {
-            if (type.getSeInterpolationType() == seInterpolationType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Interpolation type " + seInterpolationType
-                + " does not exist");
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/InterpolationType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,63 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.util.NoSuchElementException;
+
+import com.esri.sde.sdk.client.SeRaster;
+
+/**
+ * An enumeration that mirrors the different possible raster interpolation types in Arcsde (ie,
+ * {@code SeRaster#SE_INTERPOLATION_*})
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/InterpolationType.java $
+ */
+public enum InterpolationType {
+    INTERPOLATION_BICUBIC, INTERPOLATION_BILINEAR, INTERPOLATION_NEAREST, INTERPOLATION_NONE;
+    static {
+        INTERPOLATION_BICUBIC.setSdeTypeId(SeRaster.SE_INTERPOLATION_BICUBIC);
+        INTERPOLATION_BILINEAR.setSdeTypeId(SeRaster.SE_INTERPOLATION_BILINEAR);
+        INTERPOLATION_NEAREST.setSdeTypeId(SeRaster.SE_INTERPOLATION_NEAREST);
+        INTERPOLATION_NONE.setSdeTypeId(SeRaster.SE_INTERPOLATION_NONE);
+    }
+
+    private int typeId;
+
+    private void setSdeTypeId(int typeId) {
+        this.typeId = typeId;
+    }
+
+    public int getSeInterpolationType() {
+        return this.typeId;
+    }
+
+    public static InterpolationType valueOf(final int seInterpolationType) {
+        for (InterpolationType type : InterpolationType.values()) {
+            if (type.getSeInterpolationType() == seInterpolationType) {
+                return type;
+            }
+        }
+        throw new NoSuchElementException("Interpolation type " + seInterpolationType
+                + " does not exist");
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,178 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.geom.Point2D;
-
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-/**
- * Represents one level in an ArcSDE pyramid. Holds information about a given pyramid level, like
- * resolution, x/y offsets, number of tiles high/wide, total pixel size and total envelope covered
- * by this level.
- *
- * @author sfarber
- *
- */
-final class PyramidLevelInfo {
-    private int pyramidLevel, xTiles, yTiles;
-
-    Point2D extentOffset;
-
-    Point imageOffset;
-
-    private double xRes, yRes;
-
-    private ReferencedEnvelope envelope;
-
-    public Dimension size;
-
-    /**
-     *
-     * @param level
-     *            the level index
-     * @param extent
-     *            the geographical extent the level covers
-     * @param imgOffset
-     *            the offset of the image at this level
-     * @param extOffset
-     *            the offset of the image extent at this level
-     * @param numTilesWide
-     * @param numTilesHigh
-     * @param levelSize
-     *            the size of the actual image inside the tiled pixel range
-     */
-    PyramidLevelInfo(int level, ReferencedEnvelope extent, Point imgOffset, Point2D extOffset,
-            int numTilesWide, int numTilesHigh, Dimension levelSize) {
-        this.pyramidLevel = level;
-        this.xRes = extent.getWidth() / levelSize.width;
-        this.yRes = extent.getHeight() / levelSize.height;
-        this.envelope = extent;
-        this.imageOffset = imgOffset;
-        this.extentOffset = extOffset;
-        this.xTiles = numTilesWide;
-        this.yTiles = numTilesHigh;
-        this.size = levelSize;
-    }
-
-    /**
-     * @return Which level in the pyramid this object represents
-     */
-    public int getLevel() {
-        return pyramidLevel;
-    }
-
-    /**
-     * @return The X and Y resolution in units/pixel for pixels at this level
-     */
-    public double getXRes() {
-        return xRes;
-    }
-
-    /**
-     * @return The X and Y resolution in units/pixel for pixels at this level
-     */
-    public double getYRes() {
-        return yRes;
-    }
-
-    /**
-     * @return DOCUMENT ME!!!
-     */
-    public int getXOffset() {
-        return imageOffset.x;
-    }
-
-    /**
-     * @return DOCUMENT ME!!!
-     */
-    public int getYOffset() {
-        return imageOffset.y;
-    }
-
-    /**
-     * @return The total number of tiles covering the width of this level
-     */
-    public int getNumTilesWide() {
-        return xTiles;
-    }
-
-    /**
-     * @return The total number of tiles covering the height of this level
-     */
-    public int getNumTilesHigh() {
-        return yTiles;
-    }
-
-    /**
-     * The envelope covering the image grid range inside fully tiled image at this pyramid level
-     *
-     * @return The geographical area covered by the {@link #getImageRange() grid range} of the
-     *         raster at this pyramid level
-     */
-    public ReferencedEnvelope getImageEnvelope() {
-        final double deltaX = extentOffset.getX();
-        final double deltaY = extentOffset.getY();
-        double minx = this.envelope.getMinX() - deltaX;
-        double miny = this.envelope.getMinY() - deltaY;
-        double maxx = minx + this.envelope.getWidth();
-        double maxy = miny + this.envelope.getHeight();
-
-        CoordinateReferenceSystem crs = this.envelope.getCoordinateReferenceSystem();
-        ReferencedEnvelope imageExtent = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
-
-        return imageExtent;
-    }
-
-    /**
-     * @return The total number of pixels in the image at this level as whole tiles
-     */
-    public Dimension getSize() {
-        return size;
-    }
-
-    /**
-     * The rectangle covering the actual raster data inside the tiled space
-     *
-     * @return
-     */
-    public Rectangle getImageRange() {
-        final int offsetX = getXOffset();
-        final int offsetY = getYOffset();
-
-        /*
-         * get the range of actual data pixels in this pyramid level in pixel space, offset and
-         * trailing no data pixels to fill up the tile space do not count
-         */
-        final Rectangle levelRange = new Rectangle(offsetX, offsetY, size.width, size.height);
-        return levelRange;
-    }
-
-    @Override
-    public String toString() {
-        return "[level: " + pyramidLevel + " size: " + size.width + "x" + size.height + "  xRes: "
-                + xRes + "  yRes: " + yRes + "  xOffset: " + getXOffset() + "  yOffset: "
-                + getYOffset() + "  extent: " + envelope.getMinX() + "," + envelope.getMinY() + " "
-                + envelope.getMaxX() + "," + envelope.getMaxY() + "  tilesWide: " + xTiles
-                + "  tilesHigh: " + yTiles + "]";
-    }
-}
\ No newline at end of file

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/PyramidLevelInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,178 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.geom.Point2D;
+
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+/**
+ * Represents one level in an ArcSDE pyramid. Holds information about a given pyramid level, like
+ * resolution, x/y offsets, number of tiles high/wide, total pixel size and total envelope covered
+ * by this level.
+ *
+ * @author sfarber
+ *
+ */
+final class PyramidLevelInfo {
+    private int pyramidLevel, xTiles, yTiles;
+
+    Point2D extentOffset;
+
+    Point imageOffset;
+
+    private double xRes, yRes;
+
+    private ReferencedEnvelope envelope;
+
+    public Dimension size;
+
+    /**
+     *
+     * @param level
+     *            the level index
+     * @param extent
+     *            the geographical extent the level covers
+     * @param imgOffset
+     *            the offset of the image at this level
+     * @param extOffset
+     *            the offset of the image extent at this level
+     * @param numTilesWide
+     * @param numTilesHigh
+     * @param levelSize
+     *            the size of the actual image inside the tiled pixel range
+     */
+    PyramidLevelInfo(int level, ReferencedEnvelope extent, Point imgOffset, Point2D extOffset,
+            int numTilesWide, int numTilesHigh, Dimension levelSize) {
+        this.pyramidLevel = level;
+        this.xRes = extent.getWidth() / levelSize.width;
+        this.yRes = extent.getHeight() / levelSize.height;
+        this.envelope = extent;
+        this.imageOffset = imgOffset;
+        this.extentOffset = extOffset;
+        this.xTiles = numTilesWide;
+        this.yTiles = numTilesHigh;
+        this.size = levelSize;
+    }
+
+    /**
+     * @return Which level in the pyramid this object represents
+     */
+    public int getLevel() {
+        return pyramidLevel;
+    }
+
+    /**
+     * @return The X and Y resolution in units/pixel for pixels at this level
+     */
+    public double getXRes() {
+        return xRes;
+    }
+
+    /**
+     * @return The X and Y resolution in units/pixel for pixels at this level
+     */
+    public double getYRes() {
+        return yRes;
+    }
+
+    /**
+     * @return DOCUMENT ME!!!
+     */
+    public int getXOffset() {
+        return imageOffset.x;
+    }
+
+    /**
+     * @return DOCUMENT ME!!!
+     */
+    public int getYOffset() {
+        return imageOffset.y;
+    }
+
+    /**
+     * @return The total number of tiles covering the width of this level
+     */
+    public int getNumTilesWide() {
+        return xTiles;
+    }
+
+    /**
+     * @return The total number of tiles covering the height of this level
+     */
+    public int getNumTilesHigh() {
+        return yTiles;
+    }
+
+    /**
+     * The envelope covering the image grid range inside fully tiled image at this pyramid level
+     *
+     * @return The geographical area covered by the {@link #getImageRange() grid range} of the
+     *         raster at this pyramid level
+     */
+    public ReferencedEnvelope getImageEnvelope() {
+        final double deltaX = extentOffset.getX();
+        final double deltaY = extentOffset.getY();
+        double minx = this.envelope.getMinX() - deltaX;
+        double miny = this.envelope.getMinY() - deltaY;
+        double maxx = minx + this.envelope.getWidth();
+        double maxy = miny + this.envelope.getHeight();
+
+        CoordinateReferenceSystem crs = this.envelope.getCoordinateReferenceSystem();
+        ReferencedEnvelope imageExtent = new ReferencedEnvelope(minx, maxx, miny, maxy, crs);
+
+        return imageExtent;
+    }
+
+    /**
+     * @return The total number of pixels in the image at this level as whole tiles
+     */
+    public Dimension getSize() {
+        return size;
+    }
+
+    /**
+     * The rectangle covering the actual raster data inside the tiled space
+     *
+     * @return
+     */
+    public Rectangle getImageRange() {
+        final int offsetX = getXOffset();
+        final int offsetY = getYOffset();
+
+        /*
+         * get the range of actual data pixels in this pyramid level in pixel space, offset and
+         * trailing no data pixels to fill up the tile space do not count
+         */
+        final Rectangle levelRange = new Rectangle(offsetX, offsetY, size.width, size.height);
+        return levelRange;
+    }
+
+    @Override
+    public String toString() {
+        return "[level: " + pyramidLevel + " size: " + size.width + "x" + size.height + "  xRes: "
+                + xRes + "  yRes: " + yRes + "  xOffset: " + getXOffset() + "  yOffset: "
+                + getYOffset() + "  extent: " + envelope.getMinX() + "," + envelope.getMinY() + " "
+                + envelope.getMaxX() + "," + envelope.getMaxY() + "  tilesWide: " + xTiles
+                + "  tilesHigh: " + yTiles + "]";
+    }
+}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,186 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.geom.Point2D;
-import java.awt.geom.Point2D.Double;
-import java.awt.image.IndexColorModel;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/RasterBandInfo.java $
- */
-public class RasterBandInfo {
-
-    long bandId;
-
-    String bandName;
-
-    int bandNumber;
-
-    /**
-     * the color map as it is on the database, except that we always create a color map with alpha
-     * channel regardless of whether the native on has alpha or not, to account for the no-data
-     * pixel to be a transparent one where appropriate
-     */
-    IndexColorModel nativeColorMap;
-
-    /**
-     * The color map as it is going to be used by this library. May differ from the native one
-     * either in the number of elements (when the native color map is not full and it has no
-     * transparent pixel to be used as no-data value), or in the pixel depth (when the native
-     * colormap is full, has no no-data pixel, and hence it needs to be promoted to a higher
-     * transfer type to make room for a no-data index)
-     */
-    IndexColorModel colorMap;
-
-    /**
-     * The band's no-data value.
-     */
-    Number noDataValue;
-
-    CompressionType compressionType;
-
-    RasterCellType cellType;
-
-    InterleaveType interleaveType;
-
-    InterpolationType interpolationType;
-
-    boolean hasStats;
-
-    Point2D.Double tileOrigin;
-
-    double statsMin;
-
-    double statsMax;
-
-    double statsMean;
-
-    double statsStdDev;
-
-    public RasterBandInfo() {
-        // do nothing
-    }
-
-    public RasterBandInfo(long bandId, RasterCellType nativeType, Number noDataValue,
-            double statsMin, double statsMax) {
-        this.bandId = bandId;
-        this.cellType = nativeType;
-        this.noDataValue = noDataValue;
-        this.statsMin = statsMin;
-        this.statsMax = statsMax;
-    }
-
-    /**
-     * @return the ArcSDE identifier for the band
-     */
-    public long getBandId() {
-        return bandId;
-    }
-
-    public String getBandName() {
-        return bandName;
-    }
-
-    public int getBandNumber() {
-        return bandNumber;
-    }
-
-    public boolean isColorMapped() {
-        return nativeColorMap != null;
-    }
-
-    public CompressionType getCompressionType() {
-        return compressionType;
-    }
-
-    public RasterCellType getCellType() {
-        return cellType;
-    }
-
-    public InterleaveType getInterleaveType() {
-        return interleaveType;
-    }
-
-    public InterpolationType getInterpolationType() {
-        return interpolationType;
-    }
-
-    public boolean isHasStats() {
-        return hasStats;
-    }
-
-    public Double getTileOrigin() {
-        return tileOrigin;
-    }
-
-    public IndexColorModel getNativeColorMap() {
-        return nativeColorMap;
-    }
-
-    public IndexColorModel getColorMap() {
-        return colorMap;
-    }
-
-    public double getStatsMin() {
-        return statsMin;
-    }
-
-    public double getStatsMax() {
-        return statsMax;
-    }
-
-    public double getStatsMean() {
-        return statsMean;
-    }
-
-    public double getStatsStdDev() {
-        return statsStdDev;
-    }
-
-    public Number getNoDataValue() {
-        return noDataValue;
-    }
-
-    @SuppressWarnings("nls")
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append(getBandName());
-        sb.append("[ id:").append(getBandId());
-        sb.append(", type:").append(getCellType());
-        sb.append(", samples: nodata=").append(getNoDataValue()).append(" min=").append(
-                getStatsMin()).append(" max=").append(getStatsMax()).append(" mean=").append(
-                getStatsMean()).append(" stddev=").append(getStatsStdDev());
-        /*
-         * sb.append(", tile origin: ").append((int) getTileOrigin().x).append(",").append( (int)
-         * getTileOrigin().y);
-         */
-        sb.append(", compression:").append(getCompressionType());
-        sb.append(", interpolation:").append(getInterpolationType());
-        sb.append(", Color Map: ").append(isColorMapped() ? "YES" : "NO");
-        return sb.toString();
-    }
-
-}
\ No newline at end of file

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterBandInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,186 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.geom.Point2D;
+import java.awt.geom.Point2D.Double;
+import java.awt.image.IndexColorModel;
+
+/**
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/RasterBandInfo.java $
+ */
+public class RasterBandInfo {
+
+    long bandId;
+
+    String bandName;
+
+    int bandNumber;
+
+    /**
+     * the color map as it is on the database, except that we always create a color map with alpha
+     * channel regardless of whether the native on has alpha or not, to account for the no-data
+     * pixel to be a transparent one where appropriate
+     */
+    IndexColorModel nativeColorMap;
+
+    /**
+     * The color map as it is going to be used by this library. May differ from the native one
+     * either in the number of elements (when the native color map is not full and it has no
+     * transparent pixel to be used as no-data value), or in the pixel depth (when the native
+     * colormap is full, has no no-data pixel, and hence it needs to be promoted to a higher
+     * transfer type to make room for a no-data index)
+     */
+    IndexColorModel colorMap;
+
+    /**
+     * The band's no-data value.
+     */
+    Number noDataValue;
+
+    CompressionType compressionType;
+
+    RasterCellType cellType;
+
+    InterleaveType interleaveType;
+
+    InterpolationType interpolationType;
+
+    boolean hasStats;
+
+    Point2D.Double tileOrigin;
+
+    double statsMin;
+
+    double statsMax;
+
+    double statsMean;
+
+    double statsStdDev;
+
+    public RasterBandInfo() {
+        // do nothing
+    }
+
+    public RasterBandInfo(long bandId, RasterCellType nativeType, Number noDataValue,
+            double statsMin, double statsMax) {
+        this.bandId = bandId;
+        this.cellType = nativeType;
+        this.noDataValue = noDataValue;
+        this.statsMin = statsMin;
+        this.statsMax = statsMax;
+    }
+
+    /**
+     * @return the ArcSDE identifier for the band
+     */
+    public long getBandId() {
+        return bandId;
+    }
+
+    public String getBandName() {
+        return bandName;
+    }
+
+    public int getBandNumber() {
+        return bandNumber;
+    }
+
+    public boolean isColorMapped() {
+        return nativeColorMap != null;
+    }
+
+    public CompressionType getCompressionType() {
+        return compressionType;
+    }
+
+    public RasterCellType getCellType() {
+        return cellType;
+    }
+
+    public InterleaveType getInterleaveType() {
+        return interleaveType;
+    }
+
+    public InterpolationType getInterpolationType() {
+        return interpolationType;
+    }
+
+    public boolean isHasStats() {
+        return hasStats;
+    }
+
+    public Double getTileOrigin() {
+        return tileOrigin;
+    }
+
+    public IndexColorModel getNativeColorMap() {
+        return nativeColorMap;
+    }
+
+    public IndexColorModel getColorMap() {
+        return colorMap;
+    }
+
+    public double getStatsMin() {
+        return statsMin;
+    }
+
+    public double getStatsMax() {
+        return statsMax;
+    }
+
+    public double getStatsMean() {
+        return statsMean;
+    }
+
+    public double getStatsStdDev() {
+        return statsStdDev;
+    }
+
+    public Number getNoDataValue() {
+        return noDataValue;
+    }
+
+    @SuppressWarnings("nls")
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append(getBandName());
+        sb.append("[ id:").append(getBandId());
+        sb.append(", type:").append(getCellType());
+        sb.append(", samples: nodata=").append(getNoDataValue()).append(" min=").append(
+                getStatsMin()).append(" max=").append(getStatsMax()).append(" mean=").append(
+                getStatsMean()).append(" stddev=").append(getStatsStdDev());
+        /*
+         * sb.append(", tile origin: ").append((int) getTileOrigin().x).append(",").append( (int)
+         * getTileOrigin().y);
+         */
+        sb.append(", compression:").append(getCompressionType());
+        sb.append(", interpolation:").append(getInterpolationType());
+        sb.append(", Color Map: ").append(isColorMapped() ? "YES" : "NO");
+        return sb.toString();
+    }
+
+}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,122 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.image.DataBuffer;
-import java.util.NoSuchElementException;
-
-import org.geotools.util.NumberRange;
-
-import com.esri.sde.sdk.client.SeRaster;
-
-/**
- * An enumeration that mirrors the different possible cell resolutions in Arcsde (ie, {@code
- * SeRaster#SE_PIXEL_TYPE_*})
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/RasterCellType.java $
- */
-public enum RasterCellType {
-    TYPE_16BIT_S(16, DataBuffer.TYPE_SHORT, true, NumberRange.create(Short.MIN_VALUE,
-            Short.MAX_VALUE)), //
-    TYPE_16BIT_U(16, DataBuffer.TYPE_USHORT, false, NumberRange.create((int) 0, (int) 65535)), //
-    TYPE_1BIT(1, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0, (byte) 1)), //
-    TYPE_32BIT_REAL(32, DataBuffer.TYPE_FLOAT, true, NumberRange.create(Float.MIN_VALUE,
-            Float.MAX_VALUE)), //
-    TYPE_32BIT_S(32, DataBuffer.TYPE_INT, true, NumberRange.create(Integer.MIN_VALUE,
-            Integer.MAX_VALUE)), //
-    TYPE_32BIT_U(64, DataBuffer.TYPE_DOUBLE, false, NumberRange.create(0D,
-            (double) Math.pow(2, 32) - 1)), //
-    TYPE_4BIT(4, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0,
-            (byte) Math.pow(2, 4) - 1)), //
-    TYPE_64BIT_REAL(64, DataBuffer.TYPE_DOUBLE, true, NumberRange.create(Double.MIN_VALUE,
-            Double.MAX_VALUE)), //
-    TYPE_8BIT_S(8, DataBuffer.TYPE_BYTE, true, NumberRange.create(Byte.MIN_VALUE, Byte.MAX_VALUE)), //
-    TYPE_8BIT_U(8, DataBuffer.TYPE_BYTE, false, NumberRange.create((int) 0, (int) 255));
-    static {
-        // Setting the se_pixel_type in a static initializer to avoid having them linked to the fake
-        // values in the dummy api
-        TYPE_16BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_S);
-        TYPE_16BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_U);
-        TYPE_1BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_1BIT);
-        TYPE_32BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_REAL);
-        TYPE_32BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_S);
-        TYPE_32BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_U);
-        TYPE_4BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_4BIT);
-        TYPE_64BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_64BIT_REAL);
-        TYPE_8BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_S);
-        TYPE_8BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_U);
-    }
-
-    private int typeId;
-
-    private final int bitsPerSample;
-
-    private final int dataBufferType;
-
-    private final boolean signed;
-
-    private final NumberRange<?> sampleValueRange;
-
-    private RasterCellType(final int bitsPerSample, final int dataBufferType, final boolean signed,
-            final NumberRange<?> sampleValueRange) {
-        this.bitsPerSample = bitsPerSample;
-        this.dataBufferType = dataBufferType;
-        this.signed = signed;
-        this.sampleValueRange = sampleValueRange;
-    }
-
-    private void setSdeTypeId(int typeId) {
-        this.typeId = typeId;
-    }
-
-    public int getSeRasterPixelType() {
-        return this.typeId;
-    }
-
-    public int getBitsPerSample() {
-        return bitsPerSample;
-    }
-
-    public int getDataBufferType() {
-        return dataBufferType;
-    }
-
-    public boolean isSigned() {
-        return signed;
-    }
-
-    public static RasterCellType valueOf(final int seRasterPixelType) {
-        for (RasterCellType type : RasterCellType.values()) {
-            if (type.getSeRasterPixelType() == seRasterPixelType) {
-                return type;
-            }
-        }
-        throw new NoSuchElementException("Raster pixel type " + seRasterPixelType
-                + " does not exist");
-    }
-
-    public NumberRange<?> getSampleValueRange() {
-        return sampleValueRange;
-    }
-
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterCellType.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,122 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.image.DataBuffer;
+import java.util.NoSuchElementException;
+
+import org.geotools.util.NumberRange;
+
+import com.esri.sde.sdk.client.SeRaster;
+
+/**
+ * An enumeration that mirrors the different possible cell resolutions in Arcsde (ie, {@code
+ * SeRaster#SE_PIXEL_TYPE_*})
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/RasterCellType.java $
+ */
+public enum RasterCellType {
+    TYPE_16BIT_S(16, DataBuffer.TYPE_SHORT, true, NumberRange.create(Short.MIN_VALUE,
+            Short.MAX_VALUE)), //
+    TYPE_16BIT_U(16, DataBuffer.TYPE_USHORT, false, NumberRange.create((int) 0, (int) 65535)), //
+    TYPE_1BIT(1, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0, (byte) 1)), //
+    TYPE_32BIT_REAL(32, DataBuffer.TYPE_FLOAT, true, NumberRange.create(Float.MIN_VALUE,
+            Float.MAX_VALUE)), //
+    TYPE_32BIT_S(32, DataBuffer.TYPE_INT, true, NumberRange.create(Integer.MIN_VALUE,
+            Integer.MAX_VALUE)), //
+    TYPE_32BIT_U(64, DataBuffer.TYPE_DOUBLE, false, NumberRange.create(0D,
+            (double) Math.pow(2, 32) - 1)), //
+    TYPE_4BIT(4, DataBuffer.TYPE_BYTE, false, NumberRange.create((byte) 0,
+            (byte) Math.pow(2, 4) - 1)), //
+    TYPE_64BIT_REAL(64, DataBuffer.TYPE_DOUBLE, true, NumberRange.create(Double.MIN_VALUE,
+            Double.MAX_VALUE)), //
+    TYPE_8BIT_S(8, DataBuffer.TYPE_BYTE, true, NumberRange.create(Byte.MIN_VALUE, Byte.MAX_VALUE)), //
+    TYPE_8BIT_U(8, DataBuffer.TYPE_BYTE, false, NumberRange.create((int) 0, (int) 255));
+    static {
+        // Setting the se_pixel_type in a static initializer to avoid having them linked to the fake
+        // values in the dummy api
+        TYPE_16BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_S);
+        TYPE_16BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_16BIT_U);
+        TYPE_1BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_1BIT);
+        TYPE_32BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_REAL);
+        TYPE_32BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_S);
+        TYPE_32BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_32BIT_U);
+        TYPE_4BIT.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_4BIT);
+        TYPE_64BIT_REAL.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_64BIT_REAL);
+        TYPE_8BIT_S.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_S);
+        TYPE_8BIT_U.setSdeTypeId(SeRaster.SE_PIXEL_TYPE_8BIT_U);
+    }
+
+    private int typeId;
+
+    private final int bitsPerSample;
+
+    private final int dataBufferType;
+
+    private final boolean signed;
+
+    private final NumberRange<?> sampleValueRange;
+
+    private RasterCellType(final int bitsPerSample, final int dataBufferType, final boolean signed,
+            final NumberRange<?> sampleValueRange) {
+        this.bitsPerSample = bitsPerSample;
+        this.dataBufferType = dataBufferType;
+        this.signed = signed;
+        this.sampleValueRange = sampleValueRange;
+    }
+
+    private void setSdeTypeId(int typeId) {
+        this.typeId = typeId;
+    }
+
+    public int getSeRasterPixelType() {
+        return this.typeId;
+    }
+
+    public int getBitsPerSample() {
+        return bitsPerSample;
+    }
+
+    public int getDataBufferType() {
+        return dataBufferType;
+    }
+
+    public boolean isSigned() {
+        return signed;
+    }
+
+    public static RasterCellType valueOf(final int seRasterPixelType) {
+        for (RasterCellType type : RasterCellType.values()) {
+            if (type.getSeRasterPixelType() == seRasterPixelType) {
+                return type;
+            }
+        }
+        throw new NoSuchElementException("Raster pixel type " + seRasterPixelType
+                + " does not exist");
+    }
+
+    public NumberRange<?> getSampleValueRange() {
+        return sampleValueRange;
+    }
+
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,503 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.image.IndexColorModel;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import javax.imageio.ImageTypeSpecifier;
-
-import org.geotools.coverage.Category;
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
-import org.geotools.referencing.operation.transform.LinearTransform1D;
-import org.geotools.resources.i18n.Vocabulary;
-import org.geotools.resources.i18n.VocabularyKeys;
-import org.geotools.util.NumberRange;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-import org.opengis.referencing.datum.PixelInCell;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.opengis.referencing.operation.TransformException;
-
-/**
- * Wraps metadata information for a raster dataset, whether it is composed of a single raster, or
- * it's raster catalog, and provides some conveinent methods to get to the raster metadata of it's
- * rasters and pyramid levels.
- * <p>
- * This is the single entry point to the metadata of a raster dataset. The associated classes
- * {@link RasterInfo} and {@link PyramidLevelInfo} are to be considered private to this class.
- * </p>
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/gce/RasterDatasetInfo.java $
- */
-@SuppressWarnings( { "nls" })
-public final class RasterDatasetInfo {
-
-    /** TRasterDatasetInfo the raster table we're pulling images from in this reader * */
-    private String rasterTable = null;
-
-    /**
-     * raster column names on this raster. If there's more than one raster column (is this
-     * possible?) then we just use the first one.
-     */
-    private String[] rasterColumns;
-
-    /** Array holding information on each level of the pyramid in this raster. * */
-    private List<RasterInfo> subRasterInfo;
-
-    /**
-     * The original (ie, pyramid level zero) envelope for the whole raster dataset
-     */
-    private GeneralEnvelope originalEnvelope;
-
-    private GeneralGridEnvelope originalGridRange;
-
-    private List<GridSampleDimension> gridSampleDimensions;
-
-    private final Map<Integer, ImageTypeSpecifier> renderedImageSpec = new HashMap<Integer, ImageTypeSpecifier>();
-
-    /**
-     * @param rasterTable
-     *            the rasterTable to set
-     */
-    void setRasterTable(String rasterTable) {
-        this.rasterTable = rasterTable;
-    }
-
-    /**
-     * @return the raster table name
-     */
-    public String getRasterTable() {
-        return rasterTable;
-    }
-
-    /**
-     * @param rasterColumns
-     *            the rasterColumns to set
-     */
-    void setRasterColumns(String[] rasterColumns) {
-        this.rasterColumns = rasterColumns;
-    }
-
-    /**
-     * @return the raster column names
-     */
-    public String[] getRasterColumns() {
-        return rasterColumns;
-    }
-
-    /**
-     * @param pyramidInfo
-     *            the pyramidInfo to set
-     */
-    public void setPyramidInfo(List<RasterInfo> pyramidInfo) {
-        this.subRasterInfo = pyramidInfo;
-    }
-
-    public GridSampleDimension[] getGridSampleDimensions() {
-        if (gridSampleDimensions == null) {
-            synchronized (this) {
-                if (gridSampleDimensions == null) {
-                    gridSampleDimensions = buildSampleDimensions();
-                }
-            }
-        }
-        return gridSampleDimensions.toArray(new GridSampleDimension[getNumBands()]);
-    }
-
-    @SuppressWarnings("unchecked")
-    private List<GridSampleDimension> buildSampleDimensions() {
-
-        final int numBands = getNumBands();
-        List<GridSampleDimension> dimensions = new ArrayList<GridSampleDimension>(numBands);
-
-        final Color transparent = new Color(0, 0, 0, 0);
-
-        List<RasterBandInfo> bands = subRasterInfo.get(0).getBands();
-
-        for (RasterBandInfo band : bands) {
-            final int bandNumber = band.getBandNumber();
-            // use native cell type, in case no-data value has been computed to account for
-            // sample depth promotion, we want to category to keep being the native range for
-            // the values category
-            final RasterCellType targetCellType = getNativeCellType();
-            String bandName = band.getBandName();
-
-            final double statsMin = band.getStatsMin();
-            final double statsMax = band.getStatsMax();
-
-            NumberRange<?> sampleValueRange;
-            if (Double.isNaN(statsMin) || Double.isNaN(statsMax)) {
-                sampleValueRange = targetCellType.getSampleValueRange();
-            } else {
-                sampleValueRange = NumberRange.create(statsMin, statsMax);
-                Class elementClass = targetCellType.getSampleValueRange().getElementClass();
-                sampleValueRange = sampleValueRange.castTo(elementClass);
-            }
-
-            final Color[] colorRange = null;
-
-            final boolean geophysics = isGeoPhysics();
-
-            Category valuesCat = new Category("values", colorRange, sampleValueRange,
-                    LinearTransform1D.IDENTITY).geophysics(geophysics);
-
-            Category[] categories;
-            if (geophysics) {
-                double noDataValue = band.getNoDataValue().doubleValue();
-                // same as Category.NODATA but for the actual nodata value instead of hardcoded to
-                // zero
-                Category nodataCat = new Category(Vocabulary
-                        .formatInternational(VocabularyKeys.NODATA), transparent, noDataValue);
-                categories = new Category[] { valuesCat, nodataCat };
-            } else {
-                // do not build a nodata category. A nodata value that doesn't overlap the value
-                // range couldn't be determined
-                categories = new Category[] { valuesCat };
-            }
-            /*
-             * if (band.isHasStats()) { //can't do this, get an exception telling categories
-             * overlap.. so no real way to express the statistics, uh? Category catMin = new
-             * Category("Min", null, band.getStatsMin()).geophysics(true); Category catMax = new
-             * Category("Max", null, band.getStatsMin()).geophysics(true); Category catMean = new
-             * Category("Mean", null, band.getStatsMin()).geophysics(true); Category catStdDev = new
-             * Category("StdDev", null, band.getStatsMin()) .geophysics(true); categories = new
-             * Category[] { valuesCat, nodataCat, catMin, catMax, catMean, catStdDev }; } else {
-             * categories = new Category[] { valuesCat, nodataCat }; }
-             */
-
-            // .geophysics(false) because our sample model always corresponds to the packed view
-            // (whether it matches the underlying sample depth or we're promoting in order to make
-            // room for the nodata value).
-            GridSampleDimension sampleDim = new GridSampleDimension(bandName, categories, null)
-                    .geophysics(false);
-
-            dimensions.add(sampleDim);
-        }
-        return dimensions;
-    }
-
-    private boolean isGeoPhysics() {
-        if (isColorMapped()) {
-            return false;
-        }
-        return RasterUtils.isGeoPhysics(getNumBands(), getNativeCellType());
-    }
-
-    public int getNumBands() {
-        return subRasterInfo.get(0).getNumBands();
-    }
-
-    public int getImageWidth() {
-        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
-        final int width = originalGridRange.getSpan(0);
-        return width;
-    }
-
-    public int getImageHeight() {
-        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
-        final int height = originalGridRange.getSpan(1);
-        return height;
-    }
-
-    /**
-     * @return the coverageCrs
-     */
-    public CoordinateReferenceSystem getCoverageCrs() {
-        return subRasterInfo.get(0).getCoordinateReferenceSystem();
-    }
-
-    /**
-     * @return the originalGridRange for the whole raster dataset, based on the first raster in the
-     *         raster dataset
-     */
-    public GeneralGridEnvelope getOriginalGridRange() {
-        if (originalGridRange == null) {
-            final MathTransform modelToRaster;
-            try {
-                final MathTransform rasterToModel = getRasterToModel();
-                modelToRaster = rasterToModel.inverse();
-            } catch (NoninvertibleTransformException e) {
-                throw new IllegalStateException("Can't create transform from model to raster");
-            }
-
-            int minx = Integer.MAX_VALUE;
-            int miny = Integer.MAX_VALUE;
-            int maxx = Integer.MIN_VALUE;
-            int maxy = Integer.MIN_VALUE;
-
-            final int rasterCount = getNumRasters();
-            for (int rasterN = 0; rasterN < rasterCount; rasterN++) {
-                final GeneralEnvelope rasterEnvelope = getGridEnvelope(rasterN, 0);
-                GeneralEnvelope rasterGridRangeInDataSet;
-                try {
-                    rasterGridRangeInDataSet = CRS.transform(modelToRaster, rasterEnvelope);
-                } catch (NoninvertibleTransformException e) {
-                    throw new IllegalArgumentException(e);
-                } catch (TransformException e) {
-                    throw new IllegalArgumentException(e);
-                }
-
-                minx = Math.min(minx, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(0)));
-                miny = Math.min(miny, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(1)));
-                maxx = Math.max(maxx, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(0)));
-                maxy = Math.max(maxy, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(1)));
-            }
-            int width = maxx - minx;
-            int height = maxy - miny;
-            Rectangle range = new Rectangle(0, 0, width, height);
-            originalGridRange = new GeneralGridEnvelope(range, 2);
-        }
-        return originalGridRange;
-    }
-
-    public MathTransform getRasterToModel() {
-
-        GeneralEnvelope firstRasterEnvelope = getGridEnvelope(0, 0);
-        Rectangle firstRasterGridRange = getGridRange(0, 0);
-        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(firstRasterGridRange, 2);
-
-        // create a raster to model transform, from this tile pixel space to the tile's geographic
-        // extent
-        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, firstRasterEnvelope);
-        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
-
-        final MathTransform rasterToModel = geMapper.createTransform();
-        return rasterToModel;
-    }
-
-    /**
-     * @return the originalEnvelope
-     */
-    public GeneralEnvelope getOriginalEnvelope() {
-        if (originalEnvelope == null) {
-            GeneralEnvelope env = null;
-            for (RasterInfo raster : subRasterInfo) {
-                GeneralEnvelope rasterEnvelope = raster.getOriginalEnvelope();
-                if (env == null) {
-                    env = new GeneralEnvelope(rasterEnvelope);
-                } else {
-                    env.add(rasterEnvelope);
-                }
-            }
-            originalEnvelope = env;
-        }
-        return originalEnvelope;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder();
-        sb.append("ArcSDE Raster: " + getRasterTable());
-        sb.append(", Raster columns: ").append(Arrays.asList(getRasterColumns()));
-        sb.append(", Num bands: ").append(getNumBands());
-        sb.append(", Dimension: ").append(getImageWidth()).append("x").append(getImageHeight());
-        sb.append(", Pixel type: ").append(getNativeCellType());
-        sb.append(", Has Color Map: ").append(isColorMapped());
-        for (int rasterIndex = 0; rasterIndex < getNumRasters(); rasterIndex++) {
-            RasterInfo raster = getRasterInfo(rasterIndex);
-            sb.append("\n ");
-            sb.append(raster.toString());
-        }
-        return sb.toString();
-    }
-
-    public int getNumRasters() {
-        return subRasterInfo.size();
-    }
-
-    public RasterBandInfo getBand(final int rasterIndex, final int bandIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getBand(bandIndex);
-    }
-
-    public int getNumPyramidLevels(final int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getNumLevels();
-    }
-
-    public GeneralEnvelope getGridEnvelope(final int rasterIndex, final int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return new GeneralEnvelope(level.getImageEnvelope());
-    }
-
-    public Rectangle getGridRange(final int rasterIndex, final int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        Rectangle levelRange = level.getImageRange();
-        return levelRange;
-    }
-
-    public int getNumTilesWide(int rasterIndex, int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return level.getNumTilesWide();
-    }
-
-    public int getNumTilesHigh(int rasterIndex, int pyramidLevel) {
-        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
-        return level.getNumTilesHigh();
-    }
-
-    public int getTileWidth(final long rasterId) {
-        return getTileDimension(rasterId).width;
-    }
-
-    public int getTileHeight(final long rasterId) {
-        return getTileDimension(rasterId).height;
-    }
-
-    public Dimension getTileDimension(final long rasterId) {
-        final int rasterIndex = getRasterIndex(rasterId);
-        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getTileDimension();
-    }
-
-    public Dimension getTileDimension(int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getTileDimension();
-    }
-
-    private PyramidLevelInfo getLevel(int rasterIndex, int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
-        return level;
-    }
-
-    private RasterInfo getRasterInfo(int rasterIndex) {
-        RasterInfo rasterInfo = subRasterInfo.get(rasterIndex);
-        return rasterInfo;
-    }
-
-    public ImageTypeSpecifier getRenderedImageSpec(final long rasterId) {
-        final int rasterIndex = getRasterIndex(rasterId);
-        return getRenderedImageSpec(rasterIndex);
-    }
-
-    public ImageTypeSpecifier getRenderedImageSpec(final int rasterIndex) {
-        if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
-            synchronized (this) {
-                if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
-                    ImageTypeSpecifier imageTypeSpecifier;
-                    imageTypeSpecifier = RasterUtils
-                            .createFullImageTypeSpecifier(this, rasterIndex);
-                    renderedImageSpec.put(Integer.valueOf(rasterIndex), imageTypeSpecifier);
-                }
-            }
-        }
-        return this.renderedImageSpec.get(Integer.valueOf(rasterIndex));
-    }
-
-    public IndexColorModel getColorMap(final int rasterIndex) {
-        final RasterBandInfo bandOne = getBand(rasterIndex, 0);
-        return bandOne.getColorMap();
-    }
-
-    public boolean isColorMapped() {
-        RasterInfo rasterInfo = getRasterInfo(0);
-        return rasterInfo.isColorMapped();
-    }
-
-    public RasterCellType getNativeCellType() {
-        RasterInfo rasterInfo = getRasterInfo(0);
-        return rasterInfo.getNativeCellType();
-    }
-
-    public RasterCellType getTargetCellType(final int rasterIndex) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getTargetCellType();
-    }
-
-    public RasterCellType getTargetCellType(final long rasterId) {
-        final int rasterIndex = getRasterIndex(rasterId);
-        return getTargetCellType(rasterIndex);
-    }
-
-    public Long getRasterId(final int rasterIndex) {
-        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        return rasterInfo.getRasterId();
-    }
-
-    public int getOptimalPyramidLevel(final int rasterIndex, final OverviewPolicy policy,
-            final GeneralEnvelope requestedEnvelope, final Rectangle requestedDim) {
-
-        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-
-        double[] requestedRes = new double[2];
-        double reqSpanX = requestedEnvelope.getSpan(0);
-        double reqSpanY = requestedEnvelope.getSpan(1);
-        requestedRes[0] = reqSpanX / requestedDim.getWidth();
-        requestedRes[1] = reqSpanY / requestedDim.getHeight();
-
-        return rasterInfo.getOptimalPyramidLevel(policy, requestedRes);
-    }
-
-    public int getRasterIndex(Long rasterId) {
-        int index = -1;
-        for (RasterInfo p : subRasterInfo) {
-            index++;
-            if (rasterId.equals(p.getRasterId())) {
-                return index;
-            }
-        }
-        throw new IllegalArgumentException("rasterId: " + rasterId);
-    }
-
-    public double[] getResolution(int rasterN, int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterN);
-        double[] resolution = rasterInfo.getResolution(pyramidLevel);
-        return resolution;
-    }
-
-    public Point getTileOffset(final int rasterIndex, final int pyramidLevel) {
-        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
-        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
-        return new Point(level.getXOffset(), level.getYOffset());
-    }
-
-    public Number getNoDataValue(final int rasterIndex, final int bandIndex) {
-        RasterBandInfo band = getBand(rasterIndex, bandIndex);
-        Number noDataValue = band.getNoDataValue();
-        return noDataValue;
-    }
-
-    /**
-     * @param rasterIndex
-     *            the raster for which bands to return the no data values
-     * @return the list of no data values, one per band for the raster at index {@code rasterIndex}
-     */
-    public List<Number> getNoDataValues(final int rasterIndex) {
-        return getRasterInfo(rasterIndex).getNoDataValues();
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterDatasetInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,503 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.image.IndexColorModel;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.imageio.ImageTypeSpecifier;
+
+import org.geotools.coverage.Category;
+import org.geotools.coverage.GridSampleDimension;
+import org.geotools.coverage.grid.GeneralGridEnvelope;
+import org.geotools.coverage.grid.io.OverviewPolicy;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
+import org.geotools.referencing.operation.transform.LinearTransform1D;
+import org.geotools.resources.i18n.Vocabulary;
+import org.geotools.resources.i18n.VocabularyKeys;
+import org.geotools.util.NumberRange;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.datum.PixelInCell;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+
+/**
+ * Wraps metadata information for a raster dataset, whether it is composed of a single raster, or
+ * it's raster catalog, and provides some conveinent methods to get to the raster metadata of it's
+ * rasters and pyramid levels.
+ * <p>
+ * This is the single entry point to the metadata of a raster dataset. The associated classes
+ * {@link RasterInfo} and {@link PyramidLevelInfo} are to be considered private to this class.
+ * </p>
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/gce/RasterDatasetInfo.java $
+ */
+@SuppressWarnings( { "nls" })
+public final class RasterDatasetInfo {
+
+    /** TRasterDatasetInfo the raster table we're pulling images from in this reader * */
+    private String rasterTable = null;
+
+    /**
+     * raster column names on this raster. If there's more than one raster column (is this
+     * possible?) then we just use the first one.
+     */
+    private String[] rasterColumns;
+
+    /** Array holding information on each level of the pyramid in this raster. * */
+    private List<RasterInfo> subRasterInfo;
+
+    /**
+     * The original (ie, pyramid level zero) envelope for the whole raster dataset
+     */
+    private GeneralEnvelope originalEnvelope;
+
+    private GeneralGridEnvelope originalGridRange;
+
+    private List<GridSampleDimension> gridSampleDimensions;
+
+    private final Map<Integer, ImageTypeSpecifier> renderedImageSpec = new HashMap<Integer, ImageTypeSpecifier>();
+
+    /**
+     * @param rasterTable
+     *            the rasterTable to set
+     */
+    void setRasterTable(String rasterTable) {
+        this.rasterTable = rasterTable;
+    }
+
+    /**
+     * @return the raster table name
+     */
+    public String getRasterTable() {
+        return rasterTable;
+    }
+
+    /**
+     * @param rasterColumns
+     *            the rasterColumns to set
+     */
+    void setRasterColumns(String[] rasterColumns) {
+        this.rasterColumns = rasterColumns;
+    }
+
+    /**
+     * @return the raster column names
+     */
+    public String[] getRasterColumns() {
+        return rasterColumns;
+    }
+
+    /**
+     * @param pyramidInfo
+     *            the pyramidInfo to set
+     */
+    public void setPyramidInfo(List<RasterInfo> pyramidInfo) {
+        this.subRasterInfo = pyramidInfo;
+    }
+
+    public GridSampleDimension[] getGridSampleDimensions() {
+        if (gridSampleDimensions == null) {
+            synchronized (this) {
+                if (gridSampleDimensions == null) {
+                    gridSampleDimensions = buildSampleDimensions();
+                }
+            }
+        }
+        return gridSampleDimensions.toArray(new GridSampleDimension[getNumBands()]);
+    }
+
+    @SuppressWarnings("unchecked")
+    private List<GridSampleDimension> buildSampleDimensions() {
+
+        final int numBands = getNumBands();
+        List<GridSampleDimension> dimensions = new ArrayList<GridSampleDimension>(numBands);
+
+        final Color transparent = new Color(0, 0, 0, 0);
+
+        List<RasterBandInfo> bands = subRasterInfo.get(0).getBands();
+
+        for (RasterBandInfo band : bands) {
+            final int bandNumber = band.getBandNumber();
+            // use native cell type, in case no-data value has been computed to account for
+            // sample depth promotion, we want to category to keep being the native range for
+            // the values category
+            final RasterCellType targetCellType = getNativeCellType();
+            String bandName = band.getBandName();
+
+            final double statsMin = band.getStatsMin();
+            final double statsMax = band.getStatsMax();
+
+            NumberRange<?> sampleValueRange;
+            if (Double.isNaN(statsMin) || Double.isNaN(statsMax)) {
+                sampleValueRange = targetCellType.getSampleValueRange();
+            } else {
+                sampleValueRange = NumberRange.create(statsMin, statsMax);
+                Class elementClass = targetCellType.getSampleValueRange().getElementClass();
+                sampleValueRange = sampleValueRange.castTo(elementClass);
+            }
+
+            final Color[] colorRange = null;
+
+            final boolean geophysics = isGeoPhysics();
+
+            Category valuesCat = new Category("values", colorRange, sampleValueRange,
+                    LinearTransform1D.IDENTITY).geophysics(geophysics);
+
+            Category[] categories;
+            if (geophysics) {
+                double noDataValue = band.getNoDataValue().doubleValue();
+                // same as Category.NODATA but for the actual nodata value instead of hardcoded to
+                // zero
+                Category nodataCat = new Category(Vocabulary
+                        .formatInternational(VocabularyKeys.NODATA), transparent, noDataValue);
+                categories = new Category[] { valuesCat, nodataCat };
+            } else {
+                // do not build a nodata category. A nodata value that doesn't overlap the value
+                // range couldn't be determined
+                categories = new Category[] { valuesCat };
+            }
+            /*
+             * if (band.isHasStats()) { //can't do this, get an exception telling categories
+             * overlap.. so no real way to express the statistics, uh? Category catMin = new
+             * Category("Min", null, band.getStatsMin()).geophysics(true); Category catMax = new
+             * Category("Max", null, band.getStatsMin()).geophysics(true); Category catMean = new
+             * Category("Mean", null, band.getStatsMin()).geophysics(true); Category catStdDev = new
+             * Category("StdDev", null, band.getStatsMin()) .geophysics(true); categories = new
+             * Category[] { valuesCat, nodataCat, catMin, catMax, catMean, catStdDev }; } else {
+             * categories = new Category[] { valuesCat, nodataCat }; }
+             */
+
+            // .geophysics(false) because our sample model always corresponds to the packed view
+            // (whether it matches the underlying sample depth or we're promoting in order to make
+            // room for the nodata value).
+            GridSampleDimension sampleDim = new GridSampleDimension(bandName, categories, null)
+                    .geophysics(false);
+
+            dimensions.add(sampleDim);
+        }
+        return dimensions;
+    }
+
+    private boolean isGeoPhysics() {
+        if (isColorMapped()) {
+            return false;
+        }
+        return RasterUtils.isGeoPhysics(getNumBands(), getNativeCellType());
+    }
+
+    public int getNumBands() {
+        return subRasterInfo.get(0).getNumBands();
+    }
+
+    public int getImageWidth() {
+        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
+        final int width = originalGridRange.getSpan(0);
+        return width;
+    }
+
+    public int getImageHeight() {
+        final GeneralGridEnvelope originalGridRange = getOriginalGridRange();
+        final int height = originalGridRange.getSpan(1);
+        return height;
+    }
+
+    /**
+     * @return the coverageCrs
+     */
+    public CoordinateReferenceSystem getCoverageCrs() {
+        return subRasterInfo.get(0).getCoordinateReferenceSystem();
+    }
+
+    /**
+     * @return the originalGridRange for the whole raster dataset, based on the first raster in the
+     *         raster dataset
+     */
+    public GeneralGridEnvelope getOriginalGridRange() {
+        if (originalGridRange == null) {
+            final MathTransform modelToRaster;
+            try {
+                final MathTransform rasterToModel = getRasterToModel();
+                modelToRaster = rasterToModel.inverse();
+            } catch (NoninvertibleTransformException e) {
+                throw new IllegalStateException("Can't create transform from model to raster");
+            }
+
+            int minx = Integer.MAX_VALUE;
+            int miny = Integer.MAX_VALUE;
+            int maxx = Integer.MIN_VALUE;
+            int maxy = Integer.MIN_VALUE;
+
+            final int rasterCount = getNumRasters();
+            for (int rasterN = 0; rasterN < rasterCount; rasterN++) {
+                final GeneralEnvelope rasterEnvelope = getGridEnvelope(rasterN, 0);
+                GeneralEnvelope rasterGridRangeInDataSet;
+                try {
+                    rasterGridRangeInDataSet = CRS.transform(modelToRaster, rasterEnvelope);
+                } catch (NoninvertibleTransformException e) {
+                    throw new IllegalArgumentException(e);
+                } catch (TransformException e) {
+                    throw new IllegalArgumentException(e);
+                }
+
+                minx = Math.min(minx, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(0)));
+                miny = Math.min(miny, (int) Math.floor(rasterGridRangeInDataSet.getMinimum(1)));
+                maxx = Math.max(maxx, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(0)));
+                maxy = Math.max(maxy, (int) Math.ceil(rasterGridRangeInDataSet.getMaximum(1)));
+            }
+            int width = maxx - minx;
+            int height = maxy - miny;
+            Rectangle range = new Rectangle(0, 0, width, height);
+            originalGridRange = new GeneralGridEnvelope(range, 2);
+        }
+        return originalGridRange;
+    }
+
+    public MathTransform getRasterToModel() {
+
+        GeneralEnvelope firstRasterEnvelope = getGridEnvelope(0, 0);
+        Rectangle firstRasterGridRange = getGridRange(0, 0);
+        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(firstRasterGridRange, 2);
+
+        // create a raster to model transform, from this tile pixel space to the tile's geographic
+        // extent
+        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, firstRasterEnvelope);
+        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
+
+        final MathTransform rasterToModel = geMapper.createTransform();
+        return rasterToModel;
+    }
+
+    /**
+     * @return the originalEnvelope
+     */
+    public GeneralEnvelope getOriginalEnvelope() {
+        if (originalEnvelope == null) {
+            GeneralEnvelope env = null;
+            for (RasterInfo raster : subRasterInfo) {
+                GeneralEnvelope rasterEnvelope = raster.getOriginalEnvelope();
+                if (env == null) {
+                    env = new GeneralEnvelope(rasterEnvelope);
+                } else {
+                    env.add(rasterEnvelope);
+                }
+            }
+            originalEnvelope = env;
+        }
+        return originalEnvelope;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("ArcSDE Raster: " + getRasterTable());
+        sb.append(", Raster columns: ").append(Arrays.asList(getRasterColumns()));
+        sb.append(", Num bands: ").append(getNumBands());
+        sb.append(", Dimension: ").append(getImageWidth()).append("x").append(getImageHeight());
+        sb.append(", Pixel type: ").append(getNativeCellType());
+        sb.append(", Has Color Map: ").append(isColorMapped());
+        for (int rasterIndex = 0; rasterIndex < getNumRasters(); rasterIndex++) {
+            RasterInfo raster = getRasterInfo(rasterIndex);
+            sb.append("\n ");
+            sb.append(raster.toString());
+        }
+        return sb.toString();
+    }
+
+    public int getNumRasters() {
+        return subRasterInfo.size();
+    }
+
+    public RasterBandInfo getBand(final int rasterIndex, final int bandIndex) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getBand(bandIndex);
+    }
+
+    public int getNumPyramidLevels(final int rasterIndex) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getNumLevels();
+    }
+
+    public GeneralEnvelope getGridEnvelope(final int rasterIndex, final int pyramidLevel) {
+        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
+        return new GeneralEnvelope(level.getImageEnvelope());
+    }
+
+    public Rectangle getGridRange(final int rasterIndex, final int pyramidLevel) {
+        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
+        Rectangle levelRange = level.getImageRange();
+        return levelRange;
+    }
+
+    public int getNumTilesWide(int rasterIndex, int pyramidLevel) {
+        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
+        return level.getNumTilesWide();
+    }
+
+    public int getNumTilesHigh(int rasterIndex, int pyramidLevel) {
+        PyramidLevelInfo level = getLevel(rasterIndex, pyramidLevel);
+        return level.getNumTilesHigh();
+    }
+
+    public int getTileWidth(final long rasterId) {
+        return getTileDimension(rasterId).width;
+    }
+
+    public int getTileHeight(final long rasterId) {
+        return getTileDimension(rasterId).height;
+    }
+
+    public Dimension getTileDimension(final long rasterId) {
+        final int rasterIndex = getRasterIndex(rasterId);
+        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getTileDimension();
+    }
+
+    public Dimension getTileDimension(int rasterIndex) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getTileDimension();
+    }
+
+    private PyramidLevelInfo getLevel(int rasterIndex, int pyramidLevel) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
+        return level;
+    }
+
+    private RasterInfo getRasterInfo(int rasterIndex) {
+        RasterInfo rasterInfo = subRasterInfo.get(rasterIndex);
+        return rasterInfo;
+    }
+
+    public ImageTypeSpecifier getRenderedImageSpec(final long rasterId) {
+        final int rasterIndex = getRasterIndex(rasterId);
+        return getRenderedImageSpec(rasterIndex);
+    }
+
+    public ImageTypeSpecifier getRenderedImageSpec(final int rasterIndex) {
+        if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
+            synchronized (this) {
+                if (!this.renderedImageSpec.containsKey(Integer.valueOf(rasterIndex))) {
+                    ImageTypeSpecifier imageTypeSpecifier;
+                    imageTypeSpecifier = RasterUtils
+                            .createFullImageTypeSpecifier(this, rasterIndex);
+                    renderedImageSpec.put(Integer.valueOf(rasterIndex), imageTypeSpecifier);
+                }
+            }
+        }
+        return this.renderedImageSpec.get(Integer.valueOf(rasterIndex));
+    }
+
+    public IndexColorModel getColorMap(final int rasterIndex) {
+        final RasterBandInfo bandOne = getBand(rasterIndex, 0);
+        return bandOne.getColorMap();
+    }
+
+    public boolean isColorMapped() {
+        RasterInfo rasterInfo = getRasterInfo(0);
+        return rasterInfo.isColorMapped();
+    }
+
+    public RasterCellType getNativeCellType() {
+        RasterInfo rasterInfo = getRasterInfo(0);
+        return rasterInfo.getNativeCellType();
+    }
+
+    public RasterCellType getTargetCellType(final int rasterIndex) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getTargetCellType();
+    }
+
+    public RasterCellType getTargetCellType(final long rasterId) {
+        final int rasterIndex = getRasterIndex(rasterId);
+        return getTargetCellType(rasterIndex);
+    }
+
+    public Long getRasterId(final int rasterIndex) {
+        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        return rasterInfo.getRasterId();
+    }
+
+    public int getOptimalPyramidLevel(final int rasterIndex, final OverviewPolicy policy,
+            final GeneralEnvelope requestedEnvelope, final Rectangle requestedDim) {
+
+        final RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+
+        double[] requestedRes = new double[2];
+        double reqSpanX = requestedEnvelope.getSpan(0);
+        double reqSpanY = requestedEnvelope.getSpan(1);
+        requestedRes[0] = reqSpanX / requestedDim.getWidth();
+        requestedRes[1] = reqSpanY / requestedDim.getHeight();
+
+        return rasterInfo.getOptimalPyramidLevel(policy, requestedRes);
+    }
+
+    public int getRasterIndex(Long rasterId) {
+        int index = -1;
+        for (RasterInfo p : subRasterInfo) {
+            index++;
+            if (rasterId.equals(p.getRasterId())) {
+                return index;
+            }
+        }
+        throw new IllegalArgumentException("rasterId: " + rasterId);
+    }
+
+    public double[] getResolution(int rasterN, int pyramidLevel) {
+        RasterInfo rasterInfo = getRasterInfo(rasterN);
+        double[] resolution = rasterInfo.getResolution(pyramidLevel);
+        return resolution;
+    }
+
+    public Point getTileOffset(final int rasterIndex, final int pyramidLevel) {
+        RasterInfo rasterInfo = getRasterInfo(rasterIndex);
+        PyramidLevelInfo level = rasterInfo.getPyramidLevel(pyramidLevel);
+        return new Point(level.getXOffset(), level.getYOffset());
+    }
+
+    public Number getNoDataValue(final int rasterIndex, final int bandIndex) {
+        RasterBandInfo band = getBand(rasterIndex, bandIndex);
+        Number noDataValue = band.getNoDataValue();
+        return noDataValue;
+    }
+
+    /**
+     * @param rasterIndex
+     *            the raster for which bands to return the no data values
+     * @return the list of no data values, one per band for the raster at index {@code rasterIndex}
+     */
+    public List<Number> getNoDataValues(final int rasterIndex) {
+        return getRasterInfo(rasterIndex).getNoDataValues();
+    }
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,406 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.geom.Point2D;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.List;
-
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.data.DataSourceException;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.geometry.jts.ReferencedEnvelope;
-import org.geotools.referencing.CRS;
-import org.opengis.referencing.FactoryException;
-import org.opengis.referencing.crs.CoordinateReferenceSystem;
-
-import com.esri.sde.sdk.client.SDEPoint;
-import com.esri.sde.sdk.client.SeException;
-import com.esri.sde.sdk.client.SeExtent;
-import com.esri.sde.sdk.client.SeRasterAttr;
-
-/**
- * A RasterInfo gathers the metadata for a single raster in a raster dataset
- * <p>
- * Basically, it wraps the SeRasterAttr object and implements some convenience methods for doing
- * calculations with it.
- * </p>
- *
- * @author Saul Farber
- * @author Gabriel Roldan
- */
-public final class RasterInfo {
-
-    /**
-     * Orders pyramid levels by their level index
-     */
-    private static final Comparator<PyramidLevelInfo> levelComparator = new Comparator<PyramidLevelInfo>() {
-        public int compare(PyramidLevelInfo p0, PyramidLevelInfo p1) {
-            return (p0.getLevel() - p1.getLevel());
-        }
-    };
-
-    ArrayList<PyramidLevelInfo> pyramidList;
-
-    private int tileWidth;
-
-    private int tileHeight;
-
-    private GeneralEnvelope originalEnvelope;
-
-    private ArrayList<RasterBandInfo> bands;
-
-    private CoordinateReferenceSystem crs;
-
-    private Long rasterId;
-
-    /**
-     * Creates an in-memory representation of an ArcSDE Raster Pyramid. Basically it wraps the
-     * supplide SeRasterAttr object and implements some convenience logic for extracting
-     * information/ doing calculations with it.
-     *
-     * @param rasterAttributes
-     *            the SeRasterAttr object for the raster of interest.
-     * @param crs
-     * @throws DataSourceException
-     */
-    RasterInfo(final SeRasterAttr rasterAttributes, final CoordinateReferenceSystem crs)
-            throws DataSourceException {
-        this.crs = crs;
-        try {
-            this.rasterId = Long.valueOf(rasterAttributes.getRasterId().longValue());
-            // levels goes from 0 to N, maxLevel is the zero-based max index of levels
-            final int numLevels = rasterAttributes.getMaxLevel() + 1;
-
-            pyramidList = new ArrayList<PyramidLevelInfo>(numLevels);
-
-            tileWidth = rasterAttributes.getTileWidth();
-            tileHeight = rasterAttributes.getTileHeight();
-
-            for (int level = 0; level < numLevels; level++) {
-                if (level == 1 && rasterAttributes.skipLevelOne()) {
-                    continue;
-                }
-
-                /*
-                 * this extent corresponds to the actual image size inside the tiled grid. That is,
-                 * to getImageWidth/Height by level. The dimensions of this extent are correct, but
-                 * it needs to be shifted by SeRasterAttr.getExtentOffsetByLevel(level) the same way
-                 * the grid envelope does by SeRasterAttr.getImageOffsetByLevel(level)
-                 */
-                final SeExtent slExtent = rasterAttributes.getExtentByLevel(level);
-
-                final int levelWidth = rasterAttributes.getImageWidthByLevel(level);
-                final int levelHeight = rasterAttributes.getImageHeightByLevel(level);
-
-                Dimension levelImageSize = new Dimension(levelWidth, levelHeight);
-
-                Point imgOffset = new Point();
-                // extent offset equals imgOffset * pixel resolution (ie, if resx == 2 and offsetX =
-                // 10, extent offset x == 20)
-                Point2D extOffset = new Point2D.Double();
-                {
-                    SDEPoint imageOffset = rasterAttributes.getImageOffsetByLevel(level);
-                    int xOffset = (int) (imageOffset == null ? 0 : imageOffset.getX());
-                    int yOffset = (int) (imageOffset == null ? 0 : imageOffset.getY());
-                    imgOffset.setLocation(xOffset, yOffset);
-
-                    SDEPoint extentOffset = rasterAttributes.getExtentOffsetByLevel(level);
-                    double xOffsetExtent = extentOffset == null ? 0D : extentOffset.getX();
-                    double yOffsetExtent = extentOffset == null ? 0D : extentOffset.getY();
-                    extOffset.setLocation(xOffsetExtent, yOffsetExtent);
-                }
-
-                final int numTilesWide = rasterAttributes.getTilesPerRowByLevel(level);
-                final int numTileHigh = rasterAttributes.getTilesPerColByLevel(level);
-
-                ReferencedEnvelope levelExtent = new ReferencedEnvelope(slExtent.getMinX(),
-                        slExtent.getMaxX(), slExtent.getMinY(), slExtent.getMaxY(), crs);
-
-                addPyramidLevel(level, levelExtent, imgOffset, extOffset, numTilesWide,
-                        numTileHigh, levelImageSize);
-            }
-
-        } catch (SeException se) {
-            throw new DataSourceException(se);
-        }
-    }
-
-    public Long getRasterId() {
-        return rasterId;
-    }
-
-    public int getTileWidth() {
-        return tileWidth;
-    }
-
-    public int getTileHeight() {
-        return tileHeight;
-    }
-
-    /**
-     * Don't use this constructor. It only exists for unit testing purposes.
-     *
-     * @param tileWidth
-     *            DON'T USE
-     * @param tileHeight
-     *            DON'T USE
-     */
-    public RasterInfo(Long rasterId, int tileWidth, int tileHeight) {
-        this.rasterId = rasterId;
-        this.tileWidth = tileWidth;
-        this.tileHeight = tileHeight;
-        pyramidList = new ArrayList<PyramidLevelInfo>(4);
-    }
-
-    public Dimension getTileDimension() {
-        return new Dimension(tileWidth, tileHeight);
-    }
-
-    public PyramidLevelInfo getPyramidLevel(int level) {
-        return pyramidList.get(level);
-    }
-
-    public int getNumLevels() {
-        return pyramidList.size();
-    }
-
-    /**
-     * @param pyramidLevel
-     * @return resx, resy, scalefactor
-     */
-    double[] getResolution(final int pyramidLevel) {
-        final double highestRes = getPyramidLevel(0).getXRes();
-        PyramidLevelInfo level = getPyramidLevel(pyramidLevel);
-        double[] resolution = new double[3];
-        resolution[0] = level.getXRes();
-        resolution[1] = level.getYRes();
-        resolution[2] = level.getXRes() / highestRes;
-        return resolution;
-    }
-
-    /**
-     * <p>
-     * NOTE: logic stolen and adapted from {@code AbstractGridCoverage2DReader#getOverviewImage()}
-     * </p>
-     *
-     * @param policy
-     * @return
-     */
-    public int getOptimalPyramidLevel(final OverviewPolicy policy, final double[] requestedRes) {
-
-        int pyramidLevelChoice = 0;
-
-        // sort resolutions from smallest pixels (higher res) to biggest pixels (higher res)
-        // keeping a reference to the original image choice
-        final double[] highestRes = getResolution(0);
-
-        // Now search for the best matching resolution.
-        // Check also for the "perfect match"... unlikely in practice unless someone
-        // tunes the clients to request exactly the resolution embedded in
-        // the overviews, something a perf sensitive person might do in fact
-
-        // the requested resolutions
-        final double reqx = requestedRes[0];
-        final double reqy = requestedRes[1];
-
-        // requested scale factor for least reduced axis
-        final double requestedScaleFactorX = reqx / highestRes[0];
-        final double requestedScaleFactorY = reqy / highestRes[1];
-        final int leastReduceAxis = requestedScaleFactorX <= requestedScaleFactorY ? 0 : 1;
-        final double requestedScaleFactor = leastReduceAxis == 0 ? requestedScaleFactorX
-                : requestedScaleFactorY;
-
-        final int numLevels = getNumLevels();
-
-        // no pyramiding or are we looking for a resolution even higher than the native one?
-        if (0 == numLevels || requestedScaleFactor <= 1) {
-            pyramidLevelChoice = 0;
-        } else {
-            // are we looking for a resolution even lower than the smallest overview?
-            final double[] min = getResolution(numLevels - 1);
-            if (requestedScaleFactor >= min[2]) {
-                pyramidLevelChoice = numLevels - 1;
-            } else {
-                // Ok, so we know the overview is between min and max, skip the first
-                // and search for an overview with a resolution lower than the one requested,
-                // that one and the one from the previous step will bound the searched resolution
-                double[] prev = highestRes;
-                for (int levelN = 1; levelN < numLevels; levelN++) {
-                    final double[] curr = getResolution(levelN);
-                    // perfect match check
-                    if (curr[2] == requestedScaleFactor) {
-                        pyramidLevelChoice = levelN;
-                    } else {
-                        /*
-                         * middle check. The first part of the condition should be sufficient, but
-                         * there are cases where the x resolution is satisfied by the lowest
-                         * resolution, the y by the one before the lowest (so the aspect ratio of
-                         * the request is different than the one of the overviews), and we would end
-                         * up going out of the loop since not even the lowest can "top" the request
-                         * for one axis
-                         */
-                        if (curr[2] > requestedScaleFactor || levelN == numLevels - 1) {
-                            if (policy == OverviewPolicy.QUALITY) {
-                                pyramidLevelChoice = levelN - 1;
-                            } else if (policy == OverviewPolicy.SPEED) {
-                                return levelN;
-                            } else if (requestedScaleFactor - prev[2] < curr[2]
-                                    - requestedScaleFactor) {
-                                pyramidLevelChoice = levelN - 1;
-                            } else {
-                                pyramidLevelChoice = levelN;
-                            }
-                            break;
-                        }
-                        prev = curr;
-                    }
-                }
-            }
-        }
-        // fallback
-        return pyramidLevelChoice;
-    }
-
-    /**
-     * Don't use this method. It's only public for unit testing purposes.
-     *
-     * @param level
-     *            the zero-based level index for the new level
-     * @param extent
-     *            the geographical extent the level covers, may need to be offsetted by {@code
-     *            extOffset}
-     * @param imgOffset
-     *            the offset on the X and Y axes of the actual image inside the tile space for this
-     *            level
-     * @param extOffset
-     *            the offset on the X and Y axes of the actual image inside the tile space for this
-     *            level
-     * @param numTilesWide
-     *            the number of tiles that make up the level on the X axis
-     * @param numTilesHigh
-     *            the number of tiles that make up the level on the Y axis
-     * @param imageSize
-     *            the size of the actual image in pixels
-     */
-    public void addPyramidLevel(int level, ReferencedEnvelope extent, Point imgOffset,
-            Point2D extOffset, int numTilesWide, int numTilesHigh, Dimension imageSize) {
-
-        PyramidLevelInfo pyramidLevel;
-        pyramidLevel = new PyramidLevelInfo(level, extent, imgOffset, extOffset, numTilesWide,
-                numTilesHigh, imageSize);
-
-        pyramidList.add(pyramidLevel);
-
-        Collections.sort(pyramidList, levelComparator);
-    }
-
-    void setOriginalEnvelope(GeneralEnvelope originalEnvelope) {
-        this.originalEnvelope = originalEnvelope;
-    }
-
-    public GeneralEnvelope getOriginalEnvelope() {
-        return originalEnvelope;
-    }
-
-    public void setBands(List<RasterBandInfo> bands) {
-        this.bands = new ArrayList<RasterBandInfo>(bands);
-    }
-
-    public List<RasterBandInfo> getBands() {
-        return new ArrayList<RasterBandInfo>(bands);
-    }
-
-    public int getNumBands() {
-        return bands.size();
-    }
-
-    public RasterBandInfo getBand(final int index) {
-        return bands.get(index);
-    }
-
-    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
-        return crs;
-    }
-
-    public RasterCellType getTargetCellType() {
-        // if (isColorMapped()) {
-        // // color map is already promoted if needed
-        // return getNativeCellType();
-        // }
-        List<Number> noDataValues = getNoDataValues();
-        RasterCellType nativeCellType = getNativeCellType();
-        RasterCellType targetCellType = RasterUtils.determineTargetCellType(nativeCellType,
-                noDataValues);
-        return targetCellType;
-    }
-
-    public boolean isColorMapped() {
-        return getBand(0).isColorMapped();
-    }
-
-    public RasterCellType getNativeCellType() {
-        return getBand(0).getCellType();
-    }
-
-    public List<Number> getNoDataValues() {
-        final List<Number> noDataValues = new ArrayList<Number>();
-        for (RasterBandInfo band : getBands()) {
-            Number noDataValue = band.getNoDataValue();
-            noDataValues.add(noDataValue);
-        }
-        return noDataValues;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder sb = new StringBuilder(getClass().getSimpleName());
-        sb.append("[Id: ").append(getRasterId());
-        String srs = null;
-        try {
-            srs = CRS.lookupIdentifier(getCoordinateReferenceSystem(), false);
-        } catch (FactoryException e) {
-            e.printStackTrace();
-        }
-        sb.append(", bands: ").append(getNumBands());
-        sb.append(", levels: ").append(getNumLevels());
-        sb.append(", tile size: ").append(getTileWidth()).append("x").append(getTileHeight());
-        sb.append(", crs: ").append(srs == null ? getCoordinateReferenceSystem().toWKT() : srs);
-        GeneralEnvelope env = getOriginalEnvelope();
-        sb.append(", Envelope: ").append(env.getMinimum(0)).append(",").append(env.getMinimum(1))
-                .append(" ").append(env.getMaximum(0)).append(",").append(env.getMaximum(1));
-
-        sb.append("]\n Bands[");
-        for (RasterBandInfo band : getBands()) {
-            sb.append("\n\t");
-            sb.append(band.toString());
-        }
-        sb.append("\n ]");
-        sb.append("\n Pyramid[");
-        for (int l = 0; l < getNumLevels(); l++) {
-            sb.append("\n\t").append(getPyramidLevel(l).toString());
-        }
-        sb.append("\n ]");
-        return sb.toString();
-    }
-
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,406 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.geom.Point2D;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+import org.geotools.coverage.grid.io.OverviewPolicy;
+import org.geotools.data.DataSourceException;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.geometry.jts.ReferencedEnvelope;
+import org.geotools.referencing.CRS;
+import org.opengis.referencing.FactoryException;
+import org.opengis.referencing.crs.CoordinateReferenceSystem;
+
+import com.esri.sde.sdk.client.SDEPoint;
+import com.esri.sde.sdk.client.SeException;
+import com.esri.sde.sdk.client.SeExtent;
+import com.esri.sde.sdk.client.SeRasterAttr;
+
+/**
+ * A RasterInfo gathers the metadata for a single raster in a raster dataset
+ * <p>
+ * Basically, it wraps the SeRasterAttr object and implements some convenience methods for doing
+ * calculations with it.
+ * </p>
+ *
+ * @author Saul Farber
+ * @author Gabriel Roldan
+ */
+public final class RasterInfo {
+
+    /**
+     * Orders pyramid levels by their level index
+     */
+    private static final Comparator<PyramidLevelInfo> levelComparator = new Comparator<PyramidLevelInfo>() {
+        public int compare(PyramidLevelInfo p0, PyramidLevelInfo p1) {
+            return (p0.getLevel() - p1.getLevel());
+        }
+    };
+
+    ArrayList<PyramidLevelInfo> pyramidList;
+
+    private int tileWidth;
+
+    private int tileHeight;
+
+    private GeneralEnvelope originalEnvelope;
+
+    private ArrayList<RasterBandInfo> bands;
+
+    private CoordinateReferenceSystem crs;
+
+    private Long rasterId;
+
+    /**
+     * Creates an in-memory representation of an ArcSDE Raster Pyramid. Basically it wraps the
+     * supplide SeRasterAttr object and implements some convenience logic for extracting
+     * information/ doing calculations with it.
+     *
+     * @param rasterAttributes
+     *            the SeRasterAttr object for the raster of interest.
+     * @param crs
+     * @throws DataSourceException
+     */
+    RasterInfo(final SeRasterAttr rasterAttributes, final CoordinateReferenceSystem crs)
+            throws DataSourceException {
+        this.crs = crs;
+        try {
+            this.rasterId = Long.valueOf(rasterAttributes.getRasterId().longValue());
+            // levels goes from 0 to N, maxLevel is the zero-based max index of levels
+            final int numLevels = rasterAttributes.getMaxLevel() + 1;
+
+            pyramidList = new ArrayList<PyramidLevelInfo>(numLevels);
+
+            tileWidth = rasterAttributes.getTileWidth();
+            tileHeight = rasterAttributes.getTileHeight();
+
+            for (int level = 0; level < numLevels; level++) {
+                if (level == 1 && rasterAttributes.skipLevelOne()) {
+                    continue;
+                }
+
+                /*
+                 * this extent corresponds to the actual image size inside the tiled grid. That is,
+                 * to getImageWidth/Height by level. The dimensions of this extent are correct, but
+                 * it needs to be shifted by SeRasterAttr.getExtentOffsetByLevel(level) the same way
+                 * the grid envelope does by SeRasterAttr.getImageOffsetByLevel(level)
+                 */
+                final SeExtent slExtent = rasterAttributes.getExtentByLevel(level);
+
+                final int levelWidth = rasterAttributes.getImageWidthByLevel(level);
+                final int levelHeight = rasterAttributes.getImageHeightByLevel(level);
+
+                Dimension levelImageSize = new Dimension(levelWidth, levelHeight);
+
+                Point imgOffset = new Point();
+                // extent offset equals imgOffset * pixel resolution (ie, if resx == 2 and offsetX =
+                // 10, extent offset x == 20)
+                Point2D extOffset = new Point2D.Double();
+                {
+                    SDEPoint imageOffset = rasterAttributes.getImageOffsetByLevel(level);
+                    int xOffset = (int) (imageOffset == null ? 0 : imageOffset.getX());
+                    int yOffset = (int) (imageOffset == null ? 0 : imageOffset.getY());
+                    imgOffset.setLocation(xOffset, yOffset);
+
+                    SDEPoint extentOffset = rasterAttributes.getExtentOffsetByLevel(level);
+                    double xOffsetExtent = extentOffset == null ? 0D : extentOffset.getX();
+                    double yOffsetExtent = extentOffset == null ? 0D : extentOffset.getY();
+                    extOffset.setLocation(xOffsetExtent, yOffsetExtent);
+                }
+
+                final int numTilesWide = rasterAttributes.getTilesPerRowByLevel(level);
+                final int numTileHigh = rasterAttributes.getTilesPerColByLevel(level);
+
+                ReferencedEnvelope levelExtent = new ReferencedEnvelope(slExtent.getMinX(),
+                        slExtent.getMaxX(), slExtent.getMinY(), slExtent.getMaxY(), crs);
+
+                addPyramidLevel(level, levelExtent, imgOffset, extOffset, numTilesWide,
+                        numTileHigh, levelImageSize);
+            }
+
+        } catch (SeException se) {
+            throw new DataSourceException(se);
+        }
+    }
+
+    public Long getRasterId() {
+        return rasterId;
+    }
+
+    public int getTileWidth() {
+        return tileWidth;
+    }
+
+    public int getTileHeight() {
+        return tileHeight;
+    }
+
+    /**
+     * Don't use this constructor. It only exists for unit testing purposes.
+     *
+     * @param tileWidth
+     *            DON'T USE
+     * @param tileHeight
+     *            DON'T USE
+     */
+    public RasterInfo(Long rasterId, int tileWidth, int tileHeight) {
+        this.rasterId = rasterId;
+        this.tileWidth = tileWidth;
+        this.tileHeight = tileHeight;
+        pyramidList = new ArrayList<PyramidLevelInfo>(4);
+    }
+
+    public Dimension getTileDimension() {
+        return new Dimension(tileWidth, tileHeight);
+    }
+
+    public PyramidLevelInfo getPyramidLevel(int level) {
+        return pyramidList.get(level);
+    }
+
+    public int getNumLevels() {
+        return pyramidList.size();
+    }
+
+    /**
+     * @param pyramidLevel
+     * @return resx, resy, scalefactor
+     */
+    double[] getResolution(final int pyramidLevel) {
+        final double highestRes = getPyramidLevel(0).getXRes();
+        PyramidLevelInfo level = getPyramidLevel(pyramidLevel);
+        double[] resolution = new double[3];
+        resolution[0] = level.getXRes();
+        resolution[1] = level.getYRes();
+        resolution[2] = level.getXRes() / highestRes;
+        return resolution;
+    }
+
+    /**
+     * <p>
+     * NOTE: logic stolen and adapted from {@code AbstractGridCoverage2DReader#getOverviewImage()}
+     * </p>
+     *
+     * @param policy
+     * @return
+     */
+    public int getOptimalPyramidLevel(final OverviewPolicy policy, final double[] requestedRes) {
+
+        int pyramidLevelChoice = 0;
+
+        // sort resolutions from smallest pixels (higher res) to biggest pixels (higher res)
+        // keeping a reference to the original image choice
+        final double[] highestRes = getResolution(0);
+
+        // Now search for the best matching resolution.
+        // Check also for the "perfect match"... unlikely in practice unless someone
+        // tunes the clients to request exactly the resolution embedded in
+        // the overviews, something a perf sensitive person might do in fact
+
+        // the requested resolutions
+        final double reqx = requestedRes[0];
+        final double reqy = requestedRes[1];
+
+        // requested scale factor for least reduced axis
+        final double requestedScaleFactorX = reqx / highestRes[0];
+        final double requestedScaleFactorY = reqy / highestRes[1];
+        final int leastReduceAxis = requestedScaleFactorX <= requestedScaleFactorY ? 0 : 1;
+        final double requestedScaleFactor = leastReduceAxis == 0 ? requestedScaleFactorX
+                : requestedScaleFactorY;
+
+        final int numLevels = getNumLevels();
+
+        // no pyramiding or are we looking for a resolution even higher than the native one?
+        if (0 == numLevels || requestedScaleFactor <= 1) {
+            pyramidLevelChoice = 0;
+        } else {
+            // are we looking for a resolution even lower than the smallest overview?
+            final double[] min = getResolution(numLevels - 1);
+            if (requestedScaleFactor >= min[2]) {
+                pyramidLevelChoice = numLevels - 1;
+            } else {
+                // Ok, so we know the overview is between min and max, skip the first
+                // and search for an overview with a resolution lower than the one requested,
+                // that one and the one from the previous step will bound the searched resolution
+                double[] prev = highestRes;
+                for (int levelN = 1; levelN < numLevels; levelN++) {
+                    final double[] curr = getResolution(levelN);
+                    // perfect match check
+                    if (curr[2] == requestedScaleFactor) {
+                        pyramidLevelChoice = levelN;
+                    } else {
+                        /*
+                         * middle check. The first part of the condition should be sufficient, but
+                         * there are cases where the x resolution is satisfied by the lowest
+                         * resolution, the y by the one before the lowest (so the aspect ratio of
+                         * the request is different than the one of the overviews), and we would end
+                         * up going out of the loop since not even the lowest can "top" the request
+                         * for one axis
+                         */
+                        if (curr[2] > requestedScaleFactor || levelN == numLevels - 1) {
+                            if (policy == OverviewPolicy.QUALITY) {
+                                pyramidLevelChoice = levelN - 1;
+                            } else if (policy == OverviewPolicy.SPEED) {
+                                return levelN;
+                            } else if (requestedScaleFactor - prev[2] < curr[2]
+                                    - requestedScaleFactor) {
+                                pyramidLevelChoice = levelN - 1;
+                            } else {
+                                pyramidLevelChoice = levelN;
+                            }
+                            break;
+                        }
+                        prev = curr;
+                    }
+                }
+            }
+        }
+        // fallback
+        return pyramidLevelChoice;
+    }
+
+    /**
+     * Don't use this method. It's only public for unit testing purposes.
+     *
+     * @param level
+     *            the zero-based level index for the new level
+     * @param extent
+     *            the geographical extent the level covers, may need to be offsetted by {@code
+     *            extOffset}
+     * @param imgOffset
+     *            the offset on the X and Y axes of the actual image inside the tile space for this
+     *            level
+     * @param extOffset
+     *            the offset on the X and Y axes of the actual image inside the tile space for this
+     *            level
+     * @param numTilesWide
+     *            the number of tiles that make up the level on the X axis
+     * @param numTilesHigh
+     *            the number of tiles that make up the level on the Y axis
+     * @param imageSize
+     *            the size of the actual image in pixels
+     */
+    public void addPyramidLevel(int level, ReferencedEnvelope extent, Point imgOffset,
+            Point2D extOffset, int numTilesWide, int numTilesHigh, Dimension imageSize) {
+
+        PyramidLevelInfo pyramidLevel;
+        pyramidLevel = new PyramidLevelInfo(level, extent, imgOffset, extOffset, numTilesWide,
+                numTilesHigh, imageSize);
+
+        pyramidList.add(pyramidLevel);
+
+        Collections.sort(pyramidList, levelComparator);
+    }
+
+    void setOriginalEnvelope(GeneralEnvelope originalEnvelope) {
+        this.originalEnvelope = originalEnvelope;
+    }
+
+    public GeneralEnvelope getOriginalEnvelope() {
+        return originalEnvelope;
+    }
+
+    public void setBands(List<RasterBandInfo> bands) {
+        this.bands = new ArrayList<RasterBandInfo>(bands);
+    }
+
+    public List<RasterBandInfo> getBands() {
+        return new ArrayList<RasterBandInfo>(bands);
+    }
+
+    public int getNumBands() {
+        return bands.size();
+    }
+
+    public RasterBandInfo getBand(final int index) {
+        return bands.get(index);
+    }
+
+    public CoordinateReferenceSystem getCoordinateReferenceSystem() {
+        return crs;
+    }
+
+    public RasterCellType getTargetCellType() {
+        // if (isColorMapped()) {
+        // // color map is already promoted if needed
+        // return getNativeCellType();
+        // }
+        List<Number> noDataValues = getNoDataValues();
+        RasterCellType nativeCellType = getNativeCellType();
+        RasterCellType targetCellType = RasterUtils.determineTargetCellType(nativeCellType,
+                noDataValues);
+        return targetCellType;
+    }
+
+    public boolean isColorMapped() {
+        return getBand(0).isColorMapped();
+    }
+
+    public RasterCellType getNativeCellType() {
+        return getBand(0).getCellType();
+    }
+
+    public List<Number> getNoDataValues() {
+        final List<Number> noDataValues = new ArrayList<Number>();
+        for (RasterBandInfo band : getBands()) {
+            Number noDataValue = band.getNoDataValue();
+            noDataValues.add(noDataValue);
+        }
+        return noDataValues;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder(getClass().getSimpleName());
+        sb.append("[Id: ").append(getRasterId());
+        String srs = null;
+        try {
+            srs = CRS.lookupIdentifier(getCoordinateReferenceSystem(), false);
+        } catch (FactoryException e) {
+            e.printStackTrace();
+        }
+        sb.append(", bands: ").append(getNumBands());
+        sb.append(", levels: ").append(getNumLevels());
+        sb.append(", tile size: ").append(getTileWidth()).append("x").append(getTileHeight());
+        sb.append(", crs: ").append(srs == null ? getCoordinateReferenceSystem().toWKT() : srs);
+        GeneralEnvelope env = getOriginalEnvelope();
+        sb.append(", Envelope: ").append(env.getMinimum(0)).append(",").append(env.getMinimum(1))
+                .append(" ").append(env.getMaximum(0)).append(",").append(env.getMaximum(1));
+
+        sb.append("]\n Bands[");
+        for (RasterBandInfo band : getBands()) {
+            sb.append("\n\t");
+            sb.append(band.toString());
+        }
+        sb.append("\n ]");
+        sb.append("\n Pyramid[");
+        for (int l = 0; l < getNumLevels(); l++) {
+            sb.append("\n\t").append(getPyramidLevel(l).toString());
+        }
+        sb.append("\n ]");
+        return sb.toString();
+    }
+
+}

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,216 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import java.awt.Rectangle;
-import java.awt.image.RenderedImage;
-import java.util.logging.Logger;
-
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.util.logging.Logging;
-
-/**
- * Captures information about a query for a single raster in a raster dataset.
- *
- * @author Gabriel Roldan
- * @version $Id$
- * @since 2.5.6
- * @see RasterUtils#findMatchingRasters
- * @see RasterUtils#fitRequestToRaster
- */
-public final class RasterQueryInfo {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private GeneralEnvelope requestedEnvelope;
-
-    private Rectangle requestedDim;
-
-    private int pyramidLevel;
-
-    /**
-     * The two-dimensional range of tile indices whose envelope intersect the requested extent. Will
-     * have negative width and height if none of the tiles do.
-     */
-    private Rectangle matchingTiles;
-
-    private GeneralEnvelope resultEnvelope;
-
-    private Rectangle resultDimension;
-
-    private Long rasterId;
-
-    private Rectangle mosaicLocation;
-
-    private RenderedImage resultImage;
-
-    private Rectangle tiledImageSize;
-
-    private double[] resolution;
-
-    private int rasterIndex;
-
-    /**
-     * The full tile range for the matching pyramid level
-     */
-    private Rectangle levelTileRange;
-
-    public RasterQueryInfo() {
-        setResultDimensionInsideTiledImage(new Rectangle(0, 0, 0, 0));
-        setMatchingTiles(new Rectangle(0, 0, 0, 0));
-        setResultEnvelope(null);
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder s = new StringBuilder("[Raster query info:");
-        s.append("\n\tRaster ID            : ").append(getRasterId());
-        s.append("\n\tPyramid level        : ").append(getPyramidLevel());
-        s.append("\n\tResolution           : ").append(
-                getResolution()[0] + "," + getResolution()[1]);
-        s.append("\n\tRequested envelope   : ").append(getRequestedEnvelope());
-        s.append("\n\tRequested dimension  : ").append(getRequestedDim());
-        Rectangle mt = getMatchingTiles();
-        Rectangle ltr = getLevelTileRange();
-        String matching = "x=" + mt.x + "-" + (mt.x + mt.width - 1) + ", y=" + mt.y + "-"
-                + (mt.y + mt.height - 1);
-        String level = "x=" + ltr.x + "-" + (ltr.width - 1) + ", y=" + ltr.y + "-"
-                + (ltr.height - 1);
-        s.append("\n\tMatching tiles       : ").append(matching).append(" out of ").append(level);
-        s.append("\n\tTiled image size     : ").append(getTiledImageSize());
-        s.append("\n\tResult dimension     : ").append(getResultDimensionInsideTiledImage());
-        s.append("\n\tMosaiced dimension   : ").append(getMosaicLocation());
-        s.append("\n\tResult envelope      : ").append(getResultEnvelope());
-        s.append("\n]");
-        return s.toString();
-    }
-
-    /**
-     * @return the rasterId (as in SeRaster.getId()) for the raster in the raster dataset this query
-     *         works upon
-     */
-    public Long getRasterId() {
-        return rasterId;
-    }
-
-    public GeneralEnvelope getRequestedEnvelope() {
-        return requestedEnvelope;
-    }
-
-    public Rectangle getRequestedDim() {
-        return requestedDim;
-    }
-
-    public int getPyramidLevel() {
-        return pyramidLevel;
-    }
-
-    public Rectangle getMatchingTiles() {
-        return matchingTiles;
-    }
-
-    public GeneralEnvelope getResultEnvelope() {
-        return resultEnvelope;
-    }
-
-    public Rectangle getResultDimensionInsideTiledImage() {
-        return resultDimension;
-    }
-
-    void setRasterId(Long rasterId) {
-        this.rasterId = rasterId;
-    }
-
-    void setPyramidLevel(int pyramidLevel) {
-        this.pyramidLevel = pyramidLevel;
-    }
-
-    void setRequestedEnvelope(GeneralEnvelope requestedEnvelope) {
-        this.requestedEnvelope = requestedEnvelope;
-    }
-
-    void setRequestedDim(Rectangle requestedDim) {
-        this.requestedDim = requestedDim;
-    }
-
-    void setResultEnvelope(GeneralEnvelope resultEnvelope) {
-        this.resultEnvelope = resultEnvelope;
-    }
-
-    void setMatchingTiles(Rectangle matchingTiles) {
-        this.matchingTiles = matchingTiles;
-    }
-
-    void setResultDimensionInsideTiledImage(Rectangle resultDimension) {
-        this.resultDimension = resultDimension;
-    }
-
-    void setMosaicLocation(Rectangle rasterMosaicLocation) {
-        this.mosaicLocation = rasterMosaicLocation;
-    }
-
-    public Rectangle getMosaicLocation() {
-        return mosaicLocation;
-    }
-
-    public void setResultImage(RenderedImage rasterImage) {
-        this.resultImage = rasterImage;
-        if (rasterImage.getWidth() != tiledImageSize.width
-                || rasterImage.getHeight() != tiledImageSize.height) {
-            LOGGER.warning("Result image and expected dimensions don't match: image="
-                    + resultImage.getWidth() + "x" + resultImage.getHeight() + ", expected="
-                    + tiledImageSize.width + "x" + tiledImageSize.height);
-        }
-    }
-
-    public RenderedImage getResultImage() {
-        return resultImage;
-    }
-
-    void setTiledImageSize(Rectangle tiledImageSize) {
-        this.tiledImageSize = tiledImageSize;
-    }
-
-    public Rectangle getTiledImageSize() {
-        return tiledImageSize;
-    }
-
-    void setResolution(double[] resolution) {
-        this.resolution = resolution;
-    }
-
-    public double[] getResolution() {
-        return resolution == null ? new double[] { -1, -1 } : resolution;
-    }
-
-    void setRasterIndex(int rasterN) {
-        this.rasterIndex = rasterN;
-    }
-
-    public int getRasterIndex() {
-        return rasterIndex;
-    }
-
-    void setLevelTileRange(Rectangle levelTileRange) {
-        this.levelTileRange = levelTileRange;
-    }
-
-    public Rectangle getLevelTileRange() {
-        return levelTileRange;
-    }
-}
\ No newline at end of file

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterQueryInfo.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,216 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import java.awt.Rectangle;
+import java.awt.image.RenderedImage;
+import java.util.logging.Logger;
+
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.util.logging.Logging;
+
+/**
+ * Captures information about a query for a single raster in a raster dataset.
+ *
+ * @author Gabriel Roldan
+ * @version $Id$
+ * @since 2.5.6
+ * @see RasterUtils#findMatchingRasters
+ * @see RasterUtils#fitRequestToRaster
+ */
+public final class RasterQueryInfo {
+
+    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
+
+    private GeneralEnvelope requestedEnvelope;
+
+    private Rectangle requestedDim;
+
+    private int pyramidLevel;
+
+    /**
+     * The two-dimensional range of tile indices whose envelope intersect the requested extent. Will
+     * have negative width and height if none of the tiles do.
+     */
+    private Rectangle matchingTiles;
+
+    private GeneralEnvelope resultEnvelope;
+
+    private Rectangle resultDimension;
+
+    private Long rasterId;
+
+    private Rectangle mosaicLocation;
+
+    private RenderedImage resultImage;
+
+    private Rectangle tiledImageSize;
+
+    private double[] resolution;
+
+    private int rasterIndex;
+
+    /**
+     * The full tile range for the matching pyramid level
+     */
+    private Rectangle levelTileRange;
+
+    public RasterQueryInfo() {
+        setResultDimensionInsideTiledImage(new Rectangle(0, 0, 0, 0));
+        setMatchingTiles(new Rectangle(0, 0, 0, 0));
+        setResultEnvelope(null);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder s = new StringBuilder("[Raster query info:");
+        s.append("\n\tRaster ID            : ").append(getRasterId());
+        s.append("\n\tPyramid level        : ").append(getPyramidLevel());
+        s.append("\n\tResolution           : ").append(
+                getResolution()[0] + "," + getResolution()[1]);
+        s.append("\n\tRequested envelope   : ").append(getRequestedEnvelope());
+        s.append("\n\tRequested dimension  : ").append(getRequestedDim());
+        Rectangle mt = getMatchingTiles();
+        Rectangle ltr = getLevelTileRange();
+        String matching = "x=" + mt.x + "-" + (mt.x + mt.width - 1) + ", y=" + mt.y + "-"
+                + (mt.y + mt.height - 1);
+        String level = "x=" + ltr.x + "-" + (ltr.width - 1) + ", y=" + ltr.y + "-"
+                + (ltr.height - 1);
+        s.append("\n\tMatching tiles       : ").append(matching).append(" out of ").append(level);
+        s.append("\n\tTiled image size     : ").append(getTiledImageSize());
+        s.append("\n\tResult dimension     : ").append(getResultDimensionInsideTiledImage());
+        s.append("\n\tMosaiced dimension   : ").append(getMosaicLocation());
+        s.append("\n\tResult envelope      : ").append(getResultEnvelope());
+        s.append("\n]");
+        return s.toString();
+    }
+
+    /**
+     * @return the rasterId (as in SeRaster.getId()) for the raster in the raster dataset this query
+     *         works upon
+     */
+    public Long getRasterId() {
+        return rasterId;
+    }
+
+    public GeneralEnvelope getRequestedEnvelope() {
+        return requestedEnvelope;
+    }
+
+    public Rectangle getRequestedDim() {
+        return requestedDim;
+    }
+
+    public int getPyramidLevel() {
+        return pyramidLevel;
+    }
+
+    public Rectangle getMatchingTiles() {
+        return matchingTiles;
+    }
+
+    public GeneralEnvelope getResultEnvelope() {
+        return resultEnvelope;
+    }
+
+    public Rectangle getResultDimensionInsideTiledImage() {
+        return resultDimension;
+    }
+
+    void setRasterId(Long rasterId) {
+        this.rasterId = rasterId;
+    }
+
+    void setPyramidLevel(int pyramidLevel) {
+        this.pyramidLevel = pyramidLevel;
+    }
+
+    void setRequestedEnvelope(GeneralEnvelope requestedEnvelope) {
+        this.requestedEnvelope = requestedEnvelope;
+    }
+
+    void setRequestedDim(Rectangle requestedDim) {
+        this.requestedDim = requestedDim;
+    }
+
+    void setResultEnvelope(GeneralEnvelope resultEnvelope) {
+        this.resultEnvelope = resultEnvelope;
+    }
+
+    void setMatchingTiles(Rectangle matchingTiles) {
+        this.matchingTiles = matchingTiles;
+    }
+
+    void setResultDimensionInsideTiledImage(Rectangle resultDimension) {
+        this.resultDimension = resultDimension;
+    }
+
+    void setMosaicLocation(Rectangle rasterMosaicLocation) {
+        this.mosaicLocation = rasterMosaicLocation;
+    }
+
+    public Rectangle getMosaicLocation() {
+        return mosaicLocation;
+    }
+
+    public void setResultImage(RenderedImage rasterImage) {
+        this.resultImage = rasterImage;
+        if (rasterImage.getWidth() != tiledImageSize.width
+                || rasterImage.getHeight() != tiledImageSize.height) {
+            LOGGER.warning("Result image and expected dimensions don't match: image="
+                    + resultImage.getWidth() + "x" + resultImage.getHeight() + ", expected="
+                    + tiledImageSize.width + "x" + tiledImageSize.height);
+        }
+    }
+
+    public RenderedImage getResultImage() {
+        return resultImage;
+    }
+
+    void setTiledImageSize(Rectangle tiledImageSize) {
+        this.tiledImageSize = tiledImageSize;
+    }
+
+    public Rectangle getTiledImageSize() {
+        return tiledImageSize;
+    }
+
+    void setResolution(double[] resolution) {
+        this.resolution = resolution;
+    }
+
+    public double[] getResolution() {
+        return resolution == null ? new double[] { -1, -1 } : resolution;
+    }
+
+    void setRasterIndex(int rasterN) {
+        this.rasterIndex = rasterN;
+    }
+
+    public int getRasterIndex() {
+        return rasterIndex;
+    }
+
+    void setLevelTileRange(Rectangle levelTileRange) {
+        this.levelTileRange = levelTileRange;
+    }
+
+    public Rectangle getLevelTileRange() {
+        return levelTileRange;
+    }
+}
\ No newline at end of file

Deleted: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java
===================================================================
--- trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java 2009-11-09 18:23:40 UTC (rev 34351)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -1,880 +0,0 @@
-/*
- *    GeoTools - The Open Source Java GIS Toolkit
- *    http://geotools.org
- *
- *    (C) 2002-2009, 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.arcsde.raster.info;
-
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_16BIT_S;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_16BIT_U;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_1BIT;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_REAL;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_S;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_U;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_4BIT;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_64BIT_REAL;
-import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_8BIT_U;
-
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Point;
-import java.awt.Rectangle;
-import java.awt.Transparency;
-import java.awt.color.ColorSpace;
-import java.awt.image.BandedSampleModel;
-import java.awt.image.ColorModel;
-import java.awt.image.ComponentColorModel;
-import java.awt.image.DataBuffer;
-import java.awt.image.IndexColorModel;
-import java.awt.image.SampleModel;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.logging.Logger;
-
-import javax.imageio.ImageTypeSpecifier;
-
-import org.geotools.coverage.GridSampleDimension;
-import org.geotools.coverage.grid.GeneralGridEnvelope;
-import org.geotools.coverage.grid.io.OverviewPolicy;
-import org.geotools.geometry.GeneralEnvelope;
-import org.geotools.referencing.CRS;
-import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
-import org.geotools.resources.image.ColorUtilities;
-import org.geotools.resources.image.ComponentColorModelJAI;
-import org.geotools.util.NumberRange;
-import org.geotools.util.logging.Logging;
-import org.opengis.geometry.Envelope;
-import org.opengis.referencing.datum.PixelInCell;
-import org.opengis.referencing.operation.MathTransform;
-import org.opengis.referencing.operation.NoninvertibleTransformException;
-import org.opengis.referencing.operation.TransformException;
-
-import com.sun.imageio.plugins.common.BogusColorSpace;
-
-/**
- *
- * @author Gabriel Roldan (OpenGeo)
- * @since 2.5.4
- * @version $Id$
- * @source $URL:
- *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
- *         /geotools/arcsde/raster/info/RasterUtils.java $
- */
-@SuppressWarnings( { "nls" })
-public class RasterUtils {
-
-    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
-
-    private RasterUtils() {
-        // do nothing
-    }
-
-    public static MathTransform createRasterToModel(final Rectangle levelGridRange,
-            final GeneralEnvelope levelEnvelope) {
-        // create a raster to model transform, from this tile pixel space to the tile's geographic
-        // extent
-        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(levelGridRange, 2);
-        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, levelEnvelope);
-        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
-
-        final MathTransform rasterToModel = geMapper.createTransform();
-        return rasterToModel;
-    }
-
-    private static Rectangle getResultDimensionForTileRange(final Rectangle tiledImageGridRange,
-            final Rectangle matchingLevelRange) {
-
-        int minx = Math.max(tiledImageGridRange.x, matchingLevelRange.x);
-        int miny = Math.max(tiledImageGridRange.y, matchingLevelRange.y);
-        int maxx = (int) Math.min(tiledImageGridRange.getMaxX(), matchingLevelRange.getMaxX());
-        int maxy = (int) Math.min(tiledImageGridRange.getMaxY(), matchingLevelRange.getMaxY());
-
-        return new Rectangle(minx, miny, maxx - minx, maxy - miny);
-    }
-
-    /**
-     * Returns the rectangle specifying the matching tiles for a given pyramid level and rectangle
-     * specifying the overlapping area to request in the level's pixel space.
-     *
-     * @param pixelRange
-     * @param tilesHigh
-     * @param tilesWide
-     * @param tileSize
-     * @param numTilesHigh
-     * @param numTilesWide
-     *
-     * @param pixelRange
-     * @param level
-     *
-     * @return a rectangle holding the coordinates in tile space that fully covers the requested
-     *         pixel range for the given pyramid level, or a negative area rectangle
-     */
-    private static Rectangle findMatchingTiles(final Dimension tileSize, int numTilesWide,
-            int numTilesHigh, final Rectangle pixelRange) {
-
-        final int minPixelX = pixelRange.x;
-        final int minPixelY = pixelRange.y;
-
-        // TODO: WARNING, we're not considering the possible x/y offsets on the level range for the
-        // given pyramid level here!
-
-        int minTileX = (int) Math.floor(minPixelX / tileSize.getWidth());
-        int minTileY = (int) Math.floor(minPixelY / tileSize.getHeight());
-
-        int numTilesX = (int) Math.ceil(pixelRange.getWidth() / tileSize.getWidth());
-        int numTilesY = (int) Math.ceil(pixelRange.getHeight() / tileSize.getHeight());
-
-        int maxTiledX = (minTileX + numTilesX) * tileSize.width;
-        int maxTiledY = (minTileY + numTilesY) * tileSize.height;
-
-        if (maxTiledX < pixelRange.getMaxX() && (minTileX + numTilesX) < numTilesWide) {
-            numTilesX++;
-        }
-
-        if (maxTiledY < pixelRange.getMaxY() && (minTileY + numTilesY) < numTilesHigh) {
-            numTilesY++;
-        }
-
-        Rectangle matchingTiles = new Rectangle(minTileX, minTileY, numTilesX, numTilesY);
-        return matchingTiles;
-    }
-
-    private static Rectangle getTargetGridRange(final MathTransform modelToRaster,
-            final Envelope requestedEnvelope) {
-        Rectangle levelOverlappingPixels;
-        int levelMinPixelX;
-        int levelMaxPixelX;
-        int levelMinPixelY;
-        int levelMaxPixelY;
-        {
-            // use a model to raster transform to find out which pixel range at the specified level
-            // better match the requested extent
-            GeneralEnvelope requestedPixels;
-            try {
-                requestedPixels = CRS.transform(modelToRaster, requestedEnvelope);
-            } catch (NoninvertibleTransformException e) {
-                throw new IllegalArgumentException(e);
-            } catch (TransformException e) {
-                throw new IllegalArgumentException(e);
-            }
-
-            levelMinPixelX = (int) Math.floor(requestedPixels.getMinimum(0));
-            levelMaxPixelX = (int) Math.floor(requestedPixels.getMaximum(0));
-
-            levelMinPixelY = (int) Math.ceil(requestedPixels.getMinimum(1));
-            levelMaxPixelY = (int) Math.ceil(requestedPixels.getMaximum(1));
-
-            final int width = levelMaxPixelX - levelMinPixelX;
-            final int height = levelMaxPixelY - levelMinPixelY;
-            levelOverlappingPixels = new Rectangle(levelMinPixelX, levelMinPixelY, width, height);
-        }
-        return levelOverlappingPixels;
-    }
-
-    /**
-     * Creates an IndexColorModel out of a DataBuffer obtained from an ArcSDE's raster color map.
-     *
-     * @param colorMapData
-     * @return
-     */
-    public static IndexColorModel sdeColorMapToJavaColorModel(final DataBuffer colorMapData,
-            final int bitsPerSample) {
-        if (colorMapData == null) {
-            throw new NullPointerException("colorMapData");
-        }
-
-        if (colorMapData.getNumBanks() < 3 || colorMapData.getNumBanks() > 4) {
-            throw new IllegalArgumentException("colorMapData shall have 3 or 4 banks: "
-                    + colorMapData.getNumBanks());
-        }
-
-        if (bitsPerSample != 8 && bitsPerSample != 16) {
-            throw new IllegalAccessError("bits per sample shall be either 8 or 16. Got "
-                    + bitsPerSample);
-        }
-
-        final int numBanks = colorMapData.getNumBanks();
-        final int mapSize = colorMapData.getSize();
-
-        byte[] r = new byte[mapSize];
-        byte[] g = new byte[mapSize];
-        byte[] b = new byte[mapSize];
-        byte[] a = new byte[mapSize];
-
-        for (int i = 0; i < mapSize; i++) {
-            r[i] = (byte) (colorMapData.getElem(0, i) & 0xFF);
-            g[i] = (byte) (colorMapData.getElem(1, i) & 0xFF);
-            b[i] = (byte) (colorMapData.getElem(2, i) & 0xFF);
-            a[i] = (byte) ((numBanks == 3 ? 255 : colorMapData.getElem(3, i)) & 0xFF);
-        }
-
-        IndexColorModel colorModel = new IndexColorModel(bitsPerSample, mapSize, r, g, b, a);
-
-        return colorModel;
-    }
-
-    public static ImageTypeSpecifier createFullImageTypeSpecifier(
-            final RasterDatasetInfo rasterInfo, final int rasterIndex) {
-
-        final int numberOfBands = rasterInfo.getNumBands();
-        final RasterCellType nativePixelType = rasterInfo.getNativeCellType();
-        final RasterCellType pixelType = rasterInfo.getTargetCellType(rasterIndex);
-
-        // Prepare temporary colorModel and sample model, needed to build the final
-        // ArcSDEPyramidLevel level;
-        int sampleImageWidth = 1;// rasterInfo.getImageWidth();
-        int sampleImageHeight = 1;// rasterInfo.getImageHeight();
-
-        final ImageTypeSpecifier its;
-        // treat special cases...
-        final int bitsPerSample = pixelType.getBitsPerSample();
-        final int dataType = pixelType.getDataBufferType();
-        final boolean hasColorMap = rasterInfo.isColorMapped();
-
-        if (hasColorMap) {
-            // special case, a single band colormapped image
-            IndexColorModel colorMap = rasterInfo.getColorMap(rasterIndex);
-            its = createColorMappedImageSpec(colorMap, sampleImageWidth, sampleImageHeight);
-
-        } else if (nativePixelType == TYPE_1BIT && numberOfBands == 1) {
-            byte noDataValue = rasterInfo.getNoDataValue(rasterIndex, 0).byteValue();
-            // special case, a single band 1-bit
-            its = createOneBitColorMappedImageSpec(sampleImageWidth, sampleImageHeight, noDataValue);
-
-        } else if (nativePixelType == TYPE_4BIT && numberOfBands == 1) {
-            byte noDataValue = rasterInfo.getNoDataValue(rasterIndex, 0).byteValue();
-            // special case, a single band 4-bit
-            its = createFourBitColorMappedImageSpec(sampleImageWidth, sampleImageHeight,
-                    noDataValue);
-        } else if (numberOfBands == 1) {
-            // special case, a single band grayscale image, no matter the pixel depth
-            its = createGrayscaleImageSpec(sampleImageWidth, sampleImageHeight, dataType,
-                    bitsPerSample);
-
-        } else if (numberOfBands == 3 && pixelType == TYPE_8BIT_U) {
-            // special case, an optimizable RGB image
-            its = createRGBImageSpec(sampleImageWidth, sampleImageHeight, dataType);
-
-        } else if (numberOfBands == 4 && pixelType == TYPE_8BIT_U) {
-            // special case, an optimizable RGBA image
-            its = createRGBAImageSpec(sampleImageWidth, sampleImageHeight, dataType);
-
-        } else {
-            /*
-             * not an special case, go for a more generic sample model, potentially slower than the
-             * special case ones, but that'll work anyway
-             */
-
-            final ColorModel colorModel;
-            final SampleModel sampleModel;
-            {
-                final ColorSpace colorSpace;
-                colorSpace = new BogusColorSpace(numberOfBands);
-                int[] numBits = new int[numberOfBands];
-                for (int i = 0; i < numberOfBands; i++) {
-                    numBits[i] = bitsPerSample;
-                }
-                colorModel = new ComponentColorModelJAI(colorSpace, numBits, false, false,
-                        Transparency.OPAQUE, dataType);
-            }
-            {
-                int[] bankIndices = new int[numberOfBands];
-                int[] bandOffsets = new int[numberOfBands];
-                // int bandOffset = (tileWidth * tileHeight * pixelType.getBitsPerSample()) / 8;
-                for (int i = 0; i < numberOfBands; i++) {
-                    bankIndices[i] = i;
-                    bandOffsets[i] = 0;// (i * bandOffset);
-                }
-                sampleModel = new BandedSampleModel(dataType, sampleImageWidth, sampleImageHeight,
-                        sampleImageWidth, bankIndices, bandOffsets);
-            }
-            its = new ImageTypeSpecifier(colorModel, sampleModel);
-        }
-
-        return its;
-    }
-
-    private static ImageTypeSpecifier createFourBitColorMappedImageSpec(int sampleImageWidth,
-            int sampleImageHeight, byte noDataValue) {
-
-        int maxValue = (int) TYPE_4BIT.getSampleValueRange().getMaximum();
-
-        int mapSize = noDataValue > maxValue ? noDataValue : maxValue + 1;
-
-        int[] cmap = new int[mapSize];
-        ColorUtilities.expand(new Color[] { Color.BLACK, Color.WHITE }, cmap, 0, maxValue);
-
-        for (int i = maxValue; i < mapSize; i++) {
-            cmap[i] = ColorUtilities.getIntFromColor(0, 0, 0, 0);
-        }
-
-        int transparentPixel = noDataValue;
-        IndexColorModel colorModel = new IndexColorModel(8, mapSize, cmap, 0, true,
-                transparentPixel, DataBuffer.TYPE_BYTE);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createOneBitColorMappedImageSpec(int sampleImageWidth,
-            int sampleImageHeight, byte noDataValue) {
-
-        assert noDataValue == 2;
-
-        final int FALSE = ColorUtilities.getIntFromColor(255, 255, 255, 255);
-        final int TRUE = ColorUtilities.getIntFromColor(0, 0, 0, 255);
-        final int NODATA = ColorUtilities.getIntFromColor(255, 255, 255, 0);
-
-        final int mapSize = 3;
-        int[] cmap = new int[mapSize];
-        cmap[0] = FALSE;
-        cmap[1] = TRUE;
-        cmap[2] = NODATA;
-
-        int transparentPixel = noDataValue;
-        IndexColorModel colorModel = new IndexColorModel(8, mapSize, cmap, 0, false,
-                transparentPixel, DataBuffer.TYPE_BYTE);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createRGBAImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType) {
-
-        final ImageTypeSpecifier its;
-
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        boolean hasAlpha = true;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.TRANSLUCENT;
-        int transferType = dataType;
-
-        int[] nBits = { 8, 8, 8, 8 };
-        ColorModel colorModel = new ComponentColorModelJAI(colorSpace, nBits, hasAlpha,
-                isAlphaPremultiplied, transparency, transferType);
-
-        /*
-         * Do not use colorModel.createCompatibleSampleModel cause it creates a
-         * PixelInterleavedSampleModel and we need a BandedSampleModel so it matches how the data
-         * comes out of ArcSDE
-         */
-        SampleModel sampleModel = new BandedSampleModel(dataType, sampleImageWidth,
-                sampleImageHeight, 4);
-
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createRGBImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType) {
-
-        final ImageTypeSpecifier its;
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_sRGB);
-        boolean hasAlpha = false;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.OPAQUE;
-        int transferType = dataType;
-        ColorModel colorModel = new ComponentColorModel(colorSpace, new int[] { 8, 8, 8 },
-                hasAlpha, isAlphaPremultiplied, transparency, transferType);
-
-        SampleModel sampleModel = new BandedSampleModel(dataType, sampleImageWidth,
-                sampleImageHeight, 3);
-
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createGrayscaleImageSpec(int sampleImageWidth,
-            int sampleImageHeight, final int dataType, int bitsPerPixel) {
-        final ImageTypeSpecifier its;
-        ColorSpace colorSpace = ColorSpace.getInstance(ColorSpace.CS_GRAY);
-        boolean hasAlpha = false;
-        boolean isAlphaPremultiplied = false;
-        int transparency = Transparency.OPAQUE;
-        int transferType = dataType;
-        int[] nbits = { bitsPerPixel };
-        ColorModel colorModel = new ComponentColorModelJAI(colorSpace, nbits, hasAlpha,
-                isAlphaPremultiplied, transparency, transferType);
-
-        SampleModel sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth,
-                sampleImageHeight);
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createOneBitImageSpec(final RasterDatasetInfo rasterInfo,
-            final int numberOfBands, int sampleImageWidth, int sampleImageHeight,
-            final int bitsPerSample, final int dataType) {
-        final ColorModel colorModel;
-        final SampleModel sampleModel;
-        if (numberOfBands != 1) {
-            throw new IllegalArgumentException(bitsPerSample
-                    + "-Bit rasters are only supported for one band");
-        }
-        int[] argb = new int[(int) Math.pow(2, bitsPerSample)];
-        ColorUtilities.expand(new Color[] { Color.WHITE, Color.BLACK }, argb, 0, argb.length);
-        GridSampleDimension gridSampleDimension = rasterInfo.getGridSampleDimensions()[0];
-        colorModel = gridSampleDimension.getColorModel(0, numberOfBands, dataType);
-        sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth, sampleImageHeight);
-
-        ImageTypeSpecifier its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-    }
-
-    private static ImageTypeSpecifier createColorMappedImageSpec(final IndexColorModel colorModel,
-            int sampleImageWidth, int sampleImageHeight) {
-
-        final SampleModel sampleModel;
-        final ImageTypeSpecifier its;
-        LOGGER.fine("Found single-band colormapped raster, using its index color model");
-        sampleModel = colorModel.createCompatibleSampleModel(sampleImageWidth, sampleImageHeight);
-        its = new ImageTypeSpecifier(colorModel, sampleModel);
-        return its;
-
-    }
-
-    /**
-     * Given a collection of {@link RasterQueryInfo} instances holding information about how a
-     * request fits for each individual raster composing a catalog, figure out where their resulting
-     * images fit into the overall mosaic that's gonna be the result of the request.
-     *
-     * @param rasterInfo
-     * @param resultEnvelope
-     * @param results
-     * @return
-     */
-    public static Rectangle setMosaicLocations(final RasterDatasetInfo rasterInfo,
-            final GeneralEnvelope resultEnvelope, final List<RasterQueryInfo> results) {
-        final Rectangle mosaicDimension;
-        final MathTransform modelToRaster;
-        final MathTransform rasterToModel;
-        {
-            /*
-             * Of all the rasters that match the requested envelope, chose the one with the lowest
-             * resolution as the base to compute the final mosaic layout, so we avoid JAI upsamples,
-             * which are buggy and produce repeated patterns over the x axis instead of just scaling
-             * up the image.
-             */
-            RasterQueryInfo dimensionChoice = findLowestResolution(results);
-            Long rasterId = dimensionChoice.getRasterId();
-            int pyramidLevel = dimensionChoice.getPyramidLevel();
-            int rasterIndex = rasterInfo.getRasterIndex(rasterId);
-            Rectangle levelRange = rasterInfo.getGridRange(rasterIndex, pyramidLevel);
-            GeneralEnvelope levelEnvelope = rasterInfo.getGridEnvelope(rasterIndex, pyramidLevel);
-            rasterToModel = createRasterToModel(levelRange, levelEnvelope);
-            try {
-                modelToRaster = rasterToModel.inverse();
-            } catch (NoninvertibleTransformException e) {
-                throw new RuntimeException(e);
-            }
-            mosaicDimension = getTargetGridRange(modelToRaster, resultEnvelope);
-        }
-
-        for (RasterQueryInfo rasterResultInfo : results) {
-            final GeneralEnvelope rasterResultEnvelope = rasterResultInfo.getResultEnvelope();
-
-            final Rectangle targetRasterGridRange;
-            targetRasterGridRange = getTargetGridRange(modelToRaster, rasterResultEnvelope);
-
-            rasterResultInfo.setMosaicLocation(targetRasterGridRange);
-        }
-
-        return mosaicDimension;
-    }
-
-    private static RasterQueryInfo findLowestResolution(List<RasterQueryInfo> results) {
-        double[] prev = { Double.MIN_VALUE, Double.MIN_VALUE };
-        RasterQueryInfo lowestResQuery = null;
-
-        double[] curr;
-        for (RasterQueryInfo query : results) {
-            curr = query.getResolution();
-            if (curr[0] > prev[0]) {
-                prev = curr;
-                lowestResQuery = query;
-            }
-        }
-        return lowestResQuery;
-    }
-
-    /**
-     * Find out the raster ids and their pyramid levels in the raster dataset for the rasters whose
-     * envelope overlaps the requested one
-     *
-     * @param rasterInfo
-     * @param requestedEnvelope
-     * @param requestedDim
-     * @param overviewPolicy
-     * @return
-     */
-    public static List<RasterQueryInfo> findMatchingRasters(final RasterDatasetInfo rasterInfo,
-            final GeneralEnvelope requestedEnvelope, final Rectangle requestedDim,
-            final OverviewPolicy overviewPolicy) {
-
-        final int numRasters = rasterInfo.getNumRasters();
-        List<RasterQueryInfo> matchingRasters = new ArrayList<RasterQueryInfo>(numRasters);
-
-        int optimalPyramidLevel;
-        GeneralEnvelope gridEnvelope;
-        for (int rasterN = 0; rasterN < numRasters; rasterN++) {
-            optimalPyramidLevel = rasterInfo.getOptimalPyramidLevel(rasterN, overviewPolicy,
-                    requestedEnvelope, requestedDim);
-            gridEnvelope = rasterInfo.getGridEnvelope(rasterN, optimalPyramidLevel);
-            final boolean edgesInclusive = true;
-            if (requestedEnvelope.intersects(gridEnvelope, edgesInclusive)) {
-                RasterQueryInfo match = new RasterQueryInfo();
-                match.setRequestedEnvelope(requestedEnvelope);
-                match.setRequestedDim(requestedDim);
-
-                match.setRasterId(rasterInfo.getRasterId(rasterN));
-                match.setRasterIndex(rasterN);
-                match.setPyramidLevel(optimalPyramidLevel);
-                match.setResolution(rasterInfo.getResolution(rasterN, optimalPyramidLevel));
-                matchingRasters.add(match);
-            }
-        }
-        return matchingRasters;
-    }
-
-    public static void fitRequestToRaster(final GeneralEnvelope requestedEnvelope,
-            final RasterDatasetInfo rasterInfo, final RasterQueryInfo query) {
-
-        final int rasterIndex = query.getRasterIndex();
-        final int pyramidLevel = query.getPyramidLevel();
-        final Rectangle rasterGridRange = rasterInfo.getGridRange(rasterIndex, pyramidLevel);
-        final GeneralEnvelope rasterEnvelope = rasterInfo
-                .getGridEnvelope(rasterIndex, pyramidLevel);
-
-        double delta = requestedEnvelope.getMinimum(0) - rasterEnvelope.getMinimum(0);
-        double resX = rasterInfo.getResolution(rasterIndex, pyramidLevel)[0];
-        int xMinPixel = (int) Math.floor(delta / resX);
-
-        delta = requestedEnvelope.getMaximum(0) - rasterEnvelope.getMinimum(0);
-        int xMaxPixel = (int) Math.ceil(delta / resX);
-
-        delta = rasterEnvelope.getMaximum(1) - requestedEnvelope.getMaximum(1);
-        double resY = rasterInfo.getResolution(rasterIndex, pyramidLevel)[1];
-        // Distance in pixels from the top of the whole pyramid image to the top
-        // of our AOI.
-        // If we're off the top, this number will be negative.
-        int yMinPixel = (int) Math.floor(delta / resY);
-
-        delta = rasterEnvelope.getMaximum(1) - requestedEnvelope.getMinimum(1);
-        int yMaxPixel = (int) Math.ceil(delta / resY);
-
-        xMinPixel = Math.max(xMinPixel, rasterGridRange.x);
-        yMinPixel = Math.max(yMinPixel, rasterGridRange.y);
-        xMaxPixel = Math.min(xMaxPixel, rasterGridRange.x + rasterGridRange.width);
-        yMaxPixel = Math.min(yMaxPixel, rasterGridRange.y + rasterGridRange.height);
-
-        final int widthPixel = xMaxPixel - xMinPixel;
-        final int heightPixel = yMaxPixel - yMinPixel;
-
-        final double xMinGeo = rasterEnvelope.getMinimum(0) + resX * xMinPixel;
-        final double yMinGeo = rasterEnvelope.getMaximum(1) - resY * (yMinPixel + heightPixel);
-        final double widthGeo = resX * widthPixel;
-        final double heightGeo = resY * heightPixel;
-
-        final Rectangle resultGridRange;
-        final GeneralEnvelope resultEnvelope;
-
-        resultEnvelope = new GeneralEnvelope(new double[] { xMinGeo, yMinGeo }, new double[] {
-                xMinGeo + widthGeo, yMinGeo + heightGeo });
-        resultEnvelope.setCoordinateReferenceSystem(rasterEnvelope.getCoordinateReferenceSystem());
-
-        resultGridRange = new Rectangle(xMinPixel, yMinPixel, widthPixel, heightPixel);
-
-        final Rectangle matchingTiles;
-        final Rectangle levelTileRange;
-        final Rectangle tiledImageGridRange;
-        {
-            final Dimension tileSize = rasterInfo.getTileDimension(rasterIndex);
-            final int numTilesWide = rasterInfo.getNumTilesWide(rasterIndex, pyramidLevel);
-            final int numTilesHigh = rasterInfo.getNumTilesHigh(rasterIndex, pyramidLevel);
-            final Point tileOffset = rasterInfo.getTileOffset(rasterIndex, pyramidLevel);
-            levelTileRange = new Rectangle(0, 0, numTilesWide, numTilesHigh);
-            matchingTiles = findMatchingTiles(tileSize, numTilesWide, numTilesHigh, resultGridRange);
-
-            int tiledImageMinX = (matchingTiles.x * tileSize.width);
-            int tiledImageMinY = (matchingTiles.y * tileSize.height);
-
-            int tiledWidth = (matchingTiles.width * tileSize.width);
-            int tiledHeight = (matchingTiles.height * tileSize.height);
-
-            tiledImageGridRange = new Rectangle(tiledImageMinX, tiledImageMinY, tiledWidth,
-                    tiledHeight);
-        }
-
-        /*
-         * What is the grid range inside the whole level grid range that fits into the matching
-         * tiles
-         */
-        Rectangle resultDimensionInsideTiledImage;
-        resultDimensionInsideTiledImage = getResultDimensionForTileRange(tiledImageGridRange,
-                resultGridRange);
-
-        query.setResultEnvelope(resultEnvelope);
-        query.setResultDimensionInsideTiledImage(resultDimensionInsideTiledImage);
-        query.setTiledImageSize(tiledImageGridRange);
-        query.setLevelTileRange(levelTileRange);
-        query.setMatchingTiles(matchingTiles);
-    }
-
-    /**
-     * Returns a color model based on {@code colorMap} that's guaranteed to have at least one
-     * transparent pixel whose index can be used as no-data value for colormapped rasters, even if
-     * the returned IndexColorModel needs to be of a higher sample depth (ie, 16 instead of 8 bit)
-     * to satisfy that.
-     *
-     * @param colorMap
-     *            the raster's native color map the returned one will be based on
-     * @return the same {@code colorMap} if it has a transparent pixel, another, possibly of a
-     *         higher depth one if not, containing all the colors from {@code colorMap} and a newly
-     *         allocated cell for the transparent pixel if necessary
-     */
-    public static IndexColorModel ensureNoDataPixelIsAvailable(final IndexColorModel colorMap) {
-        int transparentPixel = colorMap.getTransparentPixel();
-        if (transparentPixel > -1) {
-            return colorMap;
-        }
-
-        final int transferType = colorMap.getTransferType();
-        final int mapSize = colorMap.getMapSize();
-        final int maxSize = 65536;// true for either transfer type
-
-        if (mapSize == maxSize) {
-            LOGGER.fine("There's no room for a new transparent pixel, "
-                    + "returning the original colorMap as is");
-            return colorMap;
-        }
-
-        /*
-         * The original map size is lower than the maximum allowed by a UShort color map, so expand
-         * the colormap by one and make that new entry transparent
-         */
-        final int newMapSize = mapSize + 1;
-        final int[] argb = new int[newMapSize];
-        colorMap.getRGBs(argb);
-
-        // set the last entry as transparent
-        argb[newMapSize - 1] = ColorUtilities.getIntFromColor(0, 0, 0, 0);
-
-        IndexColorModel targetColorModel;
-        final int significantBits;
-        final int newTransferType;
-
-        {
-            if (DataBuffer.TYPE_BYTE == transferType && newMapSize <= 256) {
-                /*
-                 * REVISIT: check if this needs to be promoted depending on whether I decide to
-                 * treat 1 and 4 bit images as indexed with 1 and 4 significant bits respectively
-                 */
-                significantBits = colorMap.getPixelSize();
-                newTransferType = DataBuffer.TYPE_BYTE;
-            } else {
-                // it's either being promoted or was already 16-bit
-                significantBits = 16;
-                newTransferType = DataBuffer.TYPE_USHORT;
-            }
-        }
-
-        final int transparentPixelIndex = newMapSize - 1;
-        final boolean hasalpha = true;
-        final int startIndex = 0;
-
-        targetColorModel = new IndexColorModel(significantBits, newMapSize, argb, startIndex,
-                hasalpha, transparentPixelIndex, newTransferType);
-
-        return targetColorModel;
-    }
-
-    /**
-     * For a color-mapped raster, the no-data value is set to the
-     * {@link IndexColorModel#getTransparentPixel() transparent pixel}
-     *
-     * @param colorMap
-     * @return the index in the colorMap that's the transparent pixel as is to be used as no-data
-     *         value
-     */
-    public static Number determineNoDataValue(IndexColorModel colorMap) {
-        int noDataPixel = colorMap.getTransparentPixel();
-        if (-1 == noDataPixel) {
-            // there were no room for a transparent pixel, find out the closest match
-            noDataPixel = ColorUtilities.getTransparentPixel(colorMap);
-        }
-        return Integer.valueOf(noDataPixel);
-    }
-
-    /**
-     * @param numBands
-     *            number of bands in the raster dataset for the band whose nodata value is to be
-     *            determined. Might be useful to treat special cases where some assumptions are made
-     *            depending on the cell type and number of bands
-     * @param statsMin
-     *            the minimum sample value for the band as reported by the band's statistics, or
-     *            {@code NaN}
-     * @param statsMax
-     *            the maximum sample value for the band as reported by the band's statistics, or
-     *            {@code NaN}
-     * @param nativeCellType
-     *            the band's native cell type
-     * @return
-     */
-    public static Number determineNoDataValue(final int numBands, final double statsMin,
-            final double statsMax, final RasterCellType nativeCellType) {
-
-        final Number nodata;
-
-        if (nativeCellType == TYPE_32BIT_REAL) {
-            LOGGER.fine("no data value is Float.NaN");
-            return Float.valueOf(Float.NaN);
-        } else if (nativeCellType == TYPE_64BIT_REAL) {
-            LOGGER.fine("no data value is Double.NaN");
-            return Double.valueOf(Double.NaN);
-        } else if (nativeCellType == TYPE_1BIT) {
-            LOGGER.fine("1BIT images no-data value is set to 2,"
-                    + " regardless of the raster statistics");
-            return Double.valueOf(2);
-        } else if (nativeCellType == TYPE_4BIT) {
-            LOGGER.fine("4BIT images no-data value is set to 16,"
-                    + " regardless of the raster statistics");
-            return Double.valueOf(16);
-        } else if (!isGeoPhysics(numBands, nativeCellType)) {
-            LOGGER.fine("3 or 4 band, 8 bit unsigned image, assumed to be "
-                    + "RGB or RGBA respectively and nodata value hardcoded to 255");
-            return (Number) nativeCellType.getSampleValueRange().getMaxValue();
-        }
-
-        final NumberRange<?> sampleValueRange = nativeCellType.getSampleValueRange();
-
-        final double minimumSample = sampleValueRange.getMinimum(true);
-        final double maximumSample = sampleValueRange.getMaximum(true);
-
-        double lower;
-        double greater;
-        if (Double.isNaN(statsMin) || Double.isNaN(statsMax)) {
-            lower = Math.ceil(minimumSample - 1);
-            greater = Math.floor(maximumSample + 1);
-        } else {
-            lower = Math.ceil(statsMin - 1);
-            greater = Math.floor(statsMax + 1);
-        }
-
-        final boolean isUnsigned = minimumSample == 0;
-
-        if (sampleValueRange.contains((Number) Double.valueOf(lower))) {
-            // lower is ok
-            nodata = lower;
-        } else if (sampleValueRange.contains((Number) Double.valueOf(greater))) {
-            // upper is ok
-            nodata = greater;
-        } else if (isUnsigned) {
-            // need to set no-data to the higher value, floor is zero
-            nodata = greater;
-            // if (cellType == TYPE_1BIT || cellType == TYPE_4BIT) {
-            // nodata = greater;
-            // } else {
-            // // best guess without promoting. We don't actually want to promote a raster that is
-            // // non
-            // // colormapped and either has no statistics or it's range is full to preserve the
-            // // cases
-            // // were it may affect badly the visualization (for example, a 3 band 8bit raster
-            // // promoted to 3 band 16bit is gonna look almost black
-            // nodata = maximumSample;
-            // }
-        } else {
-            // no-data as the lower value is ok, floor is non zero (the celltype is signed)
-            nodata = lower;
-        }
-
-        return nodata;
-    }
-
-    public static boolean isGeoPhysics(final int numBands, final RasterCellType nativeCellType) {
-        boolean geophysics = true;
-        if (nativeCellType == TYPE_8BIT_U && (numBands == 3 || numBands == 4)) {
-            geophysics = false;
-        }
-        return geophysics;
-    }
-
-    public static RasterCellType determineTargetCellType(final RasterCellType nativeCellType,
-            final List<Number> noDataValues) {
-
-        if (TYPE_32BIT_REAL == nativeCellType || TYPE_64BIT_REAL == nativeCellType) {
-            // no data value is NaN, so no need to promote. For other types NaN is not available
-            for (Number nodata : noDataValues) {
-                if (!Double.isNaN(nodata.doubleValue())) {
-                    throw new IllegalArgumentException("no data values for float and "
-                            + "double cell types shall be NaN: " + nodata);
-                }
-            }
-            return nativeCellType;
-        }
-
-        // find a cell type that's deep enough for all the bands in the given raster
-        double noDataMin = Double.POSITIVE_INFINITY, noDataMax = Double.NEGATIVE_INFINITY;
-        {
-            for (Number noData : noDataValues) {
-                noDataMin = Math.min(noDataMin, noData.doubleValue());
-                noDataMax = Math.max(noDataMax, noData.doubleValue());
-            }
-        }
-        final NumberRange<Double> sampleValueRange;
-        sampleValueRange = nativeCellType.getSampleValueRange().castTo(Double.class);
-
-        final RasterCellType targetCellType;
-
-        if (sampleValueRange.contains((Number) Double.valueOf(noDataMin))
-                && sampleValueRange.contains((Number) Double.valueOf(noDataMax))) {
-            /*
-             * The native cell type can hold the no-data values for all bands in the raster
-             */
-            targetCellType = nativeCellType;
-        } else {
-            targetCellType = promote(nativeCellType);
-        }
-        return targetCellType;
-    }
-
-    private static RasterCellType promote(final RasterCellType nativeCellType) {
-        switch (nativeCellType) {
-        case TYPE_1BIT:
-        case TYPE_4BIT:
-            return TYPE_8BIT_U;
-        case TYPE_8BIT_U:
-            return TYPE_16BIT_U;
-        case TYPE_8BIT_S:
-            return TYPE_16BIT_S;
-        case TYPE_16BIT_U:
-            return TYPE_32BIT_U;
-        case TYPE_16BIT_S:
-            return TYPE_32BIT_S;
-        case TYPE_32BIT_S:
-        case TYPE_32BIT_REAL:
-        case TYPE_32BIT_U:
-            return TYPE_64BIT_REAL;
-        default:
-            throw new IllegalArgumentException(
-                    "Can't promote a raster of type 64-bit-real, there's "
-                            + "no higher pixel depth than that!");
-        }
-    }
-}

Copied: branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java (from rev 34351, trunk/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java)
===================================================================
--- branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java                        (rev 0)
+++ branches/2.5.x/modules/plugin/arcsde/datastore/src/main/java/org/geotools/arcsde/raster/info/RasterUtils.java 2009-11-09 18:53:16 UTC (rev 34354)
@@ -0,0 +1,880 @@
+/*
+ *    GeoTools - The Open Source Java GIS Toolkit
+ *    http://geotools.org
+ *
+ *    (C) 2002-2009, 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.arcsde.raster.info;
+
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_16BIT_S;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_16BIT_U;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_1BIT;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_REAL;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_S;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_32BIT_U;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_4BIT;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_64BIT_REAL;
+import static org.geotools.arcsde.raster.info.RasterCellType.TYPE_8BIT_U;
+
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Point;
+import java.awt.Rectangle;
+import java.awt.Transparency;
+import java.awt.color.ColorSpace;
+import java.awt.image.BandedSampleModel;
+import java.awt.image.ColorModel;
+import java.awt.image.ComponentColorModel;
+import java.awt.image.DataBuffer;
+import java.awt.image.IndexColorModel;
+import java.awt.image.SampleModel;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Logger;
+
+import javax.imageio.ImageTypeSpecifier;
+
+import org.geotools.coverage.GridSampleDimension;
+import org.geotools.coverage.grid.GeneralGridEnvelope;
+import org.geotools.coverage.grid.io.OverviewPolicy;
+import org.geotools.geometry.GeneralEnvelope;
+import org.geotools.referencing.CRS;
+import org.geotools.referencing.operation.builder.GridToEnvelopeMapper;
+import org.geotools.resources.image.ColorUtilities;
+import org.geotools.resources.image.ComponentColorModelJAI;
+import org.geotools.util.NumberRange;
+import org.geotools.util.logging.Logging;
+import org.opengis.geometry.Envelope;
+import org.opengis.referencing.datum.PixelInCell;
+import org.opengis.referencing.operation.MathTransform;
+import org.opengis.referencing.operation.NoninvertibleTransformException;
+import org.opengis.referencing.operation.TransformException;
+
+import com.sun.imageio.plugins.common.BogusColorSpace;
+
+/**
+ *
+ * @author Gabriel Roldan (OpenGeo)
+ * @since 2.5.4
+ * @version $Id$
+ * @source $URL:
+ *         http://svn.osgeo.org/geotools/trunk/modules/plugin/arcsde/datastore/src/main/java/org
+ *         /geotools/arcsde/raster/info/RasterUtils.java $
+ */
+@SuppressWarnings( { "nls" })
+public class RasterUtils {
+
+    private static final Logger LOGGER = Logging.getLogger("org.geotools.arcsde.gce");
+
+    private RasterUtils() {
+        // do nothing
+    }
+
+    public static MathTransform createRasterToModel(final Rectangle levelGridRange,
+            final GeneralEnvelope levelEnvelope) {
+        // create a raster to model transform, from this tile pixel space to the tile's geographic
+        // extent
+        GeneralGridEnvelope gridRange = new GeneralGridEnvelope(levelGridRange, 2);
+        GridToEnvelopeMapper geMapper = new GridToEnvelopeMapper(gridRange, levelEnvelope);
+        geMapper.setPixelAnchor(PixelInCell.CELL_CORNER);
+
+        final MathTransform rasterToModel = geMapper.createTransform();
+       &nb