Statistics
| Revision:

root / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / MrSidDriver.java @ 22422

History | View | Annotate | Download (18 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.dataset.io;
20

    
21
import java.awt.geom.AffineTransform;
22
import java.awt.geom.Point2D;
23
import java.awt.image.BufferedImage;
24

    
25
import org.cresques.cts.ICoordTrans;
26
import org.cresques.cts.IProjection;
27
import org.gvsig.raster.dataset.BandAccessException;
28
import org.gvsig.raster.dataset.BandList;
29
import org.gvsig.raster.dataset.FileNotOpenException;
30
import org.gvsig.raster.dataset.GeoInfo;
31
import org.gvsig.raster.dataset.IBuffer;
32
import org.gvsig.raster.dataset.InvalidSetViewException;
33
import org.gvsig.raster.dataset.RasterDataset;
34
import org.gvsig.raster.dataset.io.rmf.ParsingException;
35
import org.gvsig.raster.dataset.properties.DatasetColorInterpretation;
36
import org.gvsig.raster.datastruct.Extent;
37
import org.gvsig.raster.datastruct.Transparency;
38
import org.gvsig.raster.process.RasterTask;
39
import org.gvsig.raster.process.RasterTaskQueue;
40
import org.gvsig.raster.util.extensionPoints.ExtensionPoint;
41

    
42
import es.gva.cit.jmrsid.MrSIDException;
43
/**
44
 * Clase encargada del acceso a los datos y repintado de imagenes MrSID. Estos
45
 * son registrados con la extensi?n sid
46
 * 
47
 * @version 15/05/2008
48
 * @author Nacho Brodin (nachobrodin@gmail.com)
49
 */
50
public class MrSidDriver extends RasterDataset {
51
        protected MrSidNative              file             = null;
52
        private Extent                     viewRequest      = null;
53
        private DatasetColorInterpretation colorInterpr     = null;
54

    
55
        /**
56
         * Estado de transparencia del raster.
57
         */
58
        protected Transparency             fileTransparency = null;
59

    
60
        public static void register() {
61
                ExtensionPoint point = ExtensionPoint.getExtensionPoint("RasterReader");
62
                point.register("sid", MrSidDriver.class);
63
        }
64
                
65
        /**
66
         * Contructor. Abre el fichero mrsid
67
         * @param proj Proyecci?n
68
         * @param fName Nombre del fichero mrsid
69
         */
70
        public MrSidDriver(IProjection proj, Object param) {
71
                super(proj, ((String) param));
72
                setParam(param);
73
                try {
74
                        file = new MrSidNative(((String) param));
75
                        load();
76
                        bandCount = file.nbands;
77
                        int[] dt = new int[bandCount];
78
                        for (int i = 0; i < dt.length; i++)
79
                                dt[i] = IBuffer.TYPE_BYTE;
80
                        setDataType(dt);
81
                        super.init();
82

    
83
                        try {
84
                                loadFromRmf(getRmfBlocksManager());
85
                        } catch (ParsingException e) {
86
                                // No lee desde rmf
87
                        }
88
                } catch (Exception e) {
89
                        System.out.println("Error en constructor de MrSID");
90
                        e.printStackTrace();
91
                        file = null;
92
                }
93
        }
94

    
95
        /**
96
         * Obtenemos o calculamos el extent de la imagen.
97
         */
98
        public GeoInfo load() {
99
                ownTransformation = file.getOwnTransformation();
100
                externalTransformation = (AffineTransform) ownTransformation.clone();
101
                return this;
102
        }
103

    
104
        /**
105
         * Libera el objeto que ha abierto el fichero
106
         */
107
        public void close() {
108
                if (file != null) {
109
                        file.close();
110
                        file = null;
111
                }
112
        }
113

    
114
        /**
115
         * Asigna el extent de la vista
116
         */
117
        public void setView(Extent e) {
118
                viewRequest = new Extent(e);
119
        }
120

    
121
        /**
122
         * Obtiene el Extent de la vista
123
         */
124
        public Extent getView() {
125
                return viewRequest;
126
        }
127

    
128
        /**
129
         * Obtiene el ancho de la imagen
130
         */
131
        public int getWidth() {
132
                return file.width;
133
        }
134

    
135
        /**
136
         * Obtiene el alto de la imagen
137
         */
138
        public int getHeight() {
139
                return file.height;
140
        }
141

    
142
        public void reProject(ICoordTrans rp) {}
143

    
144
        /**
145
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en
146
         * el vector de enteros.
147
         * @param image imagen con los datos actuales
148
         * @param startX inicio de la posici?n en X dentro de la imagen
149
         * @param startY inicio de la posici?n en X dentro de la imagen
150
         * @param w Ancho de la imagen
151
         * @param h Alto de la imagen
152
         * @param rgbArray vector que contiene la banda que se va a sustituir
153
         * @param offset desplazamiento
154
         * @param scansize tama?o de imagen recorrida por cada p
155
         */
156
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h,
157
                                                                                                                int[] rgbArray, int offset, int scansize) {
158
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
159
        }
160

    
161
        /*
162
         * (non-Javadoc)
163
         * @see org.gvsig.raster.dataset.RasterDataset#getData(int, int, int)
164
         */
165
        public Object getData(int x, int y, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
166
                if (file != null) {
167
                        if (x < 0 || y < 0 || x >= file.width || y >= file.height)
168
                                throw new InvalidSetViewException("Request out of grid");
169
                        Object[] data = file.getData(x, y);
170
                        return data[band];
171
                }
172
                throw new FileNotOpenException("MrSIDNative not exist");
173
        }
174
         
175
        /**
176
         * Devuelve el tama?o de bloque
177
         * @return Tama?o de bloque
178
         */
179
        public int getBlockSize() {
180
                return file.blocksize;
181
        }
182

    
183
        /**
184
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el
185
         * driver el que colocar? el valor de esta variable cada vez que dibuja.
186
         * @return true si se ha supersampleado y false si no se ha hecho.
187
         */
188
        public boolean isSupersampling() {
189
                return file.isSupersampling;
190
        }
191

    
192
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry,
193
                                                                                                                                        BandList bandList, IBuffer rasterBuf)
