Revision 2669 branches/CqCMSDvp/libraries/libCq CMS for java.old/src/org/cresques/io/EcwFile.java

View differences:

EcwFile.java
1 1
/*
2 2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 * 
4
 * Copyright (C) 2004-5. 
5 3
 *
4
 * Copyright (C) 2004-5.
5
 *
6 6
 * This program is free software; you can redistribute it and/or
7 7
 * modify it under the terms of the GNU General Public License
8 8
 * as published by the Free Software Foundation; either version 2
......
18 18
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19 19
 *
20 20
 * For more information, contact:
21
 * 
21
 *
22 22
 * cresques@gmail.com
23 23
 */
24 24
package org.cresques.io;
25 25

  
26
import com.ermapper.ecw.JNCSFile;
27
import com.ermapper.ecw.JNCSFileNotOpenException;
28
import com.ermapper.ecw.JNCSProgressiveUpdate;
29

  
30
import com.ermapper.util.JNCSDatasetPoint;
31
import com.ermapper.util.JNCSWorldPoint;
32

  
33
import org.cresques.cts.ICoordTrans;
34
import org.cresques.cts.IProjection;
35

  
36
import org.cresques.px.Extent;
37

  
26 38
import java.awt.Dimension;
27 39
import java.awt.Image;
28 40
import java.awt.Point;
29 41
import java.awt.image.BufferedImage;
30 42
import java.awt.image.PixelGrabber;
31 43

  
32
import org.cresques.cts.ICoordTrans;
33
import org.cresques.cts.IProjection;
34
import org.cresques.px.Extent;
35 44

  
36
import com.ermapper.ecw.JNCSFile;
37
import com.ermapper.ecw.JNCSFileNotOpenException;
38
import com.ermapper.ecw.JNCSProgressiveUpdate;
39
import com.ermapper.util.JNCSDatasetPoint;
40
import com.ermapper.util.JNCSWorldPoint;
41

  
42

  
43 45
/**
44 46
 * Soporte para los ficheros .ecw de ErMapper.
45 47
 * <br>
......
68 70
 *
69 71
 * @author "Luis W. Sevilla" <sevilla_lui@gva.es>
70 72
 */
