svn - r34326 - in branches/2.6.x/modules/unsupported/jp2kakadu: . src/main/java/org/geotools/coverageio/jp2kak

1 message Options
Embed this post
Permalink
svn_geotools

svn - r34326 - in branches/2.6.x/modules/unsupported/jp2kakadu: . src/main/java/org/geotools/coverageio/jp2kak

Reply Threaded More More options
Print post
Permalink
Author: danieleromagnoli
Date: 2009-11-04 11:32:24 -0500 (Wed, 04 Nov 2009)
New Revision: 34326

Modified:
   branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java
   branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java
Log:
Porting improvements from mosaic's plugin computations

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/pom.xml 2009-11-04 16:32:24 UTC (rev 34326)
@@ -90,7 +90,7 @@
     <dependency>
       <groupId>it.geosolutions.imageio-ext</groupId>
       <artifactId>imageio-ext-kakadu</artifactId>
-      <version>${imageio.ext.version}</version>
+      <version>1.0-SNAPSHOT</version>
     </dependency>
      <dependency>
       <groupId>it.geosolutions.imageio-ext</groupId>

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Granule.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -16,6 +16,7 @@
 
 import javax.imageio.ImageReadParam;
 import javax.imageio.ImageReader;
+import javax.imageio.spi.ImageReaderSpi;
 import javax.imageio.stream.ImageInputStream;
 import javax.media.jai.ImageLayout;
 import javax.media.jai.Interpolation;
@@ -325,6 +326,8 @@
  final Map<Integer,Level> granuleLevels= Collections.synchronizedMap(new HashMap<Integer,Level>());
 
  AffineTransform baseGridToWorld;
+
+ ImageReaderSpi cachedSPI;
 
  public Granule(BoundingBox granuleBBOX, File granuleFile) {
  super();
@@ -342,14 +345,18 @@
  // get a stream
  inStream = Utils.getInputStream(granuleFile);
  if(inStream==null)
- throw new IllegalArgumentException("Unable to get an input stream for the provided file "+granuleFile.toString());
-
- // get a reader
- reader = Utils.getReader(inStream);
+ throw new IllegalArgumentException("Unable to get an input stream for the provided file "+granuleFile.getAbsolutePath());
+
+ // get a reader and try to cache the relevant SPI
+ if(cachedSPI==null){
+ reader = Utils.getReader( inStream);
+ if(reader!=null)
+ cachedSPI=reader.getOriginatingProvider();
+ }
+ else
+ reader=cachedSPI.createReaderInstance();
  if(reader==null)
- {
- throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.toString());
- }
+ throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.getAbsolutePath());
 
  //get selected level and base level dimensions
  final Rectangle originalDimension = Utils.getDimension(0,inStream, reader);
@@ -395,7 +402,7 @@
  final ImageReadParam readParameters,
  final int imageIndex,
  final ReferencedEnvelope cropBBox,
