Statistics
| Revision:

svn-gvsig-desktop / branches / CqCMSDvp / libraries / libCq CMS for java.old / src-dvp / org / cresques / io / EcwWriter.java @ 1739

History | View | Annotate | Download (17.4 KB)

1
package org.cresques.io;
2

    
3
import java.io.IOException;
4

    
5
import es.gva.cit.jecwcompress.*;
6
import es.gva.cit.jgdal.GdalRasterBand;
7

    
8
import org.cresques.geo.ViewPortData;
9
import org.cresques.px.PxRaster;
10

    
11
/**
12
 * 
13
 * @author Nacho Brodin <brodin_ign@gva.es>
14
 *
15
 * Driver para la compresi?n en formato Ecw. 
16
 * 
17
 * Puede exportar un fichero desde un GeoRasterFile en cualquier formato soportado 
18
 * por los drivers de lectura a uno en formato Ecw.
19
 * 
20
 * Puede salvar a disco en formato Ecw obteniendo los datos que van siendo servidos 
21
 * desde el cliente. Este cliente debe implementar un IDataWriter o tener un objeto 
22
 * que lo implemente. Inicialmente le pasar? los par?metros de la imagen de salida 
23
 * y cuando el driver comience a escribir le ir? solicitando m?s a trav?s del m?todo 
24
 * readData de IDataWriter. El cliente ser? el que lleve el control de lo que va 
25
 * sirviendo y lo que le queda por servir.
26
 */
