Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / dataset / io / MrSidDriver.java @ 12767

History | View | Annotate | Download (15.2 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.BandList;
28
import org.gvsig.raster.dataset.FileNotOpenException;
29
import org.gvsig.raster.dataset.GeoInfo;
30
import org.gvsig.raster.dataset.IBuffer;
31
import org.gvsig.raster.dataset.InvalidSetViewException;
32
import org.gvsig.raster.dataset.RasterDataset;
33
import org.gvsig.raster.dataset.RasterDriverException;
34
import org.gvsig.raster.dataset.io.rmf.ParsingException;
35
import org.gvsig.raster.datastruct.Extent;
36
import org.gvsig.raster.datastruct.Transparency;
37
import org.gvsig.raster.util.extensionPoints.ExtensionPoints;
38
import org.gvsig.raster.util.extensionPoints.ExtensionPointsSingleton;
39

    
40
import es.gva.cit.jmrsid.MrSIDException;
41

    
42

    
43
/**
44
 * @author Nacho Brodin (nachobrodin@gmail.com)
45
 *
46
 * Clase encargada del acceso a los datos y repintado de imagenes MrSID. Estos
47
 * son registrados con la extensi?n sid
48
 */
49
public class MrSidDriver extends RasterDataset {
50
    public final static int BAND_HEIGHT = 64;
51

    
52
    protected MrSidNative file = null;
53
    private Extent viewRequest = null;
54
        /**
55
         * Estado de transparencia del raster.
56
         */
57
        protected Transparency                  fileTransparency = null;
58

    
59
    public static void register() {
60
                ExtensionPoints extensionPoints = ExtensionPointsSingleton.getInstance();
61
                extensionPoints.add("RasterReader", "sid", MrSidDriver.class);
62
        }
63
    
64
    /**
65
     * Contructor. Abre el fichero mrsid
66
     * @param proj        Proyecci?n
67
     * @param fName        Nombre del fichero mrsid
68
     */
69
    public MrSidDriver(IProjection proj, Object param) {
70
            super(proj, ((String)param));
71
            setParam(param);
72
        try {
73
            file = new MrSidNative(((String)param));
74
            load();
75
            bandCount = file.nbands;
76
            setDataType(IBuffer.TYPE_BYTE);
77
            super.init();
78
            
79
            try {
80
                             loadFromRmf(getRmfBlocksManager());
81
                     } catch (ParsingException e) {
82
                             //No lee desde rmf
83
                     }        
84
        } catch (Exception e) {
85
            System.out.println("Error en constructor de MrSID");
86
            e.printStackTrace();
87
            file = null;
88
        }
89
    }
90

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

    
100
    /**
101
     * Libera el objeto que ha abierto el fichero
102
     */
103
    public void close() {
104
            if(file != null){
105
                    file.close();
106
                    file = null;
107
            }
108
    }
109

    
110
    /**
111
     * Asigna el extent de la vista
112
     */
113
    public void setView(Extent e) {
114
            viewRequest = new Extent(e);
115
    }
116

    
117
    /**
118
     * Obtiene el Extent de la vista
119
     */
120
    public Extent getView() {
121
        return viewRequest;
122
    }
123

    
124
    /**
125
     * Obtiene el ancho de la imagen
126
     */
127
    public int getWidth() {
128
        return file.width;
129
    }
130

    
131
    /**
132
     * Obtiene el alto de la imagen
133
     */
134
    public int getHeight() {
135
        return file.height;
136
    }
137

    
138
    public void reProject(ICoordTrans rp) {
139
    }
140

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

    
159
    /* (non-Javadoc)
160
     * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
161
     */
162
    public Object getData(int x, int y, int band)throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
163
            if(file != null){
164
                        if(x < 0 || y < 0 || x >= file.width || y >= file.height)
165
                                throw new InvalidSetViewException("Request out of grid");
166
                        Object[] data = file.getData(x, y);
167
                        return data[band];
168
                }
169
                throw new FileNotOpenException("MrSIDNative not exist");
170
    }
171
   
172
    /**
173
     * Devuelve el tama?o de bloque
174
     * @return Tama?o de bloque
175
     */
176
    public int getBlockSize() {
177
        return file.blocksize;
178
    }
179
    
180
    /**
181
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
182
         * el valor de esta variable cada vez que dibuja. 
183
         * @return true si se ha supersampleado y false si no se ha hecho.
184
         */
185
        public boolean isSupersampling() {
186
                return file.isSupersampling;
187
        }
188

    
189
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, BandList bandList, IBuffer rasterBuf) {
190
                //TODO: FUNCIONALIDAD: Hacer caso del bandList
191
                int width = rasterBuf.getWidth();
192
                int height = rasterBuf.getHeight();
193
                                
194
                //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
195
        if (width <= 0) 
196
                width = 1;
197
        
198
        if (height <= 0) 
199
                height = 1;
200
        
201
        setView(new Extent(ulx, uly, lrx, lry));
202
                file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), width, height);
203
                
204
                int[] pRGBArray = new int[width * height];
