001 //$HeadURL: svn+ssh://jwilden@svn.wald.intevation.org/deegree/base/branches/2.5_testing/src/org/deegree/io/imgapi/IMGReader.java $ 002 /*---------------------------------------------------------------------------- 003 This file is part of deegree, http://deegree.org/ 004 Copyright (C) 2001-2009 by: 005 Department of Geography, University of Bonn 006 and 007 lat/lon GmbH 008 009 This library is free software; you can redistribute it and/or modify it under 010 the terms of the GNU Lesser General Public License as published by the Free 011 Software Foundation; either version 2.1 of the License, or (at your option) 012 any later version. 013 This library is distributed in the hope that it will be useful, but WITHOUT 014 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 015 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more 016 details. 017 You should have received a copy of the GNU Lesser General Public License 018 along with this library; if not, write to the Free Software Foundation, Inc., 019 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 020 021 Contact information: 022 023 lat/lon GmbH 024 Aennchenstr. 19, 53177 Bonn 025 Germany 026 http://lat-lon.de/ 027 028 Department of Geography, University of Bonn 029 Prof. Dr. Klaus Greve 030 Postfach 1147, 53001 Bonn 031 Germany 032 http://www.geographie.uni-bonn.de/deegree/ 033 034 e-mail: info@deegree.org 035 ----------------------------------------------------------------------------*/ 036 037 package org.deegree.io.imgapi; 038 039 import java.io.IOException; 040 import java.io.RandomAccessFile; 041 042 import org.deegree.graphics.transformation.GeoTransform; 043 import org.deegree.graphics.transformation.WorldToScreenTransform; 044 import org.deegree.model.spatialschema.ByteUtils; 045 import org.deegree.model.spatialschema.Envelope; 046 047 /** 048 * @author <a href="mailto:poth@lat-lon.de">Andreas Poth</a> 049 */ 050 051 public class IMGReader { 052 053 public static final int BYTE = 1; 054 055 public static final int SMALLINT = 2; 056 057 public static final int INT = 3; 058 059 public static final int FLOAT = 4; 060 061 public static final int DOUBLE = 8; 062 063 private String fileName = null; 064 065 private int width = 0; 066 067 private int height = 0; 068 069 private int type = 0; 070 071 private GeoTransform trans = null; 072 073 /** 074 * Creates a new instance of IMGReader 075 * 076 * @param fileName 077 * @param width 078 * @param height 079 * @param bbox 080 * @param type 081 */ 082 public IMGReader( String fileName, int width, int height, Envelope bbox, int type ) { 083 084 this.fileName = fileName; 085 this.width = width; 086 this.height = height; 087 this.type = type; 088 trans = new WorldToScreenTransform( bbox.getMin().getX(), bbox.getMin().getY(), bbox.getMax().getX(), 089 bbox.getMax().getY(), 0, 0, width - 1, height - 1 ); 090 } 091 092 /** 093 * reads a rectangular subset from the image 094 * 095 * @param bbox 096 * desired bounding box 097 */ 098 public float[][] read( Envelope bbox ) 099 throws IOException { 100 101 float[][] data = null; 102 switch ( type ) { 103 case BYTE: 104 data = readByte( bbox ); 105 break; 106 case SMALLINT: 107 data = readSmallInt( bbox ); 108 break; 109 case INT: 110 data = readInt( bbox ); 111 break; 112 case FLOAT: 113 data = readFloat( bbox ); 114 break; 115 case DOUBLE: 116 data = readDouble( bbox ); 117 break; 118 default: 119 throw new IOException( "not supported file format!" ); 120 } 121 122 return data; 123 } 124 125 /** 126 * 127 * @param bbox 128 * @return 129 * @throws IOException 130 */ 131 private float[][] readByte( Envelope bbox ) 132 throws IOException { 133 134 int x1 = (int) trans.getDestX( bbox.getMin().getX() ); 135 if ( x1 < 0 ) 136 x1 = 0; 137 int y1 = (int) trans.getDestY( bbox.getMin().getY() ); 138 if ( y1 >= height ) 139 y1 = height - 1; 140 int x2 = (int) trans.getDestX( bbox.getMax().getX() ); 141 if ( x2 >= width ) 142 x1 = width - 1; 143 int y2 = (int) trans.getDestY( bbox.getMax().getY() ); 144 if ( y2 < 0 ) 145 y2 = 0; 146 147 int w = Math.abs( x2 - x1 ); 148 int h = Math.abs( y1 - y2 ); 149 150 RandomAccessFile raf = new RandomAccessFile( fileName, "r" ); 151 152 byte[] b = new byte[w]; 153 float[][] data = new float[h][w]; 154 for ( int i = 0; i < h; i++ ) { 155 raf.seek( width * ( y2 + i ) + x1 ); 156 raf.read( b ); 157 for ( int j = 0; j < w; j++ ) { 158 data[i][j] = b[j] + 127f; 159 } 160 } 161 raf.close(); 162 163 return data; 164 } 165 166 /** 167 * 168 * @param bbox 169 * @return 170 * @throws IOException 171 */ 172 private float[][] readSmallInt( Envelope bbox ) 173 throws IOException { 174 int x1 = (int) trans.getDestX( bbox.getMin().getX() ); 175 if ( x1 < 0 ) 176 x1 = 0; 177 int y1 = (int) trans.getDestY( bbox.getMin().getY() ); 178 if ( y1 >= height ) 179 y1 = height - 1; 180 int x2 = (int) trans.getDestX( bbox.getMax().getX() ); 181 if ( x2 >= width ) 182 x1 = width - 1; 183 int y2 = (int) trans.getDestY( bbox.getMax().getY() ); 184 if ( y2 < 0 ) 185 y2 = 0; 186 187 int w = Math.abs( x2 - x1 ); 188 int h = Math.abs( y1 - y2 ); 189 RandomAccessFile raf = new RandomAccessFile( fileName, "r" ); 190 191 byte[] b = new byte[w * 4]; 192 float[][] data = new float[h][w]; 193 for ( int i = 0; i < h; i++ ) { 194 raf.seek( ( width * ( y2 + i ) + x1 ) * 4 ); 195 raf.read( b ); 196 int k = 0; 197 for ( int j = 0; j < w; j++ ) { 198 data[i][j] = ByteUtils.readBEShort( b, k ); 199 k += 4; 200 } 201 } 202 raf.close(); 203 204 return data; 205 } 206 207 /** 208 * 209 * @param bbox 210 * @return 211 * @throws IOException 212 */ 213 private float[][] readInt( Envelope bbox ) 214 throws IOException { 215 216 int x1 = (int) trans.getDestX( bbox.getMin().getX() ); 217 if ( x1 < 0 ) 218 x1 = 0; 219 int y1 = (int) trans.getDestY( bbox.getMin().getY() ); 220 if ( y1 >= height ) 221 y1 = height - 1; 222 int x2 = (int) trans.getDestX( bbox.getMax().getX() ); 223 if ( x2 >= width ) 224 x1 = width - 1; 225 int y2 = (int) trans.getDestY( bbox.getMax().getY() ); 226 if ( y2 < 0 ) 227 y2 = 0; 228 229 int w = Math.abs( x2 - x1 ); 230 int h = Math.abs( y1 - y2 ); 231 RandomAccessFile raf = new RandomAccessFile( fileName, "r" ); 232 233 byte[] b = new byte[w * 4]; 234 float[][] data = new float[h][w]; 235 for ( int i = 0; i < h; i++ ) { 236 raf.seek( ( width * ( y2 + i ) + x1 ) * 4 ); 237 raf.read( b ); 238 int k = 0; 239 for ( int j = 0; j < w; j++ ) { 240 data[i][j] = ByteUtils.readBEInt( b, k ); 241 k += 4; 242 } 243 } 244 raf.close(); 245 246 return data; 247 } 248 249 /** 250 * 251 * @param bbox 252 * @return 253 * @throws IOException 254 */ 255 private float[][] readFloat( Envelope bbox ) 256 throws IOException { 257 258 int x1 = (int) trans.getDestX( bbox.getMin().getX() ); 259 int y1 = (int) trans.getDestY( bbox.getMin().getY() ); 260 int x2 = (int) trans.getDestX( bbox.getMax().getX() ); 261 int y2 = (int) trans.getDestY( bbox.getMax().getY() ); 262 263 int w = Math.abs( x2 - x1 ); 264 int h = Math.abs( y1 - y2 ); 265 266 if ( w <= 0 || h <= 0 ) 267 return new float[0][0]; 268 269 RandomAccessFile raf = new RandomAccessFile( fileName, "r" ); 270 271 byte[] b = new byte[width * FLOAT]; 272 float[][] data = new float[h][w]; 273 for ( int i = y2; i < y1; i++ ) { 274 if ( i >= 0 && i < height ) { 275 raf.seek( width * i * FLOAT ); 276 raf.readFully( b ); 277 int k = 0; 278 if ( x1 > 0 ) 279 k = x1 * FLOAT; 280 for ( int j = x1; j < x2; j++ ) { 281 if ( j >= 0 && j < width ) { 282 data[i - y2][j - x1] = ByteUtils.readBEFloat( b, k ); 283 k += FLOAT; 284 } 285 } 286 } 287 } 288 raf.close(); 289 290 return data; 291 } 292 293 /** 294 * 295 * @param bbox 296 * @return 297 * @throws IOException 298 */ 299 private float[][] readDouble( Envelope bbox ) 300 throws IOException { 301 302 int x1 = (int) trans.getDestX( bbox.getMin().getX() ); 303 if ( x1 < 0 ) 304 x1 = 0; 305 int y1 = (int) trans.getDestY( bbox.getMin().getY() ); 306 if ( y1 >= height ) 307 y1 = height - 1; 308 int x2 = (int) trans.getDestX( bbox.getMax().getX() ); 309 if ( x2 >= width ) 310 x1 = width - 1; 311 int y2 = (int) trans.getDestY( bbox.getMax().getY() ); 312 if ( y2 < 0 ) 313 y2 = 0; 314 315 int w = Math.abs( x2 - x1 ); 316 int h = Math.abs( y1 - y2 ); 317 318 RandomAccessFile raf = new RandomAccessFile( fileName, "r" ); 319 320 byte[] b = new byte[w * DOUBLE]; 321 float[][] data = new float[h][w]; 322 for ( int i = 0; i < h; i++ ) { 323 raf.seek( ( width * ( y2 + i ) + x1 ) * DOUBLE ); 324 raf.read( b ); 325 int k = 0; 326 for ( int j = 0; j < w; j++ ) { 327 data[i][j] = (float) ByteUtils.readBEDouble( b, k ); 328 k += DOUBLE; 329 } 330 } 331 raf.close(); 332 333 return data; 334 } 335 336 }