Statistics
| Revision:

gvsig-raster / org.gvsig.raster.lizardtech / branches / org.gvsig.raster.lizardtech_dataaccess_refactoring / org.gvsig.raster.lizardtech.io / src / main / java / org / gvsig / raster / lizardtech / io / LizardTechProvider.java @ 2308

History | View | Annotate | Download (18.8 KB)

1
package org.gvsig.raster.lizardtech.io;
2

    
3
import java.awt.geom.AffineTransform;
4
import java.awt.geom.Point2D;
5
import java.awt.image.BufferedImage;
6

    
7
import org.gvsig.fmap.dal.DALFileLocator;
8
import org.gvsig.fmap.dal.DALLocator;
9
import org.gvsig.fmap.dal.DataStore;
10
import org.gvsig.fmap.dal.coverage.RasterLocator;
11
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
12
import org.gvsig.fmap.dal.coverage.datastruct.BandList;
13
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
14
import org.gvsig.fmap.dal.coverage.exception.BandAccessException;
15
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
16
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
17
import org.gvsig.fmap.dal.coverage.exception.NotSupportedExtensionException;
18
import org.gvsig.fmap.dal.coverage.exception.ParsingException;
19
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
20
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
21
import org.gvsig.fmap.dal.spi.DataManagerProviderServices;
22
import org.gvsig.fmap.dal.spi.DataStoreProviderServices;
23
import org.gvsig.metadata.MetadataLocator;
24
import org.gvsig.raster.cache.tile.provider.TileServer;
25
import org.gvsig.raster.impl.buffer.SpiRasterQuery;
26
import org.gvsig.raster.impl.datastruct.ExtentImpl;
27
import org.gvsig.raster.impl.process.RasterTask;
28
import org.gvsig.raster.impl.process.RasterTaskQueue;
29
import org.gvsig.raster.impl.provider.AbstractRasterProvider;
30
import org.gvsig.raster.impl.provider.RasterProvider;
31
import org.gvsig.raster.impl.provider.tile.FileTileServer;
32
import org.gvsig.raster.impl.store.AbstractRasterDataParameters;
33
import org.gvsig.raster.impl.store.DefaultRasterStore;
34
import org.gvsig.raster.impl.store.DefaultStoreFactory;
35
import org.gvsig.raster.impl.store.properties.DataStoreColorInterpretation;
36
import org.gvsig.raster.impl.store.properties.DataStoreTransparency;
37
import org.gvsig.tools.ToolsLocator;
38

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

    
135
        /**
136
         * Contructor. Abre el fichero mrsid
137
         * @param proj Proyecci?n
138
         * @param fName Nombre del fichero mrsid
139
         */
140
        public void init(AbstractRasterDataParameters params,
141
                        DataStoreProviderServices storeServices) throws NotSupportedExtensionException {
142
                setParam(storeServices, params);
143
                try {
144
                        file = new LizardTechNative(params.getURI());
145
                        load();
146
                        bandCount = file.nbands;
147
                        int[] dt = new int[bandCount];
148
                        for (int i = 0; i < dt.length; i++)
149
                                dt[i] = Buffer.TYPE_BYTE;
150
                        setDataType(dt);
151
                        super.init();
152

    
153
                        try {
154
                                loadFromRmf(getRmfBlocksManager());
155
                        } catch (ParsingException e) {
156
                                // No lee desde rmf
157
                        }
158
                } catch (Exception e) {
159
                        System.out.println("Error en constructor de MrSID");
160
                        e.printStackTrace();
161
                        file = null;
162
                }
163
                open = true;
164
        }
165

    
166
        public RasterProvider load() {
167
                ownTransformation = file.getOwnTransformation();
168
                externalTransformation = (AffineTransform) ownTransformation.clone();
169
                return this;
170
        }
171
        
172
        public boolean isOpen() {
173
                return open;
174
        }
175

    
176
        public void close() {
177
                if (file != null) {
178
                        file.close();
179
                        file = null;
180
                }
181
                open = false;
182
        }