73
public class EcwFile extends GeoRasterFile implements JNCSProgressiveUpdate {
74
    //Lleva la cuenta del n?mero de actualizaciones que se hace de una imagen que corresponde con el 
75
    //n?mero de bandas que tiene. Esto es necesario ya que si una imagen tiene el mustResize a
76
    //true solo debe llamar a la funci?n resizeImage al actualizar la ?ltima banda, sino al hacer
77
    //un zoom menor que 1:1 se veria mal
78
    private static int nUpdate = 0;
79
    private JNCSFile file = null;
80
    private boolean bErrorOnOpen = false;
81
    private String errorMessage = null;
82
    private boolean multifile = false;
83
    private Extent v = null;
71 84

  
72
public class EcwFile extends GeoRasterFile  implements JNCSProgressiveUpdate {
73
	private JNCSFile file = null;
74
	private boolean bErrorOnOpen = false;
75
	private String errorMessage = null;
76
	
77
	//Lleva la cuenta del n?mero de actualizaciones que se hace de una imagen que corresponde con el 
78
	//n?mero de bandas que tiene. Esto es necesario ya que si una imagen tiene el mustResize a
79
	//true solo debe llamar a la funci?n resizeImage al actualizar la ?ltima banda, sino al hacer
80
	//un zoom menor que 1:1 se veria mal
81
	private static int nUpdate = 0;
82
	
83
	private boolean multifile = false;
85
    // Ultimo porcentaje de refresco. Se carga en el update y se
86
    // actualiza en el refreshUpdate
87
    private int lastRefreshPercent = 0;
84 88

  
85
	private Extent v = null;
86
	
87
	// Ultimo porcentaje de refresco. Se carga en el update y se
88
	// actualiza en el refreshUpdate
89
	private int lastRefreshPercent = 0;
90
	
91
	public EcwFile(IProjection proj, String fName) {
92
		super(proj, null);
93
		fName = DataSource.normalize(fName);
94
		super.setName(fName);
95
		extent = new Extent();
96
		try {
97
			//System.err.println("Abriendo "+fName);
98
			file = new JNCSFile(fName, false);
99
			load();
100
			bandCount = file.numBands;
101
			/*if ( bandCount > 2) {
102
				setBand(RED_BAND,   0);
103
				setBand(GREEN_BAND, 1);
104
				setBand(BLUE_BAND,  2);
105
			} else
106
				setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);*/
107
		} catch(Exception e) {
108
		  bErrorOnOpen = true;
109
		  errorMessage = e.getMessage();
110
		  System.err.println(errorMessage);
111
		  e.printStackTrace();
112
		}
113
	}
114
		
115
	public void setView(Extent e) { v = new Extent(e); }
116
	public Extent getView() { return v; }
117
	
118
	/**
119
	 * Carga un ECW.
120
	 * 
121
	 * @param fname
122
	 */
123
	
124
	public GeoFile load() {
125
		double minX, minY, maxX, maxY;
89
    public EcwFile(IProjection proj, String fName) {
90
        super(proj, null);
91
        fName = DataSource.normalize(fName);
92
        super.setName(fName);
93
        extent = new Extent();
126 94

  
127
		/*System.out.println("ECW size = ("+file.width+","+file.height+")\n"+
128
			" inc=("+file.cellIncrementX+","+file.cellIncrementY+")\n"+
129
			" datum='"+file.datum+"', proyeccion='"+file.projection+"'");*/
130
		minX = file.originX;
131
		maxY = file.originY;
132
		maxX = file.originX + (double)(file.width-1)*file.cellIncrementX;
133
		minY = file.originY + (double)(file.height-1)*file.cellIncrementY;
134
		extent = new Extent(minX, minY, maxX, maxY);
135
			System.out.println(extent);
136
		
137
		return this;
138
	}
139
	
140
	public void close() {
141
		file.close(true);
142
		file = null;
143
	}
144
	
145
	/**
146
	 * Devuelve el ancho de la imagen
147
	 */
148
	public int getWidth() { 
149
		return file.width; 
150
	}
151
	
152
	/**
153
	 * Devuelve el alto de la imagen
154
	 */
155
	public int getHeight() { 
156
		return file.height; 
157
	}
158
	
159
	/**
160
	 * 
161
	 */
162
	public void setMultifile(boolean mult){
163
		this.multifile = mult;
164
	}
165
	
166
	/**
167
	 * Trozo de imagen (Chunk) en que se divide la consulta a la librer?a,
168
	 * para esquivar el bug#2.
169
	 * 
170
	 * @author luisw
171
	 */
172
	static class ChunkFrame {
173
		// Ancho m?ximo (~2500 px)
174
		final static int MAX_WIDTH = 1536;
175
		// Alto m?ximo (no hay l?mite)
176
		final static int MAX_HEIGHT = 1536;
177
		Point pos;
178
		Extent v;
179
		int width, height;
180
		boolean mustResize = false;
181
		public ChunkFrame(Extent vista, int w, int h) {
182
			v = vista;
183
			width = w;
184
			height = h;
185
		}
186
		/**
187
		 * Calcula el array de chunks (trozos).
188
		 * @param file	Fichero ecw que hay que trocear.
189
		 * @param v Extent total de la vista.
190
		 * @param sz	Tama?o total de la vista.
191
		 * @return array de ChunkFrames.
192
		 * @throws JNCSFileNotOpenException
193
		 */
194
		public static ChunkFrame [] computeFrames(JNCSFile file, Extent v, Dimension sz) throws JNCSFileNotOpenException {
195
			ChunkFrame [] frames = null;
196
			ChunkFrame f = null;
197
			
198
			// Calcula el n? de chunks (filas y columnas)
199
			int numCol = (sz.width / MAX_WIDTH), numRow = (sz.height / MAX_HEIGHT);
200
			if (sz.width -(numCol*MAX_WIDTH) > 0) numCol++;
201
			if (sz.height - (numRow*MAX_HEIGHT) > 0) numRow++;
202
			frames = new ChunkFrame[numCol*numRow];
95
        try {
96
            //System.err.println("Abriendo "+fName);
97
            file = new JNCSFile(fName, false);
98
            load();
99
            bandCount = file.numBands;
203 100

  
204
			// Coprobaci?n previa para resolver el bug#1
205
			JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
206
			JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY());
207
			/*System.out.println("Dataset coords Width = "+(ptMax.x-ptMin.x)+", px width = "+sz.width+
208
					" px heigh = "+sz.height);*/
209
			// BEGIN Cambiando para soportar e < 1:1
210
			// TODO Mejorarlo para que los PAN con un zoom muy grande sean correctos
211
			//System.out.println("MAXX MINX-"+ptMax.x+","+ptMin.x);
212
			if ((ptMax.x-ptMin.x)<sz.width) {
213
				numCol = numRow = 1;
214
				frames = new ChunkFrame[numCol*numRow];
215
				f = frames[0] = new ChunkFrame(v, ptMax.x-ptMin.x, ptMin.y-ptMax.y);
216
				//System.out.println("Size=("+f.width+","+f.height+")");
217
				f.pos = new Point(0,0);
218
				f.mustResize = true;
219
				f.v = new Extent(v);
220
			} else {
221
				// Calcula cada chunk
222
				double stepx = ((double) ptMax.x-ptMin.x)/sz.getWidth();
223
				double stepy = ((double) ptMax.y-ptMin.y)/sz.getHeight();
224
				int h = sz.height;
225
				for (int r=0; r<numRow; r++) {
226
					int w = sz.width;
227
					for (int c = 0; c<numCol; c++) {
228
						f = new ChunkFrame(null, -1, -1);
229
						// Posici?n del chunk
230
						f.pos = new Point(c*MAX_WIDTH, r*MAX_HEIGHT);
231
						// Tama?o del chunk
232
						f.width = Math.min(MAX_WIDTH, w);
233
						f.height = Math.min(MAX_HEIGHT, h);
234
						// Extent del chunk
235
						int x1 = ptMin.x+(int) (f.pos.x*stepx);
236
						int x2 = x1+(int)(f.width*stepx);
237
						int y1 = ptMax.y-(int) (f.pos.y*stepy); //ptMax.y;
238
						int y2 = y1-(int)(f.height*stepy);//ptMin.y;
239
						JNCSWorldPoint pt1 = file.convertDatasetToWorld(x1, y1);
240
						JNCSWorldPoint pt2 = file.convertDatasetToWorld(x2, y2);
241
						f.v = new Extent(pt1.x, pt1.y, pt2.x, pt2.y); // Hay que calcularlo
242
						/*System.out.println(" View DataSet = ("+x1+","+y1+","+x2+","+y2+")");
243
						System.out.println(" View Extent  = "+ v);
244
						System.out.println("Frame Extent  = "+ f.v);*/
101
            /*if ( bandCount > 2) {
102
                    setBand(RED_BAND,   0);
103
                    setBand(GREEN_BAND, 1);
104
                    setBand(BLUE_BAND,  2);
105
            } else
106
                    setBand(RED_BAND|GREEN_BAND|BLUE_BAND, 0);*/
107
        } catch (Exception e) {
108
            bErrorOnOpen = true;
109
            errorMessage = e.getMessage();
110
            System.err.println(errorMessage);
111
            e.printStackTrace();
112
        }
113
    }
245 114

  
246
						frames[r*numCol+c] = f;
247
						w -= MAX_WIDTH;
248
					}
249
					h -= MAX_HEIGHT;
250
				}
251
			}
252
			//System.out.println("Hay "+numRow+" filas y "+numCol+" columnas.");
253
			return frames;
254
		}
255
	}
115
    public void setView(Extent e) {
116
        v = new Extent(e);
117
    }
256 118

  
257
	/**
258
	 * Obtiene un trozo de imagen (determinado por la vista y los par?metros.
259
	 * 
260
	 * @param width
261
	 * @param height
262
	 */
263
	
264
	public synchronized Image updateImage(int width, int height, ICoordTrans rp) {
265
		// TODO reproyectar para devolver el trozo de imagen pedida sobre ...
266
		// la proyecci?n de destino.
267
		int line = 0; 
268
		boolean mustResize = false;
269
		Dimension fullSize = null;
270
		Image ecwImage = null;
271
		if (file == null) return ecwImage;
272
		try {
273
			double dFileAspect, dWindowAspect;
274
			//double dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY;
275
			int bandlist[];
276
			int bandListTriband[];
277
			int pRGBArray[] = null;
119
    public Extent getView() {
120
        return v;
121
    }
278 122

  
279
			// Work out the correct aspect for the setView call.
280
			dFileAspect = (double)v.width()/(double)v.height();
281
			dWindowAspect = (double)width /(double)height;
123
    /**
124
     * Carga un ECW.
125
     *
126
     * @param fname
127
     */
128
    public GeoFile load() {
129
        double minX;
130
        double minY;
131
        double maxX;
132
        double maxY;
282 133

  
283
			if (dFileAspect > dWindowAspect) {
284
			  height =(int)((double)width/dFileAspect);
285
			} else {
286
			  width = (int)((double)height*dFileAspect);
287
			}
134
        /*System.out.println("ECW size = ("+file.width+","+file.height+")\n"+
135
                " inc=("+file.cellIncrementX+","+file.cellIncrementY+")\n"+
136
                " datum='"+file.datum+"', proyeccion='"+file.projection+"'");*/
137
        minX = file.originX;
138
        maxY = file.originY;
139
        maxX = file.originX +
140
               ((double) (file.width - 1) * file.cellIncrementX);
141
        minY = file.originY +
142
               ((double) (file.height - 1) * file.cellIncrementY);
143
        extent = new Extent(minX, minY, maxX, maxY);
144
        System.out.println(extent);
288 145

  
289
			
290
			fullSize = new Dimension(width, height);
291
			//System.out.println("fullSize = ("+width+","+height+")");
292
			// Peta en los peque?os ... arreglar antes de meter del todo
293
			ChunkFrame frames[] = ChunkFrame.computeFrames(file, v, fullSize);
294
			/*for (int nChunk=0; nChunk<frames.length; nChunk++) {
295
				System.out.println("chunck "+nChunk+"->"+frames[nChunk]);
296
			}*/
297
			
298
			if (frames.length == 1) {
299
				width = frames[0].width; 
300
				height = frames[0].height;
301
				if(width<=0)width=1;
302
				if(height<=0)height=1;
303
				//System.out.println("frameSize = ("+width+","+height+")");
304
				//System.out.println("Cambio el ancho total a ("+width+","+height+")");
305
			}
306
			
307
/*			JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
308
			JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY());
309
			System.out.println("Dataset coords Width = "+(ptMax.x-ptMin.x)+", px width ="+width);
310
			// BEGIN Cambiando para soportar e < 1:1
311
			// TODO Mejorarlo para que los PAN con un zoom muy grande sean correctos
312
			if ((ptMax.x-ptMin.x)<width) {
313
				width = ptMax.x-ptMin.x;
314
				height = ptMin.y-ptMax.y;
315
				System.out.println("Size=("+width+","+height+")");
316
				mustResize = true;
317
			}*/
318
			// Create an image of the ecw file.
319
			if (doTransparency)
320
				ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) ;
321
			else
322
				ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
146
        return this;
147
    }
323 148

  
324
			pRGBArray = new int[width];
149
    public void close() {
150
        file.close(true);
151
        file = null;
152
    }
325 153

  
326
			// Setup the view parameters for the ecw file.
327
			bandlist = new int[bandCount];
328
			bandListTriband = new int[bandCount];
329
			if ( bandCount > 2) {
330
				bandlist[0] = getBand(RED_BAND);
331
				bandlist[1] = getBand(GREEN_BAND);
332
				bandlist[2] = getBand(BLUE_BAND);
333
				if (bandCount > 3)
334
					for (int i=3; i< bandCount; i++) {
335
						 bandlist[i] = 0;
336
					}
337
			} else {
338
				for (int i=0; i< bandCount; i++) {
339
				  bandlist[i] = i;
340
				}
341
			}
342
			
343
			if(bandCount==3){
344
				bandListTriband[0] = 0;
345
				bandListTriband[1] = 1;
346
				bandListTriband[2] = 2;
347
			}
348
			
349
			for (int nChunk=0; nChunk<frames.length; nChunk++) {
350
				ChunkFrame f = frames[nChunk];
351
				
352
				// Set the view			
353
				if(bandCount!=3)
354
					file.setView(file.numBands, bandlist, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);
355
				else
356
					file.setView(file.numBands, bandListTriband, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);
357
				
358
				//System.out.println("f.Size = ("+f.width+","+f.height+")+CHUNK="+nChunk);
359
				
360
				/* Esta peli es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
361
				 * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as? 
362
				 * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy 
363
				 * con las bandas alteradas de orden
364
				 */
365
				
366
				int pRGBArrayCopy[] = null;
367
				int mascara[] = new int[3];
368
				int shl[] = new int[3];
369
				int shr[] = new int[3];
370
				boolean order = true;
371
				
372
				if(bandCount==3){
373
					for(int i=0;i<bandCount;i++)
374
						if(bandlist[i]!=i)order=false;
375
					if(!order){
376
						for(int i=0;i<bandCount;i++){
377
							switch(bandlist[i]){
378
								case 0:mascara[i] = 0x00ff0000;break;
379
								case 1:mascara[i] = 0x0000ff00;break;
380
							    case 2:mascara[i] = 0x000000ff;break;
381
							}
382
							if(i==1 && bandlist[i]==0)shr[i] = 8;
383
							if(i==2 && bandlist[i]==0)shr[i] = 16;
384
							if(i==0 && bandlist[i]==1)shl[i] = 8;
385
							if(i==2 && bandlist[i]==1)shr[i] = 8;
386
							if(i==0 && bandlist[i]==2)shl[i] = 16;
387
							if(i==1 && bandlist[i]==2)shl[i] = 8;
388
						}
389
					}
390
				}
391
				
392
				// Read the scan lines
393
				for (line=0; line < f.height; line++) {
394
					file.readLineRGBA(pRGBArray);
395
					
396
					if(bandCount==3 && !order){
397
							pRGBArrayCopy = new int[pRGBArray.length];
398
							for(int i=0;i<pRGBArray.length;i++){ 
399
								pRGBArrayCopy[i] = 	(pRGBArray[i] & 0xff000000) + 
400
													(((pRGBArray[i] & mascara[2]) << shl[2] ) >> shr[2]) + 
401
													(((pRGBArray[i] & mascara[1]) << shl[1] ) >> shr[1]) +
402
													(((pRGBArray[i] & mascara[0]) << shl[0] ) >> shr[0]);
403
							}
404
							pRGBArray = pRGBArrayCopy;
405
					}
406
					
407
					// Prueba de sustituci?n de color transparente
408
					if (doTransparency) {
409
						if (line == 0) tFilter.debug = true;
410
				  		tFilter.filterLine(pRGBArray);
411
						tFilter.debug = false; 
412
					}
413
					//System.out.println("setRGB("+f.pos.x+","+f.pos.y+line+","+f.width+","+1+","+pRGBArray+","+0+","+f.width+")");
414
					((BufferedImage)ecwImage).setRGB(f.pos.x, f.pos.y+line, f.width, 1, pRGBArray, 0, f.width);
415
				}
416
			}
417
			if (frames[0].mustResize) {
418
				//System.out.println("resize "+fullSize);
419
				return resizeImage(fullSize, ecwImage);
420
			}
421
		/*
422
		 * La excepci?n atrapada es la de 'zoom > 1:1 no valido'
423
		} catch (com.ermapper.ecw.JNCSInvalidSetViewException e) {
424
			System.err.println(errorMessage);
425
			e.printStackTrace(); */
426
		} catch(com.ermapper.ecw.JNCSException e) { //java.lang.ArrayIndexOutOfBoundsException:
427
			bErrorOnOpen = true;
428
			System.err.println("EcwFile JNCS Error en la l?nea "+line+"/"+height);
429
			System.err.println(e.getMessage());
430
			e.printStackTrace();
431
		} catch(java.lang.ArrayIndexOutOfBoundsException e) { //:
432
			bErrorOnOpen = true;
433
			System.err.println("EcwFile ArrayIndex Error en la l?nea "+line+"/"+height);
434
			System.err.println(e.getMessage());
435
			e.printStackTrace();
436
		} catch(Exception e) {
437
			bErrorOnOpen = true;
438
			errorMessage = e.getMessage();
439
//			g.drawString(errorMessage, 0, 50);
440
			System.err.println(errorMessage);
441
			e.printStackTrace();
442
		}
443
		lastRefreshPercent = file.getPercentComplete();
444
		System.out.println("Leido al "+lastRefreshPercent+" %.");
445
		return ecwImage;
446
	}