194
                                                                                                                                        throws InterruptedException, RasterDriverException {
195
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
196

    
197
                // TODO: FUNCIONALIDAD: Hacer caso del bandList
198
                int width = rasterBuf.getWidth();
199
                int height = rasterBuf.getHeight();
200

    
201
                // Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
202
                if (width <= 0)
203
                        width = 1;
204

    
205
                if (height <= 0)
206
                        height = 1;
207

    
208
                setView(new Extent(ulx, uly, lrx, lry));
209
                file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), width, height);
210

    
211
                int[] pRGBArray = new int[width * height];
212

    
213
                try {
214
                        file.readScene(pRGBArray, task);
215
                        int wBuf = rasterBuf.getWidth();
216
                        for (int row = 0; row < rasterBuf.getHeight(); row++) {
217
                                for (int col = 0; col < wBuf; col++) {
218
                                        rasterBuf.setElem(row, col, 0, (byte) ((pRGBArray[(row * wBuf) + col] & 0x00ff0000) >> 16));
219
                                        rasterBuf.setElem(row, col, 1, (byte) ((pRGBArray[(row * wBuf) + col] & 0x0000ff00) >> 8));
220
                                        rasterBuf.setElem(row, col, 2, (byte) (pRGBArray[(row * wBuf) + col] & 0x000000ff));
221
                                }
222
                                if (task.getEvent() != null)
223
                                        task.manageEvent(task.getEvent());
224
                        }
225
                } catch (MrSIDException e) {
226
                        throw new RasterDriverException("Error reading data");
227
                }
228
                return rasterBuf;
229
        }
230
        
231
        /*
232
         * (non-Javadoc)
233
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
234
         */