183

    
184
        public void setView(Extent e) {
185
                viewRequest = new ExtentImpl(e);
186
        }
187

    
188
        public Extent getView() {
189
                return viewRequest;
190
        }
191

    
192
        public double getWidth() {
193
                return file.width;
194
        }
195

    
196
        public double getHeight() {
197
                return file.height;
198
        }
199

    
200
        /**
201
         * Asigna al objeto Image los valores con los dato de la imagen contenidos en
202
         * el vector de enteros.
203
         * @param image imagen con los datos actuales
204
         * @param startX inicio de la posici?n en X dentro de la imagen
205
         * @param startY inicio de la posici?n en X dentro de la imagen
206
         * @param w Ancho de la imagen
207
         * @param h Alto de la imagen
208
         * @param rgbArray vector que contiene la banda que se va a sustituir
209
         * @param offset desplazamiento
210
         * @param scansize tama?o de imagen recorrida por cada p
211
         */
212
        protected void setRGBLine(BufferedImage image, int startX, int startY, int w, int h,
213
                                                                                                                int[] rgbArray, int offset, int scansize) {
214
                image.setRGB(startX, startY, w, h, rgbArray, offset, scansize);
215
        }
216

    
217
        public Object getData(int x, int y, int band) throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
218
                if (file != null) {
219
                        if (x < 0 || y < 0 || x >= file.width || y >= file.height)
220
                                throw new InvalidSetViewException("Request out of grid");
221
                        Object[] data = file.getData(x, y);
222
                        return data[band];
223
                }
224
                throw new FileNotOpenException("MrSIDNative not exist");
225
        }
226

    
227
        public int getBlockSize() {
228
                return file.blocksize;
229
        }
230

    
231
        /**
232
         * Informa de si el driver ha supersampleado en el ?ltimo dibujado. Es el
233
         * driver el que colocar? el valor de esta variable cada vez que dibuja.
234
         * @return true si se ha supersampleado y false si no se ha hecho.
235
         */
236
        public boolean isSupersampling() {
237
                return file.isSupersampling;
238
        }
239
        
240
        @Override
241
        public void loadBuffer(SpiRasterQuery query)
242
                        throws ProcessInterruptedException, RasterDriverException {
243
                setView(query.getAdjustedRequestBoundingBox());
244
                int width = query.getAdjustedBufWidth();
245
                int height = query.getAdjustedBufHeight();
246
                file.setView(viewRequest.getULX(), viewRequest.getULY(), viewRequest.getLRX(), viewRequest.getLRY(), width, height);
247

    
248
                int[] pRGBArray = new int[width * height];
249

    
250
                try {
251
                        RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
252
                        file.readScene(pRGBArray, task);
253
                        loadBuffer(height, 
254
                                        width, 
255
                                        query.getBandList(), 
256
                                        query.getBufferForProviders(), 
257
                                        pRGBArray);
258
                } catch (MrSIDException e) {
259
                        throw new RasterDriverException("Error reading data");
260
                }
261
        }
262
        
