001 //$HeadURL: svn+ssh://rbezema@svn.wald.intevation.org/deegree/base/branches/2.2_testing/src/org/deegree/io/ecwapi/ECWReader.java $
002 /*---------------- FILE HEADER ------------------------------------------
003
004 This file is part of deegree.
005 Copyright (C) 2003 by:
006 IDgis bv, Holten, The Netherlands
007 http://www.idgis.nl
008
009 This library is free software; you can redistribute it and/or
010 modify it under the terms of the GNU Lesser General Public
011 License as published by the Free Software Foundation; either
012 version 2.1 of the License, or (at your option) any later version.
013
014 This library is distributed in the hope that it will be useful,
015 but WITHOUT ANY WARRANTY; without even the implied warranty of
016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017 Lesser General Public License for more details.
018
019 You should have received a copy of the GNU Lesser General Public
020 License along with this library; if not, write to the Free Software
021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
022
023 ---------------------------------------------------------------------------*/
024 package org.deegree.io.ecwapi;
025
026 import java.awt.Graphics;
027 import java.awt.image.BufferedImage;
028 import java.io.File;
029 import java.net.URL;
030
031 import org.deegree.framework.log.ILogger;
032 import org.deegree.framework.log.LoggerFactory;
033 import org.deegree.model.spatialschema.Envelope;
034
035 import com.ermapper.ecw.JNCSException;
036 import com.ermapper.ecw.JNCSFile;
037
038 /**
039 * ECWReader.java
040 *
041 * @author Herman Assink
042 * @author last edited by: $Author: apoth $
043 * @version 1.0 2003-11-06
044 */
045
046 public class ECWReader {
047
048 private static final ILogger LOG = LoggerFactory.getLogger( ECWReader.class );
049
050 private static boolean ECW_USE_CACHE = true;
051
052 private boolean usedCacheOnOpen = true;
053 private JNCSFile ecwFile;
054
055 /**
056 * read part from ECW-file which falls within env and return this part
057 * dimenions width and height
058 *
059 * @param fileName
060 * full pathname of the ECW-file
061 */
062 public ECWReader( String fileName ) throws JNCSException {
063
064 if ( fileName.toLowerCase().startsWith( "file:/" ) ) {
065 try {
066 File f = new File( new URL( fileName ).getFile() );
067 fileName = f.getAbsolutePath();
068 } catch ( Exception e ) {
069 new JNCSException( fileName + " is not a valid URL" );
070 }
071 }
072 LOG.logDebug( "ECWReader: " + fileName );
073
074 if (ECW_USE_CACHE) {
075 this.ecwFile = ECWFileCache.claimAccess( fileName );
076 usedCacheOnOpen = true;
077 }
078 else {
079 this.ecwFile = new JNCSFile( fileName, false );
080 usedCacheOnOpen = false;
081 }
082 }
083
084 /** Decide, if to use the cache.
085 * <p>
086 * Default is TRUE.
087 */
088 public static void useECWCache(boolean Use) {
089 ECW_USE_CACHE = Use;
090 }
091
092 /** Free the memory of the image cache
093 */
094 public void close() {
095 if (usedCacheOnOpen) {
096 ECWFileCache.releaseFile( ecwFile );
097 }
098 else {
099 ecwFile.close(true);
100 }
101 }
102
103 /**
104 * retuns the width of the entire image encapsulated in the ECW file
105 * @return width of the image
106 */
107 public int getWidth() {
108 return ecwFile.width;
109 }
110
111 /**
112 * retuns the height of the entire image encapsulated in the ECW file
113 * @return height of the image
114 */
115 public int getHeight() {
116 return ecwFile.height;
117 }
118
119 /**
120 * read part from ECW-file which falls within env and return this part as
121 * BufferedImage with dimenions width and height
122 *
123 * @param env
124 * bounding box in world coordinates of requested part
125 * @param width
126 * width of the returned image
127 * @param height
128 * height of the returned image
129 */
130 public BufferedImage getBufferedImage( Envelope env, int width, int height )
131 throws JNCSException {
132
133 int bandlist[];
134 int line, pRGBArray[] = null;
135
136 // Setup the view parameters for the ecw file.
137 bandlist = new int[ecwFile.numBands];
138 for ( int i = 0; i < ecwFile.numBands; i++ ) {
139 bandlist[i] = i;
140 }
141
142 //Check if the envelope is within the area of the ecw-image
143 double dWorldTLX = env.getMin().getX();
144 double dWorldTLY = env.getMax().getY();
145
146 LOG.logDebug( "tlx: " + dWorldTLX + " tly: " + dWorldTLY );
147
148 if ( dWorldTLX < ecwFile.originX )
149 dWorldTLX = ecwFile.originX;
150 if ( dWorldTLY > ecwFile.originY )
151 dWorldTLY = ecwFile.originY;
152 double dWorldBRX = env.getMax().getX();
153 double dWorldBRY = env.getMin().getY();
154
155 LOG.logDebug( "brx: " + dWorldBRX + " bry: " + dWorldBRY );
156
157 if ( dWorldBRX > ( ecwFile.originX + ( ( ecwFile.width - 1 ) * ecwFile.cellIncrementX ) ) ) // Huh?
158 // ECW
159 // does
160 // not
161 // except
162 // the
163 // full
164 // width
165 dWorldBRX = ecwFile.originX + ( ( ecwFile.width - 1 ) * ecwFile.cellIncrementX );
166 if ( dWorldBRY < ( ecwFile.originY + ( ecwFile.height * ecwFile.cellIncrementY ) - ( ecwFile.cellIncrementY / 2 ) ) )
167 dWorldBRY = ecwFile.originY + ( ecwFile.height * ecwFile.cellIncrementY )
168 - ( ecwFile.cellIncrementY / 2 );
169
170 // Work out the correct aspect for the setView call.
171 //double dEnvAspect = (dWorldBRX - dWorldTLX) / (dWorldTLY - dWorldBRY);
172 //double dImgAspect = (double) width / (double) height;
173
174 LOG.logDebug( "tlx: " + dWorldTLX + " tly: " + dWorldTLY );
175 LOG.logDebug( "brx: " + dWorldBRX + " bry: " + dWorldBRY );
176 LOG.logDebug( "width: " + width + " height: " + height );
177
178 int nDatasetTLX = (int) Math.round( ( dWorldTLX - ecwFile.originX )
179 / ecwFile.cellIncrementX );
180 int nDatasetTLY = (int) Math.round( ( dWorldTLY - ecwFile.originY )
181 / ecwFile.cellIncrementY );
182
183 LOG.logDebug( "ptlx: " + nDatasetTLX + " ptly: " + nDatasetTLY );
184
185 int nDatasetBRX = (int) Math.round( ( dWorldBRX - ecwFile.originX )
186 / ecwFile.cellIncrementX );
187 int nDatasetBRY = (int) Math.round( ( dWorldBRY - ecwFile.originY )
188 / ecwFile.cellIncrementY );
189
190 LOG.logDebug( "pbrx: " + nDatasetBRX + " pbry: " + nDatasetBRY );
191
192 if ( nDatasetBRX > ( ecwFile.width - 1 ) )
193 nDatasetBRX = ecwFile.width - 1;
194 if ( nDatasetBRY > ( ecwFile.height - 1 ) )
195 nDatasetBRY = ecwFile.height - 1;
196
197 LOG.logDebug( "pbrx: " + nDatasetBRX + " pbry: " + nDatasetBRY );
198
199 // Check for supersampling
200 int viewWidth = width;
201 int viewHeight = height;
202 if ( ( nDatasetBRX - nDatasetTLX ) < viewWidth
203 || ( nDatasetBRY - nDatasetTLY ) < viewHeight ) {
204 viewWidth = nDatasetBRX - nDatasetTLX;
205 viewHeight = nDatasetBRY - nDatasetTLY;
206 }
207 if ( viewWidth == 0 )
208 viewWidth = 1;
209 if ( viewHeight == 0 )
210 viewHeight = 1;
211
212 LOG.logDebug( "Width: " + width + " Height: " + height );
213 LOG.logDebug( "viewWidth: " + viewWidth + " viewHeight: " + viewHeight );
214
215 // Create an image of the ecw file.
216 BufferedImage ecwImage = new BufferedImage( viewWidth, viewHeight,
217 BufferedImage.TYPE_INT_RGB );
218 pRGBArray = new int[width];
219
220 // Set the view
221 ecwFile.setView( ecwFile.numBands, bandlist, nDatasetTLX, nDatasetTLY, nDatasetBRX,
222 nDatasetBRY, viewWidth, viewHeight );
223
224 // Read the scan lines
225 for ( line = 0; line < viewHeight; line++ ) {
226 ecwFile.readLineRGBA( pRGBArray );
227 ecwImage.setRGB( 0, line, viewWidth, 1, pRGBArray, 0, viewWidth );
228 }
229
230 if ( width != viewWidth || height != viewHeight ) {
231 LOG.logDebug( "enlarge image" );
232 BufferedImage enlargedImg = new BufferedImage( width, height,
233 BufferedImage.TYPE_INT_RGB );
234 Graphics g = enlargedImg.getGraphics();
235 g.drawImage( ecwImage, 0, 0, width, height, 0, 0, viewWidth, viewHeight, null );
236 ecwImage = enlargedImg;
237 g.dispose();
238 }
239
240 return ecwImage;
241
242 }
243 }