Statistics
| Revision:

root / branches / CqCMSDvp / libraries / libCq CMS for java.old / src / org / cresques / io / raster / RasterFilterStackManager.java @ 2249

History | View | Annotate | Download (21.4 KB)

1
/*
2
 * Created on 17-may-2005
3
 *
4
 * To change the template for this generated file go to
5
 * Window>Preferences>Java>Code Generation>Code and Comments
6
 */
7
/* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
8
 *
9
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
10
 *
11
 * This program is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU General Public License
13
 * as published by the Free Software Foundation; either version 2
14
 * of the License, or (at your option) any later version.
15
 *
16
 * This program is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
24
 *
25
 * For more information, contact:
26
 *
27
 *  Generalitat Valenciana
28
 *   Conselleria d'Infraestructures i Transport
29
 *   Av. Blasco Ib??ez, 50
30
 *   46010 VALENCIA
31
 *   SPAIN
32
 *
33
 *      +34 963862235
34
 *   gvsig@gva.es
35
 *      www.gvsig.gva.es
36
 *
37
 *    or
38
 *
39
 *   IVER T.I. S.A
40
 *   Salamanca 50
41
 *   46005 Valencia
42
 *   Spain
43
 *
44
 *   +34 963163400
45
 *   dac@iver.es
46
 */
47
package org.cresques.io.raster;
48

    
49
import java.lang.reflect.Constructor;
50
import java.util.ArrayList;
51
import java.util.Hashtable;
52
import java.util.StringTokenizer;
53
import java.util.regex.Matcher;
54
import java.util.regex.Pattern;
55
 
56
/**
57
 * 
58
 * @author Nacho Brodin <brodin_ign@gva.es>
59
 * 
60
 * Esta clase es de la parte cliente y es la encargada de la gesti?n 
61
 * de la pila de filtros. Es la que conoce el orden en que se deben apilar
62
 * estos para que la ejecuci?n sea correcta. Un cliente que desee aplicar un 
63
 * filtro deber? introducirlo en la pila usando para ello esta clase.
64
 */
