Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1008 / libraries / libCq_CMS_praster / src / org / cresques / io / MrSidFile.java @ 12520

History | View | Annotate | Download (38.6 KB)

1
/*
2
 * Cresques Mapping Suite. Graphic Library for constructing mapping applications.
3
 *
4
 * Copyright (C) 2004-5.
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., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
19
 *
20
 * For more information, contact:
21
 *
22
 * cresques@gmail.com
23
 */
24
package org.cresques.io;
25

    
26
import java.awt.Image;
27
import java.awt.geom.Point2D;
28
import java.awt.image.BufferedImage;
29
import java.io.IOException;
30
import java.util.Vector;
31

    
32
import org.cresques.cts.ICoordTrans;
33
import org.cresques.cts.IProjection;
34
import org.cresques.io.MrSidNative.Contour;
35
import org.cresques.io.data.BandList;
36
import org.cresques.io.data.RasterBuf;
37
import org.cresques.io.exceptions.SupersamplingNotSupportedException;
38
import org.cresques.px.Extent;
39

    
40
import es.gva.cit.jgdal.GdalBuffer;
41
import es.gva.cit.jgdal.GdalException;
42
import es.gva.cit.jgdal.GdalRasterBand;
43
import es.gva.cit.jmrsid.LTIColorSpace;
44
import es.gva.cit.jmrsid.LTIDataType;
45
import es.gva.cit.jmrsid.LTIGeoCoord;
46
import es.gva.cit.jmrsid.LTIImageStage;
47
import es.gva.cit.jmrsid.LTIMetadataDatabase;
48
import es.gva.cit.jmrsid.LTIMetadataRecord;
49
import es.gva.cit.jmrsid.LTIPixel;
50
import es.gva.cit.jmrsid.LTIScene;
51
import es.gva.cit.jmrsid.LTISceneBuffer;
52
import es.gva.cit.jmrsid.LTIUtils;
53
import es.gva.cit.jmrsid.MrSIDException;
54
import es.gva.cit.jmrsid.MrSIDImageReader;
55

    
56

    
57
/**
58
 * Soporte para los fichero MrSID de Lizardtech
59
 * @author Nacho Brodin (brodin_ign@gva.es)
60
 */
