Revision 1463

View differences:

org.gvsig.raster.lizardtech/tags/buildNumber_27/org.gvsig.raster.lizardtech/org.gvsig.raster.lizardtech.io/src/main/resources/META-INF/services/org.gvsig.tools.library.Library
1
org.gvsig.raster.lizardtech.io.DefaultLizardtechIOLibrary
org.gvsig.raster.lizardtech/tags/buildNumber_27/org.gvsig.raster.lizardtech/org.gvsig.raster.lizardtech.io/src/main/java/org/gvsig/raster/lizardtech/io/LizardTechNative.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.lizardtech.io;
23

  
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.io.IOException;
28

  
29
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
30
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
31
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
32
import org.gvsig.raster.impl.process.RasterTask;
33
import org.gvsig.raster.impl.process.RasterTaskQueue;
34

  
35
import es.gva.cit.jmrsid.LTIDataType;
36
import es.gva.cit.jmrsid.LTIGeoCoord;
37
import es.gva.cit.jmrsid.LTIImageStage;
38
import es.gva.cit.jmrsid.LTIMetadataDatabase;
39
import es.gva.cit.jmrsid.LTIMetadataRecord;
40
import es.gva.cit.jmrsid.LTISceneBuffer;
41
import es.gva.cit.jmrsid.LTIUtils;
42
import es.gva.cit.jmrsid.MrSIDException;
43
import es.gva.cit.jmrsid.MrSIDImageReader;
44

  
45
public class LizardTechNative extends MrSIDImageReader {
46
	static boolean                  WITH_OVERVIEWS          = true;
47
	public int                      width                   = 0;
48
	public int                      height                  = 0;
49
	public double 					originX                 = 0D;
50
	public double 					originY                 = 0D;
51
	public String 					version                 = "";
52
	public LTIMetadataDatabase 		metadata;
53
	private int 					alpha                   = 0;
54
	protected int 					rBandNr                 = 1;
55
	protected int 					gBandNr                 = 2;
56
	protected int 					bBandNr                 = 3;
57
	protected byte[] 				bandR;
58
	protected byte[] 				bandG;
59
	protected byte[] 				bandB;
60
	private int 					dataType                = LTIDataType.LTI_DATATYPE_UINT8;
61
	//View
62
	private double                  zoomoverview            = 0.0;
63
	private int 					eSampleType;
64
	private int 					noverviews;
65
	public int                      xini;
66
	public int                      yini;
67
	/**
68
	 * Ancho y alto de la overview
69
	 */
70
	public int                      anchoOver;
71
	public int                      altoOver;
72
	public int                      blocksize               = 1;
73
	/**
74
	 * N?mero de bandas de la imagen
75
	 */
76
	public int                      nbands;
77
	/**
78
	 * Posici?n de la esquina superior izquierda en coordenadas pixel
79
	 */
80
	private double                  currentViewY            = -1;
81
	private double                  currentViewX            = 0D;
82
	/**
83
	 * Ancho y alto de la im�gen (pixeles en pantalla)
84
	 */
85
	private int 					currentViewWidth        = -1;
86
	private int 					currentViewHeight       = -1;
87
	/**
88
	 * Ancho y alto de la imagen completa en pixeles
89
	 */
90
	@SuppressWarnings("unused")
91
	private int 					currentFullWidth        = -1;
92
	@SuppressWarnings("unused")
93
	private int 					currentFullHeight       = -1;
94
	private int 					overviewFullWidth       = -1;
95
	private int 					overviewFullHeight      = -1;
96
	/**
97
	 * Escala del viewport en X e Y
98
	 */
99
	private double                  viewportScaleX          = 0D;
100
	private double                  viewportScaleY          = 0D;
101
	/**
102
	 * ?ltimo extent de la ventana seleccionada por el usuario. Este extent corresponde al de la
103
	 * imagen, no al del viewport de la vista.
104
	 */
105
	private double[]				currentImageView        = new double[4];
106
	public int[]					stepArrayX              = null;
107
	public int[]					stepArrayY              = null;
108
	public boolean  				isSupersampling         = false;
109
	private String					fileName                = null;
110
	protected AffineTransform       ownTransformation       = null;
111
	protected AffineTransform       externalTransformation  = new AffineTransform();
112
	/**
113
	 *Array de transformaciones afines donde cada elemento es la transformaci�n correspondiente a una overview
114
	 */
115
	protected AffineTransform[]     overviewsTransformation = null;
116

  
117
	/**
118
	 * Constructor
119
	 * @param fName
120
	 * @throws MrSIDException
121
	 * @throws IOException
122
	 */
123
	public LizardTechNative(String fName) throws MrSIDException, IOException {
124
		super(fName);
125
		init(fName);
126
	}
127

  
128
	/**
129
	 * Inicializa las variables de instancia con los valores de la imagen
130
	 * @param fName
131
	 * @throws MrSIDException
132
	 * @throws IOException
133
	 */
134
	private void init(String fName) throws MrSIDException, IOException {
135
		this.initialize();
136

  
137
		fileName = fName;
138
		width = this.getWidth();
139
		height = this.getHeight();
140
		eSampleType = this.getDataType();
141
		nbands = this.getNumBands();
142
		//eColorSpace = this.getColorSpace();
143
		noverviews = this.getNumLevels();
144
		overviewsTransformation = new AffineTransform[noverviews];
145
		
146
		//Creamos una matriz de transformaci�n por nivel de overview con el factor de escala de esta overview
147
		overviewsTransformation[0] = new AffineTransform();
148
		int[] dims = this.getDimsAtMag(LTIUtils.levelToMag(0));
149
		int dimLastX = dims[0];
150
		int dimLastY = dims[1];
151
		for (int i = 1; i < noverviews; i++) {
152
			dims = this.getDimsAtMag(LTIUtils.levelToMag(i));
153
						
154
			double scaleFactorX = (double)dims[0] / (double)dimLastX;
155
			double scaleFactorY = (double)dims[1] / (double)dimLastY;
156
			//System.out.println("Over:" + i + " zoom:" + LTIUtils.levelToMag(i) + " dims:" + dims[0] + "X" + dims[1]);
157
			overviewsTransformation[i] = new AffineTransform(scaleFactorX, 0, 0, scaleFactorY, 0, 0);
158
		}
159
		
160
		metadata = this.getMetadata();
161

  
162
		double ox = 0D;
163
		double oy = 0D;
164
		double resx = 0D;
165
		double resy = 0D;
166

  
167
		LTIGeoCoord geoc = this.getGeoCoord();
168

  
169
		ox = geoc.getX();
170
		oy = geoc.getY();
171
		resx = geoc.getXRes();
172
		resy = geoc.getYRes();
173
		
174
    	ownTransformation = new AffineTransform(resx, 0, 0, resy, ox, oy);
175
    	externalTransformation = (AffineTransform)ownTransformation.clone();
176
		
177
		currentFullWidth = width;
178
		currentFullHeight = height;
179

  
180
		blocksize = this.getStripHeight();
181
		
182
		if(nbands == 1) {
183
			rBandNr = gBandNr = bBandNr = 1;
184
		}
185
		if(nbands == 2) {
186
			rBandNr = gBandNr = 1;
187
			bBandNr = 2;
188
		}
189
	}
190

  
191
	/**
192
	 * Asigna el valor de Alpha
193
	 * @param a        alpha
194
	 */
195
	public void setAlpha(int a) {
196
		alpha = a;
197
	}
198

  
199
	/**
200
	 * Asigna el tipo de datos
201
	 * @param dt        tipo de datos
202
	 */
203
	public void setDataType(int dt) {
204
		dataType = dt;
205
	}
206

  
207
	/**
208
	 * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
209
	 * del punto real.
210
	 * Supone rasters no girados
211
	 * @param pt	punto en coordenadas del punto real
212
	 * @return	punto en coordenadas del raster
213
	 */
214
	public Point2D worldToRaster(Point2D pt) {
215
		Point2D p = new Point2D.Double();
216
		try {
217
			externalTransformation.inverseTransform(pt, p);
218
		} catch (NoninvertibleTransformException e) {
219
			return pt;
220
		}
221
		return p;
222
	}
223
	
224
	/**
225
	 * Obtiene un punto del raster en coordenadas pixel a partir de un punto en coordenadas
226
	 * reales. 
227
	 * @param pt Punto en coordenadas reales
228
	 * @return Punto en coordenadas pixel.
229
	 */
230
	public Point2D rasterToWorld(Point2D pt) {
231
		Point2D p = new Point2D.Double();
232
		externalTransformation.transform(pt, p);
233
		return p;
234
	}
235

  
236
	/**
237
	 * Calcula el overview a usar de la imagen y el viewport a partir del ancho, alto y
238
	 * coordenadas del mundo real
239
	 * @param dWorldTLX        Coordenada X superior izquierda
240
	 * @param dWorldTLY        Coordenada Y superior izquierda
241
	 * @param dWorldBRX        Coordenada X inferior derecha
242
	 * @param dWorldBRY        Coordenada Y inferior derecha
243
	 * @param nWidth        ancho
244
	 * @param nHeight        alto
245
	 */
246
	public void setView(double ulx, double uly, double lrx, double lry, 
247
			int nWidth, int nHeight) {
248
		currentImageView[0] = ulx;
249
		currentImageView[1] = uly;
250
		currentImageView[2] = lrx;
251
		currentImageView[3] = lry;
252

  
253
		//Ancho y alto de la im�gen en pixeles (pixeles de la overview)
254
		overviewFullWidth = currentFullWidth = width;
255
		overviewFullHeight = currentFullHeight = height;
256

  
257
		//Ventana de la imagen. (en tama�o completo)
258
		//tl->esq sup izda en pixeles
259
		//br->esq inf der en pixeles
260
		Point2D a = worldToRaster(new Point2D.Double(ulx, uly));
261
		Point2D b = worldToRaster(new Point2D.Double(lrx, lry));
262
		Point2D tl = new Point2D.Double(Math.min(a.getX(), b.getX()), Math.min(a.getY(), b.getY()));
263
		Point2D br = new Point2D.Double(Math.max(a.getX(), b.getX()), Math.max(a.getY(), b.getY()));
264

  
265
		//Ancho y alto de la im�gen (pixeles en pantalla)
266
		currentViewWidth = nWidth;
267
		currentViewHeight = nHeight;
268

  
269
		//Posici�n de la esquina superior izquierda en coordenadas pixel
270
		currentViewX = tl.getX();
271
		currentViewY = tl.getY();
272

  
273
		//Escala de la vista en X e Y
274
		viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
275
		viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
276

  
277
		try {
278
			// calcula el overview a usar
279
			int[] dims = null;
280
			double zoom = 1.0;
281
			zoomoverview = 1.0;
282

  
283
			if (WITH_OVERVIEWS && ((noverviews - 1) > 0)) {
284
				for (int i = (noverviews - 1); i > 0; i--) {
285
					zoom = LTIUtils.levelToMag(i);
286
					dims = this.getDimsAtMag(zoom);
287

  
288
					if (dims[0] > (this.getWidth() * viewportScaleX)) {
289
						zoomoverview = zoom;
290
						viewportScaleX /= zoomoverview;
291
						viewportScaleY /= zoomoverview;
292
						overviewFullWidth = currentFullWidth = dims[0];
293
						overviewFullHeight = currentFullHeight = dims[1];
294
						tl = worldToRaster(new Point2D.Double(ulx, uly));
295
						br = worldToRaster(new Point2D.Double(lrx, lry));
296
						tl.setLocation(Math.min(tl.getX(), br.getX()), Math.min(tl.getY(), br.getY()));
297
						overviewsTransformation[i].transform(tl, tl);
298
						//Hemos asignado currentFull solo para calcular tl en relaci�n al tama�o de la overview
299
						currentFullWidth = width;
300
						currentFullHeight = height;
301
						currentViewX = tl.getX();
302
						currentViewY = tl.getY();
303
						break;
304
					}
305
				}
306
			}
307

  
308
			setDataType(eSampleType);
309
		} catch (MrSIDException e) {
310
			e.printStackTrace();
311
		}
312
	}
313

  
314
	/**
315
	 * Muestra alguna informaci�n para la depuraci�n
316
	 */
317
	void pintaInfo() {
318
		try {
319
			System.out.println("GeoTransform:");
320

  
321
			LTIGeoCoord geoc = this.getGeoCoord();
322

  
323
			System.out.println("  param[0]=" + geoc.getX());
324
			System.out.println("  param[0]=" + geoc.getY());
325
			System.out.println("  param[0]=" + geoc.getXRes());
326
			System.out.println("  param[0]=" + geoc.getYRes());
327
			System.out.println("  param[0]=" + geoc.getXRot());
328
			System.out.println("  param[0]=" + geoc.getYRot());
329
			System.out.println("Metadata:");
330

  
331
			LTIMetadataDatabase metadata = this.getMetadata();
332

  
333
			for (int i = 0; i < metadata.getIndexCount(); i++) {
334
				LTIMetadataRecord rec = null;
335
				rec = metadata.getDataByIndex(i);
336
				System.out.println(rec.getTagName());
337

  
338
				if (rec.isScalar()) {
339
					System.out.println(rec.getScalarData());
340
				} else if (rec.isVector()) {
341
					String[] s = rec.getVectorData();
342

  
343
					for (int j = 0; j < s.length; j++)
344
						System.out.println("V" + j + "->" + s[j]);
345
				} else if (rec.isArray()) {
346
					String[] s = rec.getArrayData();
347

  
348
					for (int j = 0; j < s.length; j++)
349
						System.out.println("A" + j + "->" + s[j]);
350
				} else {
351
					System.out.println("");
352
				}
353
			}
354
		} catch (MrSIDException e) {
355
			// TODO Auto-generated catch block
356
			e.printStackTrace();
357
		}
358
	}
359

  
360

  
361
	public LTISceneBuffer readBuffer(int x, int y, int SceneWidth, int SceneHeight)throws MrSIDException{
362
		LTISceneBuffer buffer = ((LTIImageStage) this).readScene((double)x, (double)y, (double)SceneWidth, (double)SceneHeight, zoomoverview, (MrSIDImageReader)this, SceneWidth, SceneHeight, true);
363
		return buffer;
364
	}
365

  
366
	
367

  
368
	/**
369
	 * Lee la escena de la imagen correspondiente a la vista seleccionada con
370
	 * currentView a trav�s de la libreria de MrSid. Esta escena es cargada sobre
371
	 * un buffer y asignada al par�metro de salida.
372
	 * @param line        Escena leida
373
	 * @throws MrSIDException Lanzada si ocurre un error en la lectura de la escena
374
	 */
375
	public void readScene(int[] line, RasterTask task) throws MrSIDException, ProcessInterruptedException {
376
		//Posici�n de inicio de la escena en entero para la petici�n a la libreria
377
		int x = (int) Math.floor(currentViewX);
378
		int y = (int) Math.floor(currentViewY);
379

  
380
		//Ancho y alto de la escena en pixeles
381
		int SceneWidth = 0;
382
		int SceneHeight = 0;
383

  
384
		SceneWidth = (int) Math.ceil((((double) currentViewWidth) / viewportScaleX) + 1);
385
		SceneHeight = (int) Math.ceil((((double) currentViewHeight) / viewportScaleY) + 1);
386

  
387
		while((x + SceneWidth) > overviewFullWidth)
388
			SceneWidth --;
389
		while((y + SceneHeight) > overviewFullHeight)
390
			SceneHeight --;
391

  
392
		if (SceneWidth == 0) 
393
			SceneWidth = 1;
394

  
395
		if (SceneHeight == 0)
396
			SceneHeight = 1;
397

  
398
		LTISceneBuffer buffer = null;
399
		buffer = ((LTIImageStage) this).readScene((double)x, (double)y, (double)SceneWidth, (double)SceneHeight, zoomoverview, (MrSIDImageReader)this, SceneWidth, SceneHeight, true);
400

  
401
		/*boolean  sizeOk = false;
402
			while (!sizeOk) {
403
				sizeOk = true;
404
				try {
405
					buffer = readBuffer(x, y, SceneWidth, SceneHeight);
406
				} catch (MrSIDException ex) {
407
					SceneWidth-- ;
408
					try{
409
						buffer = readBuffer(x, y, SceneWidth, SceneHeight);
410
					} catch (MrSIDException ex1) {
411
						SceneWidth++;
412
						SceneHeight--;
413
						try{
414
							buffer = readBuffer(x, y, SceneWidth, SceneHeight);
415
						} catch (MrSIDException ex2) {
416
							SceneWidth-- ;
417
							try{
418
								buffer = readBuffer(x, y, SceneWidth, SceneHeight);
419
							} catch (MrSIDException ex3) {
420
								sizeOk = false;
421
							}
422
						}
423
					}
424
				}
425
			}*/
426

  
427
		if(task.getEvent() != null)
428
			task.manageEvent(task.getEvent());
429

  
430
		if ((dataType == LTIDataType.LTI_DATATYPE_UINT8) ||
431
				(dataType == LTIDataType.LTI_DATATYPE_SINT8) ||
432
				(dataType == LTIDataType.LTI_DATATYPE_SINT16) ||
433
				(dataType == LTIDataType.LTI_DATATYPE_SINT32) ||
434
				(dataType == LTIDataType.LTI_DATATYPE_UINT16) ||
435
				(dataType == LTIDataType.LTI_DATATYPE_UINT32)) {
436
			int kd;
437
			int k;
438
			double scaleX = 1 / viewportScaleX;
439
			double scaleY = 1 / viewportScaleY;
440

  
441
			int alpha = (this.alpha & 0xff) << 24;
442

  
443
			if (rBandNr == 1) {
444
				bandR = buffer.buf1;
445
			} else if (rBandNr == 2) {
446
				bandR = buffer.buf2;
447
			} else if (rBandNr == 3) {
448
				bandR = buffer.buf3;
449
			}
450

  
451
			if (gBandNr == 1) {
452
				bandG = buffer.buf1;
453
			} else if (gBandNr == 2) {
454
				bandG = buffer.buf2;
455
			} else if (gBandNr == 3) {
456
				bandG = buffer.buf3;
457
			}
458

  
459
			if (bBandNr == 1) {
460
				bandB = buffer.buf1;
461
			} else if (bBandNr == 2) {
462
				bandB = buffer.buf2;
463
			} else if (bBandNr == 3) {
464
				bandB = buffer.buf3;
465
			}
466

  
467
			//Desplazamiento para la X y la Y leidas. Estas tienen efecto cuando un pixel no empieza a visualizarse
468
			//justo en su esquina superior izquierda y tiene que ser cortado en la visualizaci�n.
469
			double offsetX = Math.abs(currentViewX - ((int)currentViewX));
470
			double offsetY = Math.abs(currentViewY - ((int)currentViewY));
471

  
472
			for (int y1 = 0; y1 < currentViewHeight; y1++) {
473
				for (int x1 = 0; x1 < currentViewWidth; x1++) {
474
					kd = (y1 * currentViewWidth) + x1;
475
					k = (((int) ((y1 * scaleY) + offsetY)) * SceneWidth) + (int) ((x1 * scaleX) + offsetX);
476
					try {
477
						line[kd] = alpha + ((0xff & bandR[k]) << 16) + ((0xff & bandG[k]) << 8) + (0xff & bandB[k]);
478
					} catch (java.lang.ArrayIndexOutOfBoundsException e) {
479
					}
480
				}
481
				if(task.getEvent() != null)
482
					task.manageEvent(task.getEvent());
483
			}
484
		}
485

  
486
		buffer = null;
487
	}
488
	
489
	/**
490
	 * Reads a window of data. The size of the input window may not coincide 
491
	 * with the size of the buffer. In that case would have to resize
492
	 * @param buf
493
	 * @param bandList
494
	 * @param x
495
	 *        Initial X position in input buffer
496
	 * @param y
497
	 *        Initial Y position in input buffer
498
	 * @throws MrSIDException
499
	 * @throws ProcessInterruptedException
500
	 */
501
	public void readWindow(Buffer buf, 
502
			BandList bandList, 
503
			int x, int y, int w, int h, 
504
			int bufWidth, int bufHeight) throws MrSIDException, ProcessInterruptedException {
505
		if(bufWidth > buf.getWidth())
506
			bufWidth = buf.getWidth();
507
		
508
		if(bufHeight > buf.getHeight())
509
			bufHeight = buf.getHeight();
510
		
511
		if(buf.isCached()) {
512
			int nBlocks = (int)(bufHeight / buf.getBlockHeight());
513
			int lastBlock = bufHeight - (nBlocks * buf.getBlockHeight());
514
			int lastBlockSrc = (lastBlock * h) / bufHeight;
515
			int sizeBlockSrc = (buf.getBlockHeight() * h) / bufHeight;
516
			if(lastBlock > 0)
517
				nBlocks ++;
518
			int initSrc = y;
519
			int init = 0;
520
			for (int i = 0; i < nBlocks; i++) {
521
				if(lastBlock > 0 && i == (nBlocks - 1)) {
522
					double[] stepSrc = new double[]{x, initSrc, w, lastBlockSrc};
523
					int[] stepDst = new int[]{0, init, bufWidth, init + lastBlock};
524
					readWindowInMemory(buf, bandList, stepSrc, stepDst, w, lastBlock);
525
				} else {
526
					double[] stepSrc = new double[]{x, initSrc, w, sizeBlockSrc};
527
					int[] stepDst = new int[]{0, init, bufWidth, init + buf.getBlockHeight()};
528
					readWindowInMemory(buf, bandList, stepSrc, stepDst, w, buf.getBlockHeight());
529
					init += buf.getBlockHeight();
530
					initSrc += sizeBlockSrc;
531
				}
532
			}
533
		} else {
534
			readWindowInMemory(buf, bandList, x, y, w, h);
535
		}
536
	}
537
	
538
	/**
539
	 * Reads a window of data. The width and height is indicated by the size of the buffer 
540
	 * @param buf
541
	 * @param bandList
542
	 * @param x
543
	 *        Initial X position in input buffer
544
	 * @param y
545
	 *        Initial Y position in input buffer
546
	 * @throws MrSIDException
547
	 * @throws ProcessInterruptedException
548
	 */
549
	public void readWindow(Buffer buf, BandList bandList, int x, int y) throws MrSIDException, ProcessInterruptedException {
550
		int w = (x + buf.getWidth()) > getWidth() ? getWidth() - x : buf.getWidth();
551
		int h = (y + buf.getHeight()) > getHeight() ? getHeight() - y : buf.getHeight();
552
		
553
		if(buf.isCached()) {
554
			int nBlocks = (int)(buf.getHeight() / buf.getBlockHeight());
555
			int lastBlock = buf.getHeight() - (nBlocks * buf.getBlockHeight());
556
			if(lastBlock > 0)
557
				nBlocks ++;
558
			int initYSrc = y;
559
			int initYBuffer = 0;
560
			for (int i = 0; i < nBlocks; i++) {
561
				if(lastBlock > 0 && i == (nBlocks - 1)) {
562
					double[] stepSrc = new double[]{x, initYSrc, w, lastBlock};
563
					int[] stepDst = new int[]{0, initYBuffer, w, initYBuffer + lastBlock};
564
					readWindowInMemory(buf, bandList, stepSrc, stepDst, w, lastBlock);
565
				} else {
566
					double[] stepSrc = new double[]{x, initYSrc, w, buf.getBlockHeight()};
567
					int[] stepDst = new int[]{0, initYBuffer, w, initYBuffer + buf.getBlockHeight()};
568
					readWindowInMemory(buf, bandList, stepSrc, stepDst, w, buf.getBlockHeight());
569
					initYSrc += buf.getBlockHeight();
570
					initYBuffer += buf.getBlockHeight();
571
				}
572
			}
573
		} else {
574
			readWindowInMemory(buf, bandList, x, y, w, h);
575
		}
576
	}
577
	
578

  
579
	private void readWindowInMemory(Buffer buf, BandList bandList, double[] srcPxPos, int[] stepDst, int sizeSrcX, int sizeSrcY) throws MrSIDException, ProcessInterruptedException {
580
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
581
		
582
		isSupersampling = false;
583
	
584
		LTISceneBuffer buffer = ((LTIImageStage) this).readScene(
585
					srcPxPos[0], srcPxPos[1], srcPxPos[2], srcPxPos[3], 
586
					1.0, 
587
					(MrSIDImageReader)this, 
588
					sizeSrcX, sizeSrcY, 
589
					true);
590
		
591
		byte[] bandBuf = null;
592
		for(int iBand = 0; iBand < getNumBands(); iBand++) {
593
			int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
594
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
595
				continue;
596
			switch(iBand) {
597
			case 0:  bandBuf = buffer.buf1; break;
598
			case 1:  bandBuf = buffer.buf2; break;
599
			case 2:  bandBuf = buffer.buf3; break;
600
			}
601
			
602
			int lineSrc = 0;
603
			for (int line = stepDst[1]; line < stepDst[3]; line++) {
604
				int colSrc = 0;
605
				for (int col = stepDst[0]; col < stepDst[2]; col++) {
606
					int kd = (int)((lineSrc * srcPxPos[2]) + colSrc);
607
					buf.setElem(line, col, iBand, (byte)bandBuf[kd]);
608
					colSrc ++;
609
				}
610
				lineSrc ++;
611
				if(task.getEvent() != null)
612
					task.manageEvent(task.getEvent());
613
			}
614
		}
615
	}
616

  
617
	/**
618
	 * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
619
	 * @param buf Buffer donde se almacenan los datos
620
	 * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
621
	 * @param x Posici�n X en pixeles
622
	 * @param y Posici�n Y en pixeles
623
	 * @param w Ancho en pixeles
624
	 * @param h Alto en pixeles
625
	 */
626
	private void readWindowInMemory(Buffer buf, BandList bandList, int x, int y, int w, int h) throws MrSIDException, ProcessInterruptedException {
627
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
628
		
629
		isSupersampling = false;
630
	
631
		LTISceneBuffer buffer = ((LTIImageStage) this).readScene((double)x, (double)y, (double)w, (double)h, 1.0, (MrSIDImageReader)this, w, h, true);
632
		
633
		byte[] bandBuf = null;
634
		for(int iBand = 0; iBand < getNumBands(); iBand++) {
635
			int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
636
			if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
637
				continue;
638
			switch(iBand) {
639
			case 0:  bandBuf = buffer.buf1; break;
640
			case 1:  bandBuf = buffer.buf2; break;
641
			case 2:  bandBuf = buffer.buf3; break;
642
			}
643
			for (int line = 0; line < h; line++){
644
				for (int col = 0; col < w; col++){
645
					int kd = (line * w) + col;
646
					buf.setElem(line, col, iBand, (byte)bandBuf[kd]);
647
				}
648
				if(task.getEvent() != null)
649
					task.manageEvent(task.getEvent());
650
			}
651
		}
652
	}
653

  
654
	/**
655
	 * Lee una ventana de la imagen y devuelve un buffer de bytes
656
	 * @param ulX        Coordenada X de la esquina superior izquierda
657
	 * @param ulY        Coordenada Y de la esquina superior izquierda
658
	 * @param sizeX        Tama�o X de la imagen
659
	 * @param sizeY        Tama�o Y de la image
660
	 * @param band        N�mero de bandas
661
	 * @return        buffer con la ventana leida
662
	 * @throws MrSIDException
663
	 */
664
	public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band) throws MrSIDException {
665
		LTISceneBuffer buffer = ((LTIImageStage) this).readScene((double)ulX, (double)ulY, (double)sizeX, (double)sizeY, 1.0, (MrSIDImageReader)this, sizeX, sizeY, true);
666

  
667
		if (band == 1) {
668
			return buffer.buf1;
669
		} else if (band == 2) {
670
			return buffer.buf2;
671
		} else if (band == 3) {
672
			return buffer.buf3;
673
		}
674

  
675
		return null;
676
	}