65
public class RasterFilterStackManager implements IStackManager{
66
        
67
        protected RasterFilterStack        filterStack = null;
68
        private boolean                                debug = false;
69
        
70
        protected Hashtable                 typeFilters = new Hashtable();
71
        public        int[]                                order = null;
72
        private ArrayList                        managers = new ArrayList();
73
        protected ArrayList                        filterList = null;
74
        
75
        public RasterFilterStackManager(RasterFilterStack filterStack){
76
                this.filterStack = filterStack;
77
                typeFilters.put("transparency", new Integer(0));
78
                typeFilters.put("enhanced", new Integer(1));
79
                typeFilters.put("computeminmax", new Integer(2));
80
                typeFilters.put("tail", new Integer(3));
81
                init();
82
                this.filterStack.setOrder(order);
83
        }
84
        
85
        /**
86
         * Registra un manager del sistema
87
         * @param manager
88
         */
89
        protected void register(IStackManager manager){
90
                managers.add(manager);
91
        }
92
        
93
        protected void init(){
94
                order = new int[typeFilters.size()];
95
                order[0] = ((Integer)typeFilters.get("computeminmax")).intValue();
96
                order[1] = ((Integer)typeFilters.get("tail")).intValue();
97
                order[2] = ((Integer)typeFilters.get("enhanced")).intValue();
98
                order[3] = ((Integer)typeFilters.get("transparency")).intValue();
99
        }
100
                
101
        /**
102
         * A?ade un nuevo tipo de filtro 
103
         * @param key        Nombre del filtro
104
         * @param type        Constante entera asignada a ese tipo
105
         */
106
        protected void addTypeFilter(String key, int type, int position){
107
                typeFilters.put(key, new Integer(type));
108
                int[] newOrder = new int[order.length+1];
109
                for(int i=0;i<position;i++)
110
                        newOrder[i] = order[i];
111
                newOrder[position] = type;
112
                for(int i=position+1;i<newOrder.length;i++)
113
                        newOrder[i] = order[i-1];
114
                order = newOrder;
115
                this.filterStack.setOrder(order);
116
        }
117
        
118
        /**
119
         * Obtiene la constante correspondiente a un tipo de filtro
120
         * @param key        Clave para obtener la constante que corresponde al nombre del filtro
121
         * @return        Tipo de filtro
122
         */
123
        public int getTypeFilter(String key){
124
                return ((Integer)typeFilters.get(key)).intValue();
125
        }
126
        
127
        /**
128
         * A?ade un filtro de transparencia
129
         * @param red        Intervalos de la banda del rojo a poner transparentes
130
         * @param green        Intervalos de la banda del verde a poner transparentes
131
         * @param blue        Intervalos de la banda del azul a poner transparentes
132
         * @param alpha        Transparencia
133
         * @param transparencyRed        Color en la banda del rojo de la transparencia
134
         * @param transparencyGreen        Color en la banda del verde de la transparencia
135
         * @param transparencyBlue        Color en la banda del azul de la transparencia
136
         */
137
        public void addTransparencyFilter(        int[][] red,
138
                                                                                int[][] green,
139
                                                                                int[][] blue,
140
                                                                                int alpha,
141
                                                                                int transparencyRed,
142
                                                                                int transparencyGreen,
143
                                                                                int transparencyBlue){
144
                RasterFilter filtro = null;
145
                switch(filterStack.getDataTypeInFilter(((Integer)typeFilters.get("transparency")).intValue())){
146
                        case RasterBuf.TYPE_IMAGE:filtro = new TransparencyImageFilter();break;
147
                        case RasterBuf.TYPE_SHORT:
148
                        case RasterBuf.TYPE_USHORT:
149
                        case RasterBuf.TYPE_INT:filtro = new TransparencyShortFilter();break;
150
                }
151
                if(red != null)filtro.addParam("red", red);
152
                if(green != null)filtro.addParam("green", green);
153
                if(blue != null)filtro.addParam("blue", blue);
154
                filtro.addParam("alpha", new Integer(alpha));
155
                filtro.addParam("transparencyRed", new Integer(transparencyRed));
156
                filtro.addParam("transparencyGreen",  new Integer(transparencyGreen));
157
                filtro.addParam("transparencyBlue",  new Integer(transparencyBlue));
158
                
159
                //Elimina los filtros que son equivalentes a este
160
                
161
                /*for(int i=0;i<filterStack.lenght();i++){
162
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
163
                                filterStack.get(i) instanceof TransparencyShortFilter){
164
                                 
165
                                //Si este filtro es equivalente a uno de la pila se elimina este
166
                                if(((TransparencyFilter)filtro).isEquivalent((TransparencyFilter)filterStack.get(i)))
167
                                        filterStack.removeFilter(filterStack.get(i));        
168
                                
169
                        }        
170
                }
171
                
172
                //A?ade el filtro si no hay uno equivalente 
173
                
174
                boolean equivalentFilter = false;
175
                for(int i=0;i<filterStack.lenght();i++){
176
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
177
                                filterStack.get(i) instanceof TransparencyShortFilter){
178
                                
179
                                //Si no existe en la pila un filtro equivalente se a?ade
180
                                if(((TransparencyFilter)filterStack.get(i)).isEquivalent((TransparencyFilter)filtro)){
181
                                        equivalentFilter = true;
182
                                        break;
183
                                }
184
                        }        
185
                }
186
                if(!equivalentFilter)*/
187
                filterStack.removeFilter(((Integer)typeFilters.get("transparency")).intValue());
188
                filterStack.addFilter(((Integer)typeFilters.get("transparency")).intValue(), filtro);
189
                this.controlTypes();
190
        }
191
        
192
        /**
193
         * Obtiene el rango de rojo del filtro de transparencia de la pila
194
         * @return rango de rojo
195
         */
196
        public int[][] getTransparecyR(){
197
                for(int i=0;i<filterStack.lenght();i++){
198
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
199
                                filterStack.get(i) instanceof TransparencyShortFilter){
200
                                return ((TransparencyFilter)filterStack.get(i)).rangesR;
201
                        }        
202
                }
203
                return null;
204
        }