235
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) throws InterruptedException, RasterDriverException {
236
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
237

    
238
                // El incremento o decremento de las X e Y depende de los signos de rotaci?n
239
                // y escala en la matriz de transformaci?n. Por esto
240
                // tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o
241
                // y - h
242
                Extent ext = getExtent();
243
                Point2D pInit = rasterToWorld(new Point2D.Double(0, 0));
244
                Point2D pEnd = rasterToWorld(new Point2D.Double(getWidth(), getHeight()));
245
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
246
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
247
                double lrx = (((ext.getULX() - wRaster) > ext.maxX()) || ((ext.getULX() - wRaster) < ext.minX())) ? (ulx + w) : (ulx - w);
248
                double lry = (((ext.getULY() - hRaster) > ext.maxY()) || ((ext.getULY() - hRaster) < ext.minY())) ? (uly + h) : (uly - h);
249

    
250
                // TODO: FUNCIONALIDAD: Hacer caso del bandList
251
                int width = rasterBuf.getWidth();
252
                int height = rasterBuf.getHeight();
253

    
254
                // Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
255
                if (width <= 0)
256
                        width = 1;
257

    
258
                if (height <= 0)
259
                        height = 1;
260

    
261
                setView(new Extent(ulx, uly, lrx, lry));
262
                file.setView(viewRequest.minX(), viewRequest.maxY(), viewRequest.maxX(), viewRequest.minY(), width, height);
263

    
264
                int[] pRGBArray = new int[width * height];
265

    
266
                try {
267
                        file.readScene(pRGBArray, task);
268
                        int wBuf = rasterBuf.getWidth();
269
                        for (int row = 0; row < rasterBuf.getHeight(); row++) {
270
                                for (int col = 0; col < wBuf; col++) {
271
                                        rasterBuf.setElem(row, col, 0, (byte) ((pRGBArray[(row * wBuf) + col] & 0x00ff0000) >> 16));
272
                                        rasterBuf.setElem(row, col, 1, (byte) ((pRGBArray[(row * wBuf) + col] & 0x0000ff00) >> 8));
273
                                        rasterBuf.setElem(row, col, 2, (byte) (pRGBArray[(row * wBuf) + col] & 0x000000ff));
274
                                }
275
                                if (task.getEvent() != null)
276
                                        task.manageEvent(task.getEvent());
277
                        }
278
                } catch (MrSIDException e) {
279
                        throw new RasterDriverException("Error reading data");
280
                }
281
                return rasterBuf;
282
        }
283

    
284
        /*
285
         * (non-Javadoc)
286
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
287
         */
288
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) throws InterruptedException, RasterDriverException {
289
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
290

    
291
                // Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
292
                if (bufWidth <= 0)
293
                        bufWidth = 1;
294

    
295
                if (bufHeight <= 0)
296
                        bufHeight = 1;
297

    
298
                setView(new Extent(ulx, uly, lrx, lry));
299
                file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), bufWidth, bufHeight);
300

    
301
                int[] pRGBArray = new int[bufWidth * bufHeight];
302

    
303
                try {
304
                        file.readScene(pRGBArray, task);
305
                        int w = rasterBuf.getWidth();
306
                        for (int row = 0; row < rasterBuf.getHeight(); row++) {
307
                                for (int col = 0; col < w; col++) {
308
                                        rasterBuf.setElem(row, col, 0, (byte) ((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16));
309
                                        rasterBuf.setElem(row, col, 1, (byte) ((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8));
310
                                        rasterBuf.setElem(row, col, 2, (byte) (pRGBArray[(row * w) + col] & 0x000000ff));
311
                                }
312
                                if (task.getEvent() != null)
313
                                        task.manageEvent(task.getEvent());
314
                        }
315
                } catch (MrSIDException e) {
316
                        throw new RasterDriverException("Error reading data");
317
                }
318
                return rasterBuf;
319
        }
320

    
321
        /*
322
         * (non-Javadoc)
323
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
324
         */
325
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf) throws InterruptedException, RasterDriverException {
326
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
327

    
328
                // TODO: FUNCIONALIDAD: Hacer caso del bandList
329
                // Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
330
                if (bufWidth <= 0)
331
                        bufWidth = 1;
332

    
333
                if (bufHeight <= 0)
334
                        bufHeight = 1;
335

    
336
                Point2D begin = rasterToWorld(new Point2D.Double(x, y));
337
                Point2D end = rasterToWorld(new Point2D.Double(x + w, y + h));
338

    
339
                file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), bufWidth, bufHeight);
