Statistics
| Revision:

svn-gvsig-desktop / trunk / libraries / libRaster / src / org / gvsig / raster / buffer / RasterBuffer.java @ 20759

History | View | Annotate | Download (19.7 KB)

1
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2007 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 */
19
package org.gvsig.raster.buffer;
20

    
21
import java.io.FileNotFoundException;
22

    
23
import org.gvsig.raster.RasterLibrary;
24
import org.gvsig.raster.buffer.cache.RasterCache;
25
import org.gvsig.raster.buffer.cache.RasterReadOnlyBuffer;
26
import org.gvsig.raster.dataset.IBuffer;
27
import org.gvsig.raster.dataset.IRasterDataSource;
28
import org.gvsig.raster.dataset.NotSupportedExtensionException;
29
import org.gvsig.raster.dataset.io.RasterDriverException;
30
import org.gvsig.raster.datastruct.Histogram;
31
import org.gvsig.raster.process.RasterTask;
32
import org.gvsig.raster.process.RasterTaskQueue;
33
import org.gvsig.raster.util.RasterUtilities;
34

    
35
/**
36
 * Rectangulo de pixeles. Para cada tipo de datos java hay un buffer distinto donde cada elemento es
37
 * accedido de la siguiente forma: [banda][fila][columna]
38
 * m[1][2][0] = cte;-> Sustituye el elemento de la fila 2 de la banda 1 columna 0
39
 * m[1][0] = array; -> Sustituye la fila 0 de la banda 1 
40
 * m[0] = matriz cuadrada; -> Sustituye la banda entera.
41
 * 
42
 */
43
public abstract class RasterBuffer implements IBuffer {
44
        public static final int      INTERPOLATION_PROCESS = 0;
45
        public static final int      HISTOGRAM_PROCESS = 1;
46
        
47
        protected boolean[]                     cancel = new boolean[1];
48

    
49
        public double                             noDataValue = -99999;
50

    
51
        protected int                             progressHistogram = 0;
52
        protected int                             progressInterpolation = 0;
53
        protected boolean                     canceled = false;
54

    
55
        protected int                             width;
56
        protected int                             height;
57
        protected int                             nBands;
58
        protected int                             dataType;
59
        
60
        /**
61
         * Variable est?tica que si est? a false desactiva el uso de cach?. Puede ser usada por un cliente
62
         * para cargar siempre los datos en memoria. independientemente de su tama?o. 
63
         */
64
        public static boolean                      cacheOn = true;
65
        /**
66
         * Fuerza la carga de los datos en cach? independientemente de su tama?o. Su
67
         * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
68
         * es siempre false.
69
         */
70
        public static boolean               forceToLoadInCache = false;
71
        /**
72
         * Fuerza la carga de los datos en cach? de solo lectura independientemente de su tama?o. Su
73
         * uso suele ser util solo para depuraci?n. Su valor por defecto y recomendado
74
         * es siempre false.
75
         */
76
        public static boolean              forceToLoadInReadOnlyCache = false;
77
        /**
78
         * Valor con el que se rellena una banda no valida del buffer. Una banda no valida es la que 
79
         * no tiene datos asignados y tampoco puede ser null. Todas las bandas no validas de un buffer
80
         * apuntan por referencia a la misma banda.
81
         */
82
        protected double                             notValidValue = 0D;
83
        
84
        private BufferInterpolation         interp = null;
85
        
86
        /**
87
         * Proceso del cual se devuelve el porcentaje cuando este es solicitado
88
         */
89
        private int                    process = HISTOGRAM_PROCESS;
90

    
91
        /**
92
         * Genera instancias del buffer de datos adecuado al tama?o del raster. Si no hay muchos datos
93
         * (menos de cacheMemorySize) crear? un buffer en memoria. Si hay m?s de esta cantidad
94
         * entonces crearemos un buffer cacheado (RasterCache). A partir de la cantidad se?alada
95
         * por multicacheMemorySize haremos un buffer cacheado donde cada p?gina no ocupa todo
96
         * el ancho del raster ya que este ser? muy grande. La gesti?n de una cache donde cada
97
         * pagina ha de partir una l?nea lleva una complejidad a?adida.
98
         *  
99
         * @param dataType Tipo de dato
100
         * @param width Ancho
101
         * @param height Alto
102
         * @param bandNr Banda
103
         * @param flag En caso de buffers de memoria este flag a true significa que se reserva la memoria
104
         * para el buffer de forma normal y si est? a false no se reserva por lo que la reserva deber? ser
105
         * posterior. 
106
         * @return Objeto RasterBuffer
107
         * @throws RasterDriverException 
108
         * @throws NotSupportedExtensionException 
109
         * @throws FileNotFoundException 
110
         */
111
        public static RasterBuffer getBuffer(int dataType, int width, int height, int bandNr, boolean malloc) 
112
                /*throws FileNotFoundException, NotSupportedExtensionException, RasterDriverException*/{
113
                //Opci?n de cachear siempre activada (Solo DEBUG)
114
                if(forceToLoadInCache)
115
                        return new RasterCache(dataType, width, height, bandNr);
116
                if(forceToLoadInReadOnlyCache){
117
                return new RasterReadOnlyBuffer(dataType, width, height, bandNr);
118
                }
119
                        
120
                if(cacheOn){
121
                        long size = (RasterUtilities.getBytesFromRasterBufType(dataType) * width * height * bandNr) / 1024;
122
                        long ms1 = RasterLibrary.cacheSize * 1024;
123
                        if(size <= ms1)
124
                                return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc);
125
                        else
126
                                return new RasterCache(dataType, width, height, bandNr);
127
                }else
128
                        return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc);