27

    
28
public class EcwWriter extends GeoRasterWriter{
29
        
30
        public final int windowSizeX = 386;
31
        public final int windowSizeY = 215;
32
        public final int panelSizeX = 350;
33
        public final int panelSizeY = 125;
34
        public final String panelLayout = "BorderLayout";
35
                
36
        private NCSEcwCompressClient        compressclient=null;
37
        private Reader                                         readerObj;
38
        private double                                        pixelSizeX;
39
        private double                                        pixelSizeY;
40
        private double                                        geoCoordOrigenX;
41
        private double                                        geoCoordOrigenY;
42
        private EcwSupportOptions                support = null;
43
        private boolean                                        consulta = false;
44
        
45
        class EcwSupportOptions extends WriterSupportOptions{
46
                
47
                private String[]                 compresionListValues = {"0","20","10","1","5"}; //min, max, valor defecto, intervalo peque?o, intervalo grande;
48
                private String[]                formatList = {"NONE","UINT8","YUV","MULTI","RGB"};
49
                
50
                private int                                formatDefault = 4;
51
                private int                                compresionDefault = 10;
52
                
53
                EcwSupportOptions(){
54
                        super("Ecw");
55
                }
56
                
57
                public void setCompressionList(String[] compresion){
58
                        this.compresionListValues = compresion;
59
                }
60
                
61
                public void setFormatDefault(int i){
62
                        this.formatDefault = i;
63
                }
64
                
65
                public void setCompressionDefault(int c){
66
                        this.compresionDefault = c;
67
                }
68
                
69
                
70
                public String getStringFormat(){
71
                        return "COMPRESS_"+formatList[formatDefault];
72
                }
73
                
74
                public String[] getFormatList(){
75
                        return formatList;
76
                }
77
                
78
                public int getFormat(){return formatDefault;}
79
                public int getCompression(){return compresionDefault;}
80
                public String[] getCompressionList(){return compresionListValues;}
81
                
82
        }
83
                
84
        static {
85
                GeoRasterWriter.registerWriterExtension("ecw", EcwWriter.class);
86
        }
87
        
88
        /**
89
         * Constructor para la obtenci?n de par?metros del driver.
90
         *
91
         */
92
        public EcwWriter(){
93
                
94
                this.support = new EcwSupportOptions();
95
                this.driver = "ecw";
96
                this.support.setBlockSize(64);
97
                this.support.setCompressionDefault(10);        
98
                this.support.setFormatDefault(4);
99
                this.support.setWriteGeoref(true);
100
                this.ident = "Ecw";
101
                this.consulta = true;
102
                
103
        }
104
        
105
        /**
106
         * Constructor para salvar una sola imagen completa
107
         * @param layerlist
108
         * @param outfilename
109
         * @param infilename
110
         */
111
        
112
         public EcwWriter(        PxRaster raster, 
113
                                                String outfilename, 
114
                                                String infilename, 
115
                                                int compresion)throws EcwException, IOException {
116
 
117
                 this.support = new EcwSupportOptions();
118
                 this.ident = "Ecw";
119
                 
120
                this.outfilename = outfilename;
121
                this.infilename = infilename;
122
                this.currentRaster = raster;
123
                
124
                this.support.setCompressionDefault(compresion);                        
125
                                
126
                this.sizeWindowX = raster.getFWidth();
127
                this.sizeWindowY = raster.getFHeight();
128
                
129
                this.support.setBlockSize(currentRaster.geoFile.getBlockSize());
130
                                
131
                nBands = currentRaster.getBandCount();
132
                
133
                //Calculamos la georeferenciaci?n
134
             
135
            double maxX=currentRaster.getExtent().maxX();
136
            geoCoordOrigenX=currentRaster.getExtent().minX();
137
            geoCoordOrigenY=currentRaster.getExtent().maxY();
138
            double minY=currentRaster.getExtent().minY();
139
            double w=currentRaster.getFWidth();
140
            double h=currentRaster.getFHeight();
141
            pixelSizeX = (maxX-geoCoordOrigenX)/w;
142
            pixelSizeY = (minY-geoCoordOrigenY)/h;
143
                        
144
            if(sizeWindowX<0 || sizeWindowY<0)
145
                        throw new IOException("Tama?o del fichero de salida erroneo.");
146
            
147
            if(nBands == 1) 
148
                        this.support.setFormatDefault(CompressFormat.COMPRESS_UINT8);
149
                else if(nBands == 3) 
150
                        this.support.setFormatDefault(CompressFormat.COMPRESS_RGB);
151
                else 
152
                        this.support.setFormatDefault(CompressFormat.COMPRESS_MULTI);
153
            
154
                init();
155
                
156
        }
157
        
158
        
159
        
160
        /**
161
         * Constructor para la lectura de datos desde el objeto cliente a partir
162
         * de un viewport dado.
163
         * @param dataWriter
164
         * @param vp
165
         * @param outFileName
166
         * @param blockSize
167
         * @param nBands
168
         * @param compresion
169
         * @throws EcwException
170
         * @throws IOException
171
         */
172
        
173
        public EcwWriter(        IDataWriter dataWriter, 
174
                                                ViewPortData vp,
175
                                                String outFileName, 
176
                                                int blockSize,
177
                                                int nBands,
178
                                                int compresion)throws EcwException, IOException {
179
                
180
                this.support = new EcwSupportOptions();
181
                this.ident = "Ecw";
182
                
183
                if(compresion <= 0)
184
                throw new EcwException("Tasa de compresi?n no valida.");
185
                if(nBands <= 0)
186
                throw new EcwException("N?mero de bandas erroneo.");
187
                if(vp.getWidth()<=0 || vp.getHeight()<=0)
188
                throw new EcwException("Tama?o de la imagen de salida erroneo.");
189
                
190
                this.outfilename = outFileName;
191
                this.dataWriter = dataWriter;
192
                this.support.setCompressionDefault(compresion);
193
                this.nBands = nBands;
194
                
195
                this.sizeWindowX = (int)vp.getWidth();
196
                this.sizeWindowY = (int)vp.getHeight();
197
                this.support.setBlockSize(blockSize);
198
                                
199
                //Calculamos la georeferenciaci?n a partir del extend pasado por el cliente.
200
                
201
                
202
                double maxX = vp.getExtent().maxX();
203
                geoCoordOrigenX = vp.getExtent().minX();
204
                geoCoordOrigenY = vp.getExtent().maxY();
205
                double minY = vp.getExtent().minY();
206
                pixelSizeX = (maxX-geoCoordOrigenX)/vp.getWidth();
207
                pixelSizeY = (minY-geoCoordOrigenY)/vp.getHeight();
208
                
209
                if(pixelSizeX==0)pixelSizeX=1.0;
210
                if(pixelSizeY==0)pixelSizeY=1.0;
211

    
212
                init();
213
                
214
        }
215
        
216
        
217
        /**
218
         * Inicializaci?n de los par?metros del compresor que ser?n obtenidos
219
         * de PxRaster.
220
         * @throws EcwException
221
         */
222
        
223
        private void init() throws EcwException{
224
                
225
                if(this.support.getCompression()==0)
226
                        this.support.setCompressionDefault(1);
227
                if(compressclient==null)
228
                        compressclient = new NCSEcwCompressClient();
229
                compressclient.setOutputFilename(outfilename);          
230
                  compressclient.setInputFilename(infilename);
231
            compressclient.setTargetCompress(this.support.getCompression());
232
            compressclient.setInOutSizeX(sizeWindowX);
233
            compressclient.setInOutSizeY(sizeWindowY);
234
            compressclient.setInputBands(nBands);
235
            compressclient.setCompressFormat(this.support.getFormat());
236
                       
237
            //System.out.println("Origen=>"+minX + "  "+maxY );
238
            //System.out.println("Pixel Size=>"+psX+"  "+psY);
239
            
240
            //compressclient.setDatum("UTM Zona 31N");
241
            //client.setProjection("WGS84");
242
            
243
            if(this.support.getGeoref()){
244
                        compressclient.setCellIncrementX(pixelSizeX);
245
                        compressclient.setCellIncrementY(pixelSizeY);
246
                        compressclient.setOriginX(geoCoordOrigenX);
247
                        compressclient.setOriginY(geoCoordOrigenY);
248
            }
249
            compressclient.setCellSizeUnits(1);
250

    
251
                //System.out.println(outfilename+" "+infilename+" "+compresion+" "+sizeWindowX+" "+sizeWindowY+" "+currentRaster.getBandCount());
252
                //System.out.println(psX+" "+psY+" "+minX+" "+maxX);
253
                
254
                if(currentRaster!=null)
255
                        readerObj = new Reader( currentRaster.geoFile, 
256
                                                                        compressclient, 
257
                                                                        ulX, 
258
                                                                        ulY, 
259
                                                                        sizeWindowX, 
260
                                                                        sizeWindowY, 
261
                                                                        this.support.getBlockSize());
262
                else if(dataWriter!=null)
263
                        readerObj = new Reader( dataWriter, 
264
                                                                        compressclient,  
265
                                                                        sizeWindowX, 
266
                                                                        sizeWindowY, 
267
                                                                        this.support.getBlockSize(),
268
                                                                        this.nBands);
269
                
270
                
271
        }
272
                
273
        /**
274
         * 
275
         * @param propValue
276
         */
277
        private void readProperty(String propValue){
278
                
279
                String prop = propValue.substring(0, propValue.indexOf("="));
280
                if(propValue.startsWith(prop)){
281
                        String value = propValue.substring(propValue.indexOf("=")+1, propValue.length());
282
                        if(value!=null && !value.equals("")){
283
                                if(prop.equals("BLOCKSIZE"))
284
                                        this.support.setBlockSize(Integer.parseInt(value));
285
                                if(prop.equals("FORMAT")){
286
                                        int select = 0;
287
                                        if(value.equals("UINT8"))
288
                                                select = 1;
289
                                        if(value.equals("YUV"))
290
                                                select = 2;
291
                                        if(value.equals("MULTI"))
292
                                                select = 3;
293
                                        if(value.equals("RGB"))
294
                                                select = 4;
295
                                        this.support.setFormatDefault(select);
296
                                }
297
                                if(prop.equals("GEOREF")){
298
                                        boolean georef = true;
299
                                        if(value.equals("yes"))
300
                                                georef = true;
301
                                        else
302
                                                georef = false;
303
                                        this.support.setWriteGeoref(georef);
304
                                }        
305
                                if(prop.equals("COMPRESSION"))
306
                                        this.support.setCompressionDefault(Integer.parseInt(value));
307
                        }
308
                }
309
                
310
        }
311
        
312
        /**
313
         * 
314
         * @param props
315
         */
316
        public void setProps(String[] props){
317

    
318
                for(int iProps=0;iProps<props.length;iProps++)
319
                        readProperty(props[iProps]);
320
                
321
                try{
322
                        if(!consulta)init();
323
                }catch(EcwException e){
324
                        e.printStackTrace();
325
                }
326
                
327
        }
328
        
329
        /**
330
         * Realiza la funci?n de compresi?n a partir de un GeoRasterFile.
331
         * @throws IOException
332
         */
333
        
334
        public void fileWrite()throws IOException{
335

    
336
                if(currentRaster==null)
337
                        throw new IOException("No se ha asignado un fichero de entrada.");
338
                
339
                try{
340
                        compressclient.NCSEcwCompressOpen(false);
341
                        compressclient.NCSEcwCompress(readerObj);
342
                }catch(EcwException e){
343
                        e.printStackTrace();
344
                }
345
        }
346
        
347
        /**
348
         * Realiza la funci?n de compresi?n a partir de los datos pasados por el cliente.
349
         * @throws IOException
350
         */
351
        
352
        public void dataWrite()throws IOException{
353
                
354
                if(dataWriter==null)
355
                        throw new IOException("No se ha obtenido un objeto para la lectura valido.");
356
                
357
                try{
358
                        compressclient.NCSEcwCompressOpen(false);
359
                        compressclient.NCSEcwCompress(readerObj);
360
                }catch(EcwException e){
361
                        e.printStackTrace();
362
                }
363
                
364
        }
365
        
366
        /**
367
         * Cierra el compresor ecw.
368
         * @throws EcwException
369
         */
370
        
371
        public void writeClose(){
372
                
373
                try{
374
                        compressclient.NCSEcwCompressClose();
375
                }catch(EcwException e){
376
                        e.printStackTrace();
377
                }
378
                
379
        }
380
        
381
        /**
382
         * 
383
         * @return
384
         */
385
        public String getXMLPropertiesDialog(){
386
                
387
                StringBuffer         options = null;
388
                options = new StringBuffer();
389
                options.append("<window sizex=\""+this.windowSizeX+"\" sizey=\""+this.windowSizeY+"\">");
390
                options.append("<panel sizex=\""+this.panelSizeX+"\" sizey=\""+this.panelSizeY+"\" layout=\""+this.panelLayout+"\" border=\"yes\">");
391
                
392
                options.append("<panel layout=\"FlowLayout\" position=\"North\" align=\"left\">");
393
                options.append("<label>Tama?o bloque:</label>");
394
                options.append("<combo ident=\"BLOCKSIZE\" selected=\""+this.support.getBlockSize() +"\">");
395
                for(int i=0;i<this.support.getBlockSizeList().length;i++)
396
                        options.append("<elem>"+this.support.getBlockSizeList()[i]+"</elem>");
397
                options.append("</combo>");
398
                options.append("<label>Formato:</label>");
399
                String sel = null; 
400
                if(this.support.getGeoref())
401
                        sel = new String("yes");
402
                else 
403
                        sel = new String("no");
404
                options.append("<check ident=\"GEOREF\" selected=\""+sel +"\" text=\"Georef Si/No\">");
405
                options.append("</check>");
406
                options.append("</panel>");
407
                                                
408
                options.append("<panel layout=\"FlowLayout\" position=\"South\">");
409
                options.append("<slider ident=\"COMPRESSION\" name=\"Nivel de Compresi?n\" sizex=\"350\" sizey=\"20\">");
410
                options.append("<min>"+this.support.getCompressionList()[0]+"</min>");
411
                options.append("<max>"+this.support.getCompressionList()[1]+"</max>");
412
                options.append("<value>"+this.support.compresionDefault+"</value>");
413
                options.append("<minorspacing>"+this.support.getCompressionList()[3]+"</minorspacing>");
414
                options.append("<majorspacing>"+this.support.getCompressionList()[4]+"</majorspacing>");
415
                options.append("</slider>");
416
                options.append("</panel>");
417
                                
418
                options.append("</panel>");                                                                
419
                options.append("</window>");
420
                                                                                                
421
                return options.toString();
422
                
423
        }
424
        
425
}
426

    
427
/**
428
 * Clase que se encarga de la lectura de datos que ser?n escritos. Hereda de JniObject
429
 * para asegurar  para asegurar que el interfaz de la libreria tiene acceso a variables
430
 * necesarias para la petici?n de datos cuando vacia el buffer. Implementa ReadCallBack
431
 * para obligar escribir el m?todo loadBuffer encargado de servir los datos cuando el 
432
 * buffer se vacia.
433
 *
434
 */