677

  
678
	/**
679
	 * Obtiene el valor de un pixel determinado por las coordenadas x e y que se pasan
680
	 * por par�metro
681
	 * @param x Coordenada X del pixel
682
	 * @param y Coordenada Y del pixel
683
	 * @return Array de Object donde cada posici�n representa una banda y el valor ser� Integer
684
	 * en caso de ser byte, shot o int, Float en caso de ser float y Double en caso de ser double.
685
	 */
686
	public Object[] getData(int x, int y) {
687
		try {
688
			Object[] data = new Object[nbands];
689
			for(int i = 0; i < nbands; i++){
690
				byte[] b = getWindow(x, y, 1, 1, nbands);
691
				switch(dataType){
692
				case 0:	break;						
693
				case 1:	data[i] = new Integer(b[0]);
694
						break;
695
				case 2:								
696
				case 3:	data[i] = new Integer(b[0]);
697
						break;
698
				case 4:								
699
				case 5: data[i] = new Integer(b[0]);
700
						break;
701
				case 6:	data[i] = new Float(b[0]);
702
						break;
703
				case 7:	data[i] = new Double(b[0]);
704
						break;
705
				}
706
			}
707
			return data;
708
		} catch (MrSIDException e) {
709
			return null;
710
		}
711
	}
712
	
