/*---------------- FILE HEADER ------------------------------------------
This file is part of deegree.
Copyright (C) 2001-2006 by:
EXSE, Department of Geography, University of Bonn
http://www.giub.uni-bonn.de/deegree/
lat/lon GmbH
http://www.lat-lon.de
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; either
version 2.1 of the License, or (at your option) any later version.
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.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Contact:
Andreas Poth
lat/lon GmbH
Aennchenstr. 19
53115 Bonn
Germany
E-Mail: poth@lat-lon.de
Prof. Dr. Klaus Greve
Department of Geography
University of Bonn
Meckenheimer Allee 166
53115 Bonn
Germany
E-Mail: greve@giub.uni-bonn.de
---------------------------------------------------------------------------*/
package org.deegree.io.imgapi;
import java.io.IOException;
import java.io.RandomAccessFile;
import org.deegree.graphics.transformation.GeoTransform;
import org.deegree.graphics.transformation.WorldToScreenTransform;
import org.deegree.model.spatialschema.ByteUtils;
import org.deegree.model.spatialschema.Envelope;
/**
* @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a>
*/
public class IMGReader {
public static final int BYTE = 1;
public static final int SMALLINT = 2;
public static final int INT = 3;
public static final int FLOAT = 4;
public static final int DOUBLE = 8;
private String fileName = null;
private int width = 0;
private int height = 0;
private int type = 0;
/**
*
* @uml.property name="trans"
* @uml.associationEnd multiplicity="(0 1)"
*/
private GeoTransform trans = null;
/** Creates a new instance of IMGReader */
public IMGReader(String fileName, int width, int height, Envelope bbox, int type) {
this.fileName = fileName;
this.width = width;
this.height = height;
this.type = type;
trans =
new WorldToScreenTransform( bbox.getMin().getX(), bbox.getMin().getY(),
bbox.getMax().getX(), bbox.getMax().getY(),
0, 0, width-1, height-1 );
}
/**
* reads a rectangular subset from the image
*/
public float[][] read(Envelope bbox) throws IOException {
float[][] data = null;
switch (type) {
case BYTE: data = readByte( bbox ); break;
case SMALLINT: data = readSmallInt( bbox ); break;
case INT: data = readInt( bbox ); break;
case FLOAT: data = readFloat( bbox ); break;
case DOUBLE: data = readDouble( bbox ); break;
default: throw new IOException( "not supported file format!" );
}
return data;
}
private float[][] readByte(Envelope bbox) throws IOException {
int x1 = (int)trans.getDestX( bbox.getMin().getX() );
if ( x1 < 0 ) x1 = 0;
int y1 = (int)trans.getDestY( bbox.getMin().getY() );
if ( y1 >= height ) y1 = height-1;
int x2 = (int)trans.getDestX( bbox.getMax().getX() );
if ( x2 >= width ) x1 = width-1;
int y2 = (int)trans.getDestY( bbox.getMax().getY() );
if ( y2 < 0 ) y2 = 0;
int w = Math.abs(x2-x1);
int h = Math.abs(y1-y2);
RandomAccessFile raf = new RandomAccessFile( fileName, "r" );
byte[] b = new byte[w];
float[][] data = new float[h][w];
for (int i = 0; i < h; i++) {
raf.seek( width * (y2+i) + x1 );
raf.read( b );
for (int j = 0; j < w; j++) {
data[i][j] = b[j] + 127f;
}
}
raf.close();
return data;
}
private float[][] readSmallInt(Envelope bbox) {
throw new UnsupportedOperationException( "readSmallInt(Envelope)" );
}
private float[][] readInt(Envelope bbox) throws IOException {
int x1 = (int)trans.getDestX( bbox.getMin().getX() );
if ( x1 < 0 ) x1 = 0;
int y1 = (int)trans.getDestY( bbox.getMin().getY() );
if ( y1 >= height ) y1 = height-1;
int x2 = (int)trans.getDestX( bbox.getMax().getX() );
if ( x2 >= width ) x1 = width-1;
int y2 = (int)trans.getDestY( bbox.getMax().getY() );
if ( y2 < 0 ) y2 = 0;
int w = Math.abs(x2-x1);
int h = Math.abs(y1-y2);
RandomAccessFile raf = new RandomAccessFile( fileName, "r" );
byte[] b = new byte[w*4];
float[][] data = new float[h][w];
for (int i = 0; i < h; i++) {
raf.seek( (width * (y2+i) + x1) * 4 );
raf.read( b );
int k = 0;
for (int j = 0; j < w; j++) {
data[i][j] = ByteUtils.readBEInt( b, k );
k += 4;
}
}
raf.close();
return data;
}
private float[][] readFloat(Envelope bbox) throws IOException {
int x1 = (int)trans.getDestX( bbox.getMin().getX() );
int y1 = (int)trans.getDestY( bbox.getMin().getY() );
int x2 = (int)trans.getDestX( bbox.getMax().getX() );
int y2 = (int)trans.getDestY( bbox.getMax().getY() );
int w = Math.abs(x2-x1);
int h = Math.abs(y1-y2);
if ( w <= 0 || h <= 0 ) return new float[0][0];
RandomAccessFile raf = new RandomAccessFile( fileName, "r" );
byte[] b = new byte[width*FLOAT];
float[][] data = new float[h][w];
for (int i = y2; i < y1; i++) {
if ( i >= 0 && i < height ) {
raf.seek( width * i * FLOAT );
raf.readFully( b );
int k = 0;
if ( x1 > 0 ) k = x1*FLOAT;
for (int j = x1; j < x2; j++) {
if ( j >= 0 && j < width ) {
data[i-y2][j-x1] = ByteUtils.readBEFloat( b, k );
k += FLOAT;
}
}
}
}
raf.close();
return data;
}
private float[][] readDouble(Envelope bbox) throws IOException {
int x1 = (int)trans.getDestX( bbox.getMin().getX() );
if ( x1 < 0 ) x1 = 0;
int y1 = (int)trans.getDestY( bbox.getMin().getY() );
if ( y1 >= height ) y1 = height-1;
int x2 = (int)trans.getDestX( bbox.getMax().getX() );
if ( x2 >= width ) x1 = width-1;
int y2 = (int)trans.getDestY( bbox.getMax().getY() );
if ( y2 < 0 ) y2 = 0;
int w = Math.abs(x2-x1);
int h = Math.abs(y1-y2);
RandomAccessFile raf = new RandomAccessFile( fileName, "r" );
byte[] b = new byte[w*DOUBLE];
float[][] data = new float[h][w];
for (int i = 0; i < h; i++) {
raf.seek( (width * (y2+i) + x1) * DOUBLE );
raf.read( b );
int k = 0;
for (int j = 0; j < w; j++) {
data[i][j] = (float)ByteUtils.readBEDouble( b, k );
k += DOUBLE;
}
}
raf.close();
return data;
}
}
/* ********************************************************************
Changes to this class. What the people have been up to:
$Log: IMGReader.java,v $
Revision 1.9 2006/11/27 09:07:53 poth
JNI integration of proj4 has been removed. The CRS functionality now will be done by native deegree code.
Revision 1.8 2006/08/08 09:06:31 poth
readSmallInt(Envelope) marked as unsupported operation
Revision 1.7 2006/07/12 14:46:19 poth
comment footer added
********************************************************************** */