340

    
341
                int[] pRGBArray = new int[bufWidth * bufHeight];
342
                try {
343
                        file.readScene(pRGBArray, task);
344
                        for (int row = 0; row < bufHeight; row++) {
345
                                for (int col = 0; col < bufWidth; col++) {
346
                                        rasterBuf.setElem(row, col, 0, (byte) ((pRGBArray[(row * bufWidth) + col] & 0x00ff0000) >> 16));
347
                                        rasterBuf.setElem(row, col, 1, (byte) ((pRGBArray[(row * bufWidth) + col] & 0x0000ff00) >> 8));
348
                                        rasterBuf.setElem(row, col, 2, (byte) (pRGBArray[(row * bufWidth) + col] & 0x000000ff));
349
                                }
350
                                if (task.getEvent() != null)
351
                                        task.manageEvent(task.getEvent());
352
                        }
353
                } catch (MrSIDException e) {
354
                        throw new RasterDriverException("Error reading data");
355
                }
356
                return rasterBuf;
357
        }
358

    
359
        /*
360
         * (non-Javadoc)
361
         * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int)
362
         */
363
        public Object readBlock(int pos, int blockHeight) throws InvalidSetViewException, FileNotOpenException, RasterDriverException, InterruptedException {
364
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
365

    
366
                if (pos < 0)
367
                        throw new InvalidSetViewException("Request out of grid");
368

    
369
                if ((pos + blockHeight) > file.height)
370
                        blockHeight = Math.abs(file.height - pos);
371

    
372
                Point2D begin = rasterToWorld(new Point2D.Double(0, pos));
373
                Point2D end = rasterToWorld(new Point2D.Double(file.width, pos + blockHeight));
374

    
375
                int w = file.width;
376

    
377
                file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), w, blockHeight);
378

    
379
                int[] pRGBArray = new int[file.width * blockHeight];
380
                try {
381
                        file.readScene(pRGBArray, task);
382
                        byte[][][] buf = new byte[3][blockHeight][w];
383
                        for (int row = 0; row < blockHeight; row++) {
384
                                for (int col = 0; col < w; col++) {
385
                                        buf[0][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16);
386
                                        buf[1][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8);
387
                                        buf[2][row][col] = (byte) (pRGBArray[(row * w) + col] & 0x000000ff);
388
                                }
389
                                if (task.getEvent() != null)
390
                                        task.manageEvent(task.getEvent());
391
                        }
392
                        return buf;
393
                } catch (MrSIDException e) {
394
                        throw new RasterDriverException("Error reading data");
395
                }
396
        }
397

    
398
        /*
399
         * (non-Javadoc)
400
         * @see org.gvsig.raster.dataset.RasterDataset#readCompleteLine(int, int)
401
         */
402
        public Object readCompleteLine(int line, int band)
403
                                        throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
404
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
405

    
406
                if (line > this.getHeight() || band > this.getBandCount())
407
                        throw new InvalidSetViewException("Request out of grid");
408

    
409
                try {
410
                        Extent extent = getExtent();
411
                        Point2D pt = rasterToWorld(new Point2D.Double(extent.minX(), line));
412
                        file.setView(extent.minX(), pt.getY(), extent.maxX(), pt.getY(), getWidth(), 1);
413
                        int[] pRGBArray = new int[getWidth()];
414
                        file.readScene(pRGBArray, task);
415
                        return pRGBArray;
416
                } catch (MrSIDException e) {
417
                        throw new RasterDriverException("Error reading data from MrSID library");
418
                } catch (InterruptedException e) {
419
                        // El proceso que debe ser interrumpido es el que llama a readLine.
420
                }