447
	
448
	/**
449
	 * Redimensionado de imagen
450
	 * La funci?n getScaledInstance nos devuelve un tipo image que no sirve por lo que
451
	 * habr? que crear  buffImg como BufferedImage y copiar los datos devueltos por esta 
452
	 * funci?n a este que es el que ser? devuelto por la funci?n
453
	 * @param sz
454
	 * @param image	Image de entrada
455
	 * @return	Imagen reescalada
456
	 */
457
	private Image resizeImage(Dimension sz, Image image) {
458
		Image buffImg = null;
459
		Image img = image.getScaledInstance((int) sz.getWidth(),
460
			(int) sz.getHeight(), Image.SCALE_SMOOTH);
461
		
462
		//Todo este pollo es para copiar el tipo image devuelto a BufferedImage
463
		
464
		buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB) ;
465
		
466
		int[] pixels = new int[img.getWidth(null) * img.getHeight(null)];
467
		PixelGrabber pg = new PixelGrabber(img, 0, 0, img.getWidth(null), img.getHeight(null), pixels, 0, img.getWidth(null));
468
		
469
		try {
470
		    pg.grabPixels();
471
		} catch (InterruptedException e) {
472
		    e.printStackTrace();
473
		}
474
		
475
		for (int j = 0; j < buffImg.getHeight(null); j++) {
476
		    for (int i = 0; i < buffImg.getWidth(null); i++) {
477
				((BufferedImage)buffImg).setRGB(i, j, pixels[j * buffImg.getWidth(null) + i]);
478
		    }
479
		}
480
		
481
		return buffImg;
482
	}
483
	
484
	/**
485
	 * Reproyecta el raster.
486
	 */
487
	public void reProject(ICoordTrans rp) {
488
		// TODO metodo reProject pendiente de implementar
489
	}
154
    /**
155
     * Devuelve el ancho de la imagen
156
     */
157
    public int getWidth() {
158
        return file.width;
159
    }
490 160

  
161
    /**
162
     * Devuelve el alto de la imagen
163
     */
164
    public int getHeight() {
165
        return file.height;
166
    }
491 167

  
492
	/**
493
	 * Soporte para actualizaci?n de la imagen
494
	 * @see com.ermapper.ecw.JNCSProgressiveUpdate#refreshUpdate(int, int, double, double, double, double)
495
	 */
496
	public void refreshUpdate(int nWidth, int nHeight, double dWorldTLX, double dWorldTLY, double dWorldBRX, double dWorldBRY) {
497
		int completado = file.getPercentComplete();
498
		System.out.println("EcwFile: se actualiza 1: "+completado+" % completado");
499
		if ((updatable != null) && (lastRefreshPercent < 100)) {
500
			if ((completado-lastRefreshPercent > 25) || completado == 100) {
501
				lastRefreshPercent = file.getPercentComplete();
502
				updatable.repaint();
503
			}
504
		}
505
	}