263
//        private void loadCachedBuffer(        Buffer buf,
264
//                                                                        Extent inputWindow,
265
//                                                                        RasterTask task, 
266
//                                                                        int[] pRGBArray, 
267
//                                                                        BandList bandList) throws ProcessInterruptedException, MrSIDException {
268
//                if(buf.isCached()) {
269
//                        Point2D blockHeightWC = rasterToWorld(new Point2D.Double(buf.getBlockHeight(), buf.getBlockHeight()));
270
//                        int nBlocks = (int)(inputWindow.height() / blockHeightWC.getX());
271
//                        double lastblockWC = inputWindow.height() - (nBlocks * blockHeightWC.getX());
272
//                        int lastBlock = buf.getHeight() - (nBlocks * buf.getBlockHeight());
273
//                        if(lastblockWC > 0)
274
//                                nBlocks ++;
275
//                        double init = inputWindow.getULY();
276
//                        Extent ext = null;
277
//                        for (int i = 0; i < nBlocks; i++) {
278
//                                if(lastblockWC > 0 && i == (nBlocks - 1)) {
279
//                                        ext = RasterLocator.getManager().getDataStructFactory().createExtent(
280
//                                                        inputWindow.getULX(), 
281
//                                                        init, 
282
//                                                        inputWindow.getLRX(), 
283
//                                                        lastblockWC);
284
//                                        file.setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), buf.getBlockHeight());
285
//                                        file.readScene(pRGBArray, task);
286
//                                        loadPartialBuffer(new int[]{0, i * buf.getBlockHeight(), buf.getWidth(), buf.getHeight() }, 
287
//                                                                        bandList, 
288
//                                                                        buf, 
289
//                                                                        pRGBArray, 
290
//                                                                        buf.getWidth());
291
//                                } else {
292
//                                        ext = RasterLocator.getManager().getDataStructFactory().createExtent(
293
//                                                        inputWindow.getULX(), 
294
//                                                        init, 
295
//                                                        inputWindow.getLRX(), 
296
//                                                        init - blockHeightWC.getX());
297
//                                        file.setView(ext.getULX(), ext.getULY(), ext.getLRX(), ext.getLRY(), buf.getWidth(), lastBlock);
298
//                                        file.readScene(pRGBArray, task);
299
//                                        loadPartialBuffer(new int[]{0, i * buf.getBlockHeight(), buf.getWidth(), i * buf.getBlockHeight() + buf.getBlockHeight() }, 
300
//                                                        bandList, 
301
//                                                        buf, 
302
//                                                        pRGBArray, 
303
//                                                        buf.getWidth());
304
//                                        init += buf.getBlockHeight();
305
//                                }
306
//                        }
307
//                } else {
308
//                        file.setView(inputWindow.getULX(), inputWindow.getULY(), inputWindow.getLRX(), inputWindow.getLRY(), buf.getWidth(), buf.getHeight());
309
//                        file.readScene(pRGBArray, task);
310
//                        loadBuffer(buf.getWidth(), buf.getHeight(), bandList, buf, pRGBArray);
311
//                }
312
//        }
313
//        
314
//        private void loadPartialBuffer(int[] stepBuffer, 
315
//                        BandList bandList, 
316
//                        Buffer rasterBuf, 
317
//                        int[] pRGBArray, 
318
//                        int bufWidth) throws ProcessInterruptedException {
319
//                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
320
//                int[] drawableBandsR = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 0);
321
//                int[] drawableBandsG = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 1);
322
//                int[] drawableBandsB = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 2);
323
//                int element = 0;
324
//                int rowSrc = 0;
325
//                
326
//                for (int row = stepBuffer[1]; row < stepBuffer[3]; row++) {
327
//                        int colSrc = 0;
328
//                        for (int col = stepBuffer[0]; col < stepBuffer[2]; col++) {
329
//                                element = pRGBArray[(rowSrc * bufWidth) + colSrc];
330
//                                if(drawableBandsR != null) {
331
//                                        for (int i = 0; i < drawableBandsR.length; i++) {
332
//                                                if(drawableBandsR[i] >= 0 && drawableBandsR[i] < rasterBuf.getBandCount())
333
//                                                        rasterBuf.setElem(row, col, drawableBandsR[i], (byte) ((element & 0x00ff0000) >> 16));
334
//                                        }
335
//                                }
336
//                                if(drawableBandsG != null) {
337
//                                        for (int i = 0; i < drawableBandsG.length; i++) {
338
//                                                if(drawableBandsG[i] >= 0 && drawableBandsG[i] < rasterBuf.getBandCount())
339
//                                                        rasterBuf.setElem(row, col, drawableBandsG[i], (byte) ((element & 0x0000ff00) >> 8));
340
//                                        }
341
//                                }
342
//                                if(drawableBandsB != null) {
343
//                                        for (int i = 0; i < drawableBandsB.length; i++) {
344
//                                                if(drawableBandsB[i] >= 0 && drawableBandsB[i] < rasterBuf.getBandCount())
345
//                                                        rasterBuf.setElem(row, col, drawableBandsB[i], (byte) (element & 0x000000ff));
346
//                                        }
347
//                                }
348
//                                colSrc ++;
349
//                        }
350
//                        if (task.getEvent() != null)
351
//                                task.manageEvent(task.getEvent());
352
//                        rowSrc ++;
353
//                }        
354
//        }
355
        
