Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster.2.4 / org.gvsig.raster / org.gvsig.raster.lib / org.gvsig.raster.lib.legend / org.gvsig.raster.lib.legend.impl / src / main / java / org / gvsig / raster / lib / legend / impl / DefaultRasterLegend.java @ 8800

History | View | Annotate | Download (53 KB)

1
package org.gvsig.raster.lib.legend.impl;
2

    
3
import java.awt.Graphics;
4
import java.awt.Image;
5
import java.awt.geom.AffineTransform;
6
import java.awt.geom.NoninvertibleTransformException;
7
import java.awt.image.BufferedImage;
8
import java.util.ArrayList;
9
import java.util.Iterator;
10
import java.util.List;
11

    
12
import org.cresques.cts.ICoordTrans;
13
import org.slf4j.Logger;
14
import org.slf4j.LoggerFactory;
15

    
16
import org.gvsig.fmap.dal.DALLocator;
17
import org.gvsig.fmap.dal.DataStore;
18
import org.gvsig.fmap.dal.raster.api.RasterStore;
19
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
20
import org.gvsig.fmap.geom.GeometryLocator;
21
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
22
import org.gvsig.fmap.geom.exception.CreateGeometryException;
23
import org.gvsig.fmap.geom.primitive.Envelope;
24
import org.gvsig.fmap.geom.primitive.Point;
25
import org.gvsig.fmap.mapcontext.ViewPort;
26
import org.gvsig.fmap.mapcontext.raster.api.legend.ChangeColorInterpretationEvent;
27
import org.gvsig.fmap.mapcontext.raster.api.legend.ChangeOperationListEvent;
28
import org.gvsig.fmap.mapcontext.raster.api.legend.ChangePaletteBandEvent;
29
import org.gvsig.fmap.mapcontext.raster.api.legend.ChangePaletteEvent;
30
import org.gvsig.fmap.mapcontext.raster.api.legend.RasterLegendEvent;
31
import org.gvsig.fmap.mapcontext.raster.api.legend.listeners.RasterLegendChangedListener;
32
import org.gvsig.fmap.mapcontext.rendering.legend.ILegend;
33
import org.gvsig.fmap.mapcontext.rendering.legend.events.LegendContentsChangedListener;
34
import org.gvsig.fmap.mapcontext.rendering.legend.events.SymbolLegendEvent;
35
import org.gvsig.fmap.mapcontext.rendering.symbols.ISymbol;
36
import org.gvsig.raster.lib.buffer.api.Band;
37
import org.gvsig.raster.lib.buffer.api.Buffer;
38
import org.gvsig.raster.lib.buffer.api.BufferLocator;
39
import org.gvsig.raster.lib.buffer.api.BufferManager;
40
import org.gvsig.raster.lib.buffer.api.NoData;
41
import org.gvsig.raster.lib.buffer.api.OperationManager;
42
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
43
import org.gvsig.raster.lib.buffer.api.exceptions.BufferOperationException;
44
import org.gvsig.raster.lib.buffer.api.operations.Operation;
45
import org.gvsig.raster.lib.buffer.api.operations.OperationList;
46
import org.gvsig.raster.lib.buffer.api.operations.OperationListEntry;
47
import org.gvsig.raster.lib.buffer.api.operations.OperationListNotification;
48
import org.gvsig.raster.lib.buffer.api.operations.SpecifiedBandsOperation;
49
import org.gvsig.raster.lib.buffer.spi.operations.AbstractOperation;
50
import org.gvsig.raster.lib.buffer.spi.operations.AbstractSpecifiedBandsOperation;
51
import org.gvsig.raster.lib.legend.api.RasterLegend;
52
import org.gvsig.raster.lib.legend.api.Transparency;
53
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
54
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretationNotification;
55
import org.gvsig.raster.lib.legend.api.colortable.ColorTable;
56
import org.gvsig.raster.lib.legend.api.operations.ColoredOperation;
57
import org.gvsig.raster.lib.legend.impl.operations.cmyktorgb.CMYKToRGBOperation;
58
import org.gvsig.raster.lib.legend.impl.operations.cmyktorgb.CMYKToRGBOperationFactory;
59
import org.gvsig.raster.lib.legend.impl.operations.colortable.ColorTableOperation;
60
import org.gvsig.raster.lib.legend.impl.operations.colortable.ColorTableOperationFactory;
61
import org.gvsig.raster.lib.legend.impl.operations.hsltorgb.HSLToRGBOperation;
62
import org.gvsig.raster.lib.legend.impl.operations.hsltorgb.HSLToRGBOperationFactory;
63
import org.gvsig.tools.ToolsLocator;
64
import org.gvsig.tools.dispose.DisposeUtils;
65
import org.gvsig.tools.dynobject.DynClass;
66
import org.gvsig.tools.dynobject.DynObject;
67
import org.gvsig.tools.dynobject.DynObjectManager;
68
import org.gvsig.tools.dynobject.DynStruct;
69
import org.gvsig.tools.dynobject.impl.DefaultDynObjectManager;
70
import org.gvsig.tools.locator.LocatorException;
71
import org.gvsig.tools.observer.Observable;
72
import org.gvsig.tools.operations.OperationException;
73
import org.gvsig.tools.persistence.PersistenceManager;
74
import org.gvsig.tools.persistence.Persistent;
75
import org.gvsig.tools.persistence.PersistentState;
76
import org.gvsig.tools.persistence.exception.PersistenceException;
77
import org.gvsig.tools.swing.api.ToolsSwingLocator;
78
import org.gvsig.tools.task.SimpleTaskStatus;
79
import org.gvsig.tools.task.TaskStatusManager;
80

    
81
/**
82
 * Default implementation of {@link RasterLegend}. This object can draw buffers
83
 * with a {@link ColorInterpretation}, {@link ColorTable} and {@link OperationList}
84
 *
85
 *
86
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
87
 *
88
 */