205

    
206
        try {
207
                file.readScene(pRGBArray);
208
                int wBuf = rasterBuf.getWidth();
209
                for (int row = 0; row < rasterBuf.getHeight(); row++) {
210
                    for(int col = 0; col < wBuf; col ++) {
211
                            rasterBuf.setElem(row, col, 0, (byte)((pRGBArray[(row * wBuf) + col] & 0x00ff0000) >> 16));
212
                            rasterBuf.setElem(row, col, 1, (byte)((pRGBArray[(row * wBuf) + col] & 0x0000ff00) >> 8));
213
                            rasterBuf.setElem(row, col, 2, (byte)(pRGBArray[(row * wBuf) + col] & 0x000000ff));
214
                    }
215
                }
216
        } catch (Exception e) {
217
                e.printStackTrace();
218
        }
219
        return rasterBuf;
220
        }
221
        
222
        /*
223
         * (non-Javadoc)
224
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
225
         */
226
        public IBuffer getWindowRaster(double ulx, double uly, double w, double h, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {
227
                //El incremento o decremento de las X e Y depende de los signos de rotaci?n y escala en la matriz de transformaci?n. Por esto
228
                //tenemos que averiguar si lrx es x + w o x -w, asi como si lry es y + h o y - h 
229
                Extent ext = getExtent();
230
                Point2D pInit = rasterToWorld(new Point2D.Double(0, 0));
231
                Point2D pEnd = rasterToWorld(new Point2D.Double(getWidth(), getHeight()));
232
                double wRaster = Math.abs(pEnd.getX() - pInit.getX());
233
                double hRaster = Math.abs(pEnd.getY() - pInit.getY());
234
                double lrx = (((ext.getULX() - wRaster) > ext.maxX()) || ((ext.getULX() - wRaster) < ext.minX())) ? (ulx + w) : (ulx - w);
235
                double lry = (((ext.getULY() - hRaster) > ext.maxY()) || ((ext.getULY() - hRaster) < ext.minY())) ? (uly + h) : (uly - h); 
236
                
237
                //TODO: FUNCIONALIDAD: Hacer caso del bandList
238
                int width = rasterBuf.getWidth();
239
                int height = rasterBuf.getHeight();
240
                                
241
                //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
242
        if (width <= 0) 
243
                width = 1;
244
        
245
        if (height <= 0) 
246
                height = 1;
247
        
248
        setView(new Extent(ulx, uly, lrx, lry));
249
                file.setView(viewRequest.minX(), viewRequest.maxY(), viewRequest.maxX(), viewRequest.minY(), width, height);
250
                
251
                int[] pRGBArray = new int[width * height];
252

    
253
        try {
254
                file.readScene(pRGBArray);
255
                int wBuf = rasterBuf.getWidth();
256
                for (int row = 0; row < rasterBuf.getHeight(); row++) {
257
                    for(int col = 0; col < wBuf; col ++) {
258
                            rasterBuf.setElem(row, col, 0, (byte)((pRGBArray[(row * wBuf) + col] & 0x00ff0000) >> 16));
259
                            rasterBuf.setElem(row, col, 1, (byte)((pRGBArray[(row * wBuf) + col] & 0x0000ff00) >> 8));
260
                            rasterBuf.setElem(row, col, 2, (byte)(pRGBArray[(row * wBuf) + col] & 0x000000ff));
261
                    }
262
                }
263
        } catch (Exception e) {
264
                e.printStackTrace();
265
        }
266
        return rasterBuf;
267
        }
268

    
269
        /*
270
         * (non-Javadoc)
271
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(double, double, double, double, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer, boolean)
272
         */
273
        public IBuffer getWindowRaster(double ulx, double uly, double lrx, double lry, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf, boolean adjustToExtent) {
274
                //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
275
        if (bufWidth <= 0) 
276
                bufWidth = 1;
277
        
278
        if (bufHeight <= 0) 
279
                bufHeight = 1;
280
        
281
        setView(new Extent(ulx, uly, lrx, lry));
282
                file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), bufWidth, bufHeight);
283
                                        
284
        int[] pRGBArray = new int[bufWidth * bufHeight];
285

    
286
        try {
287
                file.readScene(pRGBArray);
288
                int w = rasterBuf.getWidth();
289
                for (int row = 0; row < rasterBuf.getHeight(); row++) {
290
                    for(int col = 0; col < w; col ++) {
291
                            rasterBuf.setElem(row, col, 0, (byte)((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16));
292
                            rasterBuf.setElem(row, col, 1, (byte)((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8));
293
                            rasterBuf.setElem(row, col, 2, (byte)(pRGBArray[(row * w) + col] & 0x000000ff));
294
                    }
295
                }
296
        } catch (Exception e) {
297
                e.printStackTrace();
298
        }
299
        return rasterBuf;
300
        }
301

    
302
        /*
303
         * (non-Javadoc)
304
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
305
         */
306
        public IBuffer getWindowRaster(int x, int y, int w, int h, int bufWidth, int bufHeight, BandList bandList, IBuffer rasterBuf) {
307
                //TODO: FUNCIONALIDAD: Hacer caso del bandList
308
                //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
309
        if (bufWidth <= 0) 
310
                bufWidth = 1;
311
        
312
        if (bufHeight <= 0) 
313
                bufHeight = 1;
314
        
315
                Point2D begin = rasterToWorld(new Point2D.Double(x, y));
316
                Point2D end = rasterToWorld(new Point2D.Double(x + w, y + h));
317
                
318
                file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), bufWidth, bufHeight);