356
        private void loadBuffer(int h, int w, BandList bandList, Buffer rasterBuf, int[] pRGBArray) throws ProcessInterruptedException {
357
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
358
                int[] drawableBandsR = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 0);
359
                int[] drawableBandsG = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 1);
360
                int[] drawableBandsB = bandList.getBufferBandToDraw(getURIOfFirstProvider(), 2);
361
                int element = 0;
362
                
363
                for (int row = 0; row < h; row++) {
364
                        for (int col = 0; col < w; col++) {
365
                                element = pRGBArray[(row * w) + col];
366
                                if(drawableBandsR != null) {
367
                                        for (int i = 0; i < drawableBandsR.length; i++) {
368
                                                if(drawableBandsR[i] >= 0 && drawableBandsR[i] < rasterBuf.getBandCount())
369
                                                        rasterBuf.setElem(row, col, drawableBandsR[i], (byte) ((element & 0x00ff0000) >> 16));
370
                                        }
371
                                }
372
                                if(drawableBandsG != null) {
373
                                        for (int i = 0; i < drawableBandsG.length; i++) {
374
                                                if(drawableBandsG[i] >= 0 && drawableBandsG[i] < rasterBuf.getBandCount())
375
                                                        rasterBuf.setElem(row, col, drawableBandsG[i], (byte) ((element & 0x0000ff00) >> 8));
376
                                        }
377
                                }
378
                                if(drawableBandsB != null) {
379
                                        for (int i = 0; i < drawableBandsB.length; i++) {
380
                                                if(drawableBandsB[i] >= 0 && drawableBandsB[i] < rasterBuf.getBandCount())
381
                                                        rasterBuf.setElem(row, col, drawableBandsB[i], (byte) (element & 0x000000ff));
382
                                        }
383
                                }
384
                        }
385
                        if (task.getEvent() != null)
386
                                task.manageEvent(task.getEvent());
387
                }        
388
        }
389

    
390
        public Object readBlock(int pos, int blockHeight, double scale) throws InvalidSetViewException, FileNotOpenException, RasterDriverException, ProcessInterruptedException {
391
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
392

    
393
                if (pos < 0)
394
                        throw new InvalidSetViewException("Request out of grid");
395

    
396
                if ((pos + blockHeight) > file.height)
397
                        blockHeight = Math.abs(file.height - pos);
398

    
399
                Point2D begin = rasterToWorld(new Point2D.Double(0, pos));
400
                Point2D end = rasterToWorld(new Point2D.Double(file.width, pos + blockHeight));
401

    
402
                int w = file.width;
403

    
404
                file.setView(begin.getX(), begin.getY(), end.getX(), end.getY(), w, blockHeight);
405

    
406
                int[] pRGBArray = new int[file.width * blockHeight];
407
                try {
408
                        file.readScene(pRGBArray, task);
409
                        byte[][][] buf = new byte[3][blockHeight][w];
410
                        for (int row = 0; row < blockHeight; row++) {
411
                                for (int col = 0; col < w; col++) {
412
                                        buf[0][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x00ff0000) >> 16);
413
                                        buf[1][row][col] = (byte) ((pRGBArray[(row * w) + col] & 0x0000ff00) >> 8);
414
                                        buf[2][row][col] = (byte) (pRGBArray[(row * w) + col] & 0x000000ff);
415
                                }
416
                                if (task.getEvent() != null)
417
                                        task.manageEvent(task.getEvent());
418
                        }
419
                        return buf;
420
                } catch (MrSIDException e) {
421
                        throw new RasterDriverException("Error reading data");
422
                }
423
        }