89
public class DefaultRasterLegend implements RasterLegend {
90

    
91
    private static final Logger LOG = LoggerFactory.getLogger(DefaultRasterLegend.class);
92

    
93
    private ColorInterpretation colorInterpretation;
94
    private Transparency transparency;
95
    private OperationList filters;
96
    private boolean transparentNoData;
97
    private ColorManager colorManager;
98

    
99
    private List<RasterLegendChangedListener> listeners =
100
        new ArrayList<RasterLegendChangedListener>();
101

    
102
    /**
103
     * Persistence definition name
104
     */
105
    public static final String PERSISTENT_NAME = "RasterLegendPersistence";
106
    /**
107
     * Description of persistence definition
108
     */
109
    public static final String PERSISTENT_DESCRIPTION = "Persistence definition of raster legend";
110

    
111
    private final static String COLOR_INTERPRETATION_PERSISTENCE_FIELD = "colorInterpretation";
112
    private final static String FILTERS_PERSISTENCE_FIELD = "filters";
113

    
114
    /**
115
     * Empty constructor
116
     */
117
    public DefaultRasterLegend() {
118

    
119
    }
120

    
121
    /**
122
     * Default {@link RasterLegend} constructor
123
     *
124
     * @param colorInterpretation
125
     *            Color interpretation of legend
126
     */
127
    public DefaultRasterLegend(ColorInterpretation colorInterpretation) {
128
        this(colorInterpretation, null, null);
129
    }
130

    
131
    /**
132
     * Default {@link RasterLegend} constructor
133
     *
134
     * @param colorTable
135
     *            Color table of legend
136
     * @param colorInterpretation
137
     *            Color interpretation of legend
138
     * @param transparency
139
     *            Transparency of legend
140
     * @param filters
141
     *            Filters of legend
142
     */
143
    public DefaultRasterLegend(ColorInterpretation colorInterpretation,
144
        Transparency transparency, OperationList filters) {
145
        this.transparency = transparency;
146
        this.filters = filters;
147
        setColorInterpretation(colorInterpretation);
148
    }
149

    
150
    @Override
151
    public void draw(Graphics graphics, Buffer buffer, ViewPort viewPort,
152
        SimpleTaskStatus taskStatus) {
153

    
154
        boolean isMyTask = false;
155
        if (taskStatus == null) {
156
            TaskStatusManager taskStatusManager = ToolsLocator.getTaskStatusManager();
157
            taskStatus =
158
                taskStatusManager.createDefaultSimpleTaskStatus("_drawing_buffer_XxellipsisxX");
159
            taskStatus.setAutoremove(true);
160
            taskStatus.add();
161
            isMyTask = true;
162
        } else {
163
            taskStatus.push();
164
        }
165

    
166
        taskStatus.setIndeterminate();
167

    
168
        if (this.colorInterpretation == null || !this.colorInterpretation.hasInterpretation()
169
            || this.colorInterpretation.isUndefined()) {
170
            taskStatus.abort();
171
            throw new IllegalStateException(
172
                "To draw buffer, raster legend has to have a color interpretation");
173
        }
174

    
175
        // Check if viewport projection is the same as buffer projection
176
        Buffer clip = null;
177
        Buffer interpolated = null;
178
        Buffer converted = null;
179
        Buffer interpolated2 = null;
180
        Buffer bufferToDraw = buffer;
181
        try {
182
            if (bufferToDraw != null && bufferToDraw.getColumns()>0 && bufferToDraw.getRows()>0) {
183

    
184
                if (!viewPort.getProjection().equals(bufferToDraw.getProjection())) {
185

    
186
                    // Convert extension to check if envelopes intersect
187
                    ICoordTrans coordTrans = viewPort.getProjection().getCT(bufferToDraw.getProjection());
188
                    ICoordTrans invertedCoordTrans = bufferToDraw.getProjection().getCT(viewPort.getProjection());
189
                    Envelope convertedEnvelope = viewPort.getAdjustedEnvelope().convert(coordTrans);
190
                    double viewPortPixelSizeX = viewPort.getAdjustedEnvelope().getLength(0) / viewPort.getImageWidth();
191
                    double viewPortPixelSizeY = viewPort.getAdjustedEnvelope().getLength(1) / viewPort.getImageHeight();
192
                    if (!convertedEnvelope.intersects(bufferToDraw.getEnvelope())) {
193
                        return;
194
                    }
195
                    try {
196
                        // Clip buffer with doubled converted envelope
197
                        clip = bufferToDraw.clip(convertedEnvelope);
198
                        Envelope bufferEnvelopeInViewPortCoords = clip.getEnvelope().convert(invertedCoordTrans);
199

    
200
                        double widthPixel = bufferEnvelopeInViewPortCoords.getLength(0) / viewPortPixelSizeX;
201
                        double heightPixel = bufferEnvelopeInViewPortCoords.getLength(1) / viewPortPixelSizeY;
202

    
203
                        interpolated =
204
                            clip.createInterpolated((int) Math.floor(heightPixel), (int) Math.floor(widthPixel),
205
                                Buffer.INTERPOLATION_Bilinear, taskStatus);
206
                        // Convert interpolated clipped buffer
207
                        converted = interpolated.convert(invertedCoordTrans, taskStatus);
208

    
209
                        widthPixel = getWidthPixel(converted.getEnvelope(), viewPortPixelSizeX);
210
                        heightPixel = getHeightPixel(converted.getEnvelope(), viewPortPixelSizeY);
211

    
212
                        interpolated2 =
213
                            converted.createInterpolated((int) Math.floor(heightPixel), (int) Math.floor(widthPixel),
214
                                Buffer.INTERPOLATION_Bilinear, taskStatus);
215

    
216
                        bufferToDraw = interpolated2;
217

    
218
                    } catch (BufferException | LocatorException | CreateEnvelopeException e) {
219
                        LOG.warn("Buffer can not be clipped, converted or interpolated", e);
220
                        taskStatus.abort();
221
                        return;
222
                    }
223
                } else if (viewPort.getAdjustedEnvelope().intersects(bufferToDraw.getEnvelope())) {
224

    
225
                    double widthPixel = 0;
226
                    double heightPixel = 0;
227
                    try {
228
                        // Clip and interpolate buffer with view port envelope
229
                        if (!bufferToDraw.getEnvelope().equals(viewPort.getAdjustedEnvelope())) {
230
                            clip = bufferToDraw.clip(viewPort.getAdjustedEnvelope());
231
                            bufferToDraw = clip;
232
                        }
233
                        widthPixel =
234
                            getWidthPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(0)
235
                                / viewPort.getImageWidth());
236
                        heightPixel =
237
                            getHeightPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(1)
238
                                / viewPort.getImageHeight());
239

    
240
                        interpolated =
241
                            bufferToDraw.createInterpolated((int) Math.floor(heightPixel),
242
                                (int) Math.floor(widthPixel), Buffer.INTERPOLATION_Bilinear, taskStatus);
243
                        bufferToDraw = interpolated;
244
                    } catch (BufferException e) {
245
                        LOG.warn(
246
                            "Buffer can not be interpolated with [rows: {} , columns: {}, method: {}]",
247
                            new String[] { String.valueOf((int) Math.floor(heightPixel)),
248
                                String.valueOf((int) Math.floor(widthPixel)),
249
                                String.valueOf(Buffer.INTERPOLATION_Bilinear) });
250
                        taskStatus.abort();
251
                        return;
252
                    }
253
                } else {
254
                    // Do nothing view port envelope does not intersect with
255
                    // buffer
256
                    return;
257
                }
258
            }
259

    
260
            OperationManager operationManager = BufferLocator.getOperationManager();
261

    
262
            if (bufferToDraw != null && bufferToDraw.getColumns()>0 && bufferToDraw.getRows()>0) {
263

    
264
                // Draw buffer
265
                Image image = null;
266
                try {
267
                    DynObjectManager dynObjectManager = new DefaultDynObjectManager();
268
                    DynClass parametersClass = dynObjectManager.createDynClass("Parameters", "Parameters to find through ultimately.");
269
                    parametersClass.addDynFieldObject(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM);
270
                    DynObject defaultParameters = dynObjectManager.createDynObject(parametersClass);
271
                    defaultParameters.setDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM, colorInterpretation);
272

    
273
                    getFilters().setDefaultParameters(defaultParameters);
274

    
275
                    Object oColorInterpretation = null;
276
                    Buffer filteredBuffer = bufferToDraw;
277
                    filteredBuffer = getFilters().execute(bufferToDraw);
278
                    oColorInterpretation = getFilters().getParameterValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM);
279
                    ColorInterpretation colorInterpretationAfterFilters = null;
280
                    if (oColorInterpretation != null) {
281
                        colorInterpretationAfterFilters = (ColorInterpretation) oColorInterpretation;
282
                    }
283
                    if (colorInterpretationAfterFilters == null) {
284
                        colorInterpretationAfterFilters = colorInterpretation;
285
                    }
286

    
287
                    if (colorInterpretationAfterFilters.isPalette()) {
288
                        DynObject colorTableOperationParameters =
289
                            operationManager.createOperationParameters(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
290
                        colorTableOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
291
                            colorInterpretationAfterFilters);
292
//                        colorTableOperationParameters.setDynValue(ColoredOperation.COPY_UNPROCESSED_BANDS_PARAM,
293
//                            true);
294
                        Buffer rgbBuffer =
295
                            operationManager.execute(ColoredOperation.COLOR_TABLE_OPERATION_NAME, filteredBuffer,
296
                                colorTableOperationParameters);
297
                        image =
298
                            drawRGBBuffer(graphics, rgbBuffer,
299
                                (ColorInterpretation) colorTableOperationParameters
300
                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
301
                                getFilters());
302

    
303
                    } else if (colorInterpretationAfterFilters.hasAnyGrayBand()) {
304
                        // Draw buffer with gray scale
305
                        image = drawGrayBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency, filters);
306
                        // } else if (this.colorInterpretation.isRGBA() ||
307
                        // this.colorInterpretation.isRGB()
308
                        // || this.colorInterpretation.isBGR() ||
309
                        // this.colorInterpretation.hasRGBBands()) {
310
                    } else if (colorInterpretationAfterFilters.hasAnyRGBBand()) {
311
                        // Draw RGB, RGBA or BGR buffer without color table
312
                        image =
313
                            drawRGBBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency,
314
                                filters);