205
        
206
        /**
207
         * Obtiene el rango de verde del filtro de transparencia de la pila
208
         * @return rango de verde
209
         */
210
        public int[][] getTransparecyG(){
211
                for(int i=0;i<filterStack.lenght();i++){
212
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
213
                                filterStack.get(i) instanceof TransparencyShortFilter){
214
                                return ((TransparencyFilter)filterStack.get(i)).rangesG;
215
                        }        
216
                }
217
                return null;
218
        }
219
        
220
        /**
221
         * Obtiene el rango de azul del filtro de transparencia de la pila
222
         * @return rango de azul
223
         */
224
        public int[][] getTransparecyB(){
225
                for(int i=0;i<filterStack.lenght();i++){
226
                        if( filterStack.get(i) instanceof TransparencyImageFilter ||
227
                                filterStack.get(i) instanceof TransparencyShortFilter){
228
                                return ((TransparencyFilter)filterStack.get(i)).rangesB;
229
                        }        
230
                }
231
                return null;
232
        }
233
        
234
        /**
235
         * A?ade un filtro de recorte de colas.
236
         * @param tail        porcentaje de recorte
237
         * @param samples        porcentaje de muestras tomadas del total de la imagen
238
         */
239
        public void addTailFilter( double tail, double samples, boolean removeMaxValue){
240
                if(filterStack.isActive(((Integer)typeFilters.get("tail")).intValue()))
241
                        filterStack.removeFilter(((Integer)typeFilters.get("tail")).intValue());
242
                
243
                RasterFilter filtro = null;
244
                switch(filterStack.getDataTypeInFilter(((Integer)typeFilters.get("tail")).intValue())){
245
                        case RasterBuf.TYPE_IMAGE:filtro = new PercentTailTrimImageFilter();break;
246
                        case RasterBuf.TYPE_SHORT:
247
                        case RasterBuf.TYPE_USHORT:
248
                        case RasterBuf.TYPE_INT:filtro = new PercentTailTrimShortFilter();break;
249
                }
250
                filtro.addParam("stats", filterStack.getStats());
251
                filtro.addParam("tail", new Double(tail));
252
                filtro.addParam("samples", new Double(samples));
253
                filtro.addParam("remove", new Boolean(removeMaxValue));
254
                
255
                filterStack.addFilter(((Integer)typeFilters.get("tail")).intValue(), filtro);
256
                this.controlTypes();
257
        }
258
        
259
        /**
260
         * A?ade un filtro de realce. Esta versi?n tiene el par?metro para a?adirle el nombre
261
         * del fichero. Esto se usa para que si a un fichero se le ha calculado ya el recorte de colas
262
         * no se vuelva a calcular, evitando as? que si hacemos un draw a una imagen por bloques cada
263
         * bloque tenga un calculo distinto para el recorte.
264
         */
265
        public void addEnhancedFilter(boolean remove, String fileName){
266
                if(filterStack.isActive(((Integer)typeFilters.get("enhanced")).intValue()))
267
                        filterStack.removeFilter(((Integer)typeFilters.get("enhanced")).intValue());
268
                                
269
                RasterFilter filtro = null;
270
                switch(filterStack.getDataTypeInFilter(((Integer)typeFilters.get("enhanced")).intValue())){
271
                        case RasterBuf.TYPE_IMAGE:filtro = new LinearEnhancementImageFilter();break;
272
                        case RasterBuf.TYPE_SHORT:
273
                        case RasterBuf.TYPE_USHORT:
274
                        case RasterBuf.TYPE_INT:filtro = new LinearEnhancementShortFilter();break;
275
                }
276
                filtro.addParam("stats", filterStack.getStats());
277
                if(remove)
278
                        filtro.addParam("remove", new Boolean(true));
279
                else
280
                        filtro.addParam("remove", new Boolean(false));
281
                if(fileName != null)
282
                        filtro.addParam("filename", fileName);
283
                else
284
                        filtro.addParam("filename", new String(""));
285
                filterStack.addFilter(((Integer)typeFilters.get("enhanced")).intValue(), filtro);
286
                this.controlTypes();
287
        }
