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