319
                
320
                int[] pRGBArray = new int[bufWidth * bufHeight];
321
                try {
322
                file.readScene(pRGBArray);
323
                for (int row = 0; row < bufHeight; row++) {
324
                        for(int col = 0; col < bufWidth; col++) {
325
                                rasterBuf.setElem(row, col, 0, (byte)((pRGBArray[(row * bufWidth) + col] & 0x00ff0000) >> 16));
326
                                rasterBuf.setElem(row, col, 1, (byte)((pRGBArray[(row * bufWidth) + col] & 0x0000ff00) >> 8));
327
                                rasterBuf.setElem(row, col, 2, (byte)(pRGBArray[(row * bufWidth) + col] & 0x000000ff));
328
                    }
329
                }
330
        } catch (Exception e) {
331
                e.printStackTrace();
332
        }
333
                return rasterBuf;
334
        }
335

    
336
        /*
337
         *  (non-Javadoc)
338
         * @see org.gvsig.raster.dataset.RasterDataset#readBlock(int, int)
339
         */
340
        public Object readBlock(int pos, int blockHeight) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
341
                if(pos < 0)
342
                        throw new InvalidSetViewException("Request out of grid");
343
                
344
                if((pos + blockHeight) > file.height)
345
                        blockHeight = Math.abs(file.height - pos);
346
        
347
                Point2D begin = rasterToWorld(new Point2D.Double(0, pos));
348
                Point2D end = rasterToWorld(new Point2D.Double(file.width, pos + blockHeight));
349
                                
350
                int w = file.width;
351
                
352
                file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), w, blockHeight);
353
                
354
                int[] pRGBArray = new int[file.width * blockHeight];
355
                try {
356
                file.readScene(pRGBArray);
357
                byte[][][] buf = new byte[3][blockHeight][w];
358
                for (int row = 0; row < blockHeight; row++) {
359
                        for(int col = 0; col < w; col++) {
360
                            buf[0][row][col] = (byte)((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16);
361
                            buf[1][row][col] = (byte)((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8);
362
                            buf[2][row][col] = (byte)(pRGBArray[(row * w) + col] & 0x000000ff);
363
                    }
364
                }
365
                return buf;
366
        } catch (Exception e) {
367
                e.printStackTrace();
368
        }
369
        return null;
370
        }
371

    
372
        /*
373
         * (non-Javadoc)
374
         * @see org.gvsig.raster.dataset.RasterDataset#readCompleteLine(int, int)
375
         */
376
        public Object readCompleteLine(int line, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
377
                if(line > this.getHeight() || band > this.getBandCount())
378
                        throw new InvalidSetViewException("Request out of grid");
379
                
380
                try{
381
                        Extent extent = getExtent();
382
                        Point2D pt = rasterToWorld(new Point2D.Double(extent.minX(), line));
383
                        file.setView(extent.minX(), pt.getY(), extent.maxX(), pt.getY(), getWidth(), 1);
384
                        int[] pRGBArray = new int[getWidth()];
385
                        file.readScene(pRGBArray);
386
                        return pRGBArray;
387
                }catch(MrSIDException e){
388
                        throw new RasterDriverException("Error reading data from MrSID library");
389
                }
390
        }
391

    
392
        /*
393
         * (non-Javadoc)
394
         * @see org.gvsig.raster.dataset.RasterDataset#getWindowRaster(int, int, int, int, org.gvsig.raster.dataset.BandList, org.gvsig.raster.dataset.IBuffer)
395
         */
396
        public IBuffer getWindowRaster(int x, int y, int w, int h, BandList bandList, IBuffer rasterBuf) {
397
                try {
398
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
399
                } catch (Exception e) {
400
                        e.printStackTrace();
401
                        return null;
402
                }
403
                return rasterBuf;
404
        }
405
        
406
    /**
407
         * Obtiene el objeto que contiene el estado de la transparencia
408
         */
409
        public Transparency getTransparencyDatasetStatus() {
410
                if(fileTransparency == null)
411
                        fileTransparency = new Transparency();
412
                return fileTransparency;
413
        }
414
        
415
        /*
416
         * (non-Javadoc)
417
         * @see org.gvsig.raster.driver.GeoData#getStringProjection()
418
         */
419
        public String getWktProjection() throws RasterDriverException{
420
                //System.err.println("======>" + file);
421
                return null;
422
        }
423
        
424
        /*
425
         * (non-Javadoc)
426
         * @see org.gvsig.raster.dataset.RasterDataset#setAffineTransform(java.awt.geom.AffineTransform)
427
         */
428
        public void setAffineTransform(AffineTransform t){
429
                super.setAffineTransform(t);
430
                file.setExternalTransform(t);
431
        }
432
}