61
class MrSidNative extends MrSIDImageReader {
62
    static boolean WITH_OVERVIEWS = true;
63

    
64
    /**
65
     * Contorno en coordenadas geogr?ficas. (y Extent del raster).
66
     */
67
    public Contour                                         esq = new Contour();
68
    public int                                                 width = 0;
69
    public int                                                 height = 0;
70
    public double                                         originX = 0D;
71
    public double                                         originY = 0D;
72
    public String                                         version = "";
73
    public LTIMetadataDatabase                 metadata;
74
    public LTIPixel                                 pixel = null;
75
    private int                                         alpha = 0;
76
    protected int                                         rBandNr = 1;
77
    protected int                                         gBandNr = 2;
78
    protected int                                         bBandNr = 3;
79
    protected byte[]                                 bandR;
80
    protected byte[]                                 bandG;
81
    protected byte[]                                 bandB;
82
    private int                                         dataType = LTIDataType.LTI_DATATYPE_UINT8;
83

    
84
    //View
85
    private double                                         zoomoverview = 0.0;
86
    private int                                         eColorSpace;
87
    private int                                         eSampleType;
88
    private int                                         noverviews;
89
    public int                                                 xini;
90
    public int                                                 yini;
91
    /**
92
     * Ancho y alto de la overview
93
     */
94
    public int                                                 anchoOver;
95
    public int                                                 altoOver;
96
    public int                                                 blocksize = 1;
97
    /**
98
     * N?mero de bandas de la imagen
99
     */
100
    public int                                                 nbands;
101
    /**
102
     * N?mero de overview actualmente seleccionada
103
     */
104
    private int                                         currentOverview = -1;
105
    /**
106
     * Posici?n de la esquina superior izquierda en coordenadas pixel
107
     */
108
    private double                                         currentViewY = -1;
109
    private double                                         currentViewX = 0D;
110
    /**
111
     * Ancho y alto de la im?gen (pixeles en pantalla)
112
     */
113
    private int                                         currentViewWidth = -1;
114
    private int                                         currentViewHeight = -1;
115
    /**
116
     * Ancho y alto de la imagen completa en pixeles
117
     */
118
    private int                                         currentFullWidth = -1;
119
    private int                                         currentFullHeight = -1;
120
    /**
121
     * Escala del viewport en X e Y
122
     */
123
    private double                                         viewportScaleX = 0D;
124
    private double                                         viewportScaleY = 0D;
125
    /**
126
     * ?ltimo extent de la ventana seleccionada por el usuario. Este extent corresponde al de la
127
     * imagen, no al del viewport de la vista.
128
     */
129
    private double[]                                currentImageView = new double[4];
130
    /**
131
     * 
132
     */
133
        public int[]                                        stepArrayX = null, stepArrayY = null;
134
        /**
135
         * 
136
         */
137
        public boolean                                  isSupersampling = false;
138
        /**
139
         * Nombre del fichero MrSID
140
         */
141
        private String                                        fileName = null;
142
        
143
    /**
144
     * Constructor
145
     * @param fName
146
     * @throws MrSIDException
147
     * @throws IOException
148
     */
149
    public MrSidNative(String fName) throws MrSIDException, IOException {
150
        super(fName);
151
        init(fName);
152
    }
153
    
154
    /**
155
     * Inicializa las variables de instancia con los valores de la imagen
156
     * @param fName
157
     * @throws MrSIDException
158
     * @throws IOException
159
     */
160
    private void init(String fName) throws MrSIDException, IOException {
161
        this.initialize();
162
        
163
        String ext = fName.toLowerCase().substring(fName.lastIndexOf('.') + 1);
164

    
165
        fileName = fName;
166
        width = this.getWidth();
167
        height = this.getHeight();
168
        eSampleType = this.getDataType();
169
        nbands = this.getNumBands();
170
        eColorSpace = this.getColorSpace();
171
        noverviews = this.getNumLevels();
172

    
173
        metadata = this.getMetadata();
174

    
175
        double ox = 0D;
176
        double oy = 0D;
177
        double resx = 0D;
178
        double resy = 0D;
179

    
180
        LTIGeoCoord geoc = this.getGeoCoord();
181

    
182
        ox = geoc.getX();
183
        oy = geoc.getY();
184
        resx = geoc.getXRes();
185
        resy = geoc.getYRes();
186

    
187
        esq.add(new Point2D.Double(ox, oy));
188
        esq.add(new Point2D.Double(ox + (resx * width), oy));
189
        esq.add(new Point2D.Double(ox, oy + (resy * height)));
190
        esq.add(new Point2D.Double(ox + (resx * width), oy + (resy * height)));
191

    
192
        blocksize = this.getStripHeight();
193
    }
194

    
195
    /**
196
     * Asigna el valor de Alpha
197
     * @param a        alpha
198
     */
199
    public void setAlpha(int a) {
200
        alpha = a;
201
    }
202

    
203
    /**
204
     * Asigna el tipo de datos
205
     * @param dt        tipo de datos
206
     */
207
    public void setDataType(int dt) {
208
        dataType = dt;
209
    }
210

    
211
    /**
212
     * Obtiene un punto 2D con las coordenadas del raster a partir de uno en coordenadas
213
     * del punto real.
214
     * @param pt        punto en coordenadas del punto real
215
     * @return        punto en coordenadas del raster
216
     */
217
    public Point2D worldToRaster(Point2D pt) {
218
        double x = (((double) currentFullWidth) / (esq.maxX - esq.minX)) * (pt.getX() - esq.minX);
219
        double y = (((double) currentFullHeight) / (esq.maxY - esq.minY)) * (esq.maxY - pt.getY());
220
        Point2D ptRes = new Point2D.Double(x, y);
221
        return ptRes;
222
    }
223

    
224
    /**
225
     * Calcula el overview a usar de la imagen y el viewport a partir del ancho, alto y
226
     * coordenadas del mundo real
227
     * @param dWorldTLX        Coordenada X superior izquierda
228
     * @param dWorldTLY        Coordenada Y superior izquierda
229
     * @param dWorldBRX        Coordenada X inferior derecha
230
     * @param dWorldBRY        Coordenada Y inferior derecha
231
     * @param nWidth        ancho
232
     * @param nHeight        alto
233
     */
234
    public void setView(double dWorldTLX, double dWorldTLY, double dWorldBRX,
235
                        double dWorldBRY, int nWidth, int nHeight) {
236
            currentImageView[0] = dWorldTLX;
237
            currentImageView[1] = dWorldTLY;
238
            currentImageView[2] = dWorldBRX;
239
            currentImageView[3] = dWorldBRY;
240
            
241
        //Ancho y alto de la im?gen en pixeles (pixeles de la overview)
242
        currentFullWidth = width;
243
        currentFullHeight = height;
244

    
245
        //Ventana de la imagen. (en tama?o completo)
246
        //tl->esq sup izda en pixeles
247
        //br->esq inf der en pixeles
248
        Point2D tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
249
        Point2D br = worldToRaster(new Point2D.Double(dWorldBRX, dWorldBRY));
250

    
251
        //Ancho y alto de la im?gen (pixeles en pantalla)
252
        currentViewWidth = nWidth;
253
        currentViewHeight = nHeight;
254

    
255
        //Posici?n de la esquina superior izquierda en coordenadas pixel
256
        currentViewX = tl.getX();
257
        currentViewY = tl.getY();
258

    
259
        //Escala de la vista en X e Y
260
        viewportScaleX = (double) currentViewWidth / (br.getX() - tl.getX());
261
        viewportScaleY = (double) currentViewHeight / (br.getY() - tl.getY());
262
       
263
        try {
264
            // calcula el overview a usar
265
            int[] dims = null;
266
            double zoom = 1.0;
267
            zoomoverview = 1.0;
268
            currentOverview = -1;
269

    
270
            if (WITH_OVERVIEWS && ((noverviews - 1) > 0)) {
271
                for (int i = (noverviews - 1); i > 0; i--) {
272
                    zoom = LTIUtils.levelToMag(i);
273
                    dims = this.getDimsAtMag(zoom);
274

    
275
                    if (dims[0] > (this.getWidth() * viewportScaleX)) {
276
                        currentOverview = i;
277
                        zoomoverview = zoom;
278
                        viewportScaleX /= zoomoverview;
279
                        viewportScaleY /= zoomoverview;
280
                        currentFullWidth = dims[0];
281
                        currentFullHeight = dims[1];
282
                        tl = worldToRaster(new Point2D.Double(dWorldTLX, dWorldTLY));
283
                        currentViewX = tl.getX();
284
                        currentViewY = tl.getY();
285

    
286
                        break;
287
                    }
288
                }
289
            }
290

    
291
            setDataType(eSampleType);
292
        } catch (MrSIDException e) {
293
            e.printStackTrace();
294
        }
295
    }
296
        
297
    /**
298
     * Muestra alguna informaci?n para la depuraci?n
299
     */
300
    void pintaInfo() {
301
        try {
302
            System.out.println("GeoTransform:");
303

    
304
            LTIGeoCoord geoc = this.getGeoCoord();
305

    
306
            System.out.println("  param[0]=" + geoc.getX());
307
            System.out.println("  param[0]=" + geoc.getY());
308
            System.out.println("  param[0]=" + geoc.getXRes());
309
            System.out.println("  param[0]=" + geoc.getYRes());
310
            System.out.println("  param[0]=" + geoc.getXRot());
311
            System.out.println("  param[0]=" + geoc.getYRot());
312
            System.out.println("Metadata:");
313

    
314
            LTIMetadataDatabase metadata = this.getMetadata();
315

    
316
            for (int i = 0; i < metadata.getIndexCount(); i++) {
317
                LTIMetadataRecord rec = null;
318
                rec = metadata.getDataByIndex(i);
319
                System.out.println(rec.getTagName());
320

    
321
                if (rec.isScalar()) {
322
                    System.out.println(rec.getScalarData());
323
                } else if (rec.isVector()) {
324
                    String[] s = rec.getVectorData();
325

    
326
                    for (int j = 0; j < s.length; j++)
327
                        System.out.println("V" + j + "->" + s[j]);
328
                } else if (rec.isArray()) {
329
                    String[] s = rec.getArrayData();
330

    
331
                    for (int j = 0; j < s.length; j++)
332
                        System.out.println("A" + j + "->" + s[j]);
333
                } else {
334
                    System.out.println("");
335
                }
336
            }
337
        } catch (MrSIDException e) {
338
            // TODO Auto-generated catch block
339
            e.printStackTrace();
340
        }
341
    }
342

    
343
    void pintaPaleta() {
344
    }
345

    
346
    public LTISceneBuffer readBuffer(int x, int y, int SceneWidth, int SceneHeight)throws MrSIDException{
347
            LTISceneBuffer buffer = null;
348
            LTIScene scene = new LTIScene(x, y, SceneWidth, SceneHeight, zoomoverview);
349
            buffer = new LTISceneBuffer(pixel, SceneWidth, SceneHeight, true);
350
            ((LTIImageStage) this).read(scene, buffer);
351
            return buffer;
352
    }
353
    
354
    /**
355
         * Esta funci?n calcula los arrays de steps en X e Y para que cuando hay supersampleo 
356
         * se aplique el filtro solo a la esquina superior izquierda de cada pixel. 
357
         */
358
        private void calcArraySteps(int w, int h, double stepX, double stepY, double offsetX, double offsetY){
359
                if(stepX < 1 && stepY < 1){
360
                        isSupersampling = true;
361
                        this.stepArrayX = new int[w];
362
                        for (double j = offsetX; j < w; j += stepX) 
363
                                        stepArrayX[(int)(j)] ++;
364
                                                        
365
                        this.stepArrayY = new int[h];
366
                        for (double j =  offsetY; j < h; j += stepY) 
367
                                stepArrayY[(int)(j)] ++;
368
                }else{
369
                        isSupersampling = false;
370
                        this.stepArrayX = this.stepArrayY = null;
371
                }
372
        }
373
        
374
    /**
375
     * Lee la escena de la imagen correspondiente a la vista seleccionada con
376
     * currentView a trav?s de la libreria de MrSid. Esta escena es cargada sobre
377
     * un buffer y asignada al par?metro de salida.
378
     * @param line        Escena leida
379
     * @throws MrSIDException Lanzada si ocurre un error en la lectura de la escena
380
     */
381
    public void readScene(int[] line) throws MrSIDException {
382
            //Posici?n de inicio de la escena en entero para la petici?n a la libreria
383
        int x = (int) Math.floor(currentViewX);
384
        int y = (int) Math.floor(currentViewY);
385
        //Ancho y alto de la escena en pixeles
386
        int SceneWidth = 0;
387
        int SceneHeight = 0;
388

    
389
        try {
390
                        SceneWidth = (int) Math.ceil((((double) currentViewWidth) / viewportScaleX) + 1);
391
                        if (SceneWidth > currentFullWidth)
392
                                SceneWidth = currentFullWidth;
393
                        SceneHeight = (int) Math.ceil((((double) currentViewHeight) / viewportScaleY) + 1);
394
                    if (SceneHeight > currentFullHeight)
395
                               SceneHeight = currentFullHeight;
396
          
397
            if (SceneWidth == 0) 
398
                SceneWidth = 1;
399
           
400
            if (SceneHeight == 0)
401
                SceneHeight = 1;
402
            
403
            if (pixel == null)
404
                pixel = new LTIPixel(eColorSpace, nbands, eSampleType);
405
            
406
            LTISceneBuffer buffer = null;
407
            
408
            boolean  sizeOk = false;
409
                        while (!sizeOk){
410
                                sizeOk = true;
411
                    try {
412
                            buffer = readBuffer(x, y, SceneWidth, SceneHeight);
413
                    } catch (MrSIDException ex) {
414
                            SceneWidth-- ;
415
                            try{
416
                                    buffer = readBuffer(x, y, SceneWidth, SceneHeight);
417
                            } catch (MrSIDException ex1) {
418
                                    SceneWidth++;
419
                                    SceneHeight--;
420
                                try{
421
                                        buffer = readBuffer(x, y, SceneWidth, SceneHeight);
422
                                } catch (MrSIDException ex2) {
423
                                        SceneWidth-- ;
424
                                    try{
425
                                            buffer = readBuffer(x, y, SceneWidth, SceneHeight);
426
                                    } catch (MrSIDException ex3) {
427
                                            sizeOk = false;
428
                                    }
429
                                }
430
                            }
431
                    }
432
                        }
433
            
434
                                    
435
            if ((dataType == LTIDataType.LTI_DATATYPE_UINT8) ||
436
                    (dataType == LTIDataType.LTI_DATATYPE_SINT8) ||
437
                    (dataType == LTIDataType.LTI_DATATYPE_SINT16) ||
438
                    (dataType == LTIDataType.LTI_DATATYPE_SINT32) ||
439
                    (dataType == LTIDataType.LTI_DATATYPE_UINT16) ||
440
                    (dataType == LTIDataType.LTI_DATATYPE_UINT32)) {
441
                int kd;
442
                int k;
443
                double scaleX = 1 / viewportScaleX;
444
                double scaleY = 1 / viewportScaleY;
445
                                
446
                int alpha = (this.alpha & 0xff) << 24;
447
                             
448
                if (rBandNr == 1) {
449
                    bandR = buffer.buf1;
450
                } else if (rBandNr == 2) {
451
                    bandR = buffer.buf2;
452
                } else if (rBandNr == 3) {
453
                    bandR = buffer.buf3;
454
                }
455

    
456
                if (gBandNr == 1) {
457
                    bandG = buffer.buf1;
458
                } else if (gBandNr == 2) {
459
                    bandG = buffer.buf2;
460
                } else if (gBandNr == 3) {
461
                    bandG = buffer.buf3;
462
                }
463

    
464
                if (bBandNr == 1) {
465
                    bandB = buffer.buf1;
466
                } else if (bBandNr == 2) {
467
                    bandB = buffer.buf2;
468
                } else if (bBandNr == 3) {
469
                    bandB = buffer.buf3;
470
                }
471
                
472
                //Desplazamiento para la X y la Y leidas. Estas tienen efecto cuando un pixel no empieza a visualizarse
473
                //justo en su esquina superior izquierda y tiene que ser cortado en la visualizaci?n.
474
                double offsetX = Math.abs(currentViewX - ((int)currentViewX));
475
                double offsetY = Math.abs(currentViewY - ((int)currentViewY));
476
                
477
                calcArraySteps(SceneWidth, SceneHeight, scaleX, scaleY, offsetX, offsetY);
478
                
479
                for (int y1 = 0; y1 < currentViewHeight; y1++){
480
                   for (int x1 = 0; x1 < currentViewWidth; x1++){
481
                      kd = (y1 * currentViewWidth) + x1;
482
                      k = (((int) ((y1 * scaleY) + offsetY)) * SceneWidth) + (int) ((x1 * scaleX) + offsetX);
483
                      try {
484
                            line[kd] = alpha + ((0xff & bandR[k]) << 16) + ((0xff & bandG[k]) << 8) + (0xff & bandB[k]);
485
                      } catch (java.lang.ArrayIndexOutOfBoundsException e) {
486
                      }
487
                   }
488
                }
489
            }
490
            
491
            buffer = null;
492
        } catch (MrSIDException e) {
493
            e.printStackTrace();
494
        }
495
    }
496
    
497
        /**
498
         * Lee una ventana de datos sin resampleo a partir de coordenadas en pixeles.
499
         * @param buf Buffer donde se almacenan los datos
500
         * @param bandList Lista de bandas que queremos leer y sobre que bandas del buffer de destino queremos escribirlas
501
         * @param x Posici?n X en pixeles
502
         * @param y Posici?n Y en pixeles
503
         * @param w Ancho en pixeles
504
         * @param h Alto en pixeles
505
         * @throws GdalException
506
         */
507
        public void readWindow(RasterBuf buf, BandList bandList, int x, int y, int w, int h) throws MrSIDException  {
508
                isSupersampling = false;
509
                if (pixel == null) {
510
            pixel = new LTIPixel(eColorSpace, nbands, eSampleType);
511
        }
512
                
513
        LTIScene scene = new LTIScene(x, y, w, h, 1.0);
514
        LTISceneBuffer buffer = new LTISceneBuffer(pixel, w, h, true);
515
        ((LTIImageStage) this).read(scene, buffer);
516
        
517
        int yMax = y + h;
518
        byte[] bandBuf = null;
519
        for(int iBand = 0; iBand < getNumBands(); iBand++){
520
                int[] drawableBands = bandList.getBufferBandToDraw(fileName, iBand);
521
                if(drawableBands == null || (drawableBands.length == 1 && drawableBands[0] == -1))
522
                                continue;
523
                switch(iBand) {
524
                case 0:  bandBuf = buffer.buf1; break;
525
                case 1:  bandBuf = buffer.buf2; break;
526
                case 2:  bandBuf = buffer.buf3; break;
527
            }
528
                for (int line = 0; line < h; line++){
529
                for (int col = 0; col < w; col++){
530
                   int kd = (line * w) + col;
531
                   buf.setElemByte(line, col, iBand, bandBuf[kd]);
532
                }
533
            }
534
        }
535
        }
536
        
537
    /**
538
     * Lee una ventana de la imagen y devuelve un buffer de bytes
539
     * @param ulX        Coordenada X de la esquina superior izquierda
540
     * @param ulY        Coordenada Y de la esquina superior izquierda
541
     * @param sizeX        Tama?o X de la imagen
542
     * @param sizeY        Tama?o Y de la image
543
     * @param band        N?mero de bandas
544
     * @return        buffer con la ventana leida
545
     * @throws MrSIDException
546
     */
547
    public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band)