315
                    } else if (colorInterpretationAfterFilters.hasAnyHSLBand()) {
316
                        // Draw HSL buffer without color table
317
                        // image = drawHSLBuffer(graphics, bufferToDraw,
318
                        // colorInterpretation, transparency, filters);
319

    
320
                        DynObject hSLToRGBOperationParameters =
321
                            operationManager.createOperationParameters(HSLToRGBOperationFactory.NAME);
322
                        hSLToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
323
                            colorInterpretationAfterFilters);
324
//                        hSLToRGBOperationParameters.setDynValue(ColoredOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
325
                        Buffer rgbBuffer =
326
                            operationManager.execute(HSLToRGBOperationFactory.NAME, filteredBuffer,
327
                                hSLToRGBOperationParameters);
328
                        image =
329
                            drawRGBBuffer(graphics, rgbBuffer,
330
                                (ColorInterpretation) hSLToRGBOperationParameters
331
                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
332
                                filters);
333

    
334
                    } else if (colorInterpretationAfterFilters.hasAnyCMYKBand()) {
335
                        // Draw CMYK buffer without color table
336
//                        image = drawCMYKBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency, filters);
337

    
338
                        DynObject cmykToRGBOperationParameters =
339
                            operationManager.createOperationParameters(CMYKToRGBOperationFactory.NAME);
340
                        cmykToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
341
                            colorInterpretationAfterFilters);
342
//                        cmykToRGBOperationParameters.setDynValue(CMYKToRGBOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
343
                        Buffer rgbBuffer =
344
                            operationManager.execute(CMYKToRGBOperationFactory.NAME, filteredBuffer,
345
                                cmykToRGBOperationParameters);
346
                        image =
347
                            drawRGBBuffer(graphics, rgbBuffer,
348
                                (ColorInterpretation) cmykToRGBOperationParameters
349
                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
350
                                filters);
351

    
352
                    } else if (colorInterpretationAfterFilters.hasAnyYCBCRBand()) {
353
                        // TODO: Hacer un filtro YCBCRToRGB y llamarlo como en
354
                        // los de arriba
355

    
356
                        // Draw YCBCR buffer without color table
357
                        image = drawYCBCRBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
358
                    }
359
                } catch (BufferOperationException e) {
360
                    LOG.warn("Error drawing legend", e);
361
                    taskStatus.abort();
362
                    return;
363
                }
364

    
365
                // Calculate where image has to be drawn
366
                double x = bufferToDraw.getEnvelope().getMinimum(0);
367
                double y = bufferToDraw.getEnvelope().getMaximum(1);
368
                AffineTransform affineTransform =
369
                    calculateAffineTransform(viewPort.getAdjustedEnvelope(), viewPort.getImageWidth(),
370
                        viewPort.getImageHeight());
371

    
372
                Point point;
373
                try {
374
                    point = GeometryLocator.getGeometryManager().createPoint(x, y, SUBTYPES.GEOM2D);
375
                    point.transform(affineTransform.createInverse());
376
                    graphics.drawImage(image, (int) Math.floor(point.getX()), (int) Math.floor(point.getY()), null);
377
                } catch (CreateGeometryException | NoninvertibleTransformException e) {
378
                    LOG.warn("Can not calculate the point of buffer in viewport image", e);
379
                    taskStatus.abort();
380
                    return;
381
                }
382
            }