713
	/**
714
	 * Asigna una transformaci�n que es aplicada sobre la que ya tiene el propio fichero
715
	 * @param t
716
	 */
717
	public void setExternalTransform(AffineTransform t){
718
		externalTransformation = t;
719
	}
720
	
721
	/**
722
	 * Devuelve la transformaci�n del fichero de georreferenciaci�n
723
	 * @return AffineTransform
724
	 */
725
	public AffineTransform getOwnTransformation() {
726
		return ownTransformation;
727
	}
728
}
0 729

  
org.gvsig.raster.lizardtech/tags/buildNumber_27/org.gvsig.raster.lizardtech/org.gvsig.raster.lizardtech.io/src/main/java/org/gvsig/raster/lizardtech/io/LizardTechProvider.java
1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 2
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.lizardtech.io;
23

  
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.Point2D;
26
import java.awt.image.BufferedImage;
27

  
28
import org.gvsig.fmap.dal.DALFileLocator;
29
import org.gvsig.fmap.dal.DALLocator;
30
import org.gvsig.fmap.dal.DataStore;
31
import org.gvsig.fmap.dal.coverage.RasterLocator;
32
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
33
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
34
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
35
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
36
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
37
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
38
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
39
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
40
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
41
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
42
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
43
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
44
import org.gvsig.metadata.MetadataLocator;
45
import org.gvsig.raster.cache.tile.provider.TileListener;
46
import org.gvsig.raster.cache.tile.provider.TileServer;
47
import org.gvsig.raster.impl.datastruct.ExtentImpl;
48
import org.gvsig.raster.impl.process.RasterTask;
49
import org.gvsig.raster.impl.process.RasterTaskQueue;
50
import org.gvsig.raster.impl.provider.DefaultRasterProvider;
51
import org.gvsig.raster.impl.provider.RasterProvider;
52
import org.gvsig.raster.impl.provider.tile.FileTileServer;
53
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
54
import org.gvsig.raster.impl.store.DefaultStoreFactory;
55
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
56
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
57
import org.gvsig.tools.ToolsLocator;
58
import org.gvsig.tools.task.TaskStatus;
59

  
60
import es.gva.cit.jmrsid.MrSIDException;
61
/**
62
 * Clase encargada del acceso a los datos y repintado de imagenes MrSID. Estos
63
 * son registrados con la extensi?n sid
64
 *
65
 * @version 15/05/2008
66
 * @author Nacho Brodin (nachobrodin@gmail.com)
67
 */