548
                     throws MrSIDException {
549
        if (pixel == null) {
550
            pixel = new LTIPixel(eColorSpace, nbands, eSampleType);
551
        }
552

    
553
        LTIScene scene = new LTIScene(ulX, ulY, sizeX, sizeY, 1.0);
554
        LTISceneBuffer buffer = new LTISceneBuffer(pixel, sizeX, sizeY, true);
555
        ((LTIImageStage) this).read(scene, buffer);
556

    
557
        if (band == 1) {
558
            return buffer.buf1;
559
        } else if (band == 2) {
560
            return buffer.buf2;
561
        } else if (band == 3) {
562
            return buffer.buf3;
563
        }
564

    
565
        return null;
566
    }
567

    
568
    // Polilinea con extent
569
    class Contour extends Vector {
570
        final private static long serialVersionUID = -3370601314380922368L;
571
        public double minX = Double.MAX_VALUE;
572
        public double minY = Double.MAX_VALUE;
573
        public double maxX = -Double.MAX_VALUE;
574
        public double maxY = -Double.MAX_VALUE;
575

    
576
        public Contour() {
577
            super();
578
        }
579

    
580
        public void add(Point2D pt) {
581
            super.add(pt);
582

    
583
            if (pt.getX() > maxX) {
584
                maxX = pt.getX();
585
            }
586

    
587
            if (pt.getX() < minX) {
588
                minX = pt.getX();
589
            }
590

    
591
            if (pt.getY() > maxY) {
592
                maxY = pt.getY();
593
            }
594

    
595
            if (pt.getY() < minY) {
596
                minY = pt.getY();
597
            }
598
        }
599
    }
