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 }