68
public class LizardTechProvider extends DefaultRasterProvider {
69
	public static String                 NAME                     = "LizardTech Store";
70
	public static String                 DESCRIPTION              = "LizardTech Raster file";
71
	public static final String           METADATA_DEFINITION_NAME = "LizardTechStore";
72
	protected LizardTechNative           file                     = null;
73
	private Extent                       viewRequest              = null;
74
	private DataStoreColorInterpretation colorInterpr             = null;
75
	protected DataStoreTransparency      fileTransparency         = null;
76
	private boolean                      open                     = false;
77
	protected static String[]            formatList               = null;
78
	
79
	public static void register() {
80
		RasterLocator.getManager().registerFileProvidersTiled(LizardTechProvider.class);
81
		registerFormats();
82
		
83
		DataManagerProviderServices dataman = (DataManagerProviderServices) DALLocator.getDataManager();
84
		if (dataman != null && !dataman.getStoreProviders().contains(NAME)) {
85
			dataman.registerStoreProvider(NAME,
86
					LizardTechProvider.class, LizardTechDataParameters.class);
87
		}
88
		
89
		if(DALFileLocator.getFilesystemServerExplorerManager() != null)
90
			DALFileLocator.getFilesystemServerExplorerManager().registerProvider(
91
					NAME, DESCRIPTION,
92
					LizardTechFilesystemServerExplorer.class);
93
		
94
		dataman.registerStoreFactory(NAME, DefaultStoreFactory.class);
95
	}
96
	
97
	private static void registerFormats() {
98
		formatList      = new String[] {"sid"};
99
		for (int i = 0; i < formatList.length; i++) 
100
			RasterLocator.getManager().addFormat(formatList[i], LizardTechProvider.class);
101
	}
102
	
103
	/*
104
	 * (non-Javadoc)
105
	 * @see org.gvsig.raster.impl.provider.RasterProvider#getFormatList()
106
	 */
107
	public String[] getFormatList() {
108
		return formatList;
109
	}
110
	
111
	/**
112
	 * Returns true if the extension is supported and false if doesn't
113
	 * @param ext
114
	 * @return
115
	 */
116
	public boolean isExtensionSupported(String ext) {
117
		if(ext.indexOf(".") != -1)
118
			ext = ext.substring(ext.lastIndexOf(".") + 1, ext.length());
119
		for (int i = 0; i < formatList.length; i++) {
120
			if(formatList[i].compareTo(ext) == 0)
121
				return true;
122
		}
123
		return false;
124
	}
125
	
126
	/**
127
	 * Mandatory constructor to instantiate an empty provider
128
	 */
129
	public LizardTechProvider() {
130
	}
131
	
132
	/**
133
	 * Constructor. Abre el dataset.
134
	 * @param proj Proyecci?n
135
	 * @param fName Nombre del fichero ecw
136
	 * @throws NotSupportedExtensionException
137
	 */
138
	public LizardTechProvider(String params) throws NotSupportedExtensionException {
139
		super(params);
140
		if(params instanceof String) {
141
			LizardTechDataParameters p = new LizardTechDataParameters();
142
			p.setURI((String)params);
143
			super.init(p, null, ToolsLocator.getDynObjectManager()
144
					.createDynObject(
145
							MetadataLocator.getMetadataManager().getDefinition(
146
									DataStore.METADATA_DEFINITION_NAME)));
147
			init(p, null);
148
		}
149
	}
150
	
151
	public LizardTechProvider(LizardTechDataParameters params,
152
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
153
		super(params, storeServices, ToolsLocator.getDynObjectManager()
154
				.createDynObject(
155
						MetadataLocator.getMetadataManager().getDefinition(
156
								DataStore.METADATA_DEFINITION_NAME)));
157
		init(params, storeServices);
158
	}
159

  
160
	/**
161
	 * Contructor. Abre el fichero mrsid
162
	 * @param proj Proyecci?n
163
	 * @param fName Nombre del fichero mrsid
164
	 */
165
	public void init(AbstractRasterDataParameters params,
166
			DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
167
		setParam(storeServices, params);
168
		try {
169
			file = new LizardTechNative(params.getURI());
170
			load();
171
			bandCount = file.nbands;
172
			int[] dt = new int[bandCount];
173
			for (int i = 0; i < dt.length; i++)
174
				dt[i] = Buffer.TYPE_BYTE;
175
			setDataType(dt);
176
			super.init();
177

  
178
			try {
179
				loadFromRmf(getRmfBlocksManager());
180
			} catch (ParsingException e) {
181
				// No lee desde rmf
182
			}
183
		} catch (Exception e) {
184
			System.out.println("Error en constructor de MrSID");
185
			e.printStackTrace();
186
			file = null;
187
		}
188
		open = true;
189
	}
190

  
191
	/*
192
	 * (non-Javadoc)
193
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#load()
194
	 */
195
	public RasterProvider load() {
196
		ownTransformation = file.getOwnTransformation();
197
		externalTransformation = (AffineTransform) ownTransformation.clone();
198
		return this;
199
	}
200
	
201
	/*
202
	 * (non-Javadoc)
203
	 * @see org.gvsig.raster.impl.provider.RasterProvider#isOpen()
204
	 */
205
	public boolean isOpen() {
206
		return open;
207
	}
208

  
209
	/*
210
	 * (non-Javadoc)
211
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#close()
212
	 */
213
	public void close() {
214
		if (file != null) {
215
			file.close();
216
			file = null;
217
		}
218
		open = false;
219
	}
220

  
221
	/*
222
	 * (non-Javadoc)
223
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#setView(org.gvsig.fmap.dal.coverage.datastruct.Extent)
224
	 */
225
	public void setView(Extent e) {
226
		viewRequest = new ExtentImpl(e);
227
	}
228

  
229
	/*
230
	 * (non-Javadoc)
231
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getView()
232
	 */
233
	public Extent getView() {
234
		return viewRequest;
235
	}
236

  
237
	/*
238
	 * (non-Javadoc)
239
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWidth()
240
	 */
241
	public double getWidth() {
242
		return file.width;
243
	}
244

  
245
	/*
246
	 * (non-Javadoc)
247
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getHeight()
248
	 */
249
	public double getHeight() {
250
		return file.height;
251
	}
252

  
253
	/**
254
	 * Asigna al objeto Image los valores con los dato de la imagen contenidos en
255
	 * el vector de enteros.
256
	 * @param image imagen con los datos actuales
257
	 * @param startX inicio de la posici?n en X dentro de la imagen
258
	 * @param startY inicio de la posici?n en X dentro de la imagen
259
	 * @param w Ancho de la imagen
260
	 * @param h Alto de la imagen
261
	 * @param rgbArray vector que contiene la banda que se va a sustituir
262
	 * @param offset desplazamiento
263
	 * @param scansize tama?o de imagen recorrida por cada p
264
	 */
265
	protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h,
266
														int[] rgbArray, int offset, int scansize) {
267
		image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
268
	}