600
}
601

    
602

    
603
/**
604
 * @author Nacho Brodin <brodin_ign@gva.es>
605
 *
606
 * Clase encargada del acceso a los datos y repintado de imagenes MrSID. Estos
607
 * son registrados con la extensi?n sid
608
 */
609
public class MrSidFile extends GeoRasterFile {
610
    public final static int BAND_HEIGHT = 64;
611

    
612
    protected MrSidNative file = null;
613
    private Extent v = null;
614

    
615
    /**
616
     * Contructor. Abre el fichero mrsid
617
     * @param proj        Proyecci?n
618
     * @param fName        Nombre del fichero mrsid
619
     */
620
    public MrSidFile(IProjection proj, String fName) {
621
        super(proj, fName);
622
        
623
        extent = new Extent();
624

    
625
        try {
626
            file = new MrSidNative(fName);
627
            load();
628
            bandCount = file.nbands;
629

    
630
            if (bandCount > 2) {
631
                setBand(RED_BAND, 0);
632
                setBand(GREEN_BAND, 1);
633
                setBand(BLUE_BAND, 2);
634
            } else {
635
                setBand(RED_BAND | GREEN_BAND | BLUE_BAND, 0);
636
            }
637
        } catch (Exception e) {
638
            System.out.println("Error en constructor de MrSID");
639
            e.printStackTrace();
640
            file = null;
641
        }
642
    }
643

    
644
        /**
645
         * Obtenemos o calculamos el extent de la imagen.
646
         */
647
    public GeoFile load() {
648
            
649
                   extent = new Extent(file.esq.minX, file.esq.minY, file.esq.maxX, file.esq.maxY);
650
                   requestExtent = extent;
651
            
652
            /*if((this.assignedExtent == GeoRasterFile.IMAGE_EXTENT || this.assignedExtent == GeoRasterFile.ORDER ) 
653
                    && file !=null        && file.esq != null){
654
                    extent = new Extent(file.esq.minX, file.esq.minY, file.esq.maxX, file.esq.maxY);
655
                    return this;
656
            }
657
            
658
            if((this.assignedExtent == GeoRasterFile.ASSIGNED_EXTENT || this.assignedExtent == GeoRasterFile.ORDER ) 
659
                    && this.getTempExtent() != null){
660
        
661
                extent = this.getTempExtent();
662
                        file.esq = file.new Contour();
663
                          file.esq.add(new Point2D.Double(extent.minX(), extent.minY()));
664
                          file.esq.add(new Point2D.Double(extent.minX()+(extent.maxX() - extent.minX()), extent.minY()));
665
                          file.esq.add(new Point2D.Double(extent.minX(), extent.minY()+(extent.maxY() - extent.minY())));
666
                          file.esq.add(new Point2D.Double(extent.minX()+(extent.maxX() - extent.minX()), extent.minY()+(extent.maxY() - extent.minY())));
667
        }*/ 
668
        
669
        return this;
670
    }
671

    
672
    /**
673
     * Libera el objeto que ha abierto el fichero
674
     */
675
    public void close() {
676
            if(file != null){
677
                    file.close();
678
                    file = null;
679
            }
680
    }
681

    
682
    /**
683
     * Asigna una banda R, G o B
684
     */
685
    public void setBand(int flag, int bandNr) {
686
        super.setBand(flag, bandNr);
687

    
688
        if ((flag & GeoRasterFile.RED_BAND) == GeoRasterFile.RED_BAND) {
689
            file.rBandNr = bandNr + 1;
690
        }
691

    
692
        if ((flag & GeoRasterFile.GREEN_BAND) == GeoRasterFile.GREEN_BAND) {
693
            file.gBandNr = bandNr + 1;
694
        }
695

    
696
        if ((flag & GeoRasterFile.BLUE_BAND) == GeoRasterFile.BLUE_BAND) {
697
            file.bBandNr = bandNr + 1;
698
        }
699
    }
700

    
701
    /**
702
     * Asigna el extent de la vista
703
     */
704
    public void setView(Extent e) {
705
        v = new Extent(e);
706
    }
707

    
708
    /**
709
     * Obtiene el Extent de la vista
710
     */
711
    public Extent getView() {
712
        return v;
713
    }
714

    
715
    /**
716
     * Obtiene el ancho de la imagen
717
     */
718
    public int getWidth() {
719
        return file.width;
720
    }
721

    
722
    /**
723
     * Obtiene el alto de la imagen
724
     */
725
    public int getHeight() {
726
        return file.height;
727
    }
728

    
729
    public void reProject(ICoordTrans rp) {
730
        // TODO Auto-generated method stub        
731
    }
732

    
733
    /**
734
     * Actualiza la imagen. Se encarga de llamar a la funci?n que calcula la vista
735
     * y luego a la que lee la escena sobre un buffer. Vuelca la informaci?n obtenida
736
     * sobre el Image que la visualiza.
737
     */
738
    public Image updateImage(int width, int height, ICoordTrans rp) {
739
        int line;
740
        int[] pRGBArray = null;
741
        Image image = null;
742
        
743
        if(mustVerifySize()){
744
                // Work out the correct aspect for the setView call.
745
                double dFileAspect = (double) v.width() / (double) v.height();
746
                double dWindowAspect = (double) width / (double) height;
747
        
748
                if (dFileAspect > dWindowAspect) {
749
                    height = (int) ((double) width / dFileAspect);
750
                } else {
751
                    width = (int) ((double) height * dFileAspect);
752
                }
753
        }
754
        
755
        // Set the view
756
        file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height);
757
                setStep(file.stepArrayX, file.stepArrayY);
758

    
759
        //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
760
        if (width <= 0) {
761
            width = 1;
762
        }
763

    
764
        if (height <= 0) {
765
            height = 1;
766
        }
767

    
768
        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
769
        pRGBArray = new int[width * height];
770

    
771
        try {
772
            file.setAlpha(getAlpha());
773
            
774
            setBand(RED_BAND, rBandNr);
775
            setBand(GREEN_BAND, gBandNr);
776
            setBand(BLUE_BAND, bBandNr);
777
                     
778

    
779
            file.readScene(pRGBArray);
780
            setStep(file.stepArrayX, file.stepArrayY);
781
            ((BufferedImage) image).setRGB(0, 0, width, height, pRGBArray, 0,
782
                                           width);
783
        } catch (Exception e) {
784
            e.printStackTrace();
785
        }
786

    
787
        return image;
788
    }