- final MathTransform2D mosaicWorldToGrid,
+ final MathTransform2D worldToGrid,
  final RasterLayerRequest request,
  final Dimension tileDimension) throws IOException {
 
@@ -418,8 +425,14 @@
  if(inStream==null)
  return null;
 
- // get a reader
- reader = Utils.getReader(inStream);
+ // get a reader and try to cache the relevant SPI
+ if(cachedSPI==null){
+ reader = Utils.getReader( inStream);
+ if(reader!=null)
+ cachedSPI=reader.getOriginatingProvider();
+ }
+ else
+ reader=cachedSPI.createReaderInstance();
  if(reader==null)
  {
  if (LOGGER.isLoggable(java.util.logging.Level.WARNING))
@@ -446,8 +459,8 @@
  XRectangle2D.intersect(sourceArea, selectedlevel.rasterDimensions, sourceArea);//make sure roundings don't bother us
  // is it empty??
  if (sourceArea.isEmpty()) {
- if (LOGGER.isLoggable(java.util.logging.Level.WARNING))
- LOGGER.warning("Got empty area for granule "+this.toString()+ " with request "+request.toString());
+ if (LOGGER.isLoggable(java.util.logging.Level.FINE))
+ LOGGER.fine("Got empty area for granule "+this.toString()+ " with request "+request.toString());
  return null;
 
  } else if (LOGGER.isLoggable(java.util.logging.Level.FINE))
@@ -497,27 +510,26 @@
 
 
  // now create the overall transform
- final AffineTransform tempRaster2Model = new AffineTransform(baseGridToWorld);
- tempRaster2Model.concatenate(Utils.CENTER_TO_CORNER);
+ final AffineTransform finalRaster2Model = new AffineTransform(baseGridToWorld);
+ finalRaster2Model.concatenate(Utils.CENTER_TO_CORNER);
  if(!XAffineTransform.isIdentity(backToBaseLevelScaleTransform,10E-6))
- tempRaster2Model.concatenate(backToBaseLevelScaleTransform);
+ finalRaster2Model.concatenate(backToBaseLevelScaleTransform);
  if(!XAffineTransform.isIdentity(afterDecimationTranslateTranform,10E-6))
- tempRaster2Model.concatenate(afterDecimationTranslateTranform);
+ finalRaster2Model.concatenate(afterDecimationTranslateTranform);
  if(!XAffineTransform.isIdentity(decimationScaleTranform,10E-6))
- tempRaster2Model.concatenate(decimationScaleTranform);
+ finalRaster2Model.concatenate(decimationScaleTranform);
 
  // keep into account translation factors to place this tile
- final AffineTransform translationTransform = new AffineTransform((AffineTransform) mosaicWorldToGrid);
- translationTransform.concatenate(tempRaster2Model);
+ finalRaster2Model.preConcatenate((AffineTransform) worldToGrid);
 
  final InterpolationNearest nearest = new InterpolationNearest();
  //paranoiac check to avoid that JAI freaks out when computing its internal layouT on images that are too small
  Rectangle2D finalLayout= layoutHelper(
  raster,
- (float)translationTransform.getScaleX(),
- (float)translationTransform.getScaleY(),
- (float)translationTransform.getTranslateX(),
- (float)translationTransform.getTranslateY(),
+ (float)finalRaster2Model.getScaleX(),
+ (float)finalRaster2Model.getScaleY(),
+ (float)finalRaster2Model.getTranslateX(),
+ (float)finalRaster2Model.getTranslateY(),
  nearest);
  if(finalLayout.isEmpty())
  {
@@ -528,7 +540,7 @@
 
  // apply the affine transform  conserving indexed color model
  final RenderingHints localHints = new RenderingHints(JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.FALSE);
- if(XAffineTransform.isIdentity(translationTransform,10E-6))
+ if(XAffineTransform.isIdentity(finalRaster2Model,10E-6))
  return raster;
  else
  {
@@ -547,7 +559,7 @@
  }
  // border extender
 // return WarpDescriptor.create(raster, new WarpAffine(translationTransform.createInverse()),new InterpolationNearest(), request.getBackgroundValues(),localHints);
- return AffineDescriptor.create(raster, translationTransform, nearest, /*request.getBackgroundValues()*/ null,localHints);
+ return AffineDescriptor.create(raster, finalRaster2Model, nearest, /*request.getBackgroundValues()*/ null,localHints);
  }
 
  } catch (IllegalStateException e) {
@@ -598,12 +610,16 @@
  if(inStream==null)
  throw new IllegalArgumentException();
 
- // get a reader
- reader = Utils.getReader( inStream);
+ // get a reader and try to cache the relevant SPI
+ if(cachedSPI==null){
+ reader = Utils.getReader( inStream);
+ if(reader!=null)
+ cachedSPI=reader.getOriginatingProvider();
+ }
+ else
+ reader=cachedSPI.createReaderInstance();
  if(reader==null)
- {
- throw new IllegalArgumentException();
- }
+ throw new IllegalArgumentException("Unable to get an ImageReader for the provided file "+granuleFile.getAbsolutePath());
 
  //get selected level and base level dimensions
  final Rectangle levelDimension = Utils.getDimension(index,inStream, reader);

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KFormat.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -26,6 +26,7 @@
 
 import javax.imageio.spi.ImageReaderSpi;
 
+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;
@@ -150,7 +151,7 @@
     /**
      * @see org.geotools.data.coverage.grid.AbstractGridFormat#getReader(Object, Hints)
      */
-    public GridCoverageReader getReader(Object source, Hints hints) {
+    public AbstractGridCoverage2DReader getReader(Object source, Hints hints) {
         try {
             return new JP2KReader(source, hints);
         } catch (MismatchedDimensionException e) {
@@ -171,7 +172,7 @@
     /**
      * @see org.geotools.data.coverage.grid.AbstractGridFormat#getReader(Object)
      */
-    public GridCoverageReader getReader( Object source ) {
+    public AbstractGridCoverage2DReader getReader( Object source ) {
         return getReader(source, null);
     }
     

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/JP2KReader.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -23,6 +23,7 @@
 
 import java.awt.Rectangle;
 import java.awt.geom.AffineTransform;
+import java.awt.image.DataBufferByte;
 import java.io.ByteArrayInputStream;
 import java.io.File;
 import java.io.FileInputStream;
@@ -32,6 +33,7 @@
 import java.net.URL;
 import java.net.URLDecoder;
 import java.util.Collection;
+import java.util.List;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -41,9 +43,9 @@
 import javax.imageio.metadata.IIOMetadataNode;
 
 import org.geotools.coverage.CoverageFactoryFinder;
-import org.geotools.coverage.grid.GeneralGridRange;
 import org.geotools.coverage.grid.GridCoverage2D;
 import org.geotools.coverage.grid.GridCoverageFactory;
+import org.geotools.coverage.grid.GridEnvelope2D;
 import org.geotools.coverage.grid.io.AbstractGridCoverage2DReader;
 import org.geotools.coverage.grid.io.AbstractGridFormat;
 import org.geotools.coverage.grid.io.imageio.geotiff.GeoTiffIIOMetadataDecoder;
@@ -60,6 +62,7 @@
 import org.opengis.coverage.grid.Format;
 import org.opengis.coverage.grid.GridCoverage;
 import org.opengis.coverage.grid.GridCoverageReader;
+import org.opengis.coverage.grid.GridRange;
 import org.opengis.geometry.Envelope;
 import org.opengis.parameter.GeneralParameterValue;
 import org.opengis.referencing.FactoryException;
@@ -89,11 +92,20 @@
  /** The system-dependent default name-separator character. */
     private final static char SEPARATOR = File.separatorChar;
 
-    private final static short[] geoJp2UUID = new short[] { 0xb1, 0x4b, 0xf8,
-            0xbd, 0x08, 0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6,
-            0xce, 0x03 };
+    private final static short[] geoJp2UUID = new short[] { 0xb1, 0x4b, 0xf8, 0xbd, 0x08,
+        0x3d, 0x4b, 0x43, 0xa5, 0xae, 0x8c, 0xd7, 0xd5, 0xa6, 0xce, 0x03 };
+    
+    private final static short[] msigWorldFileBoxUUID = new short[] { 0x96, 0xa9, 0xf1, 0xf1,
+        0xdc, 0x98, 0x40, 0x2d, 0xa7, 0xae, 0xd6, 0x8e, 0x34, 0x45, 0x18, 0x09 };
 
     /**
+     * The base {@link GridRange} for the {@link GridCoverage2D} of this reader.
+     */
+    private GridEnvelope2D nativeGridRange = null;
+    
+    private GeneralEnvelope nativeEnvelope = null;
+    
+    /**
      * Creates a new instance of a {@link JP2KReader}. I assume nothing about
      * file extension.
      *
@@ -124,41 +136,81 @@
         int hrHeight = reader.getHeight(0);
         final Rectangle actualDim = new Rectangle(0, 0, hrWidth,
                 hrHeight);
-        this.originalGridRange = new GeneralGridRange(actualDim);
+        this.nativeGridRange = new GridEnvelope2D(actualDim);
         if (this.crs == null) {
             parsePRJFile();
         }
-        if (this.originalEnvelope == null)
+        if (this.nativeEnvelope == null)
          parseWorldFile();
 
-        if (this.crs == null || this.originalEnvelope == null)
-         checkGeoJP2CRS(metadata);
+        if (this.crs == null || this.nativeEnvelope == null)
+         checkUUIDBoxes(metadata);
         // //
         //
         // If no sufficient information have been found to set the
         // envelope, try other ways, such as looking for a WorldFile
         //
         // //
-        if (this.originalEnvelope == null) {
+        if (this.nativeEnvelope == null) {
                 throw new DataSourceException(
                         "Unavailable envelope for this coverage");
         }
 
         // setting the coordinate reference system for the envelope
+        originalEnvelope = getCoverageEnvelope();
         originalEnvelope.setCoordinateReferenceSystem(crs);
+        originalGridRange = getCoverageGridRange();
 
         // Additional settings due to "final" methods getOriginalXXX
     }
 
-    private boolean isGeoJP2(byte[] id) {
-        for (int i = 0; i < geoJp2UUID.length; i++) {
-            if ((id[i] & 0xFF) != geoJp2UUID[i])
+    /**
+     * @param nativeEnvelope
+     *                the nativeEnvelope to set
+     */
+    protected void setCoverageEnvelope(GeneralEnvelope coverageEnvelope) {
+        this.nativeEnvelope = coverageEnvelope;
+    }
+
+    /**
+     * @return the nativeEnvelope
+     */
+    protected GeneralEnvelope getCoverageEnvelope() {
+        return nativeEnvelope;
+    }
+
+    /**
+     * @param nativeGridRange
+     *                the nativeGridRange to set
+     */
+    protected void setCoverageGridRange(GridEnvelope2D coverageGridRange) {
+        this.nativeGridRange = coverageGridRange;
+    }
+
+    /**
+     * @return the nativeGridRange
+     */
+    protected GridEnvelope2D getCoverageGridRange() {
+        return nativeGridRange;
+    }
+    
+    private boolean isGeoJP2(final byte[] id) {
+     return isSameUUID(id, geoJp2UUID);
+    }
+    
+    private boolean isWorldBox(final byte[] id) {
+     return isSameUUID(id, msigWorldFileBoxUUID);
+    }
+    
+    private boolean isSameUUID(final byte[] id, final short[] uuid) {
+        for (int i = 0; i < uuid.length; i++) {
+            if ((id[i] & 0xFF) != uuid[i])
                 return false;
         }
         return true;
     }
     
-    private void checkGeoJP2CRS(final IIOMetadata metadata) throws IOException{
+    private void checkUUIDBoxes(final IIOMetadata metadata) throws IOException{
      if (!(metadata instanceof JP2KStreamMetadata)) {
             if (LOGGER.isLoggable(Level.WARNING))
              LOGGER.warning("Unexpected error! Metadata should be an instance of the expected class:"
@@ -169,75 +221,152 @@
         // Looking for the UUIDBoxMetadataNode
         //
         // //
-        CoordinateReferenceSystem coordinateReferenceSystem = null;
-        IIOMetadataNode uuidBoxMetadataNode = ((JP2KStreamMetadata) metadata)
-                .searchFirstOccurrenceNode(UUIDBox.BOX_TYPE);
-        if (uuidBoxMetadataNode != null
-                && uuidBoxMetadataNode instanceof UUIDBoxMetadataNode) {
-            UUIDBoxMetadataNode uuid = (UUIDBoxMetadataNode) uuidBoxMetadataNode;
-            final byte[] id = uuid.getUuid();
-            final boolean isGeoJP2 = isGeoJP2(id);
-
-            if (isGeoJP2) {
-                final ByteArrayInputStream inputStream = new ByteArrayInputStream(
-                        uuid.getData());
-                final TIFFImageReader tiffreader = (TIFFImageReader) new TIFFImageReaderSpi()
-                        .createReaderInstance();
-                tiffreader
-                        .setInput(ImageIO.createImageInputStream(inputStream));
-                final IIOMetadata tiffmetadata = tiffreader.getImageMetadata(0);
-                final GeoTiffIIOMetadataDecoder metadataDecoder = new GeoTiffIIOMetadataDecoder(
-                        tiffmetadata);
-                final GeoTiffMetadata2CRSAdapter adapter = new GeoTiffMetadata2CRSAdapter(
-                        null);
-                try {
-                    coordinateReferenceSystem = adapter
-                            .createCoordinateSystem(metadataDecoder);
-                    if (coordinateReferenceSystem != null) {
-                     if (this.crs == null)
-                     this.crs = coordinateReferenceSystem;
+        final List<IIOMetadataNode> uuidBoxMetadataNodes = ((JP2KStreamMetadata) metadata)
+                .searchOccurrencesNode(UUIDBox.BOX_TYPE);
+        if (uuidBoxMetadataNodes != null && !uuidBoxMetadataNodes.isEmpty()){
+         for (IIOMetadataNode node: uuidBoxMetadataNodes){
+         if (node instanceof UUIDBoxMetadataNode) {
+                    final UUIDBoxMetadataNode uuid = (UUIDBoxMetadataNode) node;
+                    final byte[] id = uuid.getUuid();
+                    if (isGeoJP2(id)) {
+                       getGeoJP2(uuid);
+                       continue;
                     }
-                    if (this.raster2Model == null){
-                    this.raster2Model = adapter
-                            .getRasterToModel(metadataDecoder);
-                    final AffineTransform tempTransform = new AffineTransform(
-                            (AffineTransform) raster2Model);
-                    tempTransform.translate(-0.5, -0.5);
-                    GeneralEnvelope envelope = CRS.transform(
-                            ProjectiveTransform.create(tempTransform),
-                            new GeneralEnvelope(originalGridRange.toRectangle()));
-                    envelope
-                            .setCoordinateReferenceSystem(crs);
-                    this.originalEnvelope = envelope;
-                    }
-
-                } catch (FactoryException e) {
-                    if (LOGGER.isLoggable(Level.FINE))
-                        LOGGER.log(Level.FINE,
-                                "Unable to parse CRS from underlying TIFF", e);
-                    coordinateReferenceSystem = null;
-                } catch (TransformException e) {
-                    if (LOGGER.isLoggable(Level.FINE))
-                        LOGGER.log(Level.FINE,
-                                "Unable to parse CRS from underlying TIFF", e);
-                    coordinateReferenceSystem = null;
-                } catch (UnsupportedOperationException e) {
-                    if (LOGGER.isLoggable(Level.FINE))
-                        LOGGER.log(Level.FINE,
-                                "Unable to parse CRS from underlying TIFF due to an unsupported CRS", e);
-                    coordinateReferenceSystem = null;
-                } finally {
-                    if (inputStream != null)
-                        try {
-                            inputStream.close();
-                        } catch (IOException ioe) {
-                            // Eat exception.
-                        }
+                    
+                    // //
+                    //
+                    // Without a proper crs, the World Box is useless
+                    //
+                    // //
+                    if (crs != null)
+                     if (isWorldBox(id)){
+                     getWorldBox(uuid);
+                    }
                 }
-            }
+         }
         }
     }
+    
+    private void getWorldBox(final UUIDBoxMetadataNode uuid) throws IOException {
+
+     // //
+     // Parsing Header
+     // //
+     final byte[] bb = uuid.getData();
+        if (bb[0]!='M'||bb[1]!='S'||bb[2]!='I'||bb[3]!='G')
+ return;
+
+        // Version number: useless
+        // bb[4] bb[5]
+        
+        final int worldFileInterpretation = bb[6];
+        final int chunkNumber = bb[14];
+        
+        // //
+        //
+        // Parsing Chunk
+        //
+        // //
+        final int ckIndex = 16;
+        final int chunkIndex = bb[ckIndex];
+        final long chunkLength = Utils.bytes2long(bb, ckIndex+2);
+        
+        if (chunkIndex!=0 && chunkLength!=48)
+         return;
+        final double xScale = Utils.bytes2double(bb,ckIndex+6);
+        final double xRotation = Utils.bytes2double(bb,ckIndex+14);
+        final double yRotation = Utils.bytes2double(bb,ckIndex+22);
+        final double yScale = Utils.bytes2double(bb,ckIndex+30);
+        final double xUpperLeft = Utils.bytes2double(bb,ckIndex+38);
+        final double yUpperLeft = Utils.bytes2double(bb,ckIndex+46);
+        
+        final boolean footerOk = (bb[ckIndex + 54] == (byte)0xFF) && (bb[ckIndex + 55] == (byte)0x00);
+
+        final AffineTransform tempTransform = new AffineTransform(
+         xScale, yRotation, xRotation,
+         yScale, xUpperLeft, yUpperLeft);
+        this.raster2Model = ProjectiveTransform.create(tempTransform);
+        tempTransform.translate(-0.5, -0.5);
+      
+        try {
+         GeneralEnvelope envelope = CRS.transform(
+            ProjectiveTransform.create(tempTransform),
+            new GeneralEnvelope(nativeGridRange));
+         envelope.setCoordinateReferenceSystem(crs);
+         this.nativeEnvelope = envelope;
+        } catch (TransformException e) {
+            if (LOGGER.isLoggable(Level.FINE))
+                LOGGER.log(Level.FINE,
+                        "Unable to parse CRS from underlying TIFF", e);
+        } catch (UnsupportedOperationException e) {
+            if (LOGGER.isLoggable(Level.FINE))
+                LOGGER.log(Level.FINE,
+                        "Unable to parse CRS from underlying TIFF due to an unsupported CRS", e);
+        }
+        
+    }
 
+ private void getGeoJP2(final UUIDBoxMetadataNode uuid) throws IOException {
+
+ CoordinateReferenceSystem coordinateReferenceSystem = null;
+ final ByteArrayInputStream inputStream = new ByteArrayInputStream(
+                 uuid.getData());
+         final TIFFImageReader tiffreader = (TIFFImageReader) new TIFFImageReaderSpi()
+                 .createReaderInstance();
+         tiffreader
+                 .setInput(ImageIO.createImageInputStream(inputStream));
+         final IIOMetadata tiffmetadata = tiffreader.getImageMetadata(0);
+         final GeoTiffIIOMetadataDecoder metadataDecoder = new GeoTiffIIOMetadataDecoder(
+                 tiffmetadata);
+         final GeoTiffMetadata2CRSAdapter adapter = new GeoTiffMetadata2CRSAdapter(
+                 null);
+         try {
+             coordinateReferenceSystem = adapter
+                     .createCoordinateSystem(metadataDecoder);
+             if (coordinateReferenceSystem != null) {
+             if (this.crs == null)
+             this.crs = coordinateReferenceSystem;
+             }
+             if (this.raster2Model == null){
+                 this.raster2Model = adapter
+                         .getRasterToModel(metadataDecoder);
+                 final AffineTransform tempTransform = new AffineTransform(
+                         (AffineTransform) raster2Model);
+                 tempTransform.translate(-0.5, -0.5);
+                 GeneralEnvelope envelope = CRS.transform(
+                         ProjectiveTransform.create(tempTransform),
+                         new GeneralEnvelope(nativeGridRange));
+                 envelope
+                         .setCoordinateReferenceSystem(crs);
+                 this.nativeEnvelope = envelope;
+             }
+
+         } catch (FactoryException e) {
+             if (LOGGER.isLoggable(Level.FINE))
+                 LOGGER.log(Level.FINE,
+                         "Unable to parse CRS from underlying TIFF", e);
+             coordinateReferenceSystem = null;
+         } catch (TransformException e) {
+             if (LOGGER.isLoggable(Level.FINE))
+                 LOGGER.log(Level.FINE,
+                         "Unable to parse CRS from underlying TIFF", e);
+             coordinateReferenceSystem = null;
+         } catch (UnsupportedOperationException e) {
+             if (LOGGER.isLoggable(Level.FINE))
+                 LOGGER.log(Level.FINE,
+                         "Unable to parse CRS from underlying TIFF due to an unsupported CRS", e);
+             coordinateReferenceSystem = null;
+         } finally {
+             if (inputStream != null)
+                 try {
+                     inputStream.close();
+                 } catch (IOException ioe) {
+                     // Eat exception.
+                 }
+         }
+
+ }
+
  /**
  * Number of coverages for this reader is 1
  *
@@ -360,7 +489,7 @@
  /**
  * @see org.opengis.coverage.grid.GridCoverageReader#read(org.opengis.parameter.GeneralParameterValue[])
  */
- public GridCoverage read(GeneralParameterValue[] params) throws IOException {
+ public GridCoverage2D read(GeneralParameterValue[] params) throws IOException {
 
  if (LOGGER.isLoggable(Level.FINE)) {
  LOGGER.fine("Reading image from " + sourceURL.toString());
@@ -518,13 +647,12 @@
             //
             // //
             
-            MathTransform tempTransform =PixelTranslation.translate(raster2Model, PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER);
+            MathTransform tempTransform = PixelTranslation.translate(raster2Model, PixelInCell.CELL_CENTER, PixelInCell.CELL_CORNER);
             try {
-                final Envelope gridRange = new GeneralEnvelope(
-                        originalGridRange.toRectangle());
+                final Envelope gridRange = new GeneralEnvelope(nativeGridRange);
                 final GeneralEnvelope coverageEnvelope = CRS.transform(
                  tempTransform, gridRange);
-                originalEnvelope = coverageEnvelope;
+                nativeEnvelope = coverageEnvelope;
             } catch (TransformException e) {
                 if (LOGGER.isLoggable(Level.WARNING)) {
                     LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e);
@@ -557,8 +685,8 @@
         final Rectangle originalDim = new Rectangle(0, 0, reader.getWidth(0),
                 reader.getHeight(0));
 
-        if (originalGridRange == null) {
-         originalGridRange = new GeneralGridRange(originalDim);
+        if (nativeGridRange == null) {
+         nativeGridRange = new GridEnvelope2D(originalDim);
         }
 
         // ///
@@ -573,17 +701,7 @@
                             highestRes[0]).append(",").append(highestRes[1])
                             .toString());
         numOverviews = 0;
-// final double[][] resolutions = configuration.getLevels();
  overViewResolutions = numOverviews >= 1 ? new double[numOverviews][2]: null;
-// highestRes = new double[2];
-// highestRes[0] = resolutions[0][0];
-// highestRes[1] =resolutions[0][1];
-// if(numOverviews>0){
-//   for (int i = 0; i < numOverviews; i++) {    
-// overViewResolutions[i][0] = resolutions[i+1][0];
-// overViewResolutions[i][1] = resolutions[i+1][1];
-//   }
-// }
         
 
     }

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerRequest.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -42,6 +42,8 @@
 import org.geotools.referencing.operation.matrix.XAffineTransform;
 import org.geotools.referencing.operation.transform.ProjectiveTransform;
 import org.geotools.resources.geometry.XRectangle2D;
+import org.geotools.resources.i18n.ErrorKeys;
+import org.geotools.resources.i18n.Errors;
 import org.opengis.geometry.BoundingBox;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.MismatchedDimensionException;
@@ -859,35 +861,41 @@
  // the effect is a degradation of quality, but we take that into account emprically
         //
  requestedResolution=null;
+//
+// // compute the raster that correspond to the crop bbox at the highest resolution
+// final Rectangle sourceRasterArea = new GeneralGridEnvelope(
+// CRS.transform(
+// PixelTranslation.translate(rasterManager.getRaster2Model(),PixelInCell.CELL_CENTER,PixelInCell.CELL_CORNER).inverse(),
+// cropBBox),PixelInCell.CELL_CORNER,false).toRectangle();
+// XRectangle2D.intersect(sourceRasterArea, rasterManager.spatialDomainManager.coverageRasterArea, sourceRasterArea);
+// if(sourceRasterArea.isEmpty())
+// throw new DataSourceException("The request source raster area is empty");
 
- // compute the raster that correspond to the crop bbox at the highest resolution
- final Rectangle sourceRasterArea = new GeneralGridEnvelope(
- CRS.transform(
- PixelTranslation.translate(rasterManager.getRaster2Model(),PixelInCell.CELL_CENTER,PixelInCell.CELL_CORNER).inverse(),
- cropBBox),PixelInCell.CELL_CORNER,false).toRectangle();
- XRectangle2D.intersect(sourceRasterArea, rasterManager.spatialDomainManager.coverageRasterArea, sourceRasterArea);
- if(sourceRasterArea.isEmpty())
- throw new DataSourceException("aaa");
-
 
  // transform the crop bbox to the request model space
- final GeneralEnvelope envelope=CRS.transform(destinationToSourceTransform.inverse(), cropBBox);
-        final GridToEnvelopeMapper geMapper= new GridToEnvelopeMapper(new GridEnvelope2D(sourceRasterArea),envelope);
+ final GeneralEnvelope requestedEnvelopeInSourceCRS=CRS.transform(destinationToSourceTransform.inverse(), cropBBox);
+        final GridToEnvelopeMapper geMapper= new GridToEnvelopeMapper(new GridEnvelope2D(requestedRasterArea),requestedEnvelopeInSourceCRS);
         final AffineTransform tempTransform = geMapper.createAffineTransform();
-        final double scaleX=XAffineTransform.getScaleX0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleX0(tempTransform);
-        final double scaleY=XAffineTransform.getScaleY0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleY0(tempTransform);
- //
- // empiric adjustment to get a finer resolution to have better quality when reprojecting
-        // TODO make it parametric
- //
-        requestedRasterScaleFactors= new double[2];
-        requestedRasterScaleFactors[0]=scaleX*1.0;
-        requestedRasterScaleFactors[1]=scaleY*1.0;
+//        final double scaleX=XAffineTransform.getScaleX0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleX0(tempTransform);
+//        final double scaleY=XAffineTransform.getScaleY0((AffineTransform) requestedGridToWorld)/XAffineTransform.getScaleY0(tempTransform);
+// //
+// // empiric adjustment to get a finer resolution to have better quality when reprojecting
+//        // TODO make it parametric
+// //
+//        requestedRasterScaleFactors= new double[2];
+//        requestedRasterScaleFactors[0]=scaleX*1.0;
+//        requestedRasterScaleFactors[1]=scaleY*1.0;
         
-        
-        // adjust the final grid to world
-        final GridToEnvelopeMapper geMapper1= new GridToEnvelopeMapper(new GridEnvelope2D(destinationRasterArea),cropBBox);
-        requestedGridToWorld= geMapper1.createAffineTransform();
+        requestedResolution= new double[]
+                                {
+ XAffineTransform.getScaleX0(tempTransform),
+ XAffineTransform.getScaleY0(tempTransform)
+ };
+//
+//        
+//        // adjust the final grid to world
+//        final GridToEnvelopeMapper geMapper1= new GridToEnvelopeMapper(new GridEnvelope2D(destinationRasterArea),cropBBox);
+//        requestedGridToWorld= geMapper1.createAffineTransform();
 
 
  }
@@ -898,34 +906,17 @@
  // the crs of the request and the one of the coverage are the
  // same, we can get the resolution from the grid to world
  //
-// if(requestedGridToWorld instanceof AffineTransform){
- requestedResolution= new double[]
-                                {
- XAffineTransform.getScaleX0(requestedGridToWorld),
- XAffineTransform.getScaleY0(requestedGridToWorld)
- };
-// }
-// else{
-// // get the matrix
-// final Matrix matrix= ((LinearTransform)requestedGridToWorld).getMatrix();
-// final XAffineTransform transform=new XAffineTransform(
-// matrix.getElement(0, 0),
-// matrix.getElement(1, 0),
-// matrix.getElement(0, 1),
-// matrix.getElement(1, 1),
-// matrix.getElement(0, 2),
-// matrix.getElement(1, 2));
-// requestedResolution= new double[]
-//                                {
-// XAffineTransform.getScaleX0(transform),
-// XAffineTransform.getScaleY0(transform)
-// };
-// }
-//
+ requestedResolution= new double[]
+                                {
+ XAffineTransform.getScaleX0(requestedGridToWorld),
+ XAffineTransform.getScaleY0(requestedGridToWorld)
+ };
  }
  }
+ else
+ // should not happen
+ throw new UnsupportedOperationException(Errors.format(ErrorKeys.UNSUPPORTED_OPERATION_$1,requestedGridToWorld.toString()));
 
-
  //leave
  return;
  }catch (Throwable e) {
@@ -1132,10 +1123,10 @@
  public Dimension getTileDimensions() {
  return tileDimensions;
  }
-
- public double[] getRequestedRasterScaleFactors() {
- return requestedRasterScaleFactors!=null?requestedRasterScaleFactors.clone():requestedRasterScaleFactors;
- }
+//
+// public double[] getRequestedRasterScaleFactors() {
+// return requestedRasterScaleFactors!=null?requestedRasterScaleFactors.clone():requestedRasterScaleFactors;
+// }
 
  @Override
  public String toString() {

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterLayerResponse.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -19,6 +19,7 @@
 import java.awt.Color;
 import java.awt.Dimension;
 import java.awt.Rectangle;
+import java.awt.geom.AffineTransform;
 import java.awt.image.ColorModel;
 import java.awt.image.IndexColorModel;
 import java.awt.image.MultiPixelPackedSampleModel;
@@ -61,6 +62,7 @@
 import org.opengis.coverage.grid.GridCoverage;
 import org.opengis.geometry.BoundingBox;
 import org.opengis.referencing.datum.PixelInCell;
+import org.opengis.referencing.operation.MathTransform;
 import org.opengis.referencing.operation.MathTransform2D;
 import org.opengis.referencing.operation.TransformException;
 
@@ -352,6 +354,8 @@
 
  private String location;
 
+ private MathTransform baseGridToWorld;
+
  /**
  * Construct a {@code RasterLayerResponse} given a specific
  * {@link RasterLayerRequest}, a {@code GridCoverageFactory} to produce
@@ -386,6 +390,7 @@
  coverageEnvelope = rasterManager.getCoverageEnvelope();
  this.coverageFactory = rasterManager.getCoverageFactory();
  this.rasterManager = rasterManager;
+ baseGridToWorld=rasterManager.getRaster2Model();
  transparentColor=request.getInputTransparentColor();
  useMultithreading = request.isUseMultithreading();
 
@@ -494,21 +499,30 @@
 
 
  //compute final world to grid
- OverviewLevel level = rasterManager.overviewsController.resolutionsLevels.get(imageChoice);
- finalGridToWorldCorner = new AffineTransform2D(
- level.resolutionX*baseReadParameters.getSourceXSubsampling(),
+ // base grid to world for the center of pixels
+ final AffineTransform g2w = new AffineTransform((AffineTransform) baseGridToWorld);
+ // move it to the corner
+ g2w.concatenate(Utils.CENTER_TO_CORNER);
+
+ //keep into account overviews and subsampling
+ final OverviewLevel level = rasterManager.overviewsController.resolutionsLevels.get(imageChoice);
+ final OverviewLevel baseLevel = rasterManager.overviewsController.resolutionsLevels.get(0);
+ final AffineTransform2D adjustments = new AffineTransform2D(
+ (level.resolutionX/baseLevel.resolutionX)*baseReadParameters.getSourceXSubsampling(),
  0,
  0,
- -level.resolutionY*baseReadParameters.getSourceYSubsampling(),
- bbox.getLowerCorner().getOrdinate(0),
- bbox.getUpperCorner().getOrdinate(1));
+ (level.resolutionY/baseLevel.resolutionY)*baseReadParameters.getSourceYSubsampling(),
+ 0,
+ 0);
+ g2w.concatenate(adjustments);
+ finalGridToWorldCorner = new AffineTransform2D(g2w);
  finalWorldToGridCorner = finalGridToWorldCorner.inverse();// compute raster bounds
  rasterBounds=new GeneralGridEnvelope(CRS.transform(finalWorldToGridCorner, bbox),PixelInCell.CELL_CORNER,false).toRectangle();
 
 
  // create the index visitor and visit the feature
  final GranuleWorker worker = new GranuleWorker();
- worker.init(bbox);
+ worker.init(new ReferencedEnvelope(coverageEnvelope));
  worker.produce();
 
  //

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/RasterManager.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -6,13 +6,14 @@
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import javax.imageio.ImageReadParam;
 
-import org.geotools.coverage.grid.GeneralGridEnvelope;
 import org.geotools.coverage.grid.GridCoverage2D;
 import org.geotools.coverage.grid.GridCoverageFactory;
+import org.geotools.coverage.grid.GridEnvelope2D;
 import org.geotools.coverage.grid.io.OverviewPolicy;
 import org.geotools.data.DataSourceException;
 import org.geotools.factory.Hints;
@@ -101,7 +102,7 @@
  // -the aspect ratio for the overviews is constant
  // -the provided resolutions are taken directly from the grid
  resolutionsLevels.add(new OverviewLevel(1, highestRes[0],highestRes[1], 0));
- if (numberOfOvervies > 0) {
+ if (numberOfOverviews > 0) {
  for (int i = 0; i < overviewsResolution.length; i++)
  resolutionsLevels.add(
  new OverviewLevel(
@@ -147,13 +148,14 @@
  requestedScaleFactorY = reqy / max.resolutionY;        
  }
  else
- {
- final double[] scaleFactors = request.getRequestedRasterScaleFactors();
- if(scaleFactors==null)
- return 0;
- requestedScaleFactorX=scaleFactors[0];
- requestedScaleFactorY=scaleFactors[1];
- }
+ return 0;
+// {
+// final double[] scaleFactors = request.getRequestedRasterScaleFactors();
+// if(scaleFactors==null)
+// return 0;
+// requestedScaleFactorX=scaleFactors[0];
+// requestedScaleFactorY=scaleFactors[1];
+// }
  final int leastReduceAxis = requestedScaleFactorX <= requestedScaleFactorY ? 0: 1;
  final double requestedScaleFactor = leastReduceAxis == 0 ? requestedScaleFactorX: requestedScaleFactorY;
         
@@ -238,19 +240,19 @@
  readParameters.setSourceSubsampling(1, 1, 0, 0);
  return;
  }
- final int rasterWidth, rasterHeight;
+
  double selectedRes[] = new double[2];
+ final OverviewLevel level=overviewsController.resolutionsLevels.get(imageIndex);
+ selectedRes[0] = level.resolutionX;
+ selectedRes[1] = level.resolutionY;
+
+ final int rasterWidth, rasterHeight;
  if (imageIndex == 0) {
  // highest resolution
  rasterWidth = spatialDomainManager.coverageRasterArea.width;
  rasterHeight = spatialDomainManager.coverageRasterArea.height;
- selectedRes[0] = spatialDomainManager.coverageFullResolution[0];
- selectedRes[1] = spatialDomainManager.coverageFullResolution[1];
  } else {
  // work on overviews
- final OverviewLevel level=overviewsController.resolutionsLevels.get(imageIndex - 1);
- selectedRes[0] = level.resolutionX;
- selectedRes[1] = level.resolutionY;
  //TODO this is bad side effect of how the Overviews are managed right now. There are two problems here,
  // first we are assuming that we are working with LON/LAT, second is that we are getting just an approximation of
  // raster dimensions. The solution is to have the rater dimensions on each level and to confront raster dimensions,
@@ -360,7 +362,7 @@
  */
  private void setBaseParameters() {
     this.coverageEnvelope = RasterManager.this.getCoverageEnvelope().clone();
-    this.coverageRasterArea =(( GeneralGridEnvelope)RasterManager.this.getCoverageGridrange()).toRectangle();
+    this.coverageRasterArea =(( GridEnvelope2D)RasterManager.this.getCoverageGridrange());
     this.coverageCRS = RasterManager.this.getCoverageCRS();
     this.coverageGridToWorld2D = (MathTransform2D) RasterManager.this.getRaster2Model();
     this.coverageFullResolution = new double[2];
@@ -390,7 +392,7 @@
  /** The hints to be used to produce this coverage */
  private Hints hints;
  private URL inputURL;
- private int numberOfOvervies;
+ private int numberOfOverviews;
  private double[][] overviewsResolution;
  // ////////////////////////////////////////////////////////////////////////
  //
@@ -425,7 +427,7 @@
         
         //resolution values
         highestRes= reader.getHighestRes();
-        numberOfOvervies=reader.getNumberOfOvervies();
+        numberOfOverviews=reader.getNumberOfOvervies();
         overviewsResolution=reader.getOverviewsResolution();
         
         //instantiating controller for subsampling and overviews
@@ -456,19 +458,14 @@
  @SuppressWarnings("deprecation")
  private OverviewPolicy extractOverviewPolicy() {
 
- // check if a policy was provided using hints (check even the
- // deprecated one)
  if (this.hints != null)
  if (this.hints.containsKey(Hints.OVERVIEW_POLICY))
  overviewPolicy = (OverviewPolicy) this.hints.get(Hints.OVERVIEW_POLICY);
- else if (this.hints.containsKey(Hints.IGNORE_COVERAGE_OVERVIEW))
- overviewPolicy = ((Boolean) this.hints
- .get(Hints.IGNORE_COVERAGE_OVERVIEW)).booleanValue() ? OverviewPolicy.IGNORE
- : OverviewPolicy.QUALITY;
 
  // use default if not provided. Default is nearest
  if (overviewPolicy == null)
- overviewPolicy = OverviewPolicy.NEAREST;
+ overviewPolicy = OverviewPolicy.getDefaultPolicy();
+
  assert overviewPolicy != null;
  return overviewPolicy;
  }
@@ -480,7 +477,9 @@
  // create a request
  final RasterLayerRequest request= new RasterLayerRequest(params,this);
  if(request.isEmpty()){
- throw new DataSourceException("The provided request resulted in no area to load");
+ if(LOGGER.isLoggable(Level.FINE))
+ LOGGER.log(Level.FINE,"Request is empty: "+request.toString());
+ return Collections.emptyList();
  }
 
  // create a response for the provided request

Modified: branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java
===================================================================
--- branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-04 13:35:29 UTC (rev 34325)
+++ branches/2.6.x/modules/unsupported/jp2kakadu/src/main/java/org/geotools/coverageio/jp2kak/Utils.java 2009-11-04 16:32:24 UTC (rev 34326)
@@ -413,4 +413,40 @@
  return false;
  return true;
  }
+
+ public static double bytes2double (final byte[] bytes, final int start) {
+ int i = 0;
+ final int length = 8;
+ int count = 0;
+ final byte[] tmp = new byte[length];
+ for (i = start; i < (start + length); i++) {
+ tmp[count] = bytes[i];
+ count++;
+ }
+ long accum = 0;
+ i = 0;
+ for ( int shiftBy = 0; shiftBy < 64; shiftBy += 8 ) {
+ accum |= ( (long)( tmp[i] & 0xff ) ) << shiftBy;
+ i++;
+ }
+ return Double.longBitsToDouble(accum);
+ }
+
+ public static long bytes2long (final byte[] bytes, final int start) {
+ int i = 0;
+ final int length = 4;
+ int count = 0;
+ final byte[] tmp = new byte[length];
+ for (i = start; i < (start + length); i++) {
+ tmp[count] = bytes[i];
+ count++;
+ }
+ long accum = 0;
+ i = 0;
+ for ( int shiftBy = 0; shiftBy < 32; shiftBy += 8 ) {
+ accum |= ( (long)( tmp[i] & 0xff ) ) << shiftBy;
+ i++;
+ }
+ return accum;
+ }
 }


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
GeoTools-commits mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/geotools-commits