288
        
289
        /**
290
         * A?ade un filtro de realce
291
         */
292
        public void addEnhancedFilter(boolean remove){
293
                addEnhancedFilter( remove, "");
294
        }
295
        
296
        /**
297
         * A?ade un filtro ComputeMinMax
298
         */
299
        public void addComputeMinMaxFilter(){
300
                if(!filterStack.isActive(((Integer)typeFilters.get("computeminmax")).intValue())){  //Solo lo a?adimos si no est?
301
                        RasterFilter filtro = null;
302
                        switch(filterStack.getDataTypeInFilter(((Integer)typeFilters.get("computeminmax")).intValue())){
303
                                case RasterBuf.TYPE_IMAGE:filtro = new ComputeMinMaxImageFilter();break;
304
                                case RasterBuf.TYPE_SHORT:
305
                                case RasterBuf.TYPE_USHORT:
306
                                case RasterBuf.TYPE_INT:filtro = new ComputeMinMaxShortFilter();break;
307
                        }
308
                        filtro.addParam("stats", filterStack.getStats());
309
                        filterStack.addFilter(((Integer)typeFilters.get("computeminmax")).intValue(), filtro);
310
                }
311
                this.controlTypes();
312
        }
313

    
314
        /**
315
         * Obtiene el tipo de filtro a partir del objeto RasterFilter
316
         * @param rasterFilter        Objeto RasterFilter del cual se quiere saber que tipo de filtro contiene
317
         * @return        Tipo de filtro seg?n las constantes contenidas en RasterFilterStackManager
318
         */
319
        protected int getType(RasterFilter rasterFilter){
320
                if(rasterFilter instanceof TransparencyFilter)
321
                        return 0;
322
                if(rasterFilter instanceof LinearEnhancementFilter)
323
                        return 1;
324
                if(rasterFilter instanceof ComputeMinMaxFilter)
325
                        return 2;
326
                if(rasterFilter instanceof PercentTailTrimFilter)
327
                        return 3;
328
                return -1;
329
        }
330
        
331
        /**
332
         * Controla que los tipos de los filtros de la pila sean correctos, es decir, que
333
         * el tipo de salida de un filtro de salida coincida con el tipo de la entrada del
334
         * siguiente. En caso de no ser as? crea el filtro de tipo adecuado y lo sustituye
335
         * en el no coincidente. Esto es necesario ya que en la eliminaci?n de filtros puede
336
         * quedarse en inconsistencia de tipos.
337
         */