789

    
790
    /**
791
     * Muestra informaci?n del fichero abierto.
792
     *
793
     */
794
    private void showOnOpen() {
795
        // Report en la apertura (quitar)
796
        System.out.println("Fichero MrSID '" + getName() + "' abierto.");
797
        System.out.println("Version = " + file.version);
798
        System.out.println("   Size = (" + file.width + "," + file.height +
799
                           ")");
800
        System.out.println("   NumBands = (" + file.nbands + ")");
801

    
802
        //file.pintaInfo();
803
        file.pintaPaleta();
804
    }
805

    
806
    /**
807
     * Asigna al objeto Image los valores con los dato de la imagen contenidos en el
808
     * vector de enteros.
809
     * @param image        imagen con los datos actuales
810
     * @param startX        inicio de la posici?n en X dentro de la imagen
811
     * @param startY        inicio de la posici?n en X dentro de la imagen
812
     * @param w        Ancho de la imagen
813
     * @param h        Alto de la imagen
814
     * @param rgbArray        vector que contiene la banda que se va a sustituir
815
     * @param offset        desplazamiento
816
     * @param scansize        tama?o de imagen recorrida por cada p
817
     */
818
    protected void setRGBLine(BufferedImage image, int startX, int startY,
819
                              int w, int h, int[] rgbArray, int offset,
820
                              int scansize) {
821
        image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
822
    }