129
        }
130
                
131
        /**
132
         * Genera una instancia del buffer de solo lectura. Este buffer consta de una cache y unos apuntadores
133
         * a las p?ginas en disco. Cuando se accede a los datos se carga en memoria la p?gina pedida.
134
         *  
135
         * @param dataType Tipo de dato
136
         * @param width Ancho
137
         * @param height Alto
138
         * @param bandNr Banda
139
         */
140
        public static RasterBuffer getReadOnlyBuffer(int dataType, int width, int height, int bandNr) {
141
                return new RasterReadOnlyBuffer(dataType, width, height, bandNr);
142
        }
143
        
144
        /**
145
         * Genera una instancia del buffer de solo lectura. Este buffer consta de una cache y unos apuntadores
146
         * a las p?ginas en disco. Cuando se accede a los datos se carga en memoria la p?gina pedida.
147
         *  
148
         * @param dataType Tipo de dato
149
         * @param width Ancho
150
         * @param height Alto
151
         * @param bandNr Banda
152
         * @param flag En caso de buffers de memoria este flag a true significa que se reserva la memoria
153
         * para el buffer de forma normal y si est? a false no se reserva por lo que la reserva deber? ser
154
         * posterior. 
155
         */
156
        public static RasterBuffer getMemoryBuffer(int dataType, int width, int height, int bandNr, boolean malloc) {
157
                return new RasterMemoryBuffer(dataType, width, height, bandNr, malloc);
158
        }
159
        /**
160
         * Devuelve true si el tama?o del dataset es menor que el de la cach? y false 
161
         * si no lo es.
162
         * @param datasource Fuente de datos
163
         * @return true si podemos cargar en memoria el raster
164
         */
165
        public static boolean loadInMemory(IRasterDataSource datasource) {
166
                return (datasource.getFileSize() < (RasterLibrary.cacheSize * 1048576));
167
        }
168
        
169
        /**
170
         * Dadas unas coordenadas pixel y un n?mero de bandas, esta funci?n comprueba si 
171
         * el tama?o de ventana que va a generarse supera el tama?o de la cach? 
172
         * @param coords Coordenadas pixel del raster
173
         * @param bands N?mero de bandas
174
         * @param ds
175
         * @return true si la ventana supera el tama?o de la cach? o false si no lo supera.
176
         */
177
        public static boolean isBufferTooBig(double[] coords, int bands) {                
178
                int w = (int)Math.abs(coords[2] - coords[0]);
179
                int h = (int)Math.abs(coords[3] - coords[1]);
180

    
181
                long windowSize = w * h * bands; 
182
                return (windowSize > (RasterLibrary.cacheSize * 1048576));
183
        }  
184
        
185
        /**
186
         * Reserva de memoria para el rasterbuf
187
         * @param dataType Tipo de dato
188
         * @param width Ancho
189
         * @param height Alto
190
         * @param bandNr Numero de bandas
191
         * @param orig
192
         */
193
        public abstract void malloc(int dataType, int width, int height, int bandNr);
