Statistics
| Revision:

gvsig-raster / org.gvsig.raster / tags / 2.0.0 / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / store / properties / DataStoreTransparency.java @ 1708

History | View | Annotate | Download (19.8 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.store.properties;
23

    
24
import java.util.ArrayList;
25
import java.util.List;
26

    
27
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
29
import org.gvsig.fmap.dal.coverage.datastruct.TransparencyRange;
30
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
31
import org.gvsig.fmap.dal.coverage.util.PropertyEvent;
32
import org.gvsig.fmap.dal.coverage.util.PropertyListener;
33
import org.gvsig.raster.impl.DefaultRasterManager;
34
import org.gvsig.tools.ToolsLocator;
35
import org.gvsig.tools.dynobject.DynStruct;
36
import org.gvsig.tools.persistence.PersistenceManager;
37
import org.gvsig.tools.persistence.Persistent;
38
import org.gvsig.tools.persistence.PersistentState;
39
import org.gvsig.tools.persistence.exception.PersistenceException;
40
/**
41
 * <p>
42
 * Esta clase contiene informaci?n de transparencia de un objeto. Los objetos
43
 * pueden ser dataset, grid u otros. Cuando un usuario quiere a?adir nueva
44
 * informaci?n de transparencia crea un objeto de este tipo que debe ser
45
 * mezclado (merge) con otros objetos de este tipo que existan para la misma
46
 * fuente de datos.
47
 * </p>
48
 * <p>
49
 * Un multirasterdatset obtiene los distintos objetos transparency de todos los
50
 * ficheros que los componen. Para realizar un solo objeto transparency se har?
51
 * un merge de todos ellos.
52
 * </p>
53
 * <p>
54
 * Finalmente y antes de renderizar se necesita un objeto Transparency. Este
55
 * estar? compuesto con toda la informaci?n de transparencia aplicar, es decir,
56
 * todos los objetos Transparency mezclados.Transparency con tiene el
57
 * m?todo de procesado de un pixel. Se le proporciona un pixel y devuelve este
58
 * mismo pixel con la transparencia aplicada.
59
 * </p>
60
 * <p>
61
 * Una transparencia que se aplica a un buffer puede tener cuatro procedencias distintas:
62
 * <UL>
63
 * <LI>Mascara: Un buffer de NxN aplicado sobre la zona a renderizar como una m?scara de
64
 * transparencia. Las bandas alpha de las imagenes se comportan de esta forma.</LI>
65
 * <LI>Opacidad global: Un valor de opacidad se aplicado a cada pixel a renderizar. Este es
66
 * igual para todos los p?xeles.</LI>
67
 * <LI>Rangos: Una lista de rangos de valores RGB. Cada pixel cuyo valor est? dentro de alguno
68
 * de los rangos se aplica como transparente.</LI>
69
 * <LI>Dato: Todos los valores del buffer que coincidan con ese dato son puestos como transparente.
70
 * Para que esto sea posible tenemos que disponer del buffer de datos originales sin ning?n proceso.</LI>
71
 * </UL>
72
 * </p>
73
 *
74
 * @version 07/06/2007
75
 * @author Nacho Brodin (nachobrodin@gmail.com)
76
 */
77
public class DataStoreTransparency implements Transparency, Persistent {
78
        public static final String PERSISTENCE_NAME = "Transparency_Persistent";
79

    
80
        public static int     MAX_OPACITY           = 255;
81
        protected int         alphaBandNumber       = -1;
82
        /**
83
         * Buffer con la banda alpha correspondiente a la zona a renderizar
84
         */
85
        private Buffer       mask                   = null;
86
        /**
87
         * Buffer con los datos originales (sin filtrar) correspondiente a la zona a renderizar.
88
         * Esto es util para aplicar el valor NoData ya que hay que consultar el valor original del
89
         * dato. Despu?s de hacer un process es recomendable hacer free para poner a null los buffers.
90
         */
91
        protected Buffer     originalData           = null;
92
        /**
93
         * Valor de dato transparente. Todos los p?xeles de originalData que correspondan con este
94
         * valor se pondr?n 100% transparentes.
95
         */
96
        protected NoData     noData                 = null;
97

    
98
        /**
99
         * Rangos de transparencia aplicados. Lista de TransparencyRange
100
         */
101
        protected ArrayList<TransparencyRange>   
102
                              transparencyRanges    = new ArrayList<TransparencyRange>();
103
        /**
104
         * Grado de opacidad de todo el raster
105
         */
106
        protected int         opacity               = 0xff;
107

    
108
        /**
109
         * Array de listeners que ser?n informados cuando cambia la propiedad de transparencia
110
         */
111
        private ArrayList<PropertyListener>     
112
                              transparencyPropertyListener = new ArrayList<PropertyListener>();
113
        /**
114
         * Flag de activaci?n de la transparencia cuando se visualiza o exporta.
115
         */
116
        private boolean       transparencyActive    = false;
117

    
118
        /**
119
         * Constructor
120
         */
121
        public DataStoreTransparency() {
122
        }
123

    
124
        /**
125
         * Constructor de copia
126
         */
127
        @SuppressWarnings("unchecked")
128
        public DataStoreTransparency(Transparency tParam) {
129
                DataStoreTransparency t = null;
130
                if(tParam instanceof DataStoreTransparency)
131
                        t = (DataStoreTransparency)tParam;
132
                else 
133
                        return;
134
                
135
                //TODO: FUNCIONALIDAD: Falta asignar lo necesario para la transparencia por selecci?n
136
                this.transparencyRanges = (ArrayList<TransparencyRange>) t.getTransparencyRange().clone();
137
                if(this.mask != null)
138
                        this.mask = t.getAlphaBand();
139
                this.opacity = t.getOpacity();
140
                this.alphaBandNumber = t.alphaBandNumber;
141
                this.noData = (NoData)t.getNoData().clone();
142
                if(this.originalData != null)
143
                        this.originalData = t.originalData;
144
                this.transparencyActive = t.transparencyActive;
145
        }
146

    
147
        /*
148
         * (non-Javadoc)
149
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#addPropertyListener(PropertyListener)
150
         */
151
        public void addPropertyListener(PropertyListener listener) {
152
                transparencyPropertyListener.add(listener);
153
        }
154

    
155
        /**
156
         * M?todo llamado cuando hay un cambio en una propiedad de transparencia
157
         */
158
        private void callPropertyChanged(Object obj) {
159
                for (int i = 0; i < transparencyPropertyListener.size(); i++) {
160
                        PropertyEvent ev = new PropertyEvent(this, "transparency", null, null);
161
                        ((PropertyListener)transparencyPropertyListener.get(i)).actionValueChanged(ev);
162
                }
163
        }
164

    
165
        /**
166
         * Obtiene la m?scara asociada
167
         * @return M?scara de transparencia
168
         */
169
        public Buffer getAlphaBand() {
170
                return mask;
171
        }
172

    
173
        /*
174
         * (non-Javadoc)
175
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#setAlphaBand(org.gvsig.fmap.dal.coverage.dataset.Buffer)
176
         */
177
        public void setAlphaBand(Buffer b) {
178
                if(b == null && mask != null) {
179
                        mask = b;
180
                        //callPropertyChanged(this);
181
                        return;
182
                } else {
183
                        mask = b;
184
                        //if(b != null)
185
                                //callPropertyChanged(this);
186
                }
187
        }
188

    
189
        /*
190
         * (non-Javadoc)
191
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#existAlphaBand()
192
         */
193
        public boolean existAlphaBand() {
194
                return (mask != null);
195
        }
196

    
197

    
198
        /**
199
         * Obtiene el ?rea de datos
200
         * @return M?scara de transparencia
201
         */
202
        public Buffer getDataBuffer() {
203
                return originalData;
204
        }
205

    
206
        /*
207
         * (non-Javadoc)
208
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#setDataBuffer(org.gvsig.fmap.dal.coverage.dataset.Buffer)
209
         */
210
        public void setDataBuffer(Buffer b) {
211
                originalData = b;
212
        }
213

    
214
        /**
215
         * Obtiene el valor noData
216
         * @return
217
         */
218
        public NoData getNoData() {
219
                return noData;
220
        }
221

    
222
        /*
223
         * (non-Javadoc)
224
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#setNoData(double)
225
         */
226
        public void setNoData(NoData noData) {
227
                if(this.noData != noData)
228
                        callPropertyChanged(this);
229
                this.noData = noData;
230
        }
231

    
232
        /**
233
         * Obtiene los rangos de pixels que son transparentes en el raster.
234
         * @return Rangos de transparencias a aplicar
235
         */
236
        public ArrayList<TransparencyRange> getTransparencyRange() {
237
                return transparencyRanges;
238
        }
239

    
240
        /*
241
         * (non-Javadoc)
242
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#setTransparencyRange(org.gvsig.fmap.dal.coverage.datastruct.TransparencyRange)
243
         */
244
        public void setTransparencyRange(TransparencyRange range) {
245
                this.transparencyRanges.add(range);
246
                callPropertyChanged(this);
247
        }
248

    
249
        /**
250
         * Asigna la lista de rangos de transparencia
251
         * @param ranges
252
         */
253
        public void setTransparencyRangeList(ArrayList<TransparencyRange> ranges) {
254
                this.transparencyRanges = ranges;
255
                callPropertyChanged(this);
256
        }
257

    
258
        /*
259
         * (non-Javadoc)
260
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#clearListOfTransparencyRange()
261
         */
262
        public void clearListOfTransparencyRange() {
263
                transparencyRanges.clear();
264
                callPropertyChanged(this);
265
        }
266

    
267
        /**
268
         * Obtiene el grado de opacidad de todo el raster
269
         * @return valor del grado de opacidad.
270
         */
271
        public int getOpacity() {
272
                return opacity;
273
        }
274

    
275
        /*
276
         * (non-Javadoc)
277
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#setOpacity(int)
278
         */
279
        public void setOpacity(int opacity) {
280
                if(opacity != this.opacity)
281
                        callPropertyChanged(this);
282
                this.opacity = opacity;
283
        }
284

    
285
        /**
286
         * Asigna la transparencia a partir de un objeto con los metadatos del raster.
287
         * @param metadata
288
         */
289
        public void setTransparencyByPixelFromMetadata(DataStoreMetadata metadata){
290
                if (metadata != null) {
291
                        TransparencyRange[] noData = metadata.parserNodataInMetadata();
292
                        if (noData != null)
293
                                for (int i = 0; i < noData.length; i++)
294
                                        getTransparencyRange().add(noData[i]);
295
                        TransparencyRange noDataValue = metadata.parserNodataByBand();
296
                        if (noData == null && noDataValue != null)
297
                                getTransparencyRange().add(noDataValue);
298
                }
299
        }
300

    
301
        /**
302
         * Mezcla el alpha actual con el que nos pasan por parametro y se asigna
303
         * directamente a destino
304
         * @param buffer
305
         * @param dst
306
         */
307
        public void mergeBuffer(Buffer buffer, Buffer dst) {
308
                for (int y = 0; y < mask.getHeight(); y++)
309
                        for (int x = 0; x < mask.getWidth(); x++)
310
                                // ((a / 255) * (b / 255)) * 255
311
                                // Es lo mismo que:
312
                                // (a * b) / 255
313
                                dst.setElem(y, x, 0,
314
                                                (byte) (((mask.getElemByte(y, x, 0) & 0xff) * (buffer.getElemByte(y, x, 0) & 0xff)) / 255D));
315
        }
316

    
317
        /**
318
         * Mezcla un objeto Transparency con el actual
319
         * @param ts objeto TransparencyStatus
320
         */
321
        public Transparency merge(Transparency tParam) {
322
                DataStoreTransparency transp = null;
323
                if(tParam instanceof DataStoreTransparency)
324
                        transp = (DataStoreTransparency)tParam;
325
                else 
326
                        return null;
327
                
328
                DataStoreTransparency t = new DataStoreTransparency();
329
                // Mezclamos la opacidad
330
                double op1 = (double) opacity / (double) MAX_OPACITY;
331
                double op2 = (double) transp.getOpacity() / (double) MAX_OPACITY;
332
                t.setOpacity((int) (op1 * op2 * MAX_OPACITY));
333

    
334
                // Mezclamos los rangos de transparencia
335
                ArrayList<TransparencyRange> tr = transp.getTransparencyRange();
336
                for (int i = 0; i < tr.size(); i++)
337
                        transparencyRanges.add(tr.get(i));
338

    
339
                // TODO: FUNCIONALIDAD Mezclamos la m?scara
340
                if (mask != null && transp.getAlphaBand() != null) {
341
                        Buffer newMask = DefaultRasterManager.getInstance().createBuffer(Buffer.TYPE_BYTE, mask.getWidth(), mask.getHeight(), 1, true);
342
                        // Mezclamos alphaBand con el que nos pasan en transp y lo asignamos al nuevo buffer
343
                        mergeBuffer(transp.getAlphaBand(), newMask);
344

    
345
                        t.setAlphaBand(newMask);
346
                } else if (mask != null) {
347
                        t.setAlphaBand(mask);
348
                        t.alphaBandNumber = alphaBandNumber;
349
                } else {
350
                        t.setAlphaBand(transp.getAlphaBand());
351
                        t.alphaBandNumber = transp.alphaBandNumber;
352
                }
353

    
354
                // TODO: FUNCIONALIDAD Mezclamos las ?reas
355

    
356
                // TODO: FUNCIONALIDAD Mezclamos las mascaras
357
                return t;
358
        }
359

    
360
        /**
361
         * Obtiene la banda de transpareci si existe o -1 si no existe.
362
         * @return n?mero de banda de transparencia o -1 si no existe.
363
         */
364
        public int getAlphaBandNumber() {
365
                return alphaBandNumber;
366
        }
367

    
368
        /**
369
         * Asigna la informaci?n de si existe o no banda de transparencia cuando este
370
         * objeto va asociado a un dataset. Si tiene este tipo de banda en cada
371
         * dibujado se cargar? la informaci?n de m?scara de transparencia en el la
372
         * variable mask.
373
         * @param true si existe banda de transparencia y false si no lo es.
374
         */
375
        public void setTransparencyBand(int alphaBandNumber) {
376
                this.alphaBandNumber = alphaBandNumber;
377
        }
378

    
379
        /**
380
         * Consulta si el valor de la posici?n (line, col) del buffer es considerado
381
         * NoData o no.
382
         * @param line Linea del buffer
383
         * @param col Columna del buffer
384
         * @return
385
         */
386
        protected boolean isNoData(int line, int col) {
387
                if(noData == null)
388
                        return false;
389
                
390
                switch (originalData.getDataType()) {
391
                case Buffer.TYPE_BYTE:
392
                        if(noData.isDefined() && 
393
                                        originalData.getElemByte(line, col, 0) == noData.getValue().byteValue())
394
                                return true;
395
                        break;
396
                case Buffer.TYPE_SHORT:
397
                        if(noData.isDefined() && 
398
                                        originalData.getElemShort(line, col, 0) == noData.getValue().shortValue())
399
                                return true;
400
                        break;
401
                case Buffer.TYPE_INT:
402
                        if(noData.isDefined() && 
403
                                        originalData.getElemInt(line, col, 0) == noData.getValue().intValue())
404
                                return true;
405
                        break;
406
                case Buffer.TYPE_FLOAT:
407
                        float f = originalData.getElemFloat(line, col, 0);
408
                        if((noData.isDefined() && 
409
                                        f == noData.getValue().floatValue()) || Float.isNaN(f))
410
                                return true;
411
                        break;
412
                case Buffer.TYPE_DOUBLE:
413
                        double d = originalData.getElemDouble(line, col, 0);
414
                        if((noData.isDefined() && 
415
                                        d == noData.getValue().doubleValue()) || Double.isNaN(d))
416
                                return true;
417
                        break;
418
                }
419
                return false;
420
        }
421

    
422
        /*
423
         * (non-Javadoc)
424
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#activeTransparency()
425
         */
426
        public void activeTransparency() {
427
                if(        existAlphaBand() || 
428
                        (getNoData() != null && getNoData().isDefined() && getNoData().isNoDataTransparent()) ||
429
                        (transparencyRanges.size() > 0) ||
430
                        (opacity != 0xff))
431
                        transparencyActive = true;
432
                else
433
                        transparencyActive = false;
434
        }
435
        
436
        /*
437
         * (non-Javadoc)
438
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#isTransparencyActive()
439
         */
440
        public boolean isTransparencyActive() {
441
                return transparencyActive;
442
        }
443
        
444
        /**
445
         * Asigna el flag de transparencia activa o desactivada.
446
         * @param transparencyActive true activa la transparencia false la desactiva
447
         */
448
        public void setTransparencyActive(boolean transparencyActive) {
449
                this.transparencyActive = transparencyActive;
450
        }
451
        
452
        /*
453
         * (non-Javadoc)
454
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#processRGB(int, int, int, int, int)
455
         */
456
        public int processRGB(int r, int g, int b, int line, int col) {
457
                // Si el valor es noData se pone totalmente transparente y ya no se tiene en
458
                // cuenta nada m?s.
459
                if (originalData != null && (getNoData().isDefined() && getNoData().isNoDataTransparent())) {
460
                        if (isNoData(line, col))
461
                                // El alpha no se pone para dejarlo a 0, totalmente transparente
462
                                return (r << 16 | g << 8 | b);
463
                }
464

    
465
                /**
466
                 * Para sacar el valor del nuevo alpha, lo que hacemos es convertir a
467
                 * porcentajes todos los alphas posibles (en porcentajes) y multiplicarlos
468
                 * entre si. Con esto conseguimos un nuevo porcentaje de alpha entre 0 y 1.
469
                 * Una vez hecho esto se multiplica por 255 para tenerlo dentro del rango
470
                 * deseado. Como queremos evitar operaciones de m?s, podemos quitar una
471
                 * division de 255 y as? nos ahorramos luego multiplicarlo por 255 otra vez.
472
                 */
473

    
474
                // Quitada la division para optimizar
475
                //double a = opacity / 255D;
476
                double a = opacity;
477

    
478
                int alphaRange = processRange(r, g, b);
479
                if (alphaRange != 255)
480
                        a *= (alphaRange / 255D);
481

    
482
                if (existAlphaBand() && getAlphaBand() != null)
483
                        a *= (getAlphaBand().getElemByte(line, col, 0) & 0xff) / 255D;
484

    
485
                // Quitada la multiplicacion para optimizar
486
                // a = (int)(a * 255D);
487

    
488
                return ((int) a << 24) | r << 16 | g << 8 | b;
489
        }
490
        
491
        /**
492
         * Aplica la transparecia por rangos al pixel pasado por par?metro. El valor
493
         * en la posici?n cero es el alpha por lo tanto ser? esta posici?n la que se
494
         * modificar?.
495
         * @param r
496
         * @param g
497
         * @param b
498
         * @return Un valor de 0 a 255. Donde 255 es totalmente opaco
499
         */
500
        private int processRange(int r, int g, int b) {
501
                for (int i = 0; i < transparencyRanges.size(); i++) {
502
                        TransparencyRange tr = ((TransparencyRange) transparencyRanges.get(i));
503
                        if (tr == null) continue;
504
                        if (tr.isAnd()) {
505
                                if (tr.getRed() == null ||
506
                                                tr.getGreen() == null ||
507
                                                tr.getBlue() == null ||
508
                                                r < tr.getRed()[0]   || r > tr.getRed()[1] ||
509
                                                g < tr.getGreen()[0] || g > tr.getGreen()[1] ||
510
                                                b < tr.getBlue()[0]  || b > tr.getBlue()[1])
511
                                        continue;
512

    
513
                                return tr.getAlpha();
514
                        } else {
515
                                if (tr.getRed() != null) {
516
                                        if (r >= tr.getRed()[0] && r <= tr.getRed()[1]) {
517
                                                return tr.getAlpha();
518
                                        }
519
                                }
520
                                if (tr.getGreen() != null) {
521
                                        if (g >= tr.getGreen()[0] && g <= tr.getGreen()[1]) {
522
                                                return tr.getAlpha();
523
                                        }
524
                                }
525
                                if (tr.getBlue() != null) {
526
                                        if (b >= tr.getBlue()[0] && b <= tr.getBlue()[1]) {
527
                                                return tr.getAlpha();
528
                                        }
529
                                }
530
                        }
531
                }
532
                return 255;
533
        }
534
        
535
        /*
536
         * (non-Javadoc)
537
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#cloneTransparency()
538
         */
539
        @SuppressWarnings("unchecked")
540
        public Transparency cloneTransparency() {
541
                DataStoreTransparency t = new DataStoreTransparency();
542
                
543
                //TODO: FUNCIONALIDAD: Falta asignar lo necesario para la transparencia por selecci?n
544
                t.transparencyRanges = (ArrayList<TransparencyRange>) getTransparencyRange().clone();
545
                t.mask = getAlphaBand();
546
                t.opacity = getOpacity();
547
                t.alphaBandNumber = alphaBandNumber;
548
                t.noData = getNoData();
549
                t.originalData = originalData;
550
                t.transparencyActive = t.transparencyActive;
551
                t.activeTransparency();
552
                return t;
553
        }
554
        
555
        /*
556
         * (non-Javadoc)
557
         * @see org.gvsig.tools.persistence.Persistent#loadFromState(org.gvsig.tools.persistence.PersistentState)
558
         */
559
        @SuppressWarnings("unchecked")
560
        public void loadFromState(PersistentState state)
561
        throws PersistenceException {                
562
                if (state.hasValue("opacity")) {
563
                        opacity = state.getInt("opacity");
564
                }
565
                
566
                List tr = state.getList("transparencyRange");
567
                if(tr != null) {
568
                        transparencyRanges = new ArrayList<TransparencyRange>(tr);        
569
                        if (state.hasValue("bandnumber")) {
570
                                alphaBandNumber = state.getInt("bandnumber");
571
                        }
572
                }
573

    
574
                this.transparencyActive = state.getBoolean("transparencyActive");
575
                //this.noData = state.getDouble("noData");
576
        }
577

    
578
        /*
579
         * (non-Javadoc)
580
         * @see org.gvsig.tools.persistence.Persistent#saveToState(org.gvsig.tools.persistence.PersistentState)
581
         */
582
        public void saveToState(PersistentState state) throws PersistenceException {
583
                if(getOpacity() != 255) {
584
                        state.set("opacity", getOpacity());
585
                }        
586

    
587
                //Rangos de transparencia                
588
                state.set("transparencyRange", transparencyRanges);
589

    
590
                if(getAlphaBandNumber() != -1) {
591
                        state.set("bandnumber", getAlphaBandNumber());
592
                }
593
                
594
                state.set("transparencyActive", transparencyActive);
595
                //state.set("noData", noData);
596
        }
597
        
598
        public static void registerPersistence() {
599
                PersistenceManager manager = ToolsLocator.getPersistenceManager();
600
                DynStruct definition = manager.addDefinition(
601
                                DataStoreTransparency.class,
602
                                PERSISTENCE_NAME,
603
                                "Transparency Persistent definition (FIXME)",
604
                                null, 
605
                                null
606
                );
607
                definition.addDynFieldInt("opacity").setMandatory(false);
608
                definition.addDynFieldInt("bandnumber").setMandatory(false);
609
                definition.addDynFieldList("transparencyRange").setClassOfItems(TransparencyRange.class).setMandatory(false);
610
                definition.addDynFieldBoolean("transparencyActive").setMandatory(false);
611
                //definition.addDynFieldDouble("noData").setMandatory(false);
612
        }
613
        
614
        /*
615
         * (non-Javadoc)
616
         * @see org.gvsig.fmap.dal.coverage.store.props.Transparency#free()
617
         */
618
        public void dispose() {
619
                if (mask != null)
620
                        mask.dispose();
621
                if (originalData != null)
622
                        originalData.dispose();
623
                mask = null;
624
                originalData = null;
625
        }
626
        
627
        /*
628
         * (non-Javadoc)
629
         * @see java.lang.Object#finalize()
630
         */
631
        protected void finalize() throws Throwable {
632
                noData           = null;
633
                mask             = null;
634
                if(transparencyPropertyListener != null) {
635
                        transparencyPropertyListener.clear();
636
                        transparencyPropertyListener = null;
637
                }
638
                if(transparencyRanges != null) {
639
                        transparencyRanges.clear();
640
                        transparencyRanges = null;
641
                }
642
                super.finalize();
643
        }
644
        
645
}