168
    /**
169
     *
170
     */
171
    public void setMultifile(boolean mult) {
172
        this.multifile = mult;
173
    }
506 174

  
507
	public void refreshUpdate(int nWidth, int nHeight, int dDatasetTLX, int dDatasetTLY, int dDatasetBRX, int dDatasetBRY) {
508
		System.out.println("EcwFile: se actualiza 2");
509
	}
175
    /**
176
     * Obtiene un trozo de imagen (determinado por la vista y los par?metros.
177
     *
178
     * @param width
179
     * @param height
180
     */
181
    public synchronized Image updateImage(int width, int height, ICoordTrans rp) {
182
        // TODO reproyectar para devolver el trozo de imagen pedida sobre ...
183
        // la proyecci?n de destino.
184
        int line = 0;
185
        boolean mustResize = false;
186
        Dimension fullSize = null;
187
        Image ecwImage = null;
510 188

  
511
	/**
512
	 *  Esta funci?n es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
513
	 * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as? 
514
	 * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy 
515
	 * con las bandas alteradas de orden
516
	 * @param bandList	lista de bandas
517
	 * @param mask mascara
518
	 * @param shl desplazamiento izquierda
519
	 * @param shr desplazamiento derecha
520
	 */
521
	private boolean calcMaskAndShift(int[] bandList, int[] mask, int[] shl, int[] shr){
522
		boolean order = true;
523
		if(bandCount==3){
524
			for(int i=0;i<bandCount;i++)
525
				if(bandList[i]!=i)order=false;
526
			if(!order){
527
				for(int i=0;i<bandCount;i++){
528
					switch(bandList[i]){
529
						case 0:mask[i] = 0x00ff0000;break;
530
						case 1:mask[i] = 0x0000ff00;break;
531
					    case 2:mask[i] = 0x000000ff;break;
532
					}
533
					if(i==1 && bandList[i]==0)shr[i] = 8;
534
					if(i==2 && bandList[i]==0)shr[i] = 16;
535
					if(i==0 && bandList[i]==1)shl[i] = 8;
536
					if(i==2 && bandList[i]==1)shr[i] = 8;
537
					if(i==0 && bandList[i]==2)shl[i] = 16;
538
					if(i==1 && bandList[i]==2)shl[i] = 8;
539
				}
540
			}
541
		}
542
		return order;
543
	}
544
	
545
	/**
546
	 * Intercambio de bandas para ecw manual. Se le pasa el array de bytes que se desea intercambiar
547
	 * la mascara y desplazamientos previamente calculados con calcMaskAndShift
548
	 * @param order	true si el orden de las bandas no est? alterado y false si lo est? 
549
	 * @param pRGBArray array de
550
	 * @param mascara
551
	 * @param shl desplazamiento a izquierda 
552
	 * @param shr desplazamiento a derecha
553
	 * @return array con las bandas cambiadas
554
	 */
555
	private int[] changeBands(boolean order, int[] pRGBArray, int[] mascara, int[] shl, int[] shr){
556
		if(bandCount==3 && !order){
557
			int[] pRGBArrayCopy = new int[pRGBArray.length];
558
			for(int i=0;i<pRGBArray.length;i++){ 
559
				pRGBArrayCopy[i] = 	(pRGBArray[i] & 0xff000000) + 
560
									(((pRGBArray[i] & mascara[2]) << shl[2] ) >> shr[2]) + 
561
									(((pRGBArray[i] & mascara[1]) << shl[1] ) >> shr[1]) +
562
									(((pRGBArray[i] & mascara[0]) << shl[0] ) >> shr[0]);
563
			}
564
			return pRGBArrayCopy;
565
		}
566
		return pRGBArray;
567
	}
568
	
569
	/**
570
	 * Asigna al objeto Image los valores con los dato de la imagen contenidos en el 
571
	 * vector de enteros.
572
	 * @param image	imagen con los datos actuales
573
	 * @param startX	inicio de la posici?n en X dentro de la imagen
574
	 * @param startY	inicio de la posici?n en X dentro de la imagen
575
	 * @param w	Ancho de la imagen
576
	 * @param h	Alto de la imagen
577
	 * @param rgbArray	vector que contiene la banda que se va a sustituir
578
	 * @param offset	desplazamiento
579
	 * @param scansize	tama?o de imagen recorrida por cada p
580
	 */
581
	protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
582
			 int offset, int scansize) {
583
		image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
584
	}
585
	
586
	/**
587
	 * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
588
	 * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
589
	 * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
590
	 * banda correspondiente a flags es sustituida por los datos del vector.
591
	 * @param image	imagen con los datos actuales
592
	 * @param startX	inicio de la posici?n en X dentro de la imagen
593
	 * @param startY	inicio de la posici?n en X dentro de la imagen
594
	 * @param w	Ancho de la imagen
595
	 * @param h	Alto de la imagen
596
	 * @param rgbArray	vector que contiene la banda que se va a sustituir
597
	 * @param offset	desplazamiento
598
	 * @param scansize	tama?o de imagen recorrida por cada paso
599
	 * @param flags	banda que se va a sustituir (Ctes de GeoRasterFile)
600
	 */
601
	protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
602
			 int offset, int scansize, int flags) {
603
		int [] line = new int[rgbArray.length]; 
604
		image.getRGB(startX, startY, w, h, line, offset, scansize);
605
		if (flags == GeoRasterFile.RED_BAND)
606
			for (int i=0; i<line.length; i++)
607
				line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
608
		else if (flags == GeoRasterFile.GREEN_BAND)
609
			for (int i=0; i<line.length; i++)
610
				line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
611
		else if (flags == GeoRasterFile.BLUE_BAND)
612
			for (int i=0; i<line.length; i++)
613
				line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
614
		image.setRGB(startX, startY, w, h, line, offset, scansize);
615
	}
616
	
617
	/**
618
	 * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores 
619
	 * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
620
	 * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
621
	 * banda correspondiente a flags es sustituida por los datos del vector.
622
	 * @param image	imagen con los datos actuales
623
	 * @param startX	inicio de la posici?n en X dentro de la imagen
624
	 * @param startY	inicio de la posici?n en X dentro de la imagen
625
	 * @param w	Ancho de la imagen
626
	 * @param h	Alto de la imagen
627
	 * @param rgbArray	vector que contiene la banda que se va a sustituir
628
	 * @param offset	desplazamiento
629
	 * @param scansize	tama?o de imagen recorrida por cada paso
630
	 * @param origBand	Banda origen del GeoRasterFile
631
	 * @param destBandFlag	banda que se va a sustituir (Ctes de GeoRasterFile)
632
	 */
633
	protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h, int[] rgbArray, 
634
			 int offset, int scansize, int origBand, int destBandFlag) {
635
		int [] line = new int[rgbArray.length]; 
636
		image.getRGB(startX, startY, w, h, line, offset, scansize);
637
		
638
		if (origBand == 0 && destBandFlag == GeoRasterFile.RED_BAND)
639
			for (int i=0; i<line.length; i++)
640
				line[i] = (line[i] & 0xff00ffff) | (rgbArray[i] & 0x00ff0000);
641
		else if (origBand == 1 && destBandFlag == GeoRasterFile.GREEN_BAND)
642
			for (int i=0; i<line.length; i++)
643
				line[i] = (line[i] & 0xffff00ff) | (rgbArray[i] & 0x0000ff00);
644
		else if (origBand == 2 && destBandFlag == GeoRasterFile.BLUE_BAND)
645
			for (int i=0; i<line.length; i++)
646
				line[i] = (line[i] & 0xffffff00) | (rgbArray[i] & 0x000000ff);
647
		
648
		else if (origBand == 0 && destBandFlag == GeoRasterFile.GREEN_BAND)
649
			for (int i=0; i<line.length; i++)
650
				line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x00ff0000) >> 8) ;