338
        protected void controlTypes(){
339
                if(debug)filterStack.show();
340
                for(int i=filterStack.lenght();i>=0;i--){
341
                        if(i-1 >= 0){
342
                                
343
                                //Para el primer filtro comprobamos con el tipo de dato de entrada a la pila
344
                                if(i == filterStack.lenght()){
345
                                        if(filterStack.getInitDataType() != filterStack.get(i-1).getInRasterDataType()){
346
                                                String oldClass = filterStack.get(i-1).getClass().toString().substring(
347
                                                                filterStack.get(i-1).getClass().toString().lastIndexOf(".")+1, 
348
                                                                filterStack.get(i-1).getClass().toString().length());
349
                                                Pattern p = Pattern.compile(RasterBuf.typesToString(filterStack.get(i-1).getInRasterDataType()));
350
                                                Matcher m = p.matcher(oldClass);
351
                                                String newClass = m.replaceAll(RasterBuf.typesToString(filterStack.getInitDataType()));
352
                                                //System.out.println("==>"+oldClass+" "+newClass);
353
                                                try{
354
                                                        Class filterClass = Class.forName("org.cresques.io.raster."+newClass);
355
                                                        Constructor con =  filterClass.getConstructor(null);
356
                                                        RasterFilter newFilter = (RasterFilter)con.newInstance(null);
357
                                                        newFilter.params = filterStack.get(i-1).params;
358
                                                        filterStack.replace(newFilter, i-1, this.getType(newFilter));
359
                                                } catch (Exception e) {
360
                                                        e.printStackTrace();
361
                                                } 
362
                                        }
363
                                
364
                                //Desde el filtro 2 en adelante se compara la salida de uno con la entrada del siguiente
365
                                        
366
                                }else if(filterStack.get(i).getOutRasterDataType() != filterStack.get(i-1).getInRasterDataType()){
367
                                        String oldClass = filterStack.get(i-1).getClass().toString().substring(
368
                                                                                        filterStack.get(i-1).getClass().toString().lastIndexOf(".")+1, 
369
                                                                                        filterStack.get(i-1).getClass().toString().length());
370
                                        Pattern p = Pattern.compile(RasterBuf.typesToString(filterStack.get(i-1).getInRasterDataType()));
371
                                        Matcher m = p.matcher(oldClass);
372
                                        String newClass = m.replaceAll(RasterBuf.typesToString(filterStack.get(i).getOutRasterDataType()));
373
                                        //System.out.println("==>"+oldClass+" "+newClass);
374
                                        try{
375
                                                Class filterClass = Class.forName("org.cresques.io.raster."+newClass);
376
                                                Constructor con =  filterClass.getConstructor(null);
377
                                                RasterFilter newFilter = (RasterFilter)con.newInstance(null);
378
                                                newFilter.params = filterStack.get(i-1).params;
379
                                                filterStack.replace(newFilter, i-1, this.getType(newFilter));
380
                                        } catch (Exception e) {
381
                                                e.printStackTrace();
382
                                        } 
383
                                }
384
                                
385
                                
386
                        }
387
                                        
388
                }
389
                if(debug)filterStack.show();
390
        }
391
        
392
        /**
393
         * M?todo que devuelve true si el tipo de filtro pasado por par?metro est? en la
394
         * pila y false si no lo est?.
395
         * @param filter        Tipo de filtro a comprobar
396
         * @return true si est? en la pila y false si no lo est?
397
         */
398
        public boolean isActive(int type){
399
                return filterStack.isActive(type);
400
        }
401
        
402
        /**
403
         * Elimina los filtros de la pila de un determinado tipo
404
         * @param type        Tipo de filtro a eliminar
405
         */
406
        public void removeFilter(int type){
407
                filterStack.removeFilter(type);
408
                this.controlTypes();
409
        }
410
        
411
        /**
412
         * Resetea el flag de temporalidad de los filtros de la pila. 
413
         * Esto equivale a fijar los filtros que ya existen en la pila. A partir de
414
         * ese momento los filtros que se introduzcan podr?n ser eliminados de golpe
415
         * llamando a la funci?n deleteTempFilters 
416
         */
417
        public void resetTempFilters(){
418
                filterStack.resetTempFilters();
419
        }
420
        
421
        /**
422
         * Elimina los filtros temporales, es decir, todos los filtros introducidos desde
423
         * el ?ltimo resetTempFilters que se ha realizado.
424
         */
425
        public void deleteTempFilters(){
426
                filterStack.deleteTempFilters();
427
        }
428
        
429
        /**
430
         * Obtiene el objeto de estadisticas asignado a la pila.
431
         * @return
432
         */
433
        public RasterStats getStackStats(){
434
                return filterStack.getStats();
435
        }
436
        
437

    
438
        /* (non-Javadoc)
439
         * @see org.cresques.io.raster.StackManager#getStringsFromStack()
440
         */