823

    
824
    /**
825
     * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
826
     * con los datos de la imagen contenidos en el vector de enteros. De los valores RGB
827
     * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
828
     * banda correspondiente a flags es sustituida por los datos del vector.
829
     * @param image        imagen con los datos actuales
830
     * @param startX        inicio de la posici?n en X dentro de la imagen
831
     * @param startY        inicio de la posici?n en X dentro de la imagen
832
     * @param w        Ancho de la imagen
833
     * @param h        Alto de la imagen
834
     * @param rgbArray        vector que contiene la banda que se va a sustituir
835
     * @param offset        desplazamiento
836
     * @param scansize        tama?o de imagen recorrida por cada paso
837
     * @param flags        banda que se va a sustituir (Ctes de GeoRasterFile)
838
     */
839
    protected void setRGBLine(BufferedImage image, int startX, int startY,
840
                              int w, int h, int[] rgbArray, int offset,
841
                              int scansize, int flags) {
842
        int[] line = new int[rgbArray.length];
843
        image.getRGB(startX, startY, w, h, line, offset, scansize);
844

    
845
        if (flags == GeoRasterFile.RED_BAND) {
846
            for (int i = 0; i < line.length; i++)
847
                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
848
        } else if (flags == GeoRasterFile.GREEN_BAND) {
849
            for (int i = 0; i < line.length; i++)
850
                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
851
        } else if (flags == GeoRasterFile.BLUE_BAND) {
852
            for (int i = 0; i < line.length; i++)
853
                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
854
        }
855

    
856
        image.setRGB(startX, startY, w, h, line, offset, scansize);
857
    }