269

  
270
	/*
271
	 * (non-Javadoc)
272
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getData(int, int, int)
273
	 */
274
	public Object getData(int x, int y, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
275
		if (file != null) {
276
			if (x < 0 || y < 0 || x >= file.width || y >= file.height)
277
				throw new InvalidSetViewException("Request out of grid");
278
			Object[] data = file.getData(x, y);
279
			return data[band];
280
		}
281
		throw new FileNotOpenException("MrSIDNative not exist");
282
	}
283

  
284
	/*
285
	 * (non-Javadoc)
286
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getBlockSize()
287
	 */
288
	public int getBlockSize() {
289
		return file.blocksize;
290
	}
291

  
292
	/**
293
	 * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el
294
	 * driver el que colocar? el valor de esta variable cada vez que dibuja.
295
	 * @return true si se ha supersampleado y false si no se ha hecho.
296
	 */
297
	public boolean isSupersampling() {
298
		return file.isSupersampling;
299
	}
300
	
301
	/*
302
	 * (non-Javadoc)
303
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.raster.cache.tile.provider.TileListener)
304
	 */
305
	public void getWindow(Extent ex, int bufWidth, int bufHeight, 
306
			BandList bandList, TileListener listener, TaskStatus taskStatus)throws ProcessInterruptedException, RasterDriverException {
307
		 
308
	}