441
        public ArrayList getStringsFromStack(){
442
                filterList = new ArrayList();
443
                for(int i=0;i<filterStack.lenght();i++){
444
                        RasterFilter rf = filterStack.get(i);
445
                        if(rf instanceof TransparencyFilter){
446
                                filterList.add("filter.transparency.active=true");
447
                                filterList.add("filter.transparency.rangeR="+rangeToString(((TransparencyFilter)rf).getRangeR()));
448
                                filterList.add("filter.transparency.rangeG="+rangeToString(((TransparencyFilter)rf).getRangeG()));
449
                                filterList.add("filter.transparency.rangeB="+rangeToString(((TransparencyFilter)rf).getRangeB()));
450
                                
451
                        }else if(rf instanceof LinearEnhancementFilter){
452
                                filterList.add("filter.enhanced.active=true");
453
                                filterList.add("filter.enhanced.remove="+((LinearEnhancementFilter)rf).getRemoveExtrema().toString());
454
                                                                
455
                        }else if(rf instanceof ComputeMinMaxFilter){
456
                                filterList.add("filter.computeminmax.active=true");
457
                                                                                                
458
                        }else if(rf instanceof PercentTailTrimFilter){
459
                                filterList.add("filter.tail.active=true");
460
                                filterList.add("filter.tail.value="+this.getStackStats().tailPercent);
461
                                filterList.add("filter.tail.remove="+((PercentTailTrimFilter)rf).removeMaxValue());
462
                        }else{ //Se recorren todos los managers registrados comprobando si corresponde a la clase del filtro 
463
                                for(int j=0;j<managers.size();j++)
464
                                        ((IStackManager)managers.get(j)).getStringsFromStack();                                        
465
                        }
466
                }
467
                return filterList;
468
        }
469
        
470
        /**
471
         * Crea una pila de filtros a partir de un Array de Strings. Cada elemento del array debe
472
         * tener la forma elemento=valor. 
473
         * @param filters 
474
         */
475
        public void createStackFromStrings(ArrayList f){
476
                this.createStackFromStrings(f, new Integer(0));
477
        }
478

    
479
        /* (non-Javadoc)
480
         * @see org.cresques.io.raster.StackManager#createStackFromStrings(java.util.ArrayList)
481
         */
482
        public void createStackFromStrings(ArrayList f, Integer pos){
483
                ArrayList filters = (ArrayList)f.clone();
484
                filterStack.clear();
485
                int filteri = pos.intValue();
486
                
487
                //Busca un filtro activo y despu?s todas las propiedades que necesita ese filtro para
488
                //ser creado. Una vez las tiene a?ade en la pila el tipo de filtro.
489
                
490
                while(filters.size()>0 && filteri<filters.size()){
491
                        String fil = (String)filters.get(filteri);
492
                        if(fil.startsWith("filter.transparency.active") && getValue(fil).equals("true")){
493
                                filters.remove(filteri);
494
                                int[][] r = null, g = null, b = null;
495
                                for(int propFilter=0;propFilter<filters.size();propFilter++){
496
                                        String elem = (String)filters.get(propFilter);
497
                                        if(elem.startsWith("filter.transparency.rangeR")){
498
                                                r = stringToRange(getValue(elem));
499
                                                filters.remove(propFilter);
500
                                                propFilter--;
501
                                        }
502
                                        if(elem.startsWith("filter.transparency.rangeG")){
503
                                                g = stringToRange(getValue(elem));
504
                                                filters.remove(propFilter);
505
                                                propFilter--;
506
                                        }
507
                                        if(elem.startsWith("filter.transparency.rangeB")){
508
                                                b = stringToRange(getValue(elem));
509
                                                filters.remove(propFilter);
510
                                                propFilter--;
511
                                        }
512
                                }
513
                                this.addTransparencyFilter(        r, g, b, 0x10, 0xff, 0xff, 0xff);
514
                                filteri = -1;
515
                        }
516
                        
517
                        if(fil.startsWith("filter.enhanced.active") && getValue(fil).equals("true")){
518
                                filters.remove(filteri);
519
                                boolean remove = false;
520
                                for(int propFilter=0;propFilter<filters.size();propFilter++){
521
                                        String elem = (String)filters.get(propFilter);
522
                                        if(elem.startsWith("filter.enhanced.remove")){
523
                                                this.addEnhancedFilter(Boolean.valueOf(getValue(elem)).booleanValue());
524
                                                filters.remove(propFilter);
525
                                                propFilter--;
526
                                        }
527
                                }
528
                                
529
                                this.addComputeMinMaxFilter();
530
                                filteri = -1;
531
                        }
532
                        
533
                        if(fil.startsWith("filter.tail.active") && getValue(fil).equals("true")){
534
                                filters.remove(filteri);
535
                                this.removeFilter(this.getTypeFilter("computeminmax"));
536
                                double recorte = 0D;
537
                                boolean remove = false;
538
                                for(int propFilter=0;propFilter<filters.size();propFilter++){
539
                                        String elem = (String)filters.get(propFilter);
540
                                        if(elem.startsWith("filter.tail.value")){
541
                                                recorte = Double.parseDouble(getValue(elem));
542
                                                filters.remove(propFilter);
543
                                                propFilter--;
544
                                        }
545
                                        if(elem.startsWith("filter.tail.remove")){
546
                                                remove = Boolean.valueOf(getValue(elem)).booleanValue();
547
                                                filters.remove(propFilter);
548
                                                propFilter--;
549
                                        }
550
                                }
551
                                this.addTailFilter( recorte, 0D, remove);
552
                                filteri = -1;
553
                        }
554
                        
555
                        for(int j=0;j<managers.size();j++)
556
                                ((IStackManager)managers.get(j)).createStackFromStrings(filters, new Integer(filteri));
557
                        
558
                        filteri++;
559
                }
560
        }