383
        } catch (LocatorException | CreateEnvelopeException e1) {
384
            LOG.warn("Can not calculate the envelope of buffer", e1);
385
            taskStatus.abort();
386
            return;
387
        } finally {
388
            if (clip != null) {
389
                DisposeUtils.dispose(clip);
390
                clip = null;
391
            }
392
            if (interpolated != null) {
393
                DisposeUtils.dispose(interpolated);
394
                interpolated = null;
395
            }
396
            if (converted != null) {
397
                DisposeUtils.dispose(converted);
398
                converted = null;
399
            }
400
            if (interpolated2 != null) {
401
                DisposeUtils.dispose(interpolated2);
402
                interpolated2 = null;
403
            }
404
            if (bufferToDraw == null && bufferToDraw != buffer) {
405
                DisposeUtils.dispose(bufferToDraw);
406
                bufferToDraw = null;
407
            }
408

    
409
            if (!isMyTask) {
410
                taskStatus.pop();
411
            }
412
        }
413
    }
414

    
415
    private AffineTransform calculateAffineTransform(Envelope envelope, double imageWidth,
416
        double imageHeight) {
417
        double pixelSizeX = envelope.getLength(0) / imageWidth;
418
        double rotationX = 0;
419
        double x = envelope.getMinimum(0);
420
        double rotationY = 0;
421
        double pixelSizeY = -envelope.getLength(1) / imageHeight;
422
        double y = envelope.getMaximum(1);
423
        return new AffineTransform(pixelSizeX, rotationY, rotationX, pixelSizeY, x, y);
424
    }
425

    
426
    private double getWidthPixel(Envelope envelope, double dist1pixel) {
427
        double widthEnvelope = envelope.getLength(0);
428
        return widthEnvelope / dist1pixel;
429
    }
430

    
431
    private double getHeightPixel(Envelope envelope, double dist1pixel) {
432
        double heightEnvelope = envelope.getLength(1);
433
        return heightEnvelope / dist1pixel;
434
    }
435

    
436

    
437

    
438
    private Image drawRGBBuffer(Graphics graphics, Buffer buffer,
439
        ColorInterpretation colorInterpretation, Transparency transparency, OperationList filters) throws BufferOperationException {
440

    
441
        Buffer byteBuffer = convertToByteBuffer(buffer);
442
        Buffer bufferToDraw = byteBuffer;
443

    
444
        BufferedImage image = null;
445

    
446
        if (colorInterpretation.isRGB() || colorInterpretation.isRGBA() || colorInterpretation.hasAnyRGBBand()) {
447
            image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(bufferToDraw.getColumns(), bufferToDraw.getRows(),
448
                    BufferedImage.TYPE_INT_ARGB);
449
        } else if (colorInterpretation.isBGR()) {
450
            image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(bufferToDraw.getColumns(), bufferToDraw.getRows(),
451
                BufferedImage.TYPE_INT_BGR);
452
        }
453

    
454
        if (image == null) {
455
            throw new IllegalStateException(
456
                "Color interpretation is not RGB,RGBA or BGR and buffer was be drawn without color table");
457
        }
458

    
459
        int redBandIndex = colorInterpretation.getBand(ColorInterpretation.RED_BAND);
460
        int greenBandIndex = colorInterpretation.getBand(ColorInterpretation.GREEN_BAND);
461
        int blueBandIndex = colorInterpretation.getBand(ColorInterpretation.BLUE_BAND);
462

    
463
        Band redBand = null;
464
        if(redBandIndex>=0){
465
            redBand = bufferToDraw.getBand(redBandIndex);
466
        }
467
        Band greenBand = null;
468
        if(greenBandIndex>=0){
469
            greenBand = bufferToDraw.getBand(greenBandIndex);
470
        }
471
        Band blueBand = null;
472
        if(blueBandIndex>=0){
473
            blueBand = bufferToDraw.getBand(blueBandIndex);
474
        }
475
        Band alphaBand = null;
476
        if (colorInterpretation.hasAlphaBand()) {
477
            int alphaBandIndex =
478
                colorInterpretation.getBand(ColorInterpretation.ALPHA_BAND);
479
            alphaBand = bufferToDraw.getBand(alphaBandIndex);
480
        }
481

    
482
        for (int i = 0; i < bufferToDraw.getRows(); i++) {
483
            for (int j = 0; j < bufferToDraw.getColumns(); j++) {
484

    
485
                int alphaByteValue = 0;
486
                int redByteValue = 0;
487
                if(redBand!=null){
488
                    Number redValue = (Number) redBand.get(i, j);
489
                    NoData noData = redBand.getNoData();
490
                    if(noData != null){
491
                        if(redValue.equals(noData.getValue())){
492
                            alphaByteValue = 0 | alphaByteValue;
493
                            redByteValue = 0;
494
                        } else {
495
                            alphaByteValue = 255;
496
                            redByteValue = redValue.byteValue();
497
                        }
498
                    } else {
499
                        redByteValue = redValue.byteValue();
500
                    }
501
                }
502
                int greenByteValue = 0;
503
                if(greenBand!=null){
504
                    Number greenValue = (Number) greenBand.get(i, j);
505
                    NoData noData = greenBand.getNoData();
506
                    if(noData != null){
507
                        if(greenValue.equals(noData.getValue())){
508
                            alphaByteValue = 0 | alphaByteValue;
509
                            greenByteValue = 0;
510
                        } else {
511
                            alphaByteValue = 255;
512
                            greenByteValue = greenValue.byteValue();
513
                        }
514
                    } else {
515
                        greenByteValue = greenValue.byteValue();
516
                    }
517
                }
518
                int blueByteValue = 0;
519
                if(blueBand!=null){
520
                    Number blueValue = (Number) blueBand.get(i, j);
521
                    NoData noData = blueBand.getNoData();
522
                    if(noData != null){
523
                        if(blueValue.equals(noData.getValue())){
524
                            alphaByteValue = 0 | alphaByteValue;
525
                            blueByteValue = 0;
526
                        } else {
527
                            alphaByteValue = 255;
528
                            blueByteValue = blueValue.byteValue();
529
                        }
530
                    } else {
531
                        blueByteValue = blueValue.byteValue();
532
                    }
533
                }
534

    
535
                if (alphaByteValue!=0 && alphaBand != null) {
536
                    Number alphaValue = (Number) alphaBand.get(i, j);
537
                    int alphaBandIndex = colorInterpretation.getBand(ColorInterpretation.ALPHA_BAND);
538
                    NoData noData = alphaBand.getNoData();
539
                    if(noData != null){
540
                        if(alphaValue.equals(noData.getValue())){
541
                            alphaByteValue = 0;
542
                        } else {
543
                            alphaByteValue = alphaValue.byteValue();
544
                        }
545
                    } else {
546
                        alphaByteValue = alphaValue.byteValue();
547
                    }
548
                }
549

    
550
                if (alphaByteValue!=0 && transparency != null) {
551
                    // Apply defined transparency ranges
552

    
553
                    int newAlpha =
554
                        transparency.getTransparencyRangeAlpha(redByteValue,
555
                            greenByteValue, blueByteValue);
556
                    alphaByteValue = getNewAlpha(alphaByteValue, newAlpha);
557

    
558
                    // Apply general transparency
559
                    int transparencyValue = transparency.getAlpha();
560
                    alphaByteValue = getNewAlpha(alphaByteValue, transparencyValue);
561
                }
562

    
563
                //FIXME: TO REMOVE??
564
//                if (filters != null) {
565
//                    // TODO Apply filters
566
//                }
567

    
568
                int intRGB = 0;
569
                if (colorInterpretation.hasAnyRGBBand()) {//colorInterpretation.isRGB() || colorInterpretation.isRGBA()) {
570
                    intRGB = (((byte)alphaByteValue & 0xFF) << 24) | // alpha
571
                        (((byte)redByteValue & 0xFF) << 16) | // red
572
                        (((byte)greenByteValue & 0xFF) << 8) | // green
573
                        (((byte)blueByteValue & 0xFF)); // blue String.format("%X", b)
574
//                    intRGB = ((alphaByteValue & 0xFF) << 24) | // alpha
575
//                        ((redByteValue & 0xFF) << 16) | // red
576
//                        ((greenByteValue & 0xFF) << 8) | // green
577
//                        ((blueByteValue & 0xFF) << 0); // blue String.format("%X", b)
578
                } else if (colorInterpretation.isBGR()) {
579
                    intRGB = (((byte)blueByteValue & 0xFF) << 16 | // blue
580
                        (((byte)greenByteValue & 0xFF) << 8) | // green
581
                        (((byte)redByteValue & 0xFF))); // red
582

    
583
                }
584
                image.setRGB(j, i, intRGB);
585
            }
586
        }
587
        return image;
588
    }