651
		else if (origBand == 0 && destBandFlag == GeoRasterFile.BLUE_BAND)
652
			for (int i=0; i<line.length; i++)
653
				line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x00ff0000) >> 16);
654
		
655
		else if (origBand == 1 && destBandFlag == GeoRasterFile.RED_BAND)
656
			for (int i=0; i<line.length; i++)
657
				line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x0000ff00) << 8);
658
		else if (origBand == 1 && destBandFlag == GeoRasterFile.BLUE_BAND)
659
			for (int i=0; i<line.length; i++)
660
				line[i] = (line[i] & 0xffffff00) | ((rgbArray[i] & 0x0000ff00) >> 8);
661
		
662
		else if (origBand == 2 && destBandFlag == GeoRasterFile.RED_BAND)
663
			for (int i=0; i<line.length; i++)
664
				line[i] = (line[i] & 0xff00ffff) | ((rgbArray[i] & 0x000000ff) << 16);
665
		else if (origBand == 2 && destBandFlag == GeoRasterFile.GREEN_BAND)
666
			for (int i=0; i<line.length; i++)
667
				line[i] = (line[i] & 0xffff00ff) | ((rgbArray[i] & 0x000000ff) << 8);
668
		
669
		image.setRGB(startX, startY, w, h, line, offset, scansize);
670
	}
671
		
672
	/* (non-Javadoc)
673
	 * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int origBand, int destBand)
674
	 */
675
	public Image updateImage(int width, int height, ICoordTrans rp, Image img, int origBand, int destBandFlag) {
676
		//TODO reproyectar para devolver el trozo de imagen pedida sobre ...
677
		// la proyecci?n de destino.
678
		int line = 0; 
679
		boolean mustResize = false;
680
		Dimension fullSize = null;
681
		
682
		if (file == null) return null;
683
		try {
684
			double dFileAspect, dWindowAspect;
685
			//double dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY;
686
			int bandlist[];
687
			int bandListTriband[];
688
			int pRGBArray[] = null;
189
        if (file == null) {
190
            return ecwImage;
191
        }
689 192

  
690
			// Work out the correct aspect for the setView call.
691
			dFileAspect = (double)v.width()/(double)v.height();
692
			dWindowAspect = (double)width /(double)height;
193
        try {
194
            double dFileAspect;
195
            double dWindowAspect;
693 196

  
694
			if (dFileAspect > dWindowAspect) {
695
			  height =(int)((double)width/dFileAspect);
696
			} else {
697
			  width = (int)((double)height*dFileAspect);
698
			}
197
            //double dWorldTLX, dWorldTLY, dWorldBRX, dWorldBRY;
198
            int[] bandlist;
199
            int[] bandListTriband;
200
            int[] pRGBArray = null;
699 201

  
700
			fullSize = new Dimension(width, height);
701
			//System.out.println("fullSize = ("+width+","+height+")");
702
			// Peta en los peque?os ... arreglar antes de meter del todo
703
			ChunkFrame frames[] = ChunkFrame.computeFrames(file, v, fullSize);
704
			/*for (int nChunk=0; nChunk<frames.length; nChunk++) {
705
				System.out.println("chunck "+nChunk+"->"+frames[nChunk]);
706
			}*/
707
			if (frames.length == 1) {
708
				width = frames[0].width; 
709
				height = frames[0].height;
710
				if(width<=0)width=1;
711
				if(height<=0)height=1;
712
				//System.out.println("frameSize = ("+width+","+height+")");
713
				//System.out.println("Cambio el ancho total a ("+width+","+height+")");
714
			}
715
					
716
			// Create an image of the ecw file.
717
						
718
			pRGBArray = new int[width];
202
            // Work out the correct aspect for the setView call.
203
            dFileAspect = (double) v.width() / (double) v.height();
204
            dWindowAspect = (double) width / (double) height;
719 205

  
720
			// Setup the view parameters for the ecw file.
721
			bandlist = new int[bandCount];
722
			bandListTriband = new int[bandCount];
723
			if ( bandCount > 2) {
724
				bandlist[0] = getBand(RED_BAND);
725
				bandlist[1] = getBand(GREEN_BAND);
726
				bandlist[2] = getBand(BLUE_BAND);
727
				if (bandCount > 3)
728
					for (int i=3; i< bandCount; i++) {
729
						 bandlist[i] = 0;
730
					}
731
			} else {
732
				for (int i=0; i< bandCount; i++) {
733
				  bandlist[i] = i;
734
				}
735
			}
736
			
737
			if(bandCount==3){
738
				bandListTriband[0] = 0;
739
				bandListTriband[1] = 1;
740
				bandListTriband[2] = 2;
741
			}
742
			
743
			int mascara[] = new int[3];
744
			int shl[] = new int[3];
745
			int shr[] = new int[3];
746
			boolean order = true;
747
			
748
			if(img==null){ //Caso en el que se crea un Image
749
				EcwFile.nUpdate = 1;
750
				Image ecwImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
751
				
752
				for (int nChunk=0; nChunk<frames.length; nChunk++) {
753
					ChunkFrame f = frames[nChunk];
754
					if(bandCount!=3)
755
						file.setView(file.numBands, bandlist, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);
756
					else
757
						file.setView(file.numBands, bandListTriband, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);					
758
					
759
					order = calcMaskAndShift(bandlist, mascara, shl, shr);
760
			
761
					for (line=0; line < f.height; line++) {
762
						file.readLineRGBA(pRGBArray);
763
						pRGBArray = changeBands(order, pRGBArray, mascara, shl, shr);
764
						setRGBLine((BufferedImage) ecwImage, f.pos.x, f.pos.y+line, f.width, 1, pRGBArray, 0, f.width);
765
					}
766
										
767
				}//Chuncks
768
				applyAlpha(ecwImage);
769
				if (frames[0].mustResize && !this.multifile) {
770
					return resizeImage(fullSize, ecwImage);
771
				}
772
				lastRefreshPercent = file.getPercentComplete();
773
				//System.out.println("Leido al "+lastRefreshPercent+" %.");
774
				return ecwImage;
775
			}else{	//Caso en el que se actualiza una banda del Image
776
				EcwFile.nUpdate ++;
777
				for (int nChunk=0; nChunk<frames.length; nChunk++) {
778
					ChunkFrame f = frames[nChunk];
779
					if(bandCount!=3)
780
						file.setView(file.numBands, bandlist, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);
781
					else
782
						file.setView(file.numBands, bandListTriband, f.v.minX(), f.v.maxY(), f.v.maxX(), f.v.minY(), f.width, f.height);					
783
					order = calcMaskAndShift(bandlist, mascara, shl, shr);
784
					
785
					//System.out.println("ORIGEN="+origBand+" DESTINO="+destBandFlag);
786
					for (line=0; line < f.height; line++) {
787
						file.readLineRGBA(pRGBArray);
788
						pRGBArray = changeBands(order, pRGBArray, mascara, shl, shr);
789
						setRGBLine((BufferedImage) img, f.pos.x, f.pos.y+line, f.width, 1, pRGBArray, 0, f.width, origBand, destBandFlag);
790
					}
791
										
792
				}//Chuncks
793
				
794
				applyAlpha(img);
795
				
796
				if (frames[0].mustResize && nUpdate == 3 && this.multifile) {
797
					return resizeImage(fullSize, img);
798
				}
799
				lastRefreshPercent = file.getPercentComplete();
800
				//System.out.println("Leido al "+lastRefreshPercent+" %.");
801
				return img;
802
			}
803
			
206
            if (dFileAspect > dWindowAspect) {
207
                height = (int) ((double) width / dFileAspect);
208
            } else {
209
                width = (int) ((double) height * dFileAspect);
210
            }
804 211

  
805
		} catch(com.ermapper.ecw.JNCSException e) { //java.lang.ArrayIndexOutOfBoundsException:
806
			bErrorOnOpen = true;
807
			System.err.println("EcwFile JNCS Error en la l?nea "+line+"/"+height);
808
			System.err.println(e.getMessage());
809
			e.printStackTrace();
810
		} catch(java.lang.ArrayIndexOutOfBoundsException e) { //:
811
			bErrorOnOpen = true;
812
			System.err.println("EcwFile ArrayIndex Error en la l?nea "+line+"/"+height);
813
			System.err.println(e.getMessage());
814
			e.printStackTrace();
815
		} catch(Exception e) {
816
			bErrorOnOpen = true;
817
			errorMessage = e.getMessage();
818
			System.err.println(errorMessage);
819
			e.printStackTrace();
820
		}
821
		return img;
822
	}
823
	
824
	private void applyAlpha(Image im) {
825
		BufferedImage img = (BufferedImage) im;
826
		int alpha = (getAlpha() & 0xff) << 24;
827
		int w = img.getWidth();
828
		int [] line = new int[w];
829
		for (int j=0; j<img.getHeight(); j++) {
830
			img.getRGB(0, j, w, 1, line, 0, w);
831
			for (int i=0; i<w; i++)
832
				line[i] = (alpha | line[i] & 0x00ffffff);
833
			img.setRGB(0, j, w, 1, line, 0, w);
834
		}
835
	}
212
            fullSize = new Dimension(width, height);
836 213

  
837
	/* (non-Javadoc)
838
	 * @see org.cresques.io.GeoRasterFile#getData(int, int)
839
	 */
840
	public Object getData(int x, int y, int band) {
841
		//file.readLineRGBA();
842
		return null;
843
	}
844
	
845
	/**
846
	 * Devuelve los datos de una ventana solicitada
847
	 * @param ulX	coordenada X superior izda.
848
	 * @param ulY	coordenada Y superior derecha.
849
	 * @param sizeX	tama?o en X de la ventana.
850
	 * @param sizeY tama?o en Y de la ventana.
851
	 * @param band	Banda solicitada.
852
	 */
853
	
854
	public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band){
855
		//TODO Nacho: Implementar getWindow de EcwFile
856
			return null;
857
		
858
	}
