001 //$HeadURL: https://svn.wald.intevation.org/svn/deegree/base/branches/2.3_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 }