589

    
590
    private Image drawHSLBuffer(Graphics graphics, Buffer buffer,
591
        ColorInterpretation colorInterpretation,Transparency transparency,
592
        OperationList filters) throws BufferOperationException {
593

    
594
        Buffer byteBuffer = convertToByteBuffer(buffer);
595

    
596
        BufferedImage image = null;
597

    
598
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
599
            BufferedImage.TYPE_INT_ARGB);
600

    
601
        int hueBandIndex = colorInterpretation.getBand(ColorInterpretation.HUE_BAND);
602
        int saturationBandIndex = colorInterpretation.getBand(ColorInterpretation.SATURATION_BAND);
603
        int lightBandIndex = colorInterpretation.getBand(ColorInterpretation.LIGHTNESS_BAND);
604

    
605

    
606
        Band hueBand = byteBuffer.getBand(hueBandIndex);
607
        Band saturationBand = byteBuffer.getBand(saturationBandIndex);
608
        Band lightBand = byteBuffer.getBand(lightBandIndex);
609

    
610

    
611
        for (int i = 0; i < buffer.getRows(); i++) {
612
            for (int j = 0; j < buffer.getColumns(); j++) {
613
                Number hueValue = (Number) hueBand.get(i, j);
614
                Number saturationValue = (Number) saturationBand.get(i, j);
615
                Number lightValue = (Number) lightBand.get(i, j);
616

    
617
                Number[] rgbaValues=ColorUtils.fromHSLtoRGBA(hueValue.floatValue(), saturationValue.floatValue(), lightValue.floatValue());
618

    
619
                Integer alphaValue =rgbaValues[3].intValue();
620
                if (transparency != null) {
621
                    // Apply defined transparency ranges
622

    
623
                    alphaValue = alphaValue.byteValue() & 0xFF;
624
                    int newAlpha =
625
                        transparency.getTransparencyRangeAlpha(rgbaValues[0].byteValue(),
626
                            rgbaValues[1].byteValue(), rgbaValues[2].byteValue());
627
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
628

    
629
                    // Apply general transparency
630
                    int transparencyValue = transparency.getAlpha();
631
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
632
                }
633

    
634
                if (filters != null) {
635
                    // TODO Apply filters
636
                }
637

    
638
                int intRGB = 0;
639
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
640
                    ((rgbaValues[0].byteValue() & 0xFF) << 16) | // red
641
                    ((rgbaValues[1].byteValue() & 0xFF) << 8) | // green
642
                    ((rgbaValues[2].byteValue() & 0xFF) << 0); // blue
643
                image.setRGB(j, i, intRGB);
644
            }
645
        }
646
        return image;
647
    }
648

    
649
    private Image drawCMYKBuffer(Graphics graphics, Buffer buffer,
650
        ColorInterpretation colorInterpretation,Transparency transparency,
651
        OperationList filters) throws BufferOperationException {
652

    
653
        Buffer byteBuffer = convertToByteBuffer(buffer);
654

    
655
        BufferedImage image = null;
656

    
657
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
658
            BufferedImage.TYPE_INT_ARGB);
659

    
660
        int cyanBandIndex = colorInterpretation.getBand(ColorInterpretation.CYAN_BAND);
661
        int magentaBandIndex = colorInterpretation.getBand(ColorInterpretation.MAGENTA_BAND);
662
        int yellowBandIndex = colorInterpretation.getBand(ColorInterpretation.YELLOW_BAND);
663
        int blackBandIndex = colorInterpretation.getBand(ColorInterpretation.BLACK_BAND);
664

    
665

    
666
        Band cyanBand = byteBuffer.getBand(cyanBandIndex);
667
        Band magentaBand = byteBuffer.getBand(magentaBandIndex);
668
        Band yellowBand = byteBuffer.getBand(yellowBandIndex);
669
        Band blackBand = byteBuffer.getBand(blackBandIndex);
670

    
671
        for (int i = 0; i < buffer.getRows(); i++) {
672
            for (int j = 0; j < buffer.getColumns(); j++) {
673
                Number cyanValue = (Number) cyanBand.get(i, j);
674
                Number magentaValue = (Number) magentaBand.get(i, j);
675
                Number yellowValue = (Number) yellowBand.get(i, j);
676
                Number blackValue = (Number) blackBand.get(i, j);
677

    
678

    
679

    
680
                Number[] rgbValues=ColorUtils.fromCMYKtoRGB(
681
                    cyanValue.floatValue(),
682
                    magentaValue.floatValue(),
683
                    yellowValue.floatValue(),
684
                    blackValue.floatValue()
685
                    );
686

    
687
                Integer alphaValue =255;
688
                if (transparency != null) {
689
                    // Apply defined transparency ranges
690

    
691
                    alphaValue = alphaValue.byteValue() & 0xFF;
692
                    int newAlpha =
693
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
694
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
695
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
696

    
697
                    // Apply general transparency
698
                    int transparencyValue = transparency.getAlpha();
699
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
700
                }
701

    
702
                if (filters != null) {
703
                    // TODO Apply filters
704
                }
705

    
706
                int intRGB = 0;
707
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
708
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
709
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
710
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
711
                image.setRGB(j, i, intRGB);
712
            }
713
        }