859
	
860
	/**
861
	 * Obtiene la zona (Norte / Sur)
862
	 * @return true si la zona es norte y false si es sur
863
	 */
864
	
865
	public boolean getZone(){
866
		//TODO Nacho: Implementar getZone de EcwFile
867
		return false;
868
	}
869
	
870
	/**
871
	 *Devuelve el n?mero de zona UTM
872
	 *@return N?mero de zona 
873
	 */
874
	
875
	public int getUTM(){
876
//		TODO Nacho: Implementar getUTM de EcwFile
877
		return 0;	
878
	}
879
	
880
	/**
881
	 * Obtiene el sistema de coordenadas geograficas
882
	 * @return Sistema de coordenadas geogr?ficas
883
	 */
884
	public String getGeogCS(){
885
		//TODO Nacho: Implementar getGeogCS de EcwFile
886
		return new String("");	
887
	}
888
	
889
	/**
890
	 * Devuelve el tama?o de bloque
891
	 * @return Tama?o de bloque
892
	 */
893
	public int getBlockSize(){
894
     //TODO Nacho: Implementar getBlockSize de EcwFile	
895
	  return 1;
896
	}
214
            //System.out.println("fullSize = ("+width+","+height+")");
215
            // Peta en los peque?os ... arreglar antes de meter del todo
216
            ChunkFrame[] frames = ChunkFrame.computeFrames(file, v, fullSize);
897 217

  
898
}
218
            /*for (int nChunk=0; nChunk<frames.length; nChunk++) {
219
                    System.out.println("chunck "+nChunk+"->"+frames[nChunk]);
220
            }*/
221
            if (frames.length == 1) {
222
                width = frames[0].width;
223
                height = frames[0].height;
224

  
225
                if (width <= 0) {
226
                    width = 1;
227
                }
228

  
229
                if (height <= 0) {
230
                    height = 1;
231
                }
232

  
233
                //System.out.println("frameSize = ("+width+","+height+")");
234
                //System.out.println("Cambio el ancho total a ("+width+","+height+")");
235
            }
236

  
237
            /*                        JNCSDatasetPoint ptMin = file.convertWorldToDataset(v.minX(), v.minY());
238
                                    JNCSDatasetPoint ptMax = file.convertWorldToDataset(v.maxX(), v.maxY());
239
                                    System.out.println("Dataset coords Width = "+(ptMax.x-ptMin.x)+", px width ="+width);
240
                                    // BEGIN Cambiando para soportar e < 1:1
241
                                    // TODO Mejorarlo para que los PAN con un zoom muy grande sean correctos
242
                                    if ((ptMax.x-ptMin.x)<width) {
243
                                            width = ptMax.x-ptMin.x;
244
                                            height = ptMin.y-ptMax.y;
245
                                            System.out.println("Size=("+width+","+height+")");
246
                                            mustResize = true;
247
                                    }*/
248

  
249
            // Create an image of the ecw file.
250
            if (doTransparency) {
251
                ecwImage = new BufferedImage(width, height,
252
                                             BufferedImage.TYPE_INT_ARGB);
253
            } else {
254
                ecwImage = new BufferedImage(width, height,
255
                                             BufferedImage.TYPE_INT_RGB);
256
            }
257

  
258
            pRGBArray = new int[width];
259

  
260
            // Setup the view parameters for the ecw file.
261
            bandlist = new int[bandCount];
262
            bandListTriband = new int[bandCount];
263

  
264
            if (bandCount > 2) {
265
                bandlist[0] = getBand(RED_BAND);
266
                bandlist[1] = getBand(GREEN_BAND);
267
                bandlist[2] = getBand(BLUE_BAND);
268

  
269
                if (bandCount > 3) {
270
                    for (int i = 3; i < bandCount; i++) {
271
                        bandlist[i] = 0;
272
                    }
273
                }
274
            } else {
275
                for (int i = 0; i < bandCount; i++) {
276
                    bandlist[i] = i;
277
                }
278
            }
279

  
280
            if (bandCount == 3) {
281
                bandListTriband[0] = 0;
282
                bandListTriband[1] = 1;
283
                bandListTriband[2] = 2;
284
            }