309

  
310
	/*
311
	 * (non-Javadoc)
312
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
313
	 */
314
	public Buffer getWindow(Extent ex, BandList bandList, Buffer rasterBuf, TaskStatus status) 
315
		throws ProcessInterruptedException, RasterDriverException {
316
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
317

  
318
		// TODO: FUNCIONALIDAD: Hacer caso del bandList
319
		int width = rasterBuf.getWidth();
320
		int height = rasterBuf.getHeight();
321

  
322
		// Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
323
		if (width <= 0)
324
			width = 1;
325

  
326
		if (height <= 0)
327
			height = 1;
328

  
329
		setView(ex);
330
		file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), width, height);
331

  
332
		int[] pRGBArray = new int[width * height];
333

  
334
		try {
335
			file.readScene(pRGBArray, task);
336
			loadBuffer(rasterBuf.getHeight(), rasterBuf.getWidth(), bandList, rasterBuf, pRGBArray);
337
		} catch (MrSIDException e) {
338
			throw new RasterDriverException("Error reading data");
339
		}
340
		return rasterBuf;
341
	}
342

  
343
	/*
344
	 * (non-Javadoc)
345
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
346
	 */
347
	public Buffer getWindow(double ulx, double uly, double w, double h, 
348
			BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
349
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
350

  
351
		// El incremento o decremento de las X e Y depende de los signos de rotaci?n
352
		// y escala en la matriz de transformaci?n. Por esto
353
		// tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o
354
		// y - h
355
		Extent ext = getExtent();
356
		Point2D pInit = rasterToWorld(new Point2D.Double(0, 0));
357
		Point2D pEnd = rasterToWorld(new Point2D.Double(getWidth(), getHeight()));
358
		double wRaster = Math.abs(pEnd.getX() - pInit.getX());
359
		double hRaster = Math.abs(pEnd.getY() - pInit.getY());
360
		double lrx = (((ext.getULX() - wRaster) > ext.maxX()) || ((ext.getULX() - wRaster) < ext.minX())) ? (ulx + w) : (ulx - w);
361
		double lry = (((ext.getULY() - hRaster) > ext.maxY()) || ((ext.getULY() - hRaster) < ext.minY())) ? (uly + h) : (uly - h);
362

  
363
		// TODO: FUNCIONALIDAD: Hacer caso del bandList
364
		int width = rasterBuf.getWidth();
365
		int height = rasterBuf.getHeight();
366

  
367
		// Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
368
		if (width <= 0)
369
			width = 1;
370

  
371
		if (height <= 0)
372
			height = 1;
373

  
374
		setView(new ExtentImpl(ulx, uly, lrx, lry));
375
		file.setView(viewRequest.minX(), viewRequest.maxY(), viewRequest.maxX(), viewRequest.minY(), width, height);
376

  
377
		int[] pRGBArray = new int[width * height];
378

  
379
		try {
380
			file.readScene(pRGBArray, task);
381
			loadBuffer(rasterBuf.getHeight(), rasterBuf.getWidth(), bandList, rasterBuf, pRGBArray);
382
		} catch (MrSIDException e) {
383
			throw new RasterDriverException("Error reading data");
384
		}
385
		return rasterBuf;
386
	}
387

  
388
	/*
389
	 * (non-Javadoc)
390
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(double, double, double, double, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer, boolean)
391
	 */
392
	public Buffer getWindow(Extent extent, int bufWidth, int bufHeight, 
393
			BandList bandList, Buffer rasterBuf, boolean adjustToExtent, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {
394
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
395

  
396
		// Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
397
		if (bufWidth <= 0)
398
			bufWidth = 1;
399

  
400
		if (bufHeight <= 0)
401
			bufHeight = 1;
402

  
403
		setView(extent);
404
		file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), bufWidth, bufHeight);