421
                return null;
422
        }
423

    
424
        /*
425
         * (non-Javadoc)
426
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
427
         */
428
        public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf) throws InterruptedException, RasterDriverException {
429
                try {
430
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
431
                } catch (MrSIDException e) {
432
                        throw new RasterDriverException("Error reading data");
433
                }
434
                return rasterBuf;
435
        }
436
        
437
        /**
438
         * Obtiene el objeto que contiene el estado de la transparencia
439
         */
440
        public Transparency getTransparencyDatasetStatus() {
441
                if (fileTransparency == null)
442
                        fileTransparency = new Transparency();
443
                return fileTransparency;
444
        }
445

    
446
        /**
447
         * Obtiene el objeto que contiene que contiene la interpretaci?n de color por banda
448
         * @return
449
         */
450
        public DatasetColorInterpretation getColorInterpretation() {
451
                if (colorInterpr == null) {
452
                        colorInterpr = new DatasetColorInterpretation();
453
                        colorInterpr.initColorInterpretation(getBandCount());
454
                        if (getBandCount() == 1)
455
                                colorInterpr.setColorInterpValue(0, DatasetColorInterpretation.GRAY_BAND);
456
                        if (getBandCount() >= 3) {
457
                                colorInterpr.setColorInterpValue(0, DatasetColorInterpretation.RED_BAND);
458
                                colorInterpr.setColorInterpValue(1, DatasetColorInterpretation.GREEN_BAND);
459
                                colorInterpr.setColorInterpValue(2, DatasetColorInterpretation.BLUE_BAND);
460
                        }
461
                }
462
                return colorInterpr;
463
        }
464

    
465
        /**
466
         * Asigna el objeto que contiene que contiene la interpretaci?n de color por banda
467
         * @param DatasetColorInterpretation
468
         */
469
        public void setColorInterpretation(DatasetColorInterpretation colorInterpretation) {
470
                this.colorInterpretation = colorInterpretation;
471
        }
472

    
473
        /*
474
         * (non-Javadoc)
475
         * @see org.gvsig.raster.dataset.GeoInfo#getWktProjection()
476
         */
477
        public String getWktProjection() {
478
                // System.err.println("======>" + file);
479
                return null;
480
        }
481
        
482
        /*
483
         * (non-Javadoc)
484
         * @see org.gvsig.raster.dataset.GeoInfo#setAffineTransform(java.awt.geom.AffineTransform)
485
         */
486
        public void setAffineTransform(AffineTransform t) {
487
                super.setAffineTransform(t);
488
                file.setExternalTransform(t);
489
        }
490
        
491
        /*
492
         * (non-Javadoc)
493
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewCount(int)
494
         */
495
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
496
                if (band >= getBandCount())
497
                        throw new BandAccessException("Wrong band");
498
                try {
499
                        return file.getNumLevels();
500
                } catch (MrSIDException e) {
501
                        throw new RasterDriverException("");
502
                }
503
        }
504
        
505
        /*
506
         * (non-Javadoc)
507
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewWidth(int, int)
508
         */
509
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
510
                if (band >= getBandCount())
511
                        throw new BandAccessException("Wrong band");
512
                return 0;
513
        }
514

    
515
        /*
516
         * (non-Javadoc)
517
         * @see org.gvsig.raster.dataset.RasterDataset#getOverviewHeight(int, int)
518
         */
519
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
520
                if (band >= getBandCount())
521
                        throw new BandAccessException("Wrong band");
522
                return 0;
523
        }
524
        
525
        /*
526
         * (non-Javadoc)
527
         * @see org.gvsig.raster.dataset.RasterDataset#overviewsSupport()
528
         */
529
        public boolean overviewsSupport() {
530
                // No podemos escribir por lo que no podemos informar de que soporta overviews aunque el formato si lo haga.
531
                return false;
532
        }
533
}