435

    
436
class Reader extends JniObject implements ReadCallBack {
437
        
438
        
439
        private NCSEcwCompressClient         compressclient=null;
440
        private int                                         width, height;                        
441
        private int                                         ulX, ulY;
442
        private GeoRasterFile                         grf=null;
443
        private IDataWriter                                dataWriter=null;
444
        private GdalRasterBand                         rband=null;
445
        private int                                         blockSizeRead=1;                //Alto del bloque leido de la imagen origen 
446
        private int                                                countLine=1;                        //Contador de l?neas procesadas en cada lectura de bloque
447
        byte[][]                                                 buf=null;
448
        byte[]                                                         bufband1=null;
449
        byte[]                                                         bufband2=null;
450
        byte[]                                                         bufband3=null;
451
        byte[]                                                         bufband4=null;
452
        byte[]                                                         bufband5=null;
453
        byte[]                                                         bufband6=null;
454
        int[]                                                                dataBuffer=null;
455
        private int                                         lineasBloqueFinal=0;        //N?mero de l?neas leidas del bloque final
456
        private int                                         nBlocks=0;                                //N?mero de bloques completos
457
        private int                                                countBlock=1;                        //Contador de bloques completos procesados
458
        private int                                                nBands=0;
459
        
460
        /**
461
         * Constructor para la escritura de un fichero desde un GeoRasterFile
462
         * @param grf
463
         * @param compressclient
464
         * @param ulx
465
         * @param uly
466
         * @param width
467
         * @param height
468
         * @param blockSizeRead
469
         */
470
        public Reader(         GeoRasterFile grf, 
471
                                        NCSEcwCompressClient compressclient, 
472
                                        int ulx, 
473
                                        int uly, 
474
                                        int width, 
475
                                        int height,
476
                                        int blockSizeRead){
477
        
478
                this.compressclient = compressclient;
479
                this.width = width;
480
                this.height = height;
481
                this.ulX = ulx;
482
                this.ulY = uly;
483
                this.grf = grf;
484
                this.nBands = grf.bandCount;
485
                
486
                if(blockSizeRead!=0)
487
                        this.blockSizeRead = blockSizeRead;
488
                
489
                nBlocks = (int)(height/this.blockSizeRead);
490
                lineasBloqueFinal = height-(nBlocks*this.blockSizeRead);
491
                
492
                if(blockSizeRead>64)  
493
                        this.blockSizeRead=64;
494
        }
495
        
496
        /**
497
         * Constructor para que los datos sean servidos desde el cliente a trav?s de un 
498
         * IDataWriter.
499
         * @param dataWriter
500
         * @param compressclient
501
         * @param width
502
         * @param height
503
         * @param blockSizeRead
504
         * @param nBands
505
         */
506
        public Reader(         IDataWriter dataWriter, 
507
                                        NCSEcwCompressClient compressclient, 
508
                                        int width, 
509
                                        int height,
510
                                        int blockSizeRead,
511
                                        int nBands){
512

    
513
                this.compressclient = compressclient;
514
                this.width = width;
515
                this.height = height;
516
                this.dataWriter =  dataWriter;
517
                this.nBands = nBands;
518
                
519
                if(blockSizeRead!=0)
520
                        this.blockSizeRead = blockSizeRead;
521
                
522
                nBlocks = (int)(height/this.blockSizeRead);
523
                lineasBloqueFinal = height-(nBlocks*this.blockSizeRead);
524
                
525
                //System.out.println("NBLOQUES="+nBlocks+" lineas ultimo="+lineasBloqueFinal);
526
                
527
                if(blockSizeRead>64)  
528
                        this.blockSizeRead=64;
529
        }
530
        
531
        /**
532
         * Lectura de bandas desde un GeoRasterFile
533
         * @param ulX
534
         * @param ulY
535
         * @param width
536
         * @param lineasLeidas
537
         */
538
        
539
        private void readBandsGRFile(int ulX, int ulY, int width, int lineasLeidas){
540
                if(nBands>=1)
541
                        bufband1 = grf.getWindow(ulX, ulY, width, lineasLeidas, 1);
542
                if(nBands>=2)
543
                        bufband2 = grf.getWindow(ulX, ulY, width, lineasLeidas, 2);
544
                if(nBands>=3)
545
                        bufband3 = grf.getWindow(ulX, ulY, width, lineasLeidas, 3);
546
                if(nBands>=4)
547
                        bufband4 = grf.getWindow(ulX, ulY, width, lineasLeidas, 4);
548
                if(nBands>=5)
549
                        bufband5 = grf.getWindow(ulX, ulY, width, lineasLeidas, 5);
550
                if(nBands>=6)
551
                        bufband6 = grf.getWindow(ulX, ulY, width, lineasLeidas, 6);
552
        }
553
        
554
        /**
555
         * Lectura de bandas llamando al objeto cliente para que nos cargue el buffer
556
         * @param width
557
         * @param height
558
         */
559
        
560
        private void readBands(int width, int height){
561
        
562
                dataBuffer = dataWriter.readData(width, height, 0);
563
        }
564
        
565
        /**
566
         * M?todo obligado por el interfaz y que es llamado desde C cuando el
567
         * compresor necesita que le sirvan m?s datos.
568
         */
569
        
570
        public void loadBuffer(){
571
                                                
572
                
573
                int lineasLeidas=0;
574
                
575
                //si se leen bloques completos lineasLeidas es == al tama?o de bloque sino
576
                //es que es el ?ltimo con lo que ser? del tama?o del bloque final
577
                
578
                if(countBlock<=nBlocks)lineasLeidas=blockSizeRead;
579
                        else lineasLeidas=lineasBloqueFinal;
580
                
581
                //Leemos un bloque nuevo cuando se han procesado todas las l?neas del anterior
582
                
583
                if(nNextLine%blockSizeRead==0){
584
                        if(grf!=null)
585
                                readBandsGRFile(ulX, ulY+nNextLine, width, lineasLeidas);
586
                        else if(dataWriter!=null)
587
                                readBands(width, lineasLeidas);
588
                        
589
                        countLine = 0;
590
                        countBlock++;
591
                }
592
                                
593
        
594
                for(int iBand=0;iBand<this.nBands;iBand++){
595
                                
596
                        for(int pos=0; pos<width; pos++){
597
                                if(grf!=null){
598
                                        if(iBand==0)
599
                                                compressclient.buffer[pos+(width*iBand)]=bufband1[pos+(width*countLine)];
600
                                        if(iBand==1)
601
                                                compressclient.buffer[pos+(width*iBand)]=bufband2[pos+(width*countLine)];
602
                                        if(iBand==2)
603
                                                compressclient.buffer[pos+(width*iBand)]=bufband3[pos+(width*countLine)];
604
                                        if(iBand==3)
605
                                                compressclient.buffer[pos+(width*iBand)]=bufband4[pos+(width*countLine)];
606
                                        if(iBand==4)
607
                                                compressclient.buffer[pos+(width*iBand)]=bufband5[pos+(width*countLine)];
608
                                        if(iBand==5)
609
                                                compressclient.buffer[pos+(width*iBand)]=bufband6[pos+(width*countLine)];
610
                                }else{
611
                                        if(iBand==0)
612
                                                compressclient.buffer[pos+(width*iBand)] = (byte)((dataBuffer[pos+(width*countLine)] & 0xff0000)>>16);
613
                                        if(iBand==1)
614
                                                compressclient.buffer[pos+(width*iBand)] = (byte)((dataBuffer[pos+(width*countLine)] & 0xff00)>>8);
615
                                        if(iBand==2)        
616
                                                compressclient.buffer[pos+(width*iBand)] = (byte)(dataBuffer[pos+(width*countLine)] & 0xff);
617
                                }
618
                                
619
                                if(pos==width-1 && iBand==this.nBands-1){
620
                                        countLine++;
621
                                }
622
                                
623
                        }
624
                                                
625

    
626
                        
627
                }
628
                                            
629
        }
630
        
631
        public void updatePercent(){
632
                System.out.println(compressclient.getPercent()+"%");
633
        }
634
        
635
}