561
        
562
        /**
563
         * Obtiene el elemento de una cadena de la forma elemento=valor
564
         * @param cadena 
565
         * @return
566
         */
567
        public String getElem(String cadena){
568
                if(cadena!=null)
569
                        return cadena.substring(0, cadena.indexOf("="));
570
                else 
571
                        return null;
572
        }
573
        
574
        /**
575
         * Obtiene el valor de una cadena de la forma elemento=valor
576
         * @param cadena 
577
         * @return
578
         */
579
        public String getValue(String cadena){
580
                if(cadena!=null)
581
                        return cadena.substring(cadena.indexOf("=")+1, cadena.length());
582
                else 
583
                        return null;
584
        }
585
        
586
        /**
587
         * Convierte un rango contenido en una array doble en una cadena
588
         * de strings para poder salvar a xml
589
         * @param rang
590
         * @return
591
         */
592
        private String rangeToString(int[][] rang){
593
                StringBuffer rangoStr = new StringBuffer();
594
                if(rang!=null){
595
                        for(int i=0;i<rang.length;i++){
596
                                rangoStr.append(String.valueOf(rang[i][0])+":");
597
                                rangoStr.append(String.valueOf(rang[i][1])+":");
598
                        }
599
                        String r = rangoStr.toString();
600
                        if(r.endsWith(":"))
601
                                r = r.substring(0, r.length()-1);
602
                        return r;
603
                }else
604
                        return null;
605
                
606
        }
607
        
608
        /**
609
         * Convierte una cadena en una lista de rangos numericos para poder 
610
         * asignar transparencias a la imagen
611
         * @param rang
612
         * @return
613
         */
614
        private int[][] stringToRange(String rang){
615
                if(rang!=null && !rang.equals("null")){
616
                        ArrayList lista = new ArrayList();
617
                        StringTokenizer tokenizer = new StringTokenizer(rang, ":");
618
                        while (tokenizer.hasMoreTokens())
619
                                lista.add(tokenizer.nextToken());
620
                        int[][] intervalos = new int[(int)(lista.size()/2)][2];
621

    
622
                        for(int i=0;i<lista.size();i=i+2){
623
                                intervalos[i/2][0] = Integer.valueOf((String)lista.get(i)).intValue();
624
                                intervalos[i/2][1] = Integer.valueOf((String)lista.get(i+1)).intValue();
625
                        }
626
                        return intervalos;
627
                }else 
628
                        return null;
629
        }
630
        
631
        
632
}