285

  
286
            for (int nChunk = 0; nChunk < frames.length; nChunk++) {
287
                ChunkFrame f = frames[nChunk];
288

  
289
                // Set the view			
290
                if (bandCount != 3) {
291
                    file.setView(file.numBands, bandlist, f.v.minX(),
292
                                 f.v.maxY(), f.v.maxX(), f.v.minY(), f.width,
293
                                 f.height);
294
                } else {
295
                    file.setView(file.numBands, bandListTriband, f.v.minX(),
296
                                 f.v.maxY(), f.v.maxX(), f.v.minY(), f.width,
297
                                 f.height);
298
                }
299

  
300
                //System.out.println("f.Size = ("+f.width+","+f.height+")+CHUNK="+nChunk);
301

  
302
                /* Esta peli es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
303
                 * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as?
304
                 * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy
305
                 * con las bandas alteradas de orden
306
                 */
307
                int[] pRGBArrayCopy = null;
308
                int[] mascara = new int[3];
309
                int[] shl = new int[3];
310
                int[] shr = new int[3];
311
                boolean order = true;
312

  
313
                if (bandCount == 3) {
314
                    for (int i = 0; i < bandCount; i++)
315
                        if (bandlist[i] != i) {
316
                            order = false;
317
                        }
318

  
319
                    if (!order) {
320
                        for (int i = 0; i < bandCount; i++) {
321
                            switch (bandlist[i]) {
322
                            case 0:
323
                                mascara[i] = 0x00ff0000;
324

  
325
                                break;
326

  
327
                            case 1:
328
                                mascara[i] = 0x0000ff00;
329

  
330
                                break;
331

  
332
                            case 2:
333
                                mascara[i] = 0x000000ff;
334

  
335
                                break;
336
                            }
337

  
338
                            if ((i == 1) && (bandlist[i] == 0)) {
339
                                shr[i] = 8;
340
                            }
341

  
342
                            if ((i == 2) && (bandlist[i] == 0)) {
343
                                shr[i] = 16;
344
                            }
345

  
346
                            if ((i == 0) && (bandlist[i] == 1)) {
347
                                shl[i] = 8;
348
                            }
349

  
350
                            if ((i == 2) && (bandlist[i] == 1)) {
351
                                shr[i] = 8;
352
                            }
353

  
354
                            if ((i == 0) && (bandlist[i] == 2)) {
355
                                shl[i] = 16;
356
                            }
357

  
358
                            if ((i == 1) && (bandlist[i] == 2)) {
359
                                shl[i] = 8;
360
                            }
361
                        }
362
                    }
363
                }
364

  
365
                // Read the scan lines
366
                for (line = 0; line < f.height; line++) {
367
                    file.readLineRGBA(pRGBArray);
368

  
369
                    if ((bandCount == 3) && !order) {
370
                        pRGBArrayCopy = new int[pRGBArray.length];
371

  
372
                        for (int i = 0; i < pRGBArray.length; i++) {
373
                            pRGBArrayCopy[i] = (pRGBArray[i] & 0xff000000) +
374
                                               (((pRGBArray[i] & mascara[2]) << shl[2]) >> shr[2]) +
375
                                               (((pRGBArray[i] & mascara[1]) << shl[1]) >> shr[1]) +
376
                                               (((pRGBArray[i] & mascara[0]) << shl[0]) >> shr[0]);
377
                        }
378

  
379
                        pRGBArray = pRGBArrayCopy;
380
                    }
381

  
382
                    // Prueba de sustituci?n de color transparente
383
                    if (doTransparency) {
384
                        if (line == 0) {
385
                            tFilter.debug = true;
386
                        }
387

  
388
                        tFilter.filterLine(pRGBArray);
389
                        tFilter.debug = false;
390
                    }
391

  
392
                    //System.out.println("setRGB("+f.pos.x+","+f.pos.y+line+","+f.width+","+1+","+pRGBArray+","+0+","+f.width+")");
393
                    ((BufferedImage) ecwImage).setRGB(f.pos.x, f.pos.y + line,
394
                                                      f.width, 1, pRGBArray, 0,
395
                                                      f.width);
396
                }
397
            }
398

  
399
            if (frames[0].mustResize) {
400
                //System.out.println("resize "+fullSize);
401
                return resizeImage(fullSize, ecwImage);
402
            }
403

  
404
            /*
405
             * La excepci?n atrapada es la de 'zoom > 1:1 no valido'
406
            } catch (com.ermapper.ecw.JNCSInvalidSetViewException e) {
407
                    System.err.println(errorMessage);
408
                    e.printStackTrace(); */
409
        } catch (com.ermapper.ecw.JNCSException e) { //java.lang.ArrayIndexOutOfBoundsException:
410
            bErrorOnOpen = true;
411
            System.err.println("EcwFile JNCS Error en la l?nea " + line + "/" +
412
                               height);
413
            System.err.println(e.getMessage());
414
            e.printStackTrace();
415
        } catch (java.lang.ArrayIndexOutOfBoundsException e) { //:
416
            bErrorOnOpen = true;
417
            System.err.println("EcwFile ArrayIndex Error en la l?nea " + line +
418
                               "/" + height);
419
            System.err.println(e.getMessage());
420
            e.printStackTrace();
421
        } catch (Exception e) {
422
            bErrorOnOpen = true;
423
            errorMessage = e.getMessage();
424

  
425
            //			g.drawString(errorMessage, 0, 50);
426
            System.err.println(errorMessage);
427
            e.printStackTrace();
428
        }
429

  
430
        lastRefreshPercent = file.getPercentComplete();
431
        System.out.println("Leido al " + lastRefreshPercent + " %.");
432

  
433
        return ecwImage;
434
    }
435

  
436
    /**
437
     * Redimensionado de imagen
438
     * La funci?n getScaledInstance nos devuelve un tipo image que no sirve por lo que
439
     * habr? que crear  buffImg como BufferedImage y copiar los datos devueltos por esta
440
     * funci?n a este que es el que ser? devuelto por la funci?n
441
     * @param sz
442
     * @param image        Image de entrada
443
     * @return        Imagen reescalada
444
     */
445
    private Image resizeImage(Dimension sz, Image image) {
446
        Image buffImg = null;
447
        Image img = image.getScaledInstance((int) sz.getWidth(),
448
                                            (int) sz.getHeight(),
449
                                            Image.SCALE_SMOOTH);
450

  
451
        //Todo este pollo es para copiar el tipo image devuelto a BufferedImage
452
        buffImg = new BufferedImage(img.getWidth(null), img.getHeight(null),
453
                                    BufferedImage.TYPE_INT_ARGB);
454

  
455
        int[] pixels = new int[img.getWidth(null) * img.getHeight(null)];
456
        PixelGrabber pg = new PixelGrabber(img, 0, 0, img.getWidth(null),
457
                                           img.getHeight(null), pixels, 0,
458
                                           img.getWidth(null));
459

  
460
        try {
461
            pg.grabPixels();
462
        } catch (InterruptedException e) {
463
            e.printStackTrace();
464
        }
465

  
466
        for (int j = 0; j < buffImg.getHeight(null); j++) {
467
            for (int i = 0; i < buffImg.getWidth(null); i++) {
468
                ((BufferedImage) buffImg).setRGB(i, j,
469
                                                 pixels[(j * buffImg.getWidth(null)) +
470
                                                 i]);
471
            }
472
        }
473

  
474
        return buffImg;
475
    }
476

  
477
    /**
478
     * Reproyecta el raster.
479
     */
480
    public void reProject(ICoordTrans rp) {
481
        // TODO metodo reProject pendiente de implementar
482
    }
483

  
484
    /**
485
     * Soporte para actualizaci?n de la imagen
486
     * @see com.ermapper.ecw.JNCSProgressiveUpdate#refreshUpdate(int, int, double, double, double, double)
487
     */
488
    public void refreshUpdate(int nWidth, int nHeight, double dWorldTLX,
489
                              double dWorldTLY, double dWorldBRX,
490
                              double dWorldBRY) {
491
        int completado = file.getPercentComplete();
492
        System.out.println("EcwFile: se actualiza 1: " + completado +
493
                           " % completado");
494

  
495
        if ((updatable != null) && (lastRefreshPercent < 100)) {
496
            if (((completado - lastRefreshPercent) > 25) ||
497
                    (completado == 100)) {
498
                lastRefreshPercent = file.getPercentComplete();
499
                updatable.repaint();
500
            }
501
        }
502
    }
503

  
504
    public void refreshUpdate(int nWidth, int nHeight, int dDatasetTLX,
505
                              int dDatasetTLY, int dDatasetBRX, int dDatasetBRY) {
506
        System.out.println("EcwFile: se actualiza 2");
507
    }
508

  
509
    /**
510
     *  Esta funci?n es porque el Ecw no intercambia las bandas con lo que me toca hacerlo
511
     * a mano. Primero detectamos si se ha alterado el orden de las mismas. Si es as?
512
     * calculamos mascaras y desplazamientos y hacemos una copia en pRGBArrayCopy
513
     * con las bandas alteradas de orden
514
     * @param bandList        lista de bandas
515
     * @param mask mascara
516
     * @param shl desplazamiento izquierda
517
     * @param shr desplazamiento derecha
518
     */