714
        return image;
715
    }
716

    
717
    private Image drawYCBCRBuffer(Graphics graphics, Buffer buffer,
718
        ColorInterpretation colorInterpretation,Transparency transparency,
719
        OperationList filters) throws BufferOperationException {
720

    
721
        Buffer byteBuffer = convertToByteBuffer(buffer);
722

    
723
        BufferedImage image = null;
724

    
725
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
726
            BufferedImage.TYPE_INT_ARGB);
727

    
728
        int yIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_Y_BAND);
729
        int cbBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CB_BAND);
730
        int crBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CR_BAND);
731

    
732

    
733
        Band yBand = byteBuffer.getBand(yIndex);
734
        Band cbBand = byteBuffer.getBand(cbBandIndex);
735
        Band crBand = byteBuffer.getBand(crBandIndex);
736

    
737
        for (int i = 0; i < buffer.getRows(); i++) {
738
            for (int j = 0; j < buffer.getColumns(); j++) {
739
                Number yValue = (Number) yBand.get(i, j);
740
                Number cbValue = (Number) cbBand.get(i, j);
741
                Number crValue = (Number) crBand.get(i, j);
742

    
743
                Number[] rgbValues=ColorUtils.fromYCBCRtoRGB(
744
                    yValue.floatValue(),
745
                    cbValue.floatValue(),
746
                    crValue.floatValue()
747
                    );
748

    
749
                Integer alphaValue =255;
750
                if (transparency != null) {
751
                    // Apply defined transparency ranges
752

    
753
                    alphaValue = alphaValue.byteValue() & 0xFF;
754
                    int newAlpha =
755
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
756
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
757
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
758

    
759
                    // Apply general transparency
760
                    int transparencyValue = transparency.getAlpha();
761
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
762
                }
763

    
764
                if (filters != null) {
765
                    // TODO Apply filters
766
                }
767

    
768
                int intRGB = 0;
769
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
770
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
771
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
772
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
773
                image.setRGB(j, i, intRGB);
774
            }
775
        }
776
        return image;
777
    }
778

    
779
    /**
780
     * Method to draw gray buffers
781
     * @param graphics
782
     * @param byteBuffer
783
     * @param filters
784
     * @return
785
     * @throws OperationException
786
     */
787
    private Image drawGrayBuffer(Graphics graphics, Buffer buffer, ColorInterpretation colorInterpretation, Transparency transparency, OperationList filters) throws BufferOperationException {
788

    
789
        BufferedImage image = null;
790
        Buffer byteBuffer = convertToByteBuffer(buffer);
791

    
792
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(byteBuffer.getColumns(), byteBuffer.getRows(),
793
            BufferedImage.TYPE_INT_ARGB);
794

    
795
        Band grayBand = byteBuffer.getBand(colorInterpretation.getBand(ColorInterpretation.GRAY_BAND));
796

    
797
        for (int i = 0; i < byteBuffer.getRows(); i++) {
798
            for (int j = 0; j < byteBuffer.getColumns(); j++) {
799
                int grayByteValue = 0;
800
                int alphaByteValue = (byte)255;
801
                Number grayValue = (Number) grayBand.get(i, j);
802
                NoData noData = grayBand.getNoData();
803
                if(noData != null){
804
                    if(grayValue.equals(noData.getValue())){
805
                        alphaByteValue = 0;
806
                        grayByteValue = 0;
807
                    } else {
808
                        alphaByteValue = 255;
809
                        grayByteValue = grayValue.byteValue();
810
                    }
811
                } else {
812
                    grayByteValue = grayValue.byteValue();
813
                }
814

    
815
                if (alphaByteValue != 0 && transparency != null) {
816
                    // Apply defined transparency ranges
817

    
818
//                    alphaByteValue = alphaValue.byteValue() & 0xFF;
819
                    int newAlpha = transparency.getTransparencyRangeAlpha(grayByteValue, grayByteValue, grayByteValue);
820
                    alphaByteValue = getNewAlpha(alphaByteValue, newAlpha);
821

    
822
                    // Apply general transparency
823
                    int transparencyValue = transparency.getAlpha();
824
                    alphaByteValue = getNewAlpha(alphaByteValue, transparencyValue);
825
                }
826

    
827
                if (filters != null) {
828
                    // TODO Apply filters
829
                }
830

    
831
                int intARGB = (((byte)alphaByteValue & 0xFF) << 24) | // alpha
832
                    (((byte)grayByteValue & 0xFF)<< 16) | // red
833
                    (((byte)grayByteValue & 0xFF)<< 8) | // green
834
                    (((byte)grayByteValue & 0xFF)); // blue
835

    
836
                image.setRGB(j, i, intARGB);
837
            }
838
        }
839
        return image;
840
    }
841

    
842
    private Buffer convertToByteBuffer(Buffer buffer) throws BufferOperationException {
843
        int[] types = buffer.getBandTypes();
844
        boolean mustConvert = false;
845
        List<Integer> bandsToProcess = new ArrayList<Integer>();
846
        for (int i = 0; i < types.length; i++) {
847
            if(types[i]!=BufferManager.TYPE_BYTE){
848
                bandsToProcess.add(i);
849
                mustConvert = true;
850
//                break;
851
            }
852
        }
853
        if(mustConvert){
854
            OperationManager operationManager = BufferLocator.getOperationManager();
855
            DynObject parameters = operationManager.createOperationParameters(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
856
            parameters.setDynValue(AbstractSpecifiedBandsOperation.BANDS_TO_PROCESS_PARAM, bandsToProcess);
857
            return operationManager.execute(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME, buffer, parameters);
858
        }
859
        return buffer;
860
    }
861

    
862
    private Image drawPaletteBuffer(Graphics graphics, Buffer buffer, ColorInterpretation colorInterpretation,
863
        Transparency transparency, OperationList filters) {
864

    
865
        BufferedImage image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
866
            BufferedImage.TYPE_INT_ARGB);
867

    
868
        for (int i = 0; i < buffer.getRows(); i++) {
869
            for (int j = 0; j < buffer.getColumns(); j++) {
870

    
871
                Object value = buffer.getBand(colorInterpretation.getPaletteBand()).get(i, j);
872
                byte[] rgba = colorInterpretation.getPalette().getRGBA(value);
873

    
874
                if (transparency != null) {
875
                    // Apply defined transparency ranges
876
                    int alpha = rgba[3] & 0xFF;
877
                    int newAlpha =
878
                        transparency.getTransparencyRangeAlpha(rgba[0], rgba[1], rgba[2]);
879
                    alpha = getNewAlpha(alpha, newAlpha);
880

    
881
                    // Apply general transparency
882
                    int transparencyValue = transparency.getAlpha();
883
                    rgba[3] = (byte) getNewAlpha(alpha, transparencyValue);
884
                }
885

    
886
                if (filters != null) {
887
                    // TODO Apply filters
888
                }
889

    
890
                int intARGB = ((rgba[3] & 0xFF) << 24) | // alpha
891
                    ((rgba[0] & 0xFF) << 16) | // red
892
                    ((rgba[1] & 0xFF) << 8) | // green
893
                    ((rgba[2] & 0xFF) << 0); // blue
894

    
895
                image.setRGB(j, i, intARGB);
896
            }
897
        }
898
        return image;
899
    }
900

    
901
    private int getNewAlpha(int alpha, int newAlpha) {
902
        return (int) Math.round(alpha * (newAlpha / 255d));
903
    }
904

    
905
    @Override
906
    public ColorInterpretation getColorInterpretation() {
907
        return this.colorInterpretation;
908
    }
909

    
910
    @Override
911
    public void setColorInterpretation(ColorInterpretation colorInterpretation) {
912
        if (this.colorInterpretation != null) {
913
            this.colorInterpretation.deleteObserver(this);
914
        }
915
        this.colorInterpretation = colorInterpretation;
916
        this.colorInterpretation.addObserver(this);
917
    }
918

    
919
    @Override
920
    public OperationList getFilters() {
921
        if(this.filters == null){
922
            BufferManager bufferManager = BufferLocator.getBufferManager();
923
            this.filters = ((OperationManager)bufferManager).createOperationList();
924
        }
925
        return this.filters;
926
    }
927

    
928
    @Override
929
    public void setFilters(OperationList filterList) {
930
        OperationList oldFilters = this.filters;
931
        this.filters = filterList;
932
        fireColorinterpretationChangedEvent(new ChangeOperationListEvent(oldFilters, this.filters));
933
    }
934

    
935
    /**
936
     *
937
     */
938
    public static void registerPersistence() {
939
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
940
        DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
941
        if (definition == null) {
942
            definition =
943
                manager.addDefinition(DefaultRasterLegend.class, PERSISTENT_NAME,
944
                    PERSISTENT_DESCRIPTION, null, null);
945
            definition.addDynFieldObject(COLOR_INTERPRETATION_PERSISTENCE_FIELD).setMandatory(false)
946
                .setClassOfValue(ColorInterpretation.class);
947
            definition.addDynFieldObject(FILTERS_PERSISTENCE_FIELD).setMandatory(false)
948
                .setClassOfValue(OperationList.class);
949
        }
950
    }
951

    
952
    @Override
953
    public void saveToState(PersistentState state) throws PersistenceException {
954
        state.set(COLOR_INTERPRETATION_PERSISTENCE_FIELD, this.getColorInterpretation());
955
        state.set(FILTERS_PERSISTENCE_FIELD, (Persistent)this.getFilters());
956
    }
957

    
958
    @Override
959
    public void loadFromState(PersistentState state) throws PersistenceException {
960
        this.setColorInterpretation((ColorInterpretation) state
961
            .get(COLOR_INTERPRETATION_PERSISTENCE_FIELD));
962
        this.setFilters((OperationList) state.get(FILTERS_PERSISTENCE_FIELD));
963
    }
964

    
965
    @Override
966
    public void setTransparency(Transparency transparency) {
967
        this.transparency = transparency;
968
    }
969

    
970
    @Override
971
    public Transparency getTransparency() {
972
        return this.transparency;
973
    }
974

    
975
    @Override
976
    public ISymbol getDefaultSymbol() {
977
        return null;
978
    }
979

    
980
    @Override
981
    public Object clone() throws CloneNotSupportedException {
982
        DefaultRasterLegend cloned = (DefaultRasterLegend) super.clone();
983

    
984
        ColorInterpretation clonedColorInterpretation = (ColorInterpretation)this.getColorInterpretation().clone();
985
        cloned.setColorInterpretation(clonedColorInterpretation);
986
        //FIXME:
987
//        cloned.setTransparency((Transparency)this.getTransparency().clone());
988
//        cloned.setFilters(getFilters());
989

    
990
        return cloned;
991
    }
992

    
993
    @Override
994
    public ILegend cloneLegend() {
995
        try {
996
            return (RasterLegend)this.clone();
997
        } catch (Exception e) {
998
            throw new RuntimeException("Can't clone the legend", e);
999
        }
1000
    }
1001

    
1002

    
1003
    @Override
1004
    public void fireDefaultSymbolChangedEvent(SymbolLegendEvent event) {
1005

    
1006
        for (int i = 0; i < listeners.size(); i++) {
1007
            ((LegendContentsChangedListener) listeners.get(i))
1008
                    .symbolChanged(event);
1009
        }
1010
    }
1011

    
1012
    @Override
1013
    public LegendContentsChangedListener[] getListeners() {
1014
        return (LegendContentsChangedListener[]) listeners
1015
                .toArray(new LegendContentsChangedListener[listeners.size()]);
1016
    }
1017

    
1018

    
1019

    
1020
    @Override
1021
    public void setTransparentNoData(boolean noDataTransparent) {
1022
        this.transparentNoData=noDataTransparent;
1023

    
1024
    }
1025

    
1026
    @Override
1027
    public boolean areTransparentNoData() {
1028
        return this.transparentNoData;
1029
    }
1030

    
1031
    @SuppressWarnings("unchecked")
1032
    @Override
1033
    public void update(Observable observable, Object notification) {
1034
        if (notification instanceof ColorInterpretationNotification) {
1035
            String type = ((ColorInterpretationNotification) notification).getType();
1036
            if(type.equals(ColorInterpretationNotification.CHANGED_COLOR_INTERPRETATION_VALUE)
1037
               || type.equals(ColorInterpretationNotification.ADDED_COLOR_INTERPRETATION)
1038
               || type.equals(ColorInterpretationNotification.COPIED_FROM_COLOR_INTERPRETATION)){
1039
            fireColorinterpretationChangedEvent(new ChangeColorInterpretationEvent(
1040
                (String[])((ColorInterpretationNotification) notification).getValue(0),
1041
                (String[])((ColorInterpretationNotification) notification).getValue(1)));
1042
            }
1043
            if (type.equals(ColorInterpretationNotification.SETTED_PALETTE)) {
1044
                fireColorinterpretationChangedEvent(new ChangePaletteEvent(
1045
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0),
1046
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(1)));
1047
            }
1048
            if (type.equals(ColorInterpretationNotification.CHANGED_PALETTE)) {
1049
                fireColorinterpretationChangedEvent(new ChangePaletteEvent(
1050
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0),
1051
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0)));
1052
            }
1053

    
1054
            if (type.equals(ColorInterpretationNotification.SETTED_PALETTE_BAND)) {
1055
                fireColorinterpretationChangedEvent(new ChangePaletteBandEvent(
1056
                    (int) ((ColorInterpretationNotification) notification).getValue(0),
1057
                    (int) ((ColorInterpretationNotification) notification).getValue(1)));
1058
            }
1059
        }
1060
        if (notification instanceof OperationListNotification) {
1061
            fireOperationListChangedEvent(new ChangeOperationListEvent(
1062
                    (List<OperationListEntry>) ((OperationListNotification) notification).getValue(0),
1063
                    (List<OperationListEntry>) ((OperationListNotification) notification).getValue(1)));
1064
        }
1065
    }
1066

    
1067
    /**
1068
     * @param event
1069
     */
1070
    public void fireColorinterpretationChangedEvent(RasterLegendEvent event) {
1071

    
1072
        for (int i = 0; i < listeners.size(); i++) {
1073
            ((RasterLegendChangedListener) listeners.get(i)).colorInterpretationChanged(event);
1074
        }
1075
    }
1076

    
1077
    /**
1078
     * @param event
1079
     */
1080
    public void fireOperationListChangedEvent(RasterLegendEvent event) {
1081

    
1082
        for (int i = 0; i < listeners.size(); i++) {
1083
            ((RasterLegendChangedListener) listeners.get(i)).operationListChanged(event);
1084
        }
1085
    }
1086

    
1087
    @Override
1088
    public void addLegendListener(LegendContentsChangedListener listener) {
1089
        if(listener instanceof RasterLegendChangedListener){
1090
            addLegendListener((RasterLegendChangedListener)listener);
1091
            return;
1092
        }
1093
        throw new UnsupportedOperationException("Raster layer can't be listened by a no RasterLegendChangedListener");
1094

    
1095
    }
1096

    
1097
    @Override
1098
    public void removeLegendListener(LegendContentsChangedListener listener) {
1099
        if(listener instanceof RasterLegendChangedListener){
1100
            removeLegendListener((RasterLegendChangedListener)listener);
1101
            return;
1102
        }
1103
        throw new UnsupportedOperationException("Raster layer can't be listened by a no RasterLegendChangedListener");
1104

    
1105
    }
1106

    
1107
    private void addLegendListener(RasterLegendChangedListener listener) {
1108
        if (listener != null && !listeners.contains(listener))
1109
            listeners.add(listener);
1110
    }
1111

    
1112
    private void removeLegendListener(RasterLegendChangedListener listener) {
1113
        listeners.remove(listener);
1114
    }
1115

    
1116
    @Override
1117
    public void addColorTableOperation(ColorInterpretation colorInterpretation, int index) {
1118

    
1119
        removeOperationIfExists(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1120
        removeOperationIfExists(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1121

    
1122
        OperationManager operationManager = BufferLocator.getOperationManager();
1123
        Operation colorTableOperation = operationManager.createOperation(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1124
        DynObject colorTableOperationParameters = operationManager.createOperationParameters(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1125
        colorTableOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM, colorInterpretation);
1126
        colorTableOperationParameters.setDynValue(AbstractOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
1127
        OperationListEntry colorTableEntry = operationManager.createOperationListEntry(colorTableOperation, colorTableOperationParameters);
1128
        getFilters().add(index, colorTableEntry);
1129
    }
1130

    
1131
    @Override
1132
    public void addLinearStretchEnhancementOperationIfNeeded(ColorInterpretation colorInterpretation,
1133
        RasterStore store, int index) {
1134

    
1135
        removeOperationIfExists(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1136
        removeOperationIfExists(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1137

    
1138
        RasterStore rasterStore = (RasterStore) store;
1139

    
1140
        OperationManager operationManager = BufferLocator.getOperationManager();
1141
        if ((!colorInterpretation.isPalette())
1142
            && (colorInterpretation.hasAnyColorInterpretationBand() || colorInterpretation.hasAlphaBand() || colorInterpretation
1143
                .hasAnyGrayBand())) {
1144

    
1145
            List<Integer> bandsToProcess = new ArrayList<Integer>();
1146
            for (int i = 0; i < rasterStore.getBands(); i++) {
1147
                if ((colorInterpretation.isColorInterpretation(i) || colorInterpretation.isAlphaInterpretation(i) || colorInterpretation
1148
                    .isGrayInterpretation(i))
1149
                    && (rasterStore.getBandDescriptor(i).getDataType() != BufferManager.TYPE_BYTE)) {
1150
                    bandsToProcess.add(i);
1151
                }
1152
            }
1153

    
1154
            if (!bandsToProcess.isEmpty()) {
1155
                Operation linearStretchEnhancementOperation = operationManager.createOperation(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1156
                DynObject linearStretchEnhancementOperationParameters =
1157
                    operationManager.createOperationParameters(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1158
                linearStretchEnhancementOperationParameters.setDynValue(
1159
                    AbstractSpecifiedBandsOperation.BANDS_TO_PROCESS_PARAM, bandsToProcess);
1160
                OperationListEntry colorTableEntry =
1161
                    ((OperationManager) operationManager).createOperationListEntry(linearStretchEnhancementOperation,
1162
                        linearStretchEnhancementOperationParameters);
1163
                getFilters().add(index, colorTableEntry);
1164
            }
1165
        }
1166
    }
1167

    
1168
    @Override
1169
    public void removeOperationIfExists(String name) {
1170
        int removed = 0;
1171
        int size = getFilters().size();
1172
        for (Iterator<OperationListEntry> iterator = getFilters().iterator(); iterator.hasNext();) {
1173
            OperationListEntry entry = (OperationListEntry) iterator.next();
1174
            Operation operation = entry.getOperation();
1175
            if (operation.getFactory().getName().equals(name)) {
1176
                iterator.remove();
1177
                removed++;
1178
            }
1179
        }
1180
        if(getFilters().size()!=size-removed){
1181
            LOG.warn("NO SE HAN ELIMINADO CORRECTAMENTE LAS ENTRADAS DE LA OPERATION_LIST.");
1182
        }
1183
    }
1184

    
1185
}