194
 
195
        /*
196
         *  (non-Javadoc)
197
         * @see org.gvsig.fmap.driver.IBuffer#getWidth()
198
         */
199
        public int getWidth() {
200
                        return width;
201
        }
202

    
203
 /*
204
        *  (non-Javadoc)
205
        * @see org.gvsig.fmap.driver.IBuffer#getHeight()
206
        */
207
        public int getHeight() {
208
                        return height;
209
        }
210

    
211
        /*
212
         *  (non-Javadoc)
213
         * @see org.gvsig.fmap.driver.IBuffer#getBandCount()
214
         */
215
        public int getBandCount() {
216
                        return nBands;
217
        }
218

    
219
        /**
220
         * Obtiene el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
221
         * @return tipo de datos
222
         */
223
        public int getDataType() {
224
                return dataType;
225
        }
226
        
227
        /**
228
         * Asigna el tipo de dato. Los tipos de dato posibles est?n definidos en IRaster.
229
         * @param dataType Tipo de dato del buffer
230
         */
231
        public void setDataType(int dataType) {
232
                this.dataType = dataType;
233
        }
234

    
235
        /**
236
         * Obtiene el tama?o del tipo de dato en bytes
237
         * @return Tipo de dato
238
         */
239
        public int getDataSize() {
240
                        if (dataType == TYPE_BYTE) {
241
                                        return 1;
242
                        } else if ((dataType == TYPE_SHORT) | (dataType == TYPE_USHORT)) {
243
                                        return 2;
244
                        } else if (dataType == TYPE_INT) {
245
                                        return 4;
246
                        }else if (dataType == TYPE_FLOAT) {
247
                                        return 8;
248
                        }else if (dataType == TYPE_DOUBLE) {
249
                                        return 16;
250
                        }
251

    
252
                        return 0;
253
        }
254

    
255
        /**
256
         * Obtiene el tama?o del buffer
257
         * @return tama?o del buffer
258
         */
259
        public long sizeof() {
260
                        return getDataSize() * width * height * nBands;
261
        }
262
        
263
        /**
264
         * Replica la banda de una posici?n sobre otra. Si la banda de destino no existe
265
         * se crea nueva. Si la posici?n de la banda de destino est? intercalada entre bandas 
266
         * que ya existen las otras se desplazan hacia abajo, NO se machacan los datos de ninguna.
267
         * Los datos se replican por referencia por lo que al modificar la banda original las
268
         * del resto quedar?n afectadas.
269
         * @param orig. Posici?n de la banda de origen. 
270
         * @param dest. Posici?n de la banda destino
271
         */   
272
        public abstract void replicateBand(int orig, int dest);
273
        
274
        /**
275
         * Cambia bandas de posici?n. Las posiciones deben existir como bandas del raster. 
276
         * Cada elemento del array representa una banda existente en el buffer (de longitud
277
         * rasterBuf.length) y el valor contenido dentro la banda que le corresponde. Por ejemplo
278
         * si pasamos un array {1, 0, 3, 2} significa que el buffer tiene cuatro bandas y que 
279
         * cambiamos la 0 por la 1 y la 2 por la 3. Un array {0, 1, 2, 3} en el mismo 
280
         * caso no producir?a nig?n cambio.
281
         * 
282
         * Si quisieramos asignar en un buffer monobanda su banda a la segunda posici?n habria
283
         * que insertar una vacia, por ejemplo con addBandFloat(0, null) se insertaria una 
284
         * banda nula en la posici?n 0 y la banda que estaba en la 0 pasar?a a la segunda.
285
         * 
286
         */
287
        public abstract void switchBands(int[] bandPosition);
288
                
289
        /**
290
         * Convierte un tipo de dato a cadena
291
         * @param type Tipo de dato
292
         * @return cadena  que representa el tipo de dato
293
         */
294
        public static String typesToString(int type) {
295
                        switch (type) {
296
                        case RasterBuffer.TYPE_IMAGE:
297
                                        return new String("Image");
298

    
299
                        case RasterBuffer.TYPE_BYTE:
300
                                        return new String("Byte");
301

    
302
                        case RasterBuffer.TYPE_DOUBLE:
303
                                        return new String("Double");
304

    
305
                        case RasterBuffer.TYPE_FLOAT:
306
                                        return new String("Float");
307

    
308
                        case RasterBuffer.TYPE_INT:
309
                                return new String("Integer");
310
                                
311
                        case RasterBuffer.TYPE_USHORT:
312
                        case RasterBuffer.TYPE_SHORT:
313
                                        return new String("Short");
314
                        }
315

    
316
                        return null;
317
        }