405

  
406
		int[] pRGBArray = new int[bufWidth * bufHeight];
407

  
408
		try {
409
			file.readScene(pRGBArray, task);
410
			loadBuffer(rasterBuf.getHeight(), rasterBuf.getWidth(), bandList, rasterBuf, pRGBArray);
411
		} catch (MrSIDException e) {
412
			throw new RasterDriverException("Error reading data");
413
		}
414
		return rasterBuf;
415
	}
416
	
417
//	private void loadCachedBuffer(	Buffer buf,
418
//									Extent inputWindow,
419
//									RasterTask task, 
420
//									int[] pRGBArray, 
421
//									BandList bandList) throws ProcessInterruptedException, MrSIDException {
422
//		if(buf.isCached()) {
423
//			Point2D blockHeightWC = rasterToWorld(new Point2D.Double(buf.getBlockHeight(), buf.getBlockHeight()));
424
//			int nBlocks = (int)(inputWindow.height() / blockHeightWC.getX());
425
//			double lastblockWC = inputWindow.height() - (nBlocks * blockHeightWC.getX());
426
//			int lastBlock = buf.getHeight() - (nBlocks * buf.getBlockHeight());
427
//			if(lastblockWC > 0)
428
//				nBlocks ++;
429
//			double init = inputWindow.getULY();
430
//			Extent ext = null;
431
//			for (int i = 0; i < nBlocks; i++) {
432
//				if(lastblockWC > 0 && i == (nBlocks - 1)) {
433
//					ext = RasterLocator.getManager().getDataStructFactory().createExtent(
434
//							inputWindow.getULX(), 
435
//							init, 
436
//							inputWindow.getLRX(), 
437
//							lastblockWC);
438
//					file.setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), buf.getBlockHeight());
439
//					file.readScene(pRGBArray, task);
440
//					loadPartialBuffer(new int[]{0, i * buf.getBlockHeight(), buf.getWidth(), buf.getHeight() }, 
441
//									bandList, 
442
//									buf, 
443
//									pRGBArray, 
444
//									buf.getWidth());
445
//				} else {
446
//					ext = RasterLocator.getManager().getDataStructFactory().createExtent(
447
//							inputWindow.getULX(), 
448
//							init, 
449
//							inputWindow.getLRX(), 
450
//							init - blockHeightWC.getX());
451
//					file.setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), lastBlock);
452
//					file.readScene(pRGBArray, task);
453
//					loadPartialBuffer(new int[]{0, i * buf.getBlockHeight(), buf.getWidth(), i * buf.getBlockHeight() + buf.getBlockHeight() }, 
454
//							bandList, 
455
//							buf, 
456
//							pRGBArray, 
457
//							buf.getWidth());
458
//					init += buf.getBlockHeight();
459
//				}
460
//			}
461
//		} else {
462
//			file.setView(inputWindow.getULX(), inputWindow.getULY(), inputWindow.getLRX(), inputWindow.getLRY(), buf.getWidth(), buf.getHeight());
463
//			file.readScene(pRGBArray, task);
464
//			loadBuffer(buf.getWidth(), buf.getHeight(), bandList, buf, pRGBArray);
465
//		}
466
//	}
467
//	
468
//	private void loadPartialBuffer(int[] stepBuffer, 
469
//			BandList bandList, 
470
//			Buffer rasterBuf, 
471
//			int[] pRGBArray, 
472
//			int bufWidth) throws ProcessInterruptedException {
473
//		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
474
//		int[] drawableBandsR = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 0);
475
//		int[] drawableBandsG = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 1);
476
//		int[] drawableBandsB = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 2);
477
//		int element = 0;
478
//		int rowSrc = 0;
479
//		
480
//		for (int row = stepBuffer[1]; row < stepBuffer[3]; row++) {
481
//			int colSrc = 0;
482
//			for (int col = stepBuffer[0]; col < stepBuffer[2]; col++) {
483
//				element = pRGBArray[(rowSrc * bufWidth) + colSrc];
484
//				if(drawableBandsR != null) {
485
//					for (int i = 0; i < drawableBandsR.length; i++) {
486
//						if(drawableBandsR[i] >= 0 && drawableBandsR[i] < rasterBuf.getBandCount())
487
//							rasterBuf.setElem(row, col, drawableBandsR[i], (byte) ((element & 0x00ff0000) >> 16));
488
//					}
489
//				}
490
//				if(drawableBandsG != null) {
491
//					for (int i = 0; i < drawableBandsG.length; i++) {
492
//						if(drawableBandsG[i] >= 0 && drawableBandsG[i] < rasterBuf.getBandCount())
493
//							rasterBuf.setElem(row, col, drawableBandsG[i], (byte) ((element & 0x0000ff00) >> 8));
494
//					}
495
//				}
496
//				if(drawableBandsB != null) {
497
//					for (int i = 0; i < drawableBandsB.length; i++) {
498
//						if(drawableBandsB[i] >= 0 && drawableBandsB[i] < rasterBuf.getBandCount())
499
//							rasterBuf.setElem(row, col, drawableBandsB[i], (byte) (element & 0x000000ff));
500
//					}
501
//				}
502
//				colSrc ++;
503
//			}
504
//			if (task.getEvent() != null)
505
//				task.manageEvent(task.getEvent());
506
//			rowSrc ++;
507
//		}	
508
//	}
509
	
510
	private void loadBuffer(int h, int w, BandList bandList, Buffer rasterBuf, int[] pRGBArray) throws ProcessInterruptedException {
511
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
512
		int[] drawableBandsR = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 0);
513
		int[] drawableBandsG = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 1);
514
		int[] drawableBandsB = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 2);
515
		int element = 0;
516
		
517
		for (int row = 0; row < h; row++) {
518
			for (int col = 0; col < w; col++) {
519
				element = pRGBArray[(row * w) + col];
520
				if(drawableBandsR != null) {
521
					for (int i = 0; i < drawableBandsR.length; i++) {
522
						if(drawableBandsR[i] >= 0 && drawableBandsR[i] < rasterBuf.getBandCount())
523
							rasterBuf.setElem(row, col, drawableBandsR[i], (byte) ((element & 0x00ff0000) >> 16));
524
					}
525
				}
526
				if(drawableBandsG != null) {
527
					for (int i = 0; i < drawableBandsG.length; i++) {
528
						if(drawableBandsG[i] >= 0 && drawableBandsG[i] < rasterBuf.getBandCount())
529
							rasterBuf.setElem(row, col, drawableBandsG[i], (byte) ((element & 0x0000ff00) >> 8));
530
					}
531
				}
532
				if(drawableBandsB != null) {
533
					for (int i = 0; i < drawableBandsB.length; i++) {
534
						if(drawableBandsB[i] >= 0 && drawableBandsB[i] < rasterBuf.getBandCount())
535
							rasterBuf.setElem(row, col, drawableBandsB[i], (byte) (element & 0x000000ff));
536
					}
537
				}
538
			}
539
			if (task.getEvent() != null)
540
				task.manageEvent(task.getEvent());
541
		}	
542
	}
543

  
544
	/*
545
	 * (non-Javadoc)
546
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWindowRaster(int, int, int, int, int, int, org.gvsig.fmap.dal.coverage.datastruct.BandList, org.gvsig.fmap.dal.coverage.dataset.Buffer)
547
	 */
