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 }