858

    
859
    /**
860
     * Asigna al objeto Image la mezcla entre los valores que ya tiene y los valores
861
     * con los dato de la imagen contenidos en el vector de enteros. De los valores RGB
862
     * que ya contiene se mantienen las bandas que no coinciden con el valor de flags. La
863
     * banda correspondiente a flags es sustituida por los datos del vector.
864
     * @param image        imagen con los datos actuales
865
     * @param startX        inicio de la posici?n en X dentro de la imagen
866
     * @param startY        inicio de la posici?n en X dentro de la imagen
867
     * @param w        Ancho de la imagen
868
     * @param h        Alto de la imagen
869
     * @param rgbArray        vector que contiene la banda que se va a sustituir
870
     * @param offset        desplazamiento
871
     * @param scansize        tama?o de imagen recorrida por cada paso
872
     * @param origBand        Banda origen del GeoRasterFile
873
     * @param destBandFlag        banda que se va a sustituir (Ctes de GeoRasterFile)
874
     */
875
    protected void setRGBLine(BufferedImage image, int startX, int startY,
876
                              int w, int h, int[] rgbArray, int offset,
877
                              int scansize, int origBand, int destBandFlag) {
878
        int[] line = new int[rgbArray.length];
879
        image.getRGB(startX, startY, w, h, line, offset, scansize);
880

    
881
        if ((origBand == 0) && (destBandFlag == GeoRasterFile.RED_BAND)) {
882
            for (int i = 0; i < line.length; i++)
883
                line[i] = (line[i] & 0x0000ffff) | (rgbArray[i] & 0xffff0000);
884
        } else if ((origBand == 1) &&
885
                       (destBandFlag == GeoRasterFile.GREEN_BAND)) {
886
            for (int i = 0; i < line.length; i++)
887
                line[i] = (line[i] & 0x00ff00ff) | (rgbArray[i] & 0xff00ff00);
888
        } else if ((origBand == 2) &&
889
                       (destBandFlag == GeoRasterFile.BLUE_BAND)) {
890
            for (int i = 0; i < line.length; i++)
891
                line[i] = (line[i] & 0x00ffff00) | (rgbArray[i] & 0xff0000ff);
892
        } else if ((origBand == 0) &&
893
                       (destBandFlag == GeoRasterFile.GREEN_BAND)) {
894
            for (int i = 0; i < line.length; i++)
895
                line[i] = (line[i] & 0xffff00ff) |
896
                          ((rgbArray[i] & 0x00ff0000) >> 8);
897
        } else if ((origBand == 0) &&
898
                       (destBandFlag == GeoRasterFile.BLUE_BAND)) {
899
            for (int i = 0; i < line.length; i++)
900
                line[i] = (line[i] & 0xffffff00) |
901
                          ((rgbArray[i] & 0x00ff0000) >> 16);
902
        } else if ((origBand == 1) && (destBandFlag == GeoRasterFile.RED_BAND)) {
903
            for (int i = 0; i < line.length; i++)
904
                line[i] = (line[i] & 0xff00ffff) |
905
                          ((rgbArray[i] & 0x0000ff00) << 8);
906
        } else if ((origBand == 1) &&
907
                       (destBandFlag == GeoRasterFile.BLUE_BAND)) {
908
            for (int i = 0; i < line.length; i++)
909
                line[i] = (line[i] & 0xffffff00) |
910
                          ((rgbArray[i] & 0x0000ff00) >> 8);
911
        } else if ((origBand == 2) && (destBandFlag == GeoRasterFile.RED_BAND)) {
912
            for (int i = 0; i < line.length; i++)
913
                line[i] = (line[i] & 0xff00ffff) |
914
                          ((rgbArray[i] & 0x000000ff) << 16);
915
        } else if ((origBand == 2) &&
916
                       (destBandFlag == GeoRasterFile.GREEN_BAND)) {
917
            for (int i = 0; i < line.length; i++)
918
                line[i] = (line[i] & 0xffff00ff) |
919
                          ((rgbArray[i] & 0x000000ff) << 8);
920
        }
921

    
922
        image.setRGB(startX, startY, w, h, line, offset, scansize);
923
    }
924

    
925
    /* (non-Javadoc)
926
     * @see org.cresques.io.GeoRasterFile#updateImage(int, int, org.cresques.cts.ICoordTrans, java.awt.Image, int)
927
     */
928
    public Image updateImage(int width, int height, ICoordTrans rp, Image img,
929
                             int origBand, int destBandFlag) throws SupersamplingNotSupportedException{
930
        int line;
931
        int[] pRGBArray = null;
932
        Image mrSidImage = null;
933

    
934
        if(mustVerifySize()){
935
                // Work out the correct aspect for the setView call.
936
                double dFileAspect = (double) v.width() / (double) v.height();
937
                double dWindowAspect = (double) width / (double) height;
938
        
939
                if (dFileAspect > dWindowAspect) {
940
                    height = (int) ((double) width / dFileAspect);
941
                } else {
942
                    width = (int) ((double) height * dFileAspect);
943
                }
944
        }
945
        // Set the view
946
        file.setView(v.minX(), v.maxY(), v.maxX(), v.minY(), width, height);
947

    
948
        //Impedimos que los valores de ancho y alto de la im?gen sean menores que 1
949
        if (width <= 0) {
950
            width = 1;
951
        }
952

    
953
        if (height <= 0) {
954
            height = 1;
955
        }
956

    
957
        file.setAlpha(getAlpha());
958
      
959
        setBand(RED_BAND, rBandNr);
960
        setBand(GREEN_BAND, gBandNr);
961
        setBand(BLUE_BAND, bBandNr);
962
       
963
        pRGBArray = new int[width * height];
964

    
965
        if (img == null) { //Caso en el que se crea una imagen
966
            mrSidImage = new BufferedImage(width, height,
967
                                           BufferedImage.TYPE_INT_ARGB);
968

    
969
            try {
970
                file.readScene(pRGBArray);
971
                setStep(file.stepArrayX, file.stepArrayY);
972
                setRGBLine((BufferedImage) mrSidImage, 0, 0, width, height, pRGBArray, 0, width);
973
            } catch (Exception e) {
974
                e.printStackTrace();
975
            }
976

    
977
            return mrSidImage;
978
        } else { //Caso en el que se actualiza una banda del Image
979

    
980
            try {
981
                file.readScene(pRGBArray);
982
                setStep(file.stepArrayX, file.stepArrayY);
983
                setRGBLine((BufferedImage) img, 0, 0, width, height, pRGBArray, 0, width, origBand, destBandFlag);
984
            } catch (Exception e) {
985
                e.printStackTrace();
986
            }
987

    
988
            return img;
989
        }
990
    }
991

    
992
    /* (non-Javadoc)
993
     * @see org.cresques.io.GeoRasterFile#getData(int, int, int)
994
     */
995
    public Object getData(int x, int y, int band) {
996
        // TODO Auto-generated method stub
997
        return null;
998
    }
999
    
1000
    public RasterBuf getWindowRasterWithNoData(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) {
1001
                return null;
1002
        }
1003
    
1004
        /**
1005
         * Obtiene una ventana de datos de la imagen a partir de coordenadas reales. 
1006
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
1007
         * pixeles de disco. 
1008
         * @param x Posici?n X superior izquierda
1009
         * @param y Posici?n Y superior izquierda
1010
         * @param w Ancho en coordenadas reales
1011
         * @param h Alto en coordenadas reales
1012
         * @param rasterBuf        Buffer de datos
1013
         * @param bandList
1014
         * @return Buffer de datos
1015
         */
1016
    public RasterBuf getWindowRaster(double x, double y, double w, double h, BandList bandList, RasterBuf rasterBuf) {                
1017
                //Extent selectedExtent = new Extent(x, y, x + w, y - h);
1018
                //setView(selectedExtent);
1019

    
1020
                int initX = (int)((x * file.width) / extent.width());
1021
                int initY = (int)((y * file.height) / extent.height());
1022
                int width = (int)((w * file.width) / extent.width());
1023
                int height = (int)((h * file.height) / extent.height());
1024
                                
1025
                return getWindowRaster(initX, initY, width, height, bandList, rasterBuf);
1026
        }
1027
        
1028
        /**
1029
         * Obtiene una ventana de datos de la imagen a partir de coordenadas pixel. 
1030
         * No aplica supersampleo ni subsampleo sino que devuelve una matriz de igual tama?o a los
1031
         * pixeles de disco. 
1032
         * @param x Posici?n X superior izquierda
1033
         * @param y Posici?n Y superior izquierda
1034
         * @param w Ancho en coordenadas reales
1035
         * @param h Alto en coordenadas reales
1036
         * @param rasterBuf        Buffer de datos
1037
         * @param bandList
1038
         * @return Buffer de datos
1039
         */
1040
        public RasterBuf getWindowRaster(int x, int y, int w, int h, BandList bandList, RasterBuf rasterBuf) {
1041
                try {
1042
                        rasterBuf = new RasterBuf(getDataType(), w, h, bandList.getDrawableBandsCount(), true);
1043
                        file.readWindow(rasterBuf, bandList, x, y, w, h);
1044
                } catch (Exception e) {
1045
                        e.printStackTrace();
1046
                }
1047
                return rasterBuf;
1048
        }
1049

    
1050
    /**
1051
     * Devuelve los datos de una ventana solicitada
1052
     * @param ulX        coordenada X superior izda.
1053
     * @param ulY        coordenada Y superior derecha.
1054
     * @param sizeX        tama?o en X de la ventana.
1055
     * @param sizeY tama?o en Y de la ventana.
1056
     * @param band        Banda solicitada.
1057
     */
1058
    public byte[] getWindow(int ulX, int ulY, int sizeX, int sizeY, int band) {
1059
        try {
1060
            return file.getWindow(ulX, ulY, sizeX, sizeY, band);
1061
        } catch (MrSIDException e) {
1062
            e.printStackTrace();
1063
        }
1064

    
1065
        return null;
1066
    }
1067

    
1068
    /**
1069
     * Devuelve el tama?o de bloque
1070
     * @return Tama?o de bloque
1071
     */
1072
    public int getBlockSize() {
1073
        return file.blocksize;
1074
    }
1075
    
1076
    /**
1077
         * Calcula la transformaci?n que se produce sobre la vista cuando la imagen tiene un fichero .rmf
1078
         * asociado. En Ecw el origen de coordenadas en Y es el valor m?ximo y decrece hasta el m?nimo.
1079
         * @param originX Origen de la imagen en la coordenada X
1080
         * @param originY Origen de la imagen en la coordenada Y
1081
         */
1082
    public void setExtentTransform(double originX, double originY, double psX, double psY) {
1083
                
1084
        }
1085
    
1086
    /**
1087
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el driver el que colocar?
1088
         * el valor de esta variable cada vez que dibuja. 
1089
         * @return true si se ha supersampleado y false si no se ha hecho.
1090
         */
1091
        public boolean isSupersampling() {
1092
                return file.isSupersampling;
1093
        }
1094
        
1095
        public RasterBuf getWindowRaster(double minX, double minY, double maxX, double maxY, int bufWidth, int bufHeight, BandList bandList, RasterBuf rasterBuf) {
1096
                // TODO Auto-generated method stub
1097
                return null;
1098
        }
1099

    
1100
        public Point2D rasterToWorld(Point2D pt) {
1101
                // TODO Auto-generated method stub
1102
                return null;
1103
        }
1104

    
1105
        public Point2D worldToRaster(Point2D pt) {
1106
                // TODO Auto-generated method stub
1107
                return null;
1108
        }
1109
}