519
    private boolean calcMaskAndShift(int[] bandList, int[] mask, int[] shl,
520
                                     int[] shr) {
521
        boolean order = true;
522

  
523
        if (bandCount == 3) {
524
            for (int i = 0; i < bandCount; i++)
525
                if (bandList[i] != i) {
526
                    order = false;
527
                }
528

  
529
            if (!order) {
530
                for (int i = 0; i < bandCount; i++) {
531
                    switch (bandList[i]) {
532
                    case 0:
533
                        mask[i] = 0x00ff0000;
534

  
535
                        break;
536

  
537
                    case 1:
538
                        mask[i] = 0x0000ff00;
539

  
540
                        break;
541

  
542
                    case 2:
543
                        mask[i] = 0x000000ff;
544

  
545
                        break;
546
                    }
547

  
548
                    if ((i == 1) && (bandList[i] == 0)) {
549
                        shr[i] = 8;
550
                    }
551

  
552
                    if ((i == 2) && (bandList[i] == 0)) {
553
                        shr[i] = 16;
554
                    }
555

  
556
                    if ((i == 0) && (bandList[i] == 1)) {
557
                        shl[i] = 8;
558
                    }
559

  
560
                    if ((i == 2) && (bandList[i] == 1)) {
561
                        shr[i] = 8;
562
                    }
563

  
564
                    if ((i == 0) && (bandList[i] == 2)) {
565
                        shl[i] = 16;
566
                    }
567

  
568
                    if ((i == 1) && (bandList[i] == 2)) {
569
                        shl[i] = 8;
570
                    }
571
                }
572
            }
573
        }
574

  
575
        return order;
576
    }
577

  
578
    /**
579
     * Intercambio de bandas para ecw manual. Se le pasa el array de bytes que se desea intercambiar
580
     * la mascara y desplazamientos previamente calculados con calcMaskAndShift
581
     * @param order        true si el orden de las bandas no est? alterado y false si lo est?
582
     * @param pRGBArray array de
583
     * @param mascara
584
     * @param shl desplazamiento a izquierda
585
     * @param shr desplazamiento a derecha
586
     * @return array con las bandas cambiadas
587
     */
588
    private int[] changeBands(boolean order, int[] pRGBArray, int[] mascara,
589
                              int[] shl, int[] shr) {
590
        if ((bandCount == 3) && !order) {
591
            int[] pRGBArrayCopy = new int[pRGBArray.length];
592

  
593
            for (int i = 0; i < pRGBArray.length; i++) {
594
                pRGBArrayCopy[i] = (pRGBArray[i] & 0xff000000) +
595
                                   (((pRGBArray[i] & mascara[2]) << shl[2]) >> shr[2]) +
596
                                   (((pRGBArray[i] & mascara[1]) << shl[1]) >> shr[1]) +
597
                                   (((pRGBArray[i] & mascara[0]) << shl[0]) >> shr[0]);
598
            }
599

  
600
            return pRGBArrayCopy;
601
        }
602

  
603
        return pRGBArray;
604
    }
605

  
606
    /**
607
     * Asigna al objeto Image los valores con los dato de la imagen contenidos en el
608
     * vector de enteros.
609
     * @param image        imagen con los datos actuales
610
     * @param startX        inicio de la posici?n en X dentro de la imagen
611
     * @param startY        inicio de la posici?n en X dentro de la imagen
612
     * @param w        Ancho de la imagen
613
     * @param h        Alto de la imagen
614
     * @param rgbArray        vector que contiene la banda que se va a sustituir
615
     * @param offset        desplazamiento
616
     * @param scansize        tama?o de imagen recorrida por cada p
617
     */
618
    protected void setRGBLine(BufferedImage image, int startX, int startY,
619
                              int w, int h, int[] rgbArray, int offset,
620
                              int scansize) {
621
        image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
622
    }
623

  
624
    /**
625
     * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
626
     * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
627
     * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
628
     * banda correspondiente a flags es sustituida por los datos del vector.
629
     * @param image        imagen con los datos actuales
630
     * @param startX        inicio de la posici?n en X dentro de la imagen
631
     * @param startY        inicio de la posici?n en X dentro de la imagen
632
     * @param w        Ancho de la imagen
633
     * @param h        Alto de la imagen
634
     * @param rgbArray        vector que contiene la banda que se va a sustituir
635
     * @param offset        desplazamiento
636
     * @param scansize        tama?o de imagen recorrida por cada paso
637
     * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
638
     */
639
    protected void setRGBLine(BufferedImage image, int startX, int startY,
640
                              int w, int h, int[] rgbArray, int offset,
641
                              int scansize, int flags) {
642
        int[] line = new int[rgbArray.length];
643
        image.getRGB(startX, startY, w, h, line, offset, scansize);
644

  
645
        if (flags == GeoRasterFile.RED_BAND) {
646
            for (int i = 0; i < line.length; i++)
647
                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
648
        } else if (flags == GeoRasterFile.GREEN_BAND) {
649
            for (int i = 0; i < line.length; i++)
650
                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
651
        } else if (flags == GeoRasterFile.BLUE_BAND) {
652
            for (int i = 0; i < line.length; i++)
653
                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
654
        }
655

  
656
        image.setRGB(startX, startY, w, h, line, offset, scansize);
657
    }
658

  
659
    /**
660
     * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
661
     * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
662
     * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
663
     * banda correspondiente a flags es sustituida por los datos del vector.
664
     * @param image        imagen con los datos actuales
665
     * @param startX        inicio de la posici?n en X dentro de la imagen
666
     * @param startY        inicio de la posici?n en X dentro de la imagen
667
     * @param w        Ancho de la imagen
668
     * @param h        Alto de la imagen
669
     * @param rgbArray        vector que contiene la banda que se va a sustituir
670
     * @param offset        desplazamiento
671
     * @param scansize        tama?o de imagen recorrida por cada paso
672
     * @param origBand        Banda origen del GeoRasterFile
673
     * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
674
     */
675
    protected void setRGBLine(BufferedImage image, int startX, int startY,
676
                              int w, int h, int[] rgbArray, int offset,
677
                              int scansize, int origBand, int destBandFlag) {
678
        int[] line = new int[rgbArray.length];
679
        image.getRGB(startX, startY, w, h, line, offset, scansize);
680

  
681
        if ((origBand == 0) && (destBandFlag == GeoRasterFile.RED_BAND)) {
682
            for (int i = 0; i < line.length; i++)
683
                line[i] = (line[i] & 0xff00ffff) | (rgbArray[i] & 0x00ff0000);
684
        } else if ((origBand == 1) &&
685
                       (destBandFlag == GeoRasterFile.GREEN_BAND)) {
686
            for (int i = 0; i < line.length; i++)
687
                line[i] = (line[i] & 0xffff00ff) | (rgbArray[i] & 0x0000ff00);
688
        } else if ((origBand == 2) &&
689
                       (destBandFlag == GeoRasterFile.BLUE_BAND)) {
690
            for (int i = 0; i < line.length; i++)
691
                line[i] = (line[i] & 0xffffff00) | (rgbArray[i] & 0x000000ff);
692
        }
693
        else if ((origBand == 0) && (destBandFlag == GeoRasterFile.GREEN_BAND)) {
694
            for (int i = 0; i < line.length; i++)
695
                line[i] = (line[i] & 0xffff00ff) |
696
                          ((rgbArray[i] & 0x00ff0000) >> 8);
697
        } else if ((origBand == 0) &&
698
                       (destBandFlag == GeoRasterFile.BLUE_BAND)) {
699
            for (int i = 0; i < line.length; i++)
700
                line[i] = (line[i] & 0xffffff00) |
701
                          ((rgbArray[i] & 0x00ff0000) >> 16);
702
        }
703
        else if ((origBand == 1) && (destBandFlag == GeoRasterFile.RED_BAND)) {
704
            for (int i = 0; i < line.length; i++)
705
                line[i] = (line[i] & 0xff00ffff) |
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff