Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.api / src / main / java / org / gvsig / fmap / dal / coverage / grid / filter / BaseRasterFilter.java @ 2308

History | View | Annotate | Download (12.5 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.fmap.dal.coverage.grid.filter;
23

    
24
import java.util.Hashtable;
25
import java.util.TreeMap;
26

    
27
import org.gvsig.fmap.dal.coverage.RasterLocator;
28
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
29
import org.gvsig.fmap.dal.coverage.dataset.BufferParam;
30
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
31
import org.gvsig.fmap.dal.coverage.datastruct.Params;
32
import org.gvsig.fmap.dal.coverage.exception.BufferCreationException;
33
import org.gvsig.fmap.dal.coverage.exception.FilterAddException;
34
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
35
import org.gvsig.fmap.dal.coverage.grid.RasterFilter;
36
import org.gvsig.fmap.dal.coverage.process.TaskEventManager;
37
import org.gvsig.fmap.dal.coverage.store.props.ColorInterpretation;
38
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
39
import org.gvsig.fmap.dal.coverage.util.RasterUtils;
40
import org.gvsig.tools.locator.LocatorException;
41

    
42
/**
43
 * Base class for all filters
44
 *
45
 * @author Nacho Brodin (nachobrodin@gmail.com)
46
 */
47
public abstract class BaseRasterFilter implements RasterFilter, Cloneable {
48
        public static final String PERSISTENT_NAME        = "BaseRasterFilter";
49
    public static final String PERSISTENT_DESCRIPTION = "BaseRasterFilter Persistent";
50
        protected Buffer           raster                 = null;
51
        protected int[]            renderBands            = null;
52
        protected Buffer           rasterResult           = null;
53
        protected int              height                 = 0;
54
        protected int              width                  = 0;
55
        protected Hashtable<String, Object> 
56
                                   params                 = new Hashtable<String, Object>();
57
        protected TreeMap<String, Object>   
58
                                   environment            = new TreeMap<String, Object>();
59
        protected Extent           extent                 = null;
60
        private int                percent                = 0;
61
        private String             fName                  = "";
62
        /**
63
         * Variable que control la aplicaci?n o no del filtro. Si est? a false aunque est? en
64
         * la pila el filtro no se ejecutar?.
65
         */
66
        protected boolean           exec                  = true;
67
        protected RasterUtils       util                  = null;
68
        protected TaskEventManager  taskEventManager      = null;
69
        protected String            managername           = null;
70
        protected Transparency      transparency          = null;
71
        
72
        private boolean             hasInputTransparency       = false;
73
        private int                 nBandsToProcess       = 0;
74
        protected ColorInterpretation 
75
                                    colorInterpretation   = null;
76
        private boolean             argbOutput            = false;
77

    
78
        /**
79
         * Constructor
80
         */
81
        public BaseRasterFilter() {
82
                if(RasterLocator.getManager() != null)
83
                        util = RasterLocator.getManager().getRasterUtils();
84
        }
85

    
86
        /**
87
         * Aplica el filtro sobre el raster pasado pixel a pixel
88
         * @throws ProcessInterruptedException
89
         * @throws FilterAddException 
90
         */
91
        public void execute() throws ProcessInterruptedException, FilterAddException {
92
                taskEventManager = RasterLocator.getManager().createRasterTask(this);
93
                pre();
94
                if (raster != null && raster.getDataType() != this.getInRasterDataType())
95
                        exec = false;
96
                percent = 0;
97
                if (exec)
98
                        for (int row = 0; row < height; row ++) {
99
                                for (int col = 0; col < width; col ++)
100
                                        try {
101
                                                process(col, row);
102
                                        }catch (ArrayIndexOutOfBoundsException e) {
103
                                        }
104

    
105
                                if (taskEventManager.getEvent() != null)
106
                                        taskEventManager.manageEvent(taskEventManager.getEvent());
107

    
108
                                percent = (row * 100) / height;
109
                        }
110
                percent = 100;
111
                post();
112
        }
113

    
114
        /**
115
         * A?ade un par?metro al filtro
116
         *
117
         * @param name Clave del par?metro
118
         * @param param Objeto pasado como par?metro
119
         */
120
        public void addParam(String name, Object param) {
121
                if (param != null)
122
                        params.put(name, param);
123
                else
124
                        params.remove(name);
125
        }
126

    
127
        /**
128
         * Elimina un par?metro del filtro
129
         * @param name Clave del par?metro a eliminar
130
         */
131
        public void removeParam(String name) {
132
                params.remove(name);
133
        }
134

    
135
        /**
136
         * Obtiene un par?metro a partir de la clave
137
         * @param name Par?metro
138
         * @return Par?metro
139
         */
140
        public Object getParam(String name) {
141
                return params.get(name);
142
        }
143

    
144
        public Hashtable<String, Object> getParams() {
145
                return params;
146
        }
147

    
148
        public void setParams(Hashtable<String, Object> params) {
149
                this.params = params;
150
        }
151

    
152
        public void setExtent(Extent extent) {
153
                this.extent = extent;
154
        }
155

    
156
        /**
157
         * Obtiene true si el filtro va a ser ejecutado o false si no va a serlo
158
         * @return
159
         */
160
        public boolean isExec() {
161
                return exec;
162
        }
163

    
164
        /**
165
         * Asigna el valor a la variable exec. Esta estar? a true si el filtro se ejecutar? la pr?xima
166
         * vez que se repinte o false si no se ejecuta.
167
         * @param exec
168
         */
169
        public void setExec(boolean exec) {
170
                this.exec = exec;
171
        }
172

    
173
        /**
174
         * Pone a cero el contador del porcentaje del proceso de filtrado
175
         * @return
176
         */
177
        public void resetPercent() {
178
                percent = 0;
179
        }
180

    
181
        /**
182
         * Obtiene el porcentaje recorrido del proceso de filtrado
183
         * @return
184
         */
185
        public int getPercent() {
186
                return percent;
187
        }
188
        
189
        public int[] getRenderBands() {
190
                return renderBands;
191
        }
192

    
193
        /**
194
         * Funci?n que contiene el c?digo a ejecutar despues de aplicar el filtro
195
         */
196
        abstract public void post();
197

    
198
        /**
199
         * Ejecuci?n del filtro para un pixel de la imagen
200
         */
201
        abstract public void process(int x, int y);
202

    
203
        /**
204
         * Obtiene el tipo de datos del raster de entrada
205
         */
206
        abstract public int getInRasterDataType();
207

    
208
        /**
209
         * Obtiene el tipo de datos del raster de salida
210
         */
211
        abstract public int getOutRasterDataType();
212

    
213
        /**
214
         * Gets the result of this filter
215
         */
216
        public Object getResult(String name) {
217
                if (name.equals(RESULT_BUFFER)) {
218
                        if (exec)
219
                                return (Object) this.rasterResult;
220
                        else
221
                                return (Object) this.raster;
222
                }
223

    
224
                if (name.equals(RESULT_TRANSPARENCY)) {
225
                        ColorInterpretation ci = null;
226
                        if(rasterResult.getDataType() == Buffer.TYPE_BYTE) {
227
                                if(argbOutput || (rasterResult.getBandCount() == 4 && hasInputTransparency())) {
228
                                        ci = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(
229
                                                        new String[]{ColorInterpretation.RED_BAND,
230
                                                                        ColorInterpretation.GREEN_BAND,
231
                                                                        ColorInterpretation.BLUE_BAND,
232
                                                                        ColorInterpretation.ALPHA_BAND});
233
                                        transparency.setColorInterpretation(ci);
234
                                        transparency.activeTransparency();
235
                                        return transparency;
236
                                } else if(rasterResult.getBandCount() == 3 && renderBands != null && renderBands.length >=3) {
237
                                        ci = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(renderBands);
238
                                        transparency.setColorInterpretation(ci);
239
                                        transparency.activeTransparency();
240
                                        return transparency;
241
                                }
242
                        } 
243
                        String[] values = new String[rasterResult.getBandCount()];
244
                        for (int i = 0; i < values.length; i++) {
245
                                values[i] = ColorInterpretation.UNDEF_BAND;
246
                        }
247
                        ci = RasterLocator.getManager().getDataStructFactory().createColorInterpretation(values);
248
                        transparency.setColorInterpretation(ci);
249
                        transparency.activeTransparency();
250
                        return transparency;
251
                }
252
                return null;
253
        }
254
        
255
        abstract public String getGroup();
256
        abstract public Params getUIParams(String nameFilter);
257
        abstract public String[] getNames();
258

    
259
        public boolean isVisible() {
260
                return true;
261
        }
262

    
263
        public Object clone() throws CloneNotSupportedException {
264
                return super.clone();
265
        }
266

    
267
        public String getName() {
268
                return fName;
269
        }
270

    
271
        public void setName(String name) {
272
                fName = name;
273
        }
274

    
275
        public TreeMap<String, Object> getEnv() {
276
                return environment;
277
        }
278

    
279
        public void setEnv(TreeMap<String, Object> env) {
280
                this.environment = env;
281
        }
282

    
283
        public String getManagerName() {
284
                return managername;
285
        }
286

    
287
        /**
288
         * Releases buffer resources
289
         */
290
        public void dispose() {
291
                
292
        }
293
        
294
        protected Buffer getOutputBuffer() {
295
                return rasterResult;
296
        }
297
        
298
        protected Buffer getInputBuffer() {
299
                return raster;
300
        }
301
        
302
        protected void finalize() throws Throwable {
303
                rasterResult = null;
304
                raster = null;
305
                extent = null;
306
                fName = null;
307
                super.finalize();
308
        }
309

    
310
        /**
311
         * Code to execute before apply a filter
312
         */
313
        public void pre() throws FilterAddException {
314
                exec = true;
315
                raster = (Buffer) params.get("raster");
316
                renderBands = (int[]) params.get("renderBands");
317
                transparency = (Transparency)environment.get("Transparency");
318
                height = raster.getHeight();
319
                width = raster.getWidth();
320
                
321
                //?til para imagenes de tipo byte que puedan traer transparencia
322
                if(        raster != null && 
323
                        transparency != null && 
324
                        raster.getDataType() == Buffer.TYPE_BYTE &&
325
                        transparency.existAlphaBand()/* || 
326
                         transparency.isTransparencyActive() || 
327
                         transparency.getColorInterpretation().isPalette())*/) {
328
                        nBandsToProcess = raster.getBandCount() - 1;
329
                        hasInputTransparency = true;
330
                        /*if(transparency.getAlphaBandNumber() == -1) {
331
                                transparency.setTransparencyBand(nBandsToProcess + 1);
332
                                transparency.activeTransparency();
333
                        }*/
334
                } else
335
                        nBandsToProcess = raster.getBandCount();
336
        }
337
        
338
        //*****************************************
339
        //Support methods
340
        //*****************************************
341
        
342
        protected void createARGBBufferResult() throws FilterAddException {
343
                BufferParam param = RasterLocator.getManager().getBufferFactory().createBufferParams(width, height, 4, Buffer.TYPE_BYTE, true);
344
                try {
345
                        rasterResult = RasterLocator.getManager().getBufferFactory().createBuffer(param);
346
                        if(raster != null)
347
                                rasterResult.setDataExtent(raster.getDataExtent());
348
                        argbOutput = true;
349
                } catch (LocatorException e) {
350
                        throw new FilterAddException("Error creating buffer", e);
351
                } catch (BufferCreationException e) {
352
                        throw new FilterAddException("Error creating buffer", e);
353
                }
354
        }
355
        
356
        protected void createBufferResult(int dataType, int bandCount) throws FilterAddException {
357
                BufferParam param = RasterLocator.getManager().getBufferFactory().createBufferParams(width, height, bandCount, dataType, true);
358
                try {
359
                        rasterResult = RasterLocator.getManager().getBufferFactory().createBuffer(param);
360
                        if(raster != null)
361
                                rasterResult.setDataExtent(raster.getDataExtent());
362
                } catch (LocatorException e) {
363
                        throw new FilterAddException("Error creating buffer", e);
364
                } catch (BufferCreationException e) {
365
                        throw new FilterAddException("Error creating buffer", e);
366
                }
367
        }
368
        
369
        /**
370
         * Checks the renderBands array for RGB inputs. If it is not good, 
371
         * it will be calculated. This function will have into account the 
372
         * transparency object to render the alpha band
373
         */
374
        protected void checkRGBRenderBands() {
375
                for (int i = 0; i < renderBands.length; i++) {
376
                        if(renderBands[i] >= raster.getBandCount())
377
                                renderBands[i] = -1;
378
                }
379
                
380
                //Necesita 3 bandas para renderizar, ya que la entrada debe ser un valor RGB
381
                int countBandsToDraw = 0;
382
                for (int i = 0; i < renderBands.length; i++) {
383
                        if(renderBands[i] >= 0 && renderBands[i] < 3)
384
                                countBandsToDraw ++;
385
                }
386
                //Si no tiene al menos 3 bandas de entrada calculamos el renderBands
387
                if(renderBands == null || countBandsToDraw < 3) {
388
                        switch (raster.getBandCount()) {
389
                        case 1:renderBands = new int[]{0, 0, 0}; break;
390
                        case 2:renderBands = new int[]{0, 1, 1}; break;
391
                        case 3:renderBands = new int[]{0, 1, 2}; break;
392
                        default:
393
                                if(transparency.existAlphaBand())
394
                                        renderBands = new int[]{0, 1, 2, 3}; 
395
                                else
396
                                        renderBands = new int[]{0, 1, 2};
397
                        }
398
                }
399
        }
400
        
401
        /**
402
         * Copies the alpha band from the input raster to the output.
403
         * In most filters, this band is not processed and it will copy
404
         * it directly in the output
405
         */
406
        protected void writeAlphaBand(int line, int col) {
407
                if(hasInputTransparency)  {
408
                        rasterResult.setElem(line, col, rasterResult.getBandCount() - 1, 
409
                                        raster.getElemByte(line, col, raster.getBandCount() - 1));
410
                }
411
        }
412
        
413
        protected boolean hasInputTransparency() {
414
                return hasInputTransparency;
415
        }
416
        
417
        protected int numberOfBandsToProcess() {
418
                return nBandsToProcess;
419
        }
420
}