548
	public Buffer getWindow(int x, int y, int w, int h, 
549
			BandList bandList, Buffer rasterBuf, TaskStatus status) throws ProcessInterruptedException, RasterDriverException {		
550
		try {
551
			file.readWindow(rasterBuf, bandList, x, y, w, h, rasterBuf.getWidth(), rasterBuf.getHeight());
552
		} catch (MrSIDException e) {
553
			throw new RasterDriverException("Error reading data");
554
		}
555
		return rasterBuf;
556
	}
557

  
558
	/*
559
	 * (non-Javadoc)
560
	 * @see org.gvsig.raster.impl.provider.RasterProvider#readBlock(int, int, double)
561
	 */
562
	public Object readBlock(int pos, int blockHeight, double scale) throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
563
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
564

  
565
		if (pos < 0)
566
			throw new InvalidSetViewException("Request out of grid");
567

  
568
		if ((pos + blockHeight) > file.height)
569
			blockHeight = Math.abs(file.height - pos);
570

  
571
		Point2D begin = rasterToWorld(new Point2D.Double(0, pos));
572
		Point2D end = rasterToWorld(new Point2D.Double(file.width, pos + blockHeight));
573

  
574
		int w = file.width;
575

  
576
		file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), w, blockHeight);
577

  
578
		int[] pRGBArray = new int[file.width * blockHeight];
579
		try {
580
			file.readScene(pRGBArray, task);
581
			byte[][][] buf = new byte[3][blockHeight][w];
582
			for (int row = 0; row < blockHeight; row++) {
583
				for (int col = 0; col < w; col++) {
584
					buf[0][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16);
585
					buf[1][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8);
586
					buf[2][row][col] = (byte) (pRGBArray[(row * w) + col] & 0x000000ff);
587
				}
588
				if (task.getEvent() != null)
589
					task.manageEvent(task.getEvent());
590
			}
591
			return buf;
592
		} catch (MrSIDException e) {
593
			throw new RasterDriverException("Error reading data");
594
		}
595
	}
596

  
597
	/**
598
	 * Read a line from the file
599
	 * @param line
600
	 * @param band
601
	 * @return
602
	 * @throws InvalidSetViewException
603
	 * @throws FileNotOpenException
604
	 * @throws RasterDriverException
605
	 * @Deprecated This operation is deprecated because is not useful and in the future
606
	 * it will not be maintained. The abstract operation has dissapear
607
	 */
608
	public Object readCompleteLine(int line, int band)
609
					throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
610
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
611

  
612
		if (line > this.getHeight() || band > this.getBandCount())
613
			throw new InvalidSetViewException("Request out of grid");
614

  
615
		try {
616
			Extent extent = getExtent();
617
			Point2D pt = rasterToWorld(new Point2D.Double(extent.minX(), line));
618
			file.setView(extent.minX(), pt.getY(), extent.maxX(), pt.getY(), (int)getWidth(), 1);
619
			int[] pRGBArray = new int[(int)getWidth()];
620
			file.readScene(pRGBArray, task);
621
			return pRGBArray;
622
		} catch (MrSIDException e) {
623
			throw new RasterDriverException("Error reading data from MrSID library");
624
		} catch (ProcessInterruptedException e) {
625
			// El proceso que debe ser interrumpido es el que llama a readLine.
626
		}
627
		return null;
628
	}
629

  
630
	/*
631
	 * (non-Javadoc)
632
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getTransparency()
633
	 */
634
	public DataStoreTransparency getTransparency() {
635
		if (fileTransparency == null)
636
			fileTransparency = new DataStoreTransparency();
637
		return fileTransparency;
638
	}
639

  
640
	/*
641
	 * (non-Javadoc)
642
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getColorInterpretation()
643
	 */
644
	public DataStoreColorInterpretation getColorInterpretation() {
645
		if (colorInterpr == null) {
646
			colorInterpr = new DataStoreColorInterpretation();
647
			colorInterpr.initColorInterpretation(getBandCount());
648
			if (getBandCount() == 1)
649
				colorInterpr.setColorInterpValue(0, DataStoreColorInterpretation.GRAY_BAND);
650
			if (getBandCount() >= 3) {
651
				colorInterpr.setColorInterpValue(0, DataStoreColorInterpretation.RED_BAND);
652
				colorInterpr.setColorInterpValue(1, DataStoreColorInterpretation.GREEN_BAND);
653
				colorInterpr.setColorInterpValue(2, DataStoreColorInterpretation.BLUE_BAND);
654
			}
655
		}
656
		return colorInterpr;
657
	}
658

  
659
	/*
660
	 * (non-Javadoc)
661
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getWktProjection()
662
	 */
663
	public String getWktProjection() {
664
		// System.err.println("======>" + file);
665
		return null;
666
	}
667

  
668
	/*
669
	 * (non-Javadoc)
670
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#setAffineTransform(java.awt.geom.AffineTransform)
671
	 */
672
	public void setAffineTransform(AffineTransform t) {
673
		super.setAffineTransform(t);
674
		file.setExternalTransform(t);
675
	}
676

  
677
	/*
678
	 * (non-Javadoc)
679
	 * @see org.gvsig.raster.impl.provider.RasterProvider#getOverviewCount(int)
680
	 */
681
	public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
682
		if (band >= getBandCount())
683
			throw new BandAccessException("Wrong band");
684
		try {
685
			return file.getNumLevels();
686
		} catch (MrSIDException e) {
687
			throw new RasterDriverException("");
688
		}
689
	}
690

  
691
	/*
692
	 * (non-Javadoc)
693
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getOverviewWidth(int, int)
694
	 */
695
	public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
696
		if (band >= getBandCount())
697
			throw new BandAccessException("Wrong band");
698
		return 0;
699
	}
700

  
701
	/*
702
	 * (non-Javadoc)
703
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#getOverviewHeight(int, int)
704
	 */
705
	public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
706
		if (band >= getBandCount())
707
			throw new BandAccessException("Wrong band");
708
		return 0;
709
	}
710

  
711
	/*
712
	 * (non-Javadoc)
713
	 * @see org.gvsig.raster.impl.provider.DefaultRasterProvider#isOverviewsSupported()
714
	 */
715
	public boolean isOverviewsSupported() {
716
		// No podemos escribir por lo que no podemos informar de que soporta overviews aunque el formato si lo haga.
717
		return false;
718
	}
719
	
720
	/*
721
	 * (non-Javadoc)
722
	 * @see org.gvsig.fmap.dal.spi.DataStoreProvider#getName()
723
	 */
724
	public String getName() {
725
		return NAME;
726
	}
727
	
728
	/*
729
	 * (non-Javadoc)
730
	 * @see org.gvsig.raster.impl.provider.RasterProvider#setStatus(org.gvsig.raster.impl.provider.RasterProvider)
731
	 */
732
	public void setStatus(RasterProvider provider) {
733
		if(provider instanceof LizardTechProvider) {
734
			//Not implemented yet
735
		}
736
	}
737
	
738
	/*
739
	 * (non-Javadoc)
740
	 * @see org.gvsig.raster.impl.provider.RasterProvider#getTileServer()
741
	 */
742
	public TileServer getTileServer() {
743
		if(tileServer == null)
744
			tileServer = new FileTileServer(this);
745
		return tileServer;
746
	}
747

  
748
}
0 749

  
... This diff was truncated because it exceeds the maximum size that can be displayed.

Also available in: Unified diff