318
        
319
        /*
320
         * (non-Javadoc)
321
         * @see org.gvsig.raster.dataset.IBuffer#isInside(int, int)
322
         */
323
        public boolean isInside(int x, int y) {
324
                if (x < 0 || y < 0 || x >= getWidth() || y >= getHeight())
325
                        return false;
326
                return true;
327
        }
328
                        
329
        /*
330
         *  (non-Javadoc)
331
         * @see org.gvsig.fmap.driver.IBuffer#getNoDataValue()
332
         */
333
        public double getNoDataValue() {
334
                return noDataValue;
335
        }
336
        
337
        /*
338
         *  (non-Javadoc)
339
         * @see org.gvsig.fmap.driver.IBuffer#getByteNoDataValue()
340
         */
341
        public byte getByteNoDataValue() {
342
                return (byte)noDataValue;
343
        }
344
        
345
        /*
346
         *  (non-Javadoc)
347
         * @see org.gvsig.fmap.driver.IBuffer#getShortNoDataValue()
348
         */
349
        public short getShortNoDataValue(){
350
                return (short)noDataValue;
351
        }
352
        
353
        /*
354
         *  (non-Javadoc)
355
         * @see org.gvsig.fmap.driver.IBuffer#getIntNoDataValue()
356
         */
357
        public int getIntNoDataValue(){
358
                return (int)noDataValue;
359
        }
360
        
361
        /*
362
         *  (non-Javadoc)
363
         * @see org.gvsig.fmap.driver.IBuffer#getFloatNoDataValue()
364
         */
365
        public float getFloatNoDataValue(){
366
                return (float)noDataValue;
367
        }
368
        
369
        /*
370
         *  (non-Javadoc)
371
         * @see org.gvsig.fmap.driver.IBuffer#setNoDataValue(double)
372
         */
373
        public void setNoDataValue(double nd){
374
                noDataValue = nd;
375
        }
376
        
377
        /*
378
         *  (non-Javadoc)
379
         * @see org.gvsig.fmap.driver.IBuffer#getNotValidValue()
380
         */
381
        public double getNotValidValue(){
382
                return notValidValue;
383
        }
384
        
385
        /*
386
         *  (non-Javadoc)
387
         * @see org.gvsig.fmap.driver.IBuffer#setNotValidValue(java.lang.Object)
388
         */
389
        public void setNotValidValue(double value){
390
                this.notValidValue = value;
391
        }
392
        
393
        /*
394
         *  (non-Javadoc)
395
         * @see org.gvsig.fmap.driver.IBuffer#cloneBuffer()
396
         */
397
        public abstract IBuffer cloneBuffer();
398

    
399
        /**
400
         * Ajusta el ?rea del grid a un ancho y un alto dado en pixeles. Este ajuste se har? 
401
         * en relaci?n a un m?todo de interpolaci?n definido en el par?metro.
402
         * @param w Ancho de la nueva imagen.
403
         * @param h Alto de la nueva imagen.
404
         * @param interpolation M?todo de interpolaci?n que se usar? en el ajuste.
405
         */
406
        public RasterBuffer getAdjustedWindow(int w, int h, int interpolationMethod) throws InterruptedException {
407
                if (interp == null)
408
                        interp = new BufferInterpolation(this);
409

    
410
                if (w == getWidth() && h == getHeight())
411
                        return this;
412
                RasterBuffer rasterBuf = null;
413
                switch (interpolationMethod) {
414
                        case BufferInterpolation.INTERPOLATION_NearestNeighbour:
415
                                rasterBuf = interp.adjustRasterNearestNeighbourInterpolation(w, h);
416
                                break;
417
                        case BufferInterpolation.INTERPOLATION_Bilinear:
418
                                rasterBuf = interp.adjustRasterBilinearInterpolation(w, h);
419
                                break;
420
                        case BufferInterpolation.INTERPOLATION_InverseDistance:
421
                                rasterBuf = interp.adjustRasterInverseDistanceInterpolation(w, h);
422
                                break;
423
                        case BufferInterpolation.INTERPOLATION_BicubicSpline:
424
                                rasterBuf = interp.adjustRasterBicubicSplineInterpolation(w, h);
425
                                break;
426
                        case BufferInterpolation.INTERPOLATION_BSpline:
427
                                rasterBuf = interp.adjustRasterBSplineInterpolation(w, h);
428
                                break;
429
                }
430
                if (rasterBuf != null)
431
                        return rasterBuf;
432
                else
433
                        return this;
434
        }
435
        
436
        public BufferInterpolation getLastInterpolation() {
437
                return interp;
438
        }
439

    
440
        /*
441
         * (non-Javadoc)
442
         * @see org.gvsig.raster.dataset.IBuffer#getLimits()
443
         */
444
        public double[] getLimits() throws InterruptedException {
445
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
446
                double max = Double.NEGATIVE_INFINITY;
447
                double secondMax = max;
448
                double min = Double.MAX_VALUE;
449
                double secondMin = min;
450
                double value = 0;
451

    
452
                switch (getDataType()) {
453
                        case IBuffer.TYPE_BYTE:
454
                                for (int i = 0; i < getBandCount(); i++)
455
                                        for (int r = 0; r < getHeight(); r++) {
456
                                                for (int c = 0; c < getWidth(); c++) {
457
                                                        value = (double) ((getElemByte(r, c, i)));
458
                                                        if (value > max) {
459
                                                                if (max != value) secondMax = max;
460
                                                                max = value;
461
                                                        }
462
                                                        if (value < min) {
463
                                                                if (min != value) secondMin = min;
464
                                                                min = value;
465
                                                        }
466
                                                }
467
                                                if (task.getEvent() != null)
468
                                                        task.manageEvent(task.getEvent());
469
                                        }
470
                                break;
471
                        case IBuffer.TYPE_SHORT:
472
                                for (int i = 0; i < getBandCount(); i++)
473
                                        for (int r = 0; r < getHeight(); r++) {
474
                                                for (int c = 0; c < getWidth(); c++) {
475
                                                        value = (double) getElemShort(r, c, i);
476
                                                        if (value > max) {
477
                                                                if (max != value) secondMax = max;
478
                                                                max = value;
479
                                                        }
480
                                                        if (value < min) {
481
                                                                if (min != value) secondMin = min;
482
                                                                min = value;
483
                                                        }
484
                                                }
485
                                                if (task.getEvent() != null)
486
                                                        task.manageEvent(task.getEvent());
487
                                        }
488
                                break;
489
                        case IBuffer.TYPE_INT:
490
                                for (int i = 0; i < getBandCount(); i++)
491
                                        for (int r = 0; r < getHeight(); r++) {
492
                                                for (int c = 0; c < getWidth(); c++) {
493
                                                        value = (double) getElemInt(r, c, i);
494
                                                        if (value > max) {
495
                                                                if (max != value) secondMax = max;
496
                                                                max = value;
497
                                                        }
498
                                                        if (value < min) {
499
                                                                if (min != value) secondMin = min;
500
                                                                min = value;
501
                                                        }
502
                                                }
503
                                                if (task.getEvent() != null)
504
                                                        task.manageEvent(task.getEvent());
505
                                        }
506
                                break;
507
                        case IBuffer.TYPE_FLOAT:
508
                                for (int i = 0; i < getBandCount(); i++)
509
                                        for (int r = 0; r < getHeight(); r++) {
510
                                                for (int c = 0; c < getWidth(); c++) {
511
                                                        value =  (double) getElemFloat(r, c, i);
512
                                                        if (value > max) {
513
                                                                if (max != value) secondMax = max;
514
                                                                max = value;
515
                                                        }
516
                                                        if (value < min) {
517
                                                                if (min != value) secondMin = min;
518
                                                                min = value;
519
                                                        }
520
                                                }
521
                                                if (task.getEvent() != null)
522
                                                        task.manageEvent(task.getEvent());
523
                                        }
524
                                break;
525
                        case IBuffer.TYPE_DOUBLE:
526
                                for (int i = 0; i < getBandCount(); i++)
527
                                        for (int r = 0; r < getHeight(); r++) {
528
                                                for (int c = 0; c < getWidth(); c++) {
529
                                                        value = getElemDouble(r, c, i);
530
                                                        if (value > max) {
531
                                                                if (max != value) secondMax = max;
532
                                                                max = value;
533
                                                        }
534
                                                        if (value < min) {
535
                                                                if (min != value) secondMin = min;
536
                                                                min = value;
537
                                                        }
538
                                                }
539
                                                if (task.getEvent() != null)
540
                                                        task.manageEvent(task.getEvent());
541
                                        }
542
                                break;
543
                }
544
                // Si no existe un secondMax lo igualo al maximo existente
545
                if (secondMax == Double.NEGATIVE_INFINITY)
546
                        secondMax = max;
547
                // Si no existe un secondMin lo igualo al minimo existente
548
                if (secondMin == Double.MAX_VALUE)
549
                        secondMin = min;
550
                
551
                double[] values = new double[4];
552
                values[0] = min;
553
                values[1] = max;
554
                values[2] = secondMin;
555
                values[3] = secondMax;
556
                return values;
557
        }
558

    
559
        /*
560
         * (non-Javadoc)
561
         * @see org.gvsig.raster.driver.datasetproperties.IHistogramable#getHistogram()
562
         */
563
        public Histogram getHistogram() throws InterruptedException {
564
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
565
                progressHistogram = 0;
566
                Histogram hist = null;
567
                double[] limits = getLimits();
568

    
569
                if (limits == null)
570
                        return null;
571

    
572
                if (getDataType() == IBuffer.TYPE_BYTE)
573
                        hist = new Histogram(getBandCount(), 256, limits[0], limits[1]);
574
                else
575
                        hist = new Histogram(getBandCount(), RasterLibrary.defaultNumberOfClasses, limits[0], limits[1]);
576
                                
577
                for (int iBand = 0; iBand < getBandCount(); iBand++) {
578
                        for (int row = 0; row < getHeight(); row++) {
579
                                switch(getDataType()) {
580
                                case IBuffer.TYPE_BYTE:
581
                                        for (int col = 0; col < getWidth(); col++) 
582
                                                hist.incrementPxValue(iBand, (double)(getElemByte(row, col, iBand)));
583
                                        break;
584
                                case IBuffer.TYPE_SHORT:
585
                                        for (int col = 0; col < getWidth(); col++) 
586
                                                hist.incrementPxValue(iBand, (double)(getElemShort(row, col, iBand)));
587
                                        break;
588
                                case IBuffer.TYPE_INT:
589
                                        for (int col = 0; col < getWidth(); col++) 
590
                                                hist.incrementPxValue(iBand, (double)(getElemInt(row, col, iBand)));
591
                                        break;
592
                                case IBuffer.TYPE_FLOAT:
593
                                        for (int col = 0; col < getWidth(); col++) 
594
                                                hist.incrementPxValue(iBand, (double)getElemFloat(row, col, iBand));
595
                                        break;
596
                                case IBuffer.TYPE_DOUBLE:
597
                                        for (int col = 0; col < getWidth(); col++) 
598
                                                hist.incrementPxValue(iBand, getElemDouble(row, col, iBand));
599
                                        break;
600
                                }
601
                                
602
                                if (task.getEvent() != null)
603
                                        task.manageEvent(task.getEvent());
604

    
605
                                progressHistogram = ((iBand*getHeight() + row) * 100) /(getHeight() * getBandCount());
606
                        }
607
                }
608
                progressHistogram = 100;
609
                return hist;
610
        }
611

    
612
        /*
613
         * (non-Javadoc)
614
         * @see org.gvsig.raster.util.IHistogramable#resetPercent()
615
         */
616
        public void resetPercent() {
617
                switch(process) {
618
                case HISTOGRAM_PROCESS: progressHistogram = 0;
619
                case INTERPOLATION_PROCESS: progressInterpolation = 0;
620
                }
621
        }
622

    
623
        /*
624
         * (non-Javadoc)
625
         * @see org.gvsig.raster.util.IHistogramable#getPercent()
626
         */
627
        public int getPercent() {
628
                switch(process) {
629
                case HISTOGRAM_PROCESS: return progressHistogram;
630
                case INTERPOLATION_PROCESS: return progressInterpolation;
631
                }
632
                return 0;
633
        }
634
        
635
        /**
636
         * Asigna el proceso del cual se desea obtener informaci?n. Los procesos
637
         * disponibles se definen como constantes en esta clase.
638
         * @param process
639
         */
640
        public void setProcess(int process) {
641
                this.process = process;
642
        }
643
}