Statistics
| Revision:

gvsig-raster / org.gvsig.raster / trunk / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / buffer / RasterBuffer.java @ 5462

History | View | Annotate | Download (19.1 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
 *
3
 * Copyright (C) 2007-2008 Infrastructures and Transports Department
4
 * of the Valencian Government (CIT)
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., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 */
22
package org.gvsig.raster.impl.buffer;
23

    
24
import java.awt.geom.AffineTransform;
25
import java.awt.geom.NoninvertibleTransformException;
26
import java.awt.geom.Point2D;
27
import java.awt.geom.Rectangle2D;
28

    
29
import org.cresques.cts.ICoordTrans;
30
import org.gvsig.fmap.dal.DataStore;
31
import org.gvsig.fmap.dal.coverage.RasterLibrary;
32
import org.gvsig.fmap.dal.coverage.RasterLocator;
33
import org.gvsig.fmap.dal.coverage.dataset.AbstractBuffer;
34
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
35
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
36
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
37
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
38
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
39
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
40
import org.gvsig.fmap.dal.coverage.exception.WarpException;
41
import org.gvsig.fmap.dal.coverage.process.IncrementableTask;
42
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
43
import org.gvsig.fmap.dal.coverage.store.props.HistogramComputer;
44
import org.gvsig.raster.impl.process.RasterTask;
45
import org.gvsig.raster.impl.process.RasterTaskQueue;
46
import org.gvsig.tools.exception.BaseException;
47
import org.gvsig.tools.visitor.Visitor;
48

    
49
/**
50
 * Rectangulo de pixeles. Para cada tipo de datos java hay un buffer distinto donde cada elemento es
51
 * accedido de la siguiente forma: [banda][fila][columna]
52
 * m[1][2][0] = cte;-> Sustituye el elemento de la fila 2 de la banda 1 columna 0
53
 * m[1][0] = array; -> Sustituye la fila 0 de la banda 1 
54
 * m[0] = matriz cuadrada; -> Sustituye la banda entera.
55
 * 
56
 */
57
public abstract class RasterBuffer extends AbstractBuffer implements Buffer {
58
        public static final int     INTERPOLATION_PROCESS      = 0;
59
        
60
        protected boolean[]                    cancel                     = new boolean[1];
61
        public NoData                            noDataValue                = null;
62
        protected int                            progressInterpolation      = 0;
63
        protected boolean                    canceled                   = false;
64

    
65
        protected int                            width;
66
        protected int                            height;
67
        protected int                            nBands;
68
        protected int                            dataType;
69
        private Rectangle2D         dataExtent                 = null;
70
        /**
71
         * Reference to the parent RasterDataStore 
72
         */
73
        private RasterDataStore     store                      = null;      
74
        
75
        /**
76
         * Variable est?tica que si est? a false desactiva el uso de cach?. Puede ser usada por un cliente
77
         * para cargar siempre los datos en memoria. independientemente de su tama?o. 
78
         */
79
        public static boolean                cacheOn                    = true;
80
        /**
81
         * Fuerza la carga de los datos en cach? independientemente de su tama?o. Su
82
         * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
83
         * es siempre false.
84
         */
85
        public static boolean             forceToLoadInCache         = false;
86
        /**
87
         * Fuerza la carga de los datos en cach? de solo lectura independientemente de su tama?o. Su
88
         * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
89
         * es siempre false.
90
         */
91
        public static boolean             forceToLoadInReadOnlyCache = false;
92
        /**
93
         * Valor con el que se rellena una banda no valida del buffer. Una banda no valida es la que 
94
         * no tiene datos asignados y tampoco puede ser null. Todas las bandas no validas de un buffer
95
         * apuntan por referencia a la misma banda.
96
         */
97
        protected double                        notValidValue              = 0D;
98
        
99
        /**
100
         * Proceso del cual se devuelve el porcentaje cuando este es solicitado
101
         */
102
        private int                 process                    = INTERPOLATION_PROCESS;
103
        private HistogramComputer   histogramComputer          = null;
104
        private BufferInterpolation interp                     = null;
105
        
106
        public RasterDataStore getStore() {
107
                return store;
108
        }
109

    
110
        public void setStore(RasterDataStore store) {
111
                this.store = store;
112
        } 
113
        
114
        /**
115
         * Reserva de memoria para el rasterbuf
116
         * @param dataType Tipo de dato
117
         * @param width Ancho
118
         * @param height Alto
119
         * @param bandNr Numero de bandas
120
         * @param orig
121
         */
122
        public abstract void malloc(int dataType, int width, int height, int bandNr);
123
 
124
        public int getWidth() {
125
                        return width;
126
        }
127
        
128
        /**
129
         * Gets a bouding box of this buffer
130
         * @return
131
         */
132
        public Rectangle2D getDataExtent() {
133
                return dataExtent;
134
        }
135
        
136
        /**
137
         * Sets a bounding box of this buffer
138
         * @param r
139
         */
140
        public void setDataExtent(Rectangle2D r) {
141
                this.dataExtent = r;
142
        }
143

    
144
        public int getHeight() {
145
                        return height;
146
        }
147

    
148
        public int getBandCount() {
149
                        return nBands;
150
        }
151

    
152
        /**
153
         * Obtiene el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
154
         * @return tipo de datos
155
         */
156
        public int getDataType() {
157
                return dataType;
158
        }
159
        
160
        /**
161
         * Asigna el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
162
         * @param dataType Tipo de dato del buffer
163
         */
164
        public void setDataType(int dataType) {
165
                this.dataType = dataType;
166
        }
167

    
168
        /**
169
         * Obtiene el tama?o del tipo de dato en bytes
170
         * @return Tipo de dato
171
         */
172
        public int getDataSize() {
173
                        if (dataType == TYPE_BYTE) {
174
                                        return 1;
175
                        } else if ((dataType == TYPE_SHORT) | (dataType == TYPE_USHORT)) {
176
                                        return 2;
177
                        } else if (dataType == TYPE_INT) {
178
                                        return 4;
179
                        }else if (dataType == TYPE_FLOAT) {
180
                                        return 8;
181
                        }else if (dataType == TYPE_DOUBLE) {
182
                                        return 16;
183
                        }
184

    
185
                        return 0;
186
        }
187

    
188
        /**
189
         * Obtiene el tama?o del buffer
190
         * @return tama?o del buffer
191
         */
192
        public long sizeof() {
193
                        return getDataSize() * width * height * nBands;
194
        }
195
        
196
        /**
197
         * Replica la banda de una posici?n sobre otra. Si la banda de destino no existe
198
         * se crea nueva. Si la posici?n de la banda de destino est? intercalada entre bandas 
199
         * que ya existen las otras se desplazan hacia abajo, NO se machacan los datos de ninguna.
200
         * Los datos se replican por referencia por lo que al modificar la banda original las
201
         * del resto quedar?n afectadas.
202
         * @param orig. Posici?n de la banda de origen. 
203
         * @param dest. Posici?n de la banda destino
204
         */   
205
        public abstract void replicateBand(int orig, int dest);
206
        
207
        /**
208
         * Cambia bandas de posici?n. Las posiciones deben existir como bandas del raster. 
209
         * Cada elemento del array representa una banda existente en el buffer (de longitud
210
         * rasterBuf.length) y el valor contenido dentro la banda que le corresponde. Por ejemplo
211
         * si pasamos un array {1, 0, 3, 2} significa que el buffer tiene cuatro bandas y que 
212
         * cambiamos la 0 por la 1 y la 2 por la 3. Un array {0, 1, 2, 3} en el mismo 
213
         * caso no producir?a nig?n cambio.
214
         * 
215
         * Si quisieramos asignar en un buffer monobanda su banda a la segunda posici?n habria
216
         * que insertar una vacia, por ejemplo con addBandFloat(0, null) se insertaria una 
217
         * banda nula en la posici?n 0 y la banda que estaba en la 0 pasar?a a la segunda.
218
         * 
219
         */
220
        public abstract void switchBands(int[] bandPosition);
221
                
222
        /**
223
         * Convierte un tipo de dato a cadena
224
         * @param type Tipo de dato
225
         * @return cadena  que representa el tipo de dato
226
         */
227
        public static String typesToString(int type) {
228
                        switch (type) {
229
                        case RasterBuffer.TYPE_IMAGE:
230
                                        return new String("Image");
231

    
232
                        case RasterBuffer.TYPE_BYTE:
233
                                        return new String("Byte");
234

    
235
                        case RasterBuffer.TYPE_DOUBLE:
236
                                        return new String("Double");
237

    
238
                        case RasterBuffer.TYPE_FLOAT:
239
                                        return new String("Float");
240

    
241
                        case RasterBuffer.TYPE_INT:
242
                                return new String("Integer");
243
                                
244
                        case RasterBuffer.TYPE_USHORT:
245
                        case RasterBuffer.TYPE_SHORT:
246
                                        return new String("Short");
247
                        }
248

    
249
                        return null;
250
        }
251
        
252
        public boolean isInside(int x, int y) {
253
                if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
254
                        return false;
255
                return true;
256
        }
257
                        
258
        public NoData getNoDataValue() {
259
                return noDataValue;
260
        }
261
        
262
        public int getBlockHeight() {
263
                return RasterLibrary.blockHeight;
264
        }
265
        
266
        public void setNoDataValue(NoData nd){
267
                noDataValue = nd;
268
        }
269
        
270
        public double getNotValidValue(){
271
                return notValidValue;
272
        }
273
        
274
        public void setNotValidValue(double value){
275
                this.notValidValue = value;
276
        }
277
        
278
        public abstract Buffer cloneBuffer();
279
        
280
        /**
281
         * Ajusta el ?rea del grid a un ancho y un alto dado en pixeles. Este ajuste se har? 
282
         * en relaci?n a un m?todo de interpolaci?n definido en el par?metro.
283
         * @param w Ancho de la nueva imagen.
284
         * @param h Alto de la nueva imagen.
285
         * @param interpolation M?todo de interpolaci?n que se usar? en el ajuste.
286
         */
287
        public Buffer getAdjustedWindow(int w, int h, int interpolationMethod) throws ProcessInterruptedException {
288
                getBufferInterpolation();
289
                if (w == getWidth() && h == getHeight())
290
                        return this;
291
                Buffer rasterBuf = null;
292
                switch (interpolationMethod) {
293
                        case Buffer.INTERPOLATION_NearestNeighbour:
294
                                rasterBuf = interp.adjustRasterNearestNeighbourInterpolation(w, h);
295
                                break;
296
                        case Buffer.INTERPOLATION_Bilinear:
297
                                rasterBuf = interp.adjustRasterBilinearInterpolation(w, h);
298
                                break;
299
                        case Buffer.INTERPOLATION_InverseDistance:
300
                                rasterBuf = interp.adjustRasterInverseDistanceInterpolation(w, h);
301
                                break;
302
                        case Buffer.INTERPOLATION_BicubicSpline:
303
                                rasterBuf = interp.adjustRasterBicubicSplineInterpolation(w, h);
304
                                break;
305
                        case Buffer.INTERPOLATION_BSpline:
306
                                rasterBuf = interp.adjustRasterBSplineInterpolation(w, h);
307
                                break;
308
                }
309
                if (rasterBuf != null)
310
                        return rasterBuf;
311
                else
312
                        return this;
313
        }
314
        
315
        public IncrementableTask getIncrementableTask(int type) {
316
                switch (type) {
317
                case INCREMENTABLE_INTERPOLATION:
318
                        return getBufferInterpolation();
319
                case INCREMENTABLE_HISTOGRAM:
320
                        return getHistogramComputer();
321
                }
322
                return null;
323
        }
324
        
325
        /**
326
         * Gets the buffer interpolation
327
         * @return
328
         */
329
        private BufferInterpolation getBufferInterpolation() {
330
                if(interp == null)
331
                        interp = new BufferInterpolation(this);
332
                return interp;
333
        }
334

    
335
        public HistogramComputer getHistogramComputer() {
336
                if(histogramComputer == null)
337
                        histogramComputer = new BufferHistogramComputer(this);
338
                return histogramComputer;
339
        }
340
        
341
        public double[] getLimits() throws ProcessInterruptedException {
342
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
343
                double max = Double.NEGATIVE_INFINITY;
344
                double secondMax = max;
345
                double min = Double.MAX_VALUE;
346
                double secondMin = min;
347
                double value = 0;
348

    
349
                switch (getDataType()) {
350
                        case Buffer.TYPE_BYTE:
351
                                for (int i = 0; i < getBandCount(); i++)
352
                                        for (int r = 0; r < getHeight(); r++) {
353
                                                for (int c = 0; c < getWidth(); c++) {
354
                                                        value = (double) ((getElemByte(r, c, i)));
355
                                                        if (value > max) {
356
                                                                if (max != value) secondMax = max;
357
                                                                max = value;
358
                                                        }
359
                                                        if (value < min) {
360
                                                                if (min != value) secondMin = min;
361
                                                                min = value;
362
                                                        }
363
                                                }
364
                                                if (task.getEvent() != null)
365
                                                        task.manageEvent(task.getEvent());
366
                                        }
367
                                break;
368
                        case Buffer.TYPE_SHORT:
369
                                for (int i = 0; i < getBandCount(); i++)
370
                                        for (int r = 0; r < getHeight(); r++) {
371
                                                for (int c = 0; c < getWidth(); c++) {
372
                                                        value = (double) getElemShort(r, c, i);
373
                                                        if (value > max) {
374
                                                                if (max != value) secondMax = max;
375
                                                                max = value;
376
                                                        }
377
                                                        if (value < min) {
378
                                                                if (min != value) secondMin = min;
379
                                                                min = value;
380
                                                        }
381
                                                }
382
                                                if (task.getEvent() != null)
383
                                                        task.manageEvent(task.getEvent());
384
                                        }
385
                                break;
386
                        case Buffer.TYPE_INT:
387
                                for (int i = 0; i < getBandCount(); i++)
388
                                        for (int r = 0; r < getHeight(); r++) {
389
                                                for (int c = 0; c < getWidth(); c++) {
390
                                                        value = (double) getElemInt(r, c, i);
391
                                                        if (value > max) {
392
                                                                if (max != value) secondMax = max;
393
                                                                max = value;
394
                                                        }
395
                                                        if (value < min) {
396
                                                                if (min != value) secondMin = min;
397
                                                                min = value;
398
                                                        }
399
                                                }
400
                                                if (task.getEvent() != null)
401
                                                        task.manageEvent(task.getEvent());
402
                                        }
403
                                break;
404
                        case Buffer.TYPE_FLOAT:
405
                                for (int i = 0; i < getBandCount(); i++)
406
                                        for (int r = 0; r < getHeight(); r++) {
407
                                                for (int c = 0; c < getWidth(); c++) {
408
                                                        value =  (double) getElemFloat(r, c, i);
409
                                                        if (value > max) {
410
                                                                if (max != value) secondMax = max;
411
                                                                max = value;
412
                                                        }
413
                                                        if (value < min) {
414
                                                                if (min != value) secondMin = min;
415
                                                                min = value;
416
                                                        }
417
                                                }
418
                                                if (task.getEvent() != null)
419
                                                        task.manageEvent(task.getEvent());
420
                                        }
421
                                break;
422
                        case Buffer.TYPE_DOUBLE:
423
                                for (int i = 0; i < getBandCount(); i++)
424
                                        for (int r = 0; r < getHeight(); r++) {
425
                                                for (int c = 0; c < getWidth(); c++) {
426
                                                        value = getElemDouble(r, c, i);
427
                                                        if (value > max) {
428
                                                                if (max != value) secondMax = max;
429
                                                                max = value;
430
                                                        }
431
                                                        if (value < min) {
432
                                                                if (min != value) secondMin = min;
433
                                                                min = value;
434
                                                        }
435
                                                }
436
                                                if (task.getEvent() != null)
437
                                                        task.manageEvent(task.getEvent());
438
                                        }
439
                                break;
440
                }
441
                // Si no existe un secondMax lo igualo al maximo existente
442
                if (secondMax == Double.NEGATIVE_INFINITY)
443
                        secondMax = max;
444
                // Si no existe un secondMin lo igualo al minimo existente
445
                if (secondMin == Double.MAX_VALUE)
446
                        secondMin = min;
447
                
448
                double[] values = new double[4];
449
                values[0] = min;
450
                values[1] = max;
451
                values[2] = secondMin;
452
                values[3] = secondMax;
453
                return values;
454
        }
455
        
456
        public double[][] getAllBandsLimits() throws ProcessInterruptedException {
457
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
458
                double max[] = new double[getBandCount()];
459
                double min[] = new double[getBandCount()];
460
                double value = 0;
461

    
462
                for (int i = 0; i < getBandCount(); i++) {
463
                        max[i] = Double.NEGATIVE_INFINITY;
464
                        min[i] = Double.MAX_VALUE;
465
                }
466
                
467
                switch (getDataType()) {
468
                        case Buffer.TYPE_BYTE:
469
                                for (int i = 0; i < getBandCount(); i++) {
470
                                        for (int r = 0; r < getHeight(); r++) {
471
                                                for (int c = 0; c < getWidth(); c++) {
472
                                                        value = (double) ((getElemByte(r, c, i)));
473
                                                        if (value > max[i])
474
                                                                max[i] = value;
475
                                                        if (value < min[i])
476
                                                                min[i] = value;
477
                                                }
478
                                                if (task.getEvent() != null)
479
                                                        task.manageEvent(task.getEvent());
480
                                        }
481
                                }
482
                                break;
483
                        case Buffer.TYPE_SHORT:
484
                                for (int i = 0; i < getBandCount(); i++) {
485
                                        for (int r = 0; r < getHeight(); r++) {
486
                                                for (int c = 0; c < getWidth(); c++) {
487
                                                        value = (double) getElemShort(r, c, i);
488
                                                        if (value > max[i])
489
                                                                max[i] = value;
490
                                                        if (value < min[i])
491
                                                                min[i] = value;
492
                                                }
493
                                                if (task.getEvent() != null)
494
                                                        task.manageEvent(task.getEvent());
495
                                        }
496
                                }
497
                                break;
498
                        case Buffer.TYPE_INT:
499
                                for (int i = 0; i < getBandCount(); i++) {
500
                                        for (int r = 0; r < getHeight(); r++) {
501
                                                for (int c = 0; c < getWidth(); c++) {
502
                                                        value = (double) getElemInt(r, c, i);
503
                                                        if (value > max[i])
504
                                                                max[i] = value;
505
                                                        if (value < min[i])
506
                                                                min[i] = value;
507
                                                }
508
                                                if (task.getEvent() != null)
509
                                                        task.manageEvent(task.getEvent());
510
                                        }
511
                                }
512
                                break;
513
                        case Buffer.TYPE_FLOAT:
514
                                for (int i = 0; i < getBandCount(); i++) {
515
                                        for (int r = 0; r < getHeight(); r++) {
516
                                                for (int c = 0; c < getWidth(); c++) {
517
                                                        value = (double) getElemFloat(r, c, i);
518
                                                        if (value > max[i])
519
                                                                max[i] = value;
520
                                                        if (value < min[i])
521
                                                                min[i] = value;
522
                                                }
523
                                                if (task.getEvent() != null)
524
                                                        task.manageEvent(task.getEvent());
525
                                        }
526
                                }
527
                                break;
528
                        case Buffer.TYPE_DOUBLE:
529
                                for (int i = 0; i < getBandCount(); i++) {
530
                                        for (int r = 0; r < getHeight(); r++) {
531
                                                for (int c = 0; c < getWidth(); c++) {
532
                                                        value = getElemDouble(r, c, i);
533
                                                        if (value > max[i])
534
                                                                max[i] = value;
535
                                                        if (value < min[i])
536
                                                                min[i] = value;
537
                                                }
538
                                                if (task.getEvent() != null)
539
                                                        task.manageEvent(task.getEvent());
540
                                        }
541
                                }
542
                                break;
543
                }
544
                double[][] values = new double[2][getBandCount()];
545

    
546
                for (int i = 0; i < getBandCount(); i++) {
547
                        values[0][i] = min[i];
548
                        values[1][i] = max[i];
549
                }
550
                return values;
551
        }
552
        
553
        public void addDrawableBands(int[] db) {
554
                
555
        }
556

    
557
        public void resetPercent() {
558
                switch(process) {
559
                case INTERPOLATION_PROCESS: progressInterpolation = 0;
560
                }
561
        }
562

    
563
        public int getPercent() {
564
                switch(process) {
565
                case INTERPOLATION_PROCESS: return progressInterpolation;
566
                }
567
                return 0;
568
        }
569
        
570
        /**
571
         * Asigna el proceso del cual se desea obtener informaci?n. Los procesos
572
         * disponibles se definen como constantes en esta clase.
573
         * @param process
574
         */
575
        public void setProcess(int process) {
576
                this.process = process;
577
        }
578
        
579
        public boolean isCached() {
580
                return false;
581
        }
582

    
583
        //****************************************************
584
        //*********Implementing DataSet methods***************
585
        //****************************************************
586

    
587
        public boolean isFromStore(DataStore store) {
588
                return store == this.store;
589
        }
590

    
591
        //****************************************************
592
        //*********Implementing Visitable methods*************
593
        //****************************************************
594

    
595
        public void accept(Visitor visitor) throws BaseException {
596
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
597

    
598
                switch (getDataType()) {
599
                case Buffer.TYPE_BYTE:
600
                        for (int i = 0; i < getBandCount(); i++) {
601
                                for (int r = 0; r < getHeight(); r++) {
602
                                        for (int c = 0; c < getWidth(); c++) 
603
                                                visitor.visit(getElemByte(r, c, i));
604
                                        if (task.getEvent() != null)
605
                                                task.manageEvent(task.getEvent());
606
                                }
607
                        }
608
                        break;
609
                case Buffer.TYPE_SHORT:
610
                        for (int i = 0; i < getBandCount(); i++) {
611
                                for (int r = 0; r < getHeight(); r++) {
612
                                        for (int c = 0; c < getWidth(); c++)
613
                                                visitor.visit(getElemShort(r, c, i));
614
                                        if (task.getEvent() != null)
615
                                                task.manageEvent(task.getEvent());
616
                                }
617
                        }
618
                        break;
619
                case Buffer.TYPE_INT:
620
                        for (int i = 0; i < getBandCount(); i++) {
621
                                for (int r = 0; r < getHeight(); r++) {
622
                                        for (int c = 0; c < getWidth(); c++)
623
                                                visitor.visit(getElemInt(r, c, i));
624
                                        if (task.getEvent() != null)
625
                                                task.manageEvent(task.getEvent());
626
                                }
627
                        }
628
                        break;
629
                case Buffer.TYPE_FLOAT:
630
                        for (int i = 0; i < getBandCount(); i++) {
631
                                for (int r = 0; r < getHeight(); r++) {
632
                                        for (int c = 0; c < getWidth(); c++)
633
                                                visitor.visit(getElemFloat(r, c, i));
634
                                        if (task.getEvent() != null)
635
                                                task.manageEvent(task.getEvent());
636
                                }
637
                        }
638
                        break;
639
                case Buffer.TYPE_DOUBLE:
640
                        for (int i = 0; i < getBandCount(); i++) {
641
                                for (int r = 0; r < getHeight(); r++) {
642
                                        for (int c = 0; c < getWidth(); c++)
643
                                                visitor.visit(getElemDouble(r, c, i));
644
                                        if (task.getEvent() != null)
645
                                                task.manageEvent(task.getEvent());
646
                                }
647
                        }
648
                        break;
649
                }
650
        }
651

    
652
        protected void finalize() throws Throwable {
653
                histogramComputer          = null;
654
                store                      = null;
655
                dataExtent                 = null;
656
                cancel                     = null;
657
                noDataValue                = null;
658
                super.finalize();
659
        }
660

    
661
}