424

    
425
        /**
426
         * Read a line from the file
427
         * @param line
428
         * @param band
429
         * @return
430
         * @throws InvalidSetViewException
431
         * @throws FileNotOpenException
432
         * @throws RasterDriverException
433
         * @Deprecated This operation is deprecated because is not useful and in the future
434
         * it will not be maintained. The abstract operation has dissapear
435
         */
436
        public Object readCompleteLine(int line, int band)
437
                                        throws InvalidSetViewException, FileNotOpenException, RasterDriverException {
438
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
439

    
440
                if (line > this.getHeight() || band > this.getBandCount())
441
                        throw new InvalidSetViewException("Request out of grid");
442

    
443
                try {
444
                        Extent extent = getExtent();
445
                        Point2D pt = rasterToWorld(new Point2D.Double(extent.minX(), line));
446
                        file.setView(extent.minX(), pt.getY(), extent.maxX(), pt.getY(), (int)getWidth(), 1);
447
                        int[] pRGBArray = new int[(int)getWidth()];
448
                        file.readScene(pRGBArray, task);
449
                        return pRGBArray;
450
                } catch (MrSIDException e) {
451
                        throw new RasterDriverException("Error reading data from MrSID library");
452
                } catch (ProcessInterruptedException e) {
453
                        // El proceso que debe ser interrumpido es el que llama a readLine.
454
                }
455
                return null;
456
        }
457

    
458
        public DataStoreTransparency getTransparency() {
459
                if (fileTransparency == null)
460
                        fileTransparency = new DataStoreTransparency(getColorInterpretation());
461
                return fileTransparency;
462
        }
463

    
464
        public DataStoreColorInterpretation getColorInterpretation() {
465
                if(colorInterpr == null) {
466
                        colorInterpr = new DataStoreColorInterpretation();
467
                        colorInterpr.initColorInterpretation(getBandCount());
468
                        if(getBandCount() == 1)
469
                                colorInterpr = DataStoreColorInterpretation.createGrayInterpretation();
470
                        if(getBandCount() == 3) {
471
                                colorInterpr =  DataStoreColorInterpretation.createRGBInterpretation();
472
                        }
473
                        if(getBandCount() >= 4) {
474
                                colorInterpr = DataStoreColorInterpretation.createARGBInterpretation();
475
                        }
476
                }
477
                return colorInterpr;
478
        }
479

    
480
        public String getWktProjection() {
481
                // System.err.println("======>" + file);
482
                return null;
483
        }
484

    
485
        public void setAffineTransform(AffineTransform t) {
486
                super.setAffineTransform(t);
487
                file.setExternalTransform(t);
488
        }
489

    
490
        public int getOverviewCount(int band) throws BandAccessException, RasterDriverException {
491
                if (band >= getBandCount())
492
                        throw new BandAccessException("Wrong band");
493
                try {
494
                        return file.getNumLevels();
495
                } catch (MrSIDException e) {
496
                        throw new RasterDriverException("");
497
                }
498
        }
499

    
500
        public int getOverviewWidth(int band, int overview) throws BandAccessException, RasterDriverException {
501
                if (band >= getBandCount())
502
                        throw new BandAccessException("Wrong band");
503
                return 0;
504
        }
505

    
506
        public int getOverviewHeight(int band, int overview) throws BandAccessException, RasterDriverException {
507
                if (band >= getBandCount())
508
                        throw new BandAccessException("Wrong band");
509
                return 0;
510
        }
511

    
512
        public boolean isOverviewsSupported() {
513
                // No podemos escribir por lo que no podemos informar de que soporta overviews aunque el formato si lo haga.
514
                return false;
515
        }
516
        
517
        public String getName() {
518
                return NAME;
519
        }
520
        
521
        public void setStatus(RasterProvider provider) {
522
                if(provider instanceof LizardTechProvider) {
523
                        //Not implemented yet
524
                }
525
        }
526
        
527
        public TileServer getTileServer() {
528
                if(tileServer == null) {
529
                        DefaultRasterStore store = new DefaultRasterStore();
530
                        store.setProvider(this);
531
                        tileServer = new FileTileServer(store);
532
                }
533
                return tileServer;
534
        }
535

    
536

    
537
}