Statistics
| Revision:

svn-gvsig-desktop / branches / org.gvsig.desktop-2018a / org.gvsig.desktop.compat.cdc / org.gvsig.fmap.mapcontext / org.gvsig.fmap.mapcontext.impl / src / main / java / org / gvsig / raster / lib / legend / impl / DefaultRasterLegend.java @ 43876

History | View | Annotate | Download (54.4 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.List;
10

    
11
import org.cresques.cts.ICoordTrans;
12
import org.gvsig.fmap.dal.raster.BandDescriptor;
13
import org.slf4j.Logger;
14
import org.slf4j.LoggerFactory;
15

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

    
74
/**
75
 * Default implementation of {@link RasterLegend}. This object can draw buffers
76
 * with a {@link ColorInterpretation}, {@link ColorTable} and {@link OperationList}
77
 *
78
 *
79
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
80
 *
81
 */
82
public class DefaultRasterLegend implements RasterLegend {
83

    
84
    public static final String LEGEND_NAME = "BaseRasterLegend";
85
    
86
    private static final Logger LOG = LoggerFactory.getLogger(DefaultRasterLegend.class);
87

    
88
    private ColorInterpretation colorInterpretation;
89
    private Transparency transparency;
90
    private OperationList filters;
91
    private boolean transparentNoData;
92

    
93
    private List<RasterLegendChangedListener> listeners =
94
        new ArrayList<RasterLegendChangedListener>();
95

    
96
    /**
97
     * Persistence definition name
98
     */
99
    public static final String PERSISTENT_NAME = "RasterLegendPersistence";
100
    /**
101
     * Description of persistence definition
102
     */
103
    public static final String PERSISTENT_DESCRIPTION = "Persistence definition of raster legend";
104

    
105
    private final static String COLOR_INTERPRETATION_PERSISTENCE_FIELD = "colorInterpretation";
106
    private final static String FILTERS_PERSISTENCE_FIELD = "filters";
107

    
108
    /**
109
     * Empty constructor
110
     */
111
    public DefaultRasterLegend() {
112

    
113
    }
114

    
115
    /**
116
     * Default {@link RasterLegend} constructor
117
     *
118
     * @param colorInterpretation
119
     *            Color interpretation of legend
120
     */
121
    public DefaultRasterLegend(ColorInterpretation colorInterpretation) {
122
        this(colorInterpretation, null, null);
123
    }
124

    
125
    /**
126
     * Default {@link RasterLegend} constructor
127
     *
128
     * @param colorTable
129
     *            Color table of legend
130
     * @param colorInterpretation
131
     *            Color interpretation of legend
132
     * @param transparency
133
     *            Transparency of legend
134
     * @param filters
135
     *            Filters of legend
136
     */
137
    @SuppressWarnings("OverridableMethodCallInConstructor")
138
    public DefaultRasterLegend(ColorInterpretation colorInterpretation,
139
        Transparency transparency, OperationList filters) {
140
        this.transparency = transparency;
141
        this.filters = filters;
142
        setColorInterpretation(colorInterpretation);
143
    }
144

    
145
    @Override
146
    public void draw(Graphics graphics, Buffer buffer, ViewPort viewPort,
147
        SimpleTaskStatus taskStatus) {
148

    
149
        boolean isMyTask = false;
150
        if (taskStatus == null) {
151
            TaskStatusManager taskStatusManager = ToolsLocator.getTaskStatusManager();
152
            taskStatus =
153
                taskStatusManager.createDefaultSimpleTaskStatus("_drawing_buffer_XxellipsisxX");
154
            taskStatus.setAutoremove(true);
155
            taskStatus.add();
156
            isMyTask = true;
157
        } else {
158
            taskStatus.push();
159
        }
160

    
161
        taskStatus.setIndeterminate();
162

    
163
        if (this.colorInterpretation == null || !this.colorInterpretation.hasInterpretation()
164
            || this.colorInterpretation.isUndefined()) {
165
            taskStatus.abort();
166
            throw new IllegalStateException(
167
                "To draw buffer, raster legend has to have a color interpretation");
168
        }
169

    
170
        // Check if viewport projection is the same as buffer projection
171
        Buffer clip = null;
172
        Buffer interpolated = null;
173
        Buffer converted = null;
174
        Buffer interpolated2 = null;
175
        Buffer bufferToDraw = buffer;
176
        try {
177
            if (buffer != null && buffer.getColumns()>0 && buffer.getRows()>0) {
178

    
179
                if (!viewPort.getProjection().equals(buffer.getProjection())) {
180

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

    
196
                        double widthPixel = bufferEnvelopeInViewPortCoords.getLength(0) / viewPortPixelSizeX;
197
                        double heightPixel = bufferEnvelopeInViewPortCoords.getLength(1) / viewPortPixelSizeY;
198

    
199
                        interpolated =
200
                            clip.createInterpolated((int) Math.floor(heightPixel), (int) Math.floor(widthPixel),
201
                                Buffer.INTERPOLATION_Bilinear, taskStatus);
202
                        DisposeUtils.dispose(clip);
203
                        // Convert interpolated clipped buffer
204
                        converted = interpolated.convert(invertedCoordTrans, taskStatus);
205
                        DisposeUtils.dispose(interpolated);
206

    
207
                        widthPixel = getWidthPixel(converted.getEnvelope(), viewPortPixelSizeX);
208
                        heightPixel = getHeightPixel(converted.getEnvelope(), viewPortPixelSizeY);
209

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

    
215
                        bufferToDraw = interpolated2;
216

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

    
224
                    double widthPixel = 0;
225
                    double heightPixel = 0;
226
                    try {
227
                        // Clip and interpolate buffer with view port envelope
228
                        if (!buffer.getEnvelope().equals(viewPort.getAdjustedEnvelope())) {
229
                            clip = buffer.clip(viewPort.getAdjustedEnvelope());
230
                            DisposeUtils.dispose(buffer);
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
                        DisposeUtils.disposeQuietly(clip);
244
                        bufferToDraw = interpolated;
245
                    } catch (BufferException e) {
246
                        LOG.warn(
247
                            "Buffer can not be interpolated with [rows: {} , columns: {}, method: {}]",
248
                            new String[] { String.valueOf((int) Math.floor(heightPixel)),
249
                                String.valueOf((int) Math.floor(widthPixel)),
250
                                String.valueOf(Buffer.INTERPOLATION_Bilinear) });
251
                        taskStatus.abort();
252
                        return;
253
                    }
254
                } else {
255
                    // Do nothing view port envelope does not intersect with
256
                    // buffer
257
                    return;
258
                }
259
            }
260

    
261
            OperationManager operationManager = BufferLocator.getOperationManager();
262

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

    
265
                // Calculate where image has to be drawn
266
                double x = bufferToDraw.getEnvelope().getMinimum(0);
267
                double y = bufferToDraw.getEnvelope().getMaximum(1);
268
                AffineTransform affineTransform =
269
                    calculateAffineTransform(viewPort.getAdjustedEnvelope(), viewPort.getImageWidth(),
270
                        viewPort.getImageHeight());
271

    
272
                Point point;
273
                try {
274
                    point = GeometryLocator.getGeometryManager().createPoint(x, y, SUBTYPES.GEOM2D);
275
                    point.transform(affineTransform.createInverse());
276
                } catch (CreateGeometryException | NoninvertibleTransformException e) {
277
                    LOG.warn("Can not calculate the point of buffer in viewport image", e);
278
                    taskStatus.abort();
279
                    return;
280
                }
281

    
282
                // Draw buffer
283
                Image image = null;
284
                Buffer filteredBuffer = bufferToDraw;
285
                try {
286
                    DynObjectManager dynObjectManager = new DefaultDynObjectManager();
287
                    DynClass parametersClass = dynObjectManager.createDynClass("Parameters", "Parameters to find through ultimately.");
288
                    parametersClass.addDynFieldObject(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM);
289
                    DynObject defaultParameters = dynObjectManager.createDynObject(parametersClass);
290
                    defaultParameters.setDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM, colorInterpretation);
291

    
292
                    getFilters().setDefaultParameters(defaultParameters);
293

    
294
                    Object oColorInterpretation = null;
295
                    filteredBuffer = getFilters().execute(taskStatus, bufferToDraw);
296
                    oColorInterpretation = getFilters().getParameterValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM);
297
                    ColorInterpretation colorInterpretationAfterFilters = null;
298
                    if (oColorInterpretation != null) {
299
                        colorInterpretationAfterFilters = (ColorInterpretation) oColorInterpretation;
300
                    }
301
                    if (colorInterpretationAfterFilters == null) {
302
                        colorInterpretationAfterFilters = colorInterpretation;
303
                    }
304

    
305
                    if (colorInterpretationAfterFilters.isPalette()) {
306
                        DynObject colorTableOperationParameters =
307
                            operationManager.createOperationParameters(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
308
                        colorTableOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
309
                            colorInterpretationAfterFilters);
310
//                        colorTableOperationParameters.setDynValue(ColoredOperation.COPY_UNPROCESSED_BANDS_PARAM,
311
//                            true);
312
                        Buffer rgbBuffer =
313
                            operationManager.execute(taskStatus, ColoredOperation.COLOR_TABLE_OPERATION_NAME, filteredBuffer,
314
                                colorTableOperationParameters);
315
                        image =
316
                            drawRGBBuffer(graphics, rgbBuffer,
317
                                (ColorInterpretation) colorTableOperationParameters
318
                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
319
                                getFilters());
320

    
321
                    } else if (colorInterpretationAfterFilters.hasAnyGrayBand()) {
322
                        // Draw buffer with gray scale
323
                        image = drawGrayBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency, filters);
324
                        // } else if (this.colorInterpretation.isRGBA() ||
325
                        // this.colorInterpretation.isRGB()
326
                        // || this.colorInterpretation.isBGR() ||
327
                        // this.colorInterpretation.hasRGBBands()) {
328
                    } else if (colorInterpretationAfterFilters.hasAnyRGBBand()) {
329
                        // Draw RGB, RGBA or BGR buffer without color table
330
                        image =
331
                            drawRGBBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency,
332
                                filters);
333
//                    } else if (colorInterpretationAfterFilters.hasAnyHSLBand()) {
334
//                        // Draw HSL buffer without color table
335
//                        // image = drawHSLBuffer(graphics, bufferToDraw,
336
//                        // colorInterpretation, transparency, filters);
337
//
338
//                        DynObject hSLToRGBOperationParameters =
339
//                            operationManager.createOperationParameters(HSLToRGBOperationFactory.NAME);
340
//                        hSLToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
341
//                            colorInterpretationAfterFilters);
342
////                        hSLToRGBOperationParameters.setDynValue(ColoredOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
343
//                        Buffer rgbBuffer =
344
//                            operationManager.execute(HSLToRGBOperationFactory.NAME, filteredBuffer,
345
//                                hSLToRGBOperationParameters);
346
//                        image =
347
//                            drawRGBBuffer(graphics, rgbBuffer,
348
//                                (ColorInterpretation) hSLToRGBOperationParameters
349
//                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
350
//                                filters);
351
//
352
//                    } else if (colorInterpretationAfterFilters.hasAnyCMYKBand()) {
353
//                        // Draw CMYK buffer without color table
354
////                        image = drawCMYKBuffer(graphics, filteredBuffer, colorInterpretationAfterFilters, transparency, filters);
355
//
356
//                        DynObject cmykToRGBOperationParameters =
357
//                            operationManager.createOperationParameters(CMYKToRGBOperationFactory.NAME);
358
//                        cmykToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM,
359
//                            colorInterpretationAfterFilters);
360
////                        cmykToRGBOperationParameters.setDynValue(CMYKToRGBOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
361
//                        Buffer rgbBuffer =
362
//                            operationManager.execute(CMYKToRGBOperationFactory.NAME, filteredBuffer,
363
//                                cmykToRGBOperationParameters);
364
//                        image =
365
//                            drawRGBBuffer(graphics, rgbBuffer,
366
//                                (ColorInterpretation) cmykToRGBOperationParameters
367
//                                    .getDynValue(ColoredOperation.OUTPUT_COLOR_INTERPRETATION_PARAM), transparency,
368
//                                filters);
369
//
370
//                    } else if (colorInterpretationAfterFilters.hasAnyYCBCRBand()) {
371
//                        // TODO: Hacer un filtro YCBCRToRGB y llamarlo como en
372
//                        // los de arriba
373
//
374
//                        // Draw YCBCR buffer without color table
375
//                        image = drawYCBCRBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
376
                    }
377
                } catch (Exception e) {
378
                    LOG.warn("Error drawing legend", e);
379
                    taskStatus.abort();
380
                    return;
381
                } finally {
382
                    if (filteredBuffer != null && filteredBuffer != bufferToDraw) {
383
                        DisposeUtils.dispose(filteredBuffer);
384
                        filteredBuffer = null;
385
                    }
386
                }
387

    
388

    
389
                graphics.drawImage(image, (int) Math.floor(point.getX()), (int) Math.floor(point.getY()), null);
390
            }
391
        } catch (LocatorException | CreateEnvelopeException e1) {
392
            LOG.warn("Can not calculate the envelope of buffer", e1);
393
            taskStatus.abort();
394
            return;
395
        } finally {
396
            if (clip != null) {
397
                DisposeUtils.dispose(clip);
398
                clip = null;
399
            }
400
            if (interpolated != null) {
401
                DisposeUtils.dispose(interpolated);
402
                interpolated = null;
403
            }
404
            if (converted != null) {
405
                DisposeUtils.dispose(converted);
406
                converted = null;
407
            }
408
            if (interpolated2 != null) {
409
                DisposeUtils.dispose(interpolated2);
410
                interpolated2 = null;
411
            }
412
            if (bufferToDraw != null && bufferToDraw != buffer) {
413
                DisposeUtils.dispose(bufferToDraw);
414
                bufferToDraw = null;
415
            }
416

    
417
            if (!isMyTask) {
418
                taskStatus.pop();
419
            }
420
        }
421
    }
422

    
423
    private AffineTransform calculateAffineTransform(Envelope envelope, double imageWidth,
424
        double imageHeight) {
425
        double pixelSizeX = envelope.getLength(0) / imageWidth;
426
        double rotationX = 0;
427
        double x = envelope.getMinimum(0);
428
        double rotationY = 0;
429
        double pixelSizeY = -envelope.getLength(1) / imageHeight;
430
        double y = envelope.getMaximum(1);
431
        return new AffineTransform(pixelSizeX, rotationY, rotationX, pixelSizeY, x, y);
432
    }
433

    
434
    private double getWidthPixel(Envelope envelope, double dist1pixel) {
435
        double widthEnvelope = envelope.getLength(0);
436
        return widthEnvelope / dist1pixel;
437
    }
438

    
439
    private double getHeightPixel(Envelope envelope, double dist1pixel) {
440
        double heightEnvelope = envelope.getLength(1);
441
        return heightEnvelope / dist1pixel;
442
    }
443

    
444

    
445

    
446
    private Image drawRGBBuffer(Graphics graphics, Buffer buffer,
447
        ColorInterpretation colorInterpretation, Transparency transparency, OperationList filters) throws BufferOperationException {
448

    
449
        Buffer byteBuffer = convertToByteBuffer(buffer);
450
        Buffer bufferToDraw = byteBuffer;
451

    
452
        BufferedImage image = null;
453

    
454
        if (colorInterpretation.isRGB() || colorInterpretation.isRGBA() || colorInterpretation.hasAnyRGBBand()) {
455
            image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(bufferToDraw.getColumns(), bufferToDraw.getRows(),
456
                    BufferedImage.TYPE_INT_ARGB);
457
        } else if (colorInterpretation.isBGR()) {
458
            image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(bufferToDraw.getColumns(), bufferToDraw.getRows(),
459
                BufferedImage.TYPE_INT_BGR);
460
        }
461

    
462
        if (image == null) {
463
            throw new IllegalStateException(
464
                "Color interpretation is not RGB,RGBA or BGR and buffer was be drawn without color table");
465
        }
466

    
467
        int redBandIndex = colorInterpretation.getBand(ColorInterpretation.RED_BAND);
468
        int greenBandIndex = colorInterpretation.getBand(ColorInterpretation.GREEN_BAND);
469
        int blueBandIndex = colorInterpretation.getBand(ColorInterpretation.BLUE_BAND);
470

    
471
        Band redBand = null;
472
        if(redBandIndex>=0){
473
            redBand = bufferToDraw.getBand(redBandIndex);
474
        }
475
        Band greenBand = null;
476
        if(greenBandIndex>=0){
477
            greenBand = bufferToDraw.getBand(greenBandIndex);
478
        }
479
        Band blueBand = null;
480
        if(blueBandIndex>=0){
481
            blueBand = bufferToDraw.getBand(blueBandIndex);
482
        }
483
        Band alphaBand = null;
484
        if (colorInterpretation.hasAlphaBand()) {
485
            int alphaBandIndex =
486
                colorInterpretation.getBand(ColorInterpretation.ALPHA_BAND);
487
            alphaBand = bufferToDraw.getBand(alphaBandIndex);
488
        }
489

    
490
        for (int i = 0; i < bufferToDraw.getRows(); i++) {
491
            for (int j = 0; j < bufferToDraw.getColumns(); j++) {
492

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

    
543
                if (alphaByteValue!=0 && alphaBand != null) {
544
                    Number alphaValue = (Number) alphaBand.get(i, j);
545
                    int alphaBandIndex = colorInterpretation.getBand(ColorInterpretation.ALPHA_BAND);
546
                    NoData noData = alphaBand.getNoData();
547
                    if(noData != null){
548
                        if(alphaValue.equals(noData.getValue())){
549
                            alphaByteValue = 0;
550
                        } else {
551
                            alphaByteValue = alphaValue.byteValue();
552
                        }
553
                    } else {
554
                        alphaByteValue = alphaValue.byteValue();
555
                    }
556
                }
557

    
558
                if (alphaByteValue!=0 && transparency != null) {
559
                    // Apply defined transparency ranges
560

    
561
                    int newAlpha =
562
                        transparency.getTransparencyRangeAlpha(redByteValue,
563
                            greenByteValue, blueByteValue);
564
                    alphaByteValue = getNewAlpha(alphaByteValue & 0xFF, newAlpha);
565

    
566
                    // Apply general transparency
567
                    int transparencyValue = transparency.getAlpha();
568
                    alphaByteValue = getNewAlpha(alphaByteValue & 0xFF, transparencyValue);
569
                }
570

    
571
                //FIXME: TO REMOVE??
572
//                if (filters != null) {
573
//                    // TODO Apply filters
574
//                }
575

    
576
                int intRGB = 0;
577
                if (colorInterpretation.hasAnyRGBBand()) {//colorInterpretation.isRGB() || colorInterpretation.isRGBA()) {
578
                    intRGB = (((byte)alphaByteValue & 0xFF) << 24) | // alpha
579
                        (((byte)redByteValue & 0xFF) << 16) | // red
580
                        (((byte)greenByteValue & 0xFF) << 8) | // green
581
                        (((byte)blueByteValue & 0xFF)); // blue String.format("%X", b)
582
//                    intRGB = ((alphaByteValue & 0xFF) << 24) | // alpha
583
//                        ((redByteValue & 0xFF) << 16) | // red
584
//                        ((greenByteValue & 0xFF) << 8) | // green
585
//                        ((blueByteValue & 0xFF) << 0); // blue String.format("%X", b)
586
                } else if (colorInterpretation.isBGR()) {
587
                    intRGB = (((byte)blueByteValue & 0xFF) << 16 | // blue
588
                        (((byte)greenByteValue & 0xFF) << 8) | // green
589
                        (((byte)redByteValue & 0xFF))); // red
590

    
591
                }
592
                image.setRGB(j, i, intRGB);
593
            }
594
        }
595
        return image;
596
    }
597

    
598
    private Image drawHSLBuffer(Graphics graphics, Buffer buffer,
599
        ColorInterpretation colorInterpretation,Transparency transparency,
600
        OperationList filters) throws BufferOperationException {
601

    
602
        Buffer byteBuffer = convertToByteBuffer(buffer);
603

    
604
        BufferedImage image = null;
605

    
606
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
607
            BufferedImage.TYPE_INT_ARGB);
608

    
609
        int hueBandIndex = colorInterpretation.getBand(ColorInterpretation.HUE_BAND);
610
        int saturationBandIndex = colorInterpretation.getBand(ColorInterpretation.SATURATION_BAND);
611
        int lightBandIndex = colorInterpretation.getBand(ColorInterpretation.LIGHTNESS_BAND);
612

    
613

    
614
        Band hueBand = byteBuffer.getBand(hueBandIndex);
615
        Band saturationBand = byteBuffer.getBand(saturationBandIndex);
616
        Band lightBand = byteBuffer.getBand(lightBandIndex);
617

    
618

    
619
        for (int i = 0; i < buffer.getRows(); i++) {
620
            for (int j = 0; j < buffer.getColumns(); j++) {
621
                Number hueValue = (Number) hueBand.get(i, j);
622
                Number saturationValue = (Number) saturationBand.get(i, j);
623
                Number lightValue = (Number) lightBand.get(i, j);
624

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

    
627
                Integer alphaValue =rgbaValues[3].intValue();
628
                if (transparency != null) {
629
                    // Apply defined transparency ranges
630

    
631
                    alphaValue = alphaValue.byteValue() & 0xFF;
632
                    int newAlpha =
633
                        transparency.getTransparencyRangeAlpha(rgbaValues[0].byteValue(),
634
                            rgbaValues[1].byteValue(), rgbaValues[2].byteValue());
635
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
636

    
637
                    // Apply general transparency
638
                    int transparencyValue = transparency.getAlpha();
639
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
640
                }
641

    
642
                if (filters != null) {
643
                    // TODO Apply filters
644
                }
645

    
646
                int intRGB = 0;
647
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
648
                    ((rgbaValues[0].byteValue() & 0xFF) << 16) | // red
649
                    ((rgbaValues[1].byteValue() & 0xFF) << 8) | // green
650
                    ((rgbaValues[2].byteValue() & 0xFF) << 0); // blue
651
                image.setRGB(j, i, intRGB);
652
            }
653
        }
654
        return image;
655
    }
656

    
657
    private Image drawCMYKBuffer(Graphics graphics, Buffer buffer,
658
        ColorInterpretation colorInterpretation,Transparency transparency,
659
        OperationList filters) throws BufferOperationException {
660

    
661
        Buffer byteBuffer = convertToByteBuffer(buffer);
662

    
663
        BufferedImage image = null;
664

    
665
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
666
            BufferedImage.TYPE_INT_ARGB);
667

    
668
        int cyanBandIndex = colorInterpretation.getBand(ColorInterpretation.CYAN_BAND);
669
        int magentaBandIndex = colorInterpretation.getBand(ColorInterpretation.MAGENTA_BAND);
670
        int yellowBandIndex = colorInterpretation.getBand(ColorInterpretation.YELLOW_BAND);
671
        int blackBandIndex = colorInterpretation.getBand(ColorInterpretation.BLACK_BAND);
672

    
673

    
674
        Band cyanBand = byteBuffer.getBand(cyanBandIndex);
675
        Band magentaBand = byteBuffer.getBand(magentaBandIndex);
676
        Band yellowBand = byteBuffer.getBand(yellowBandIndex);
677
        Band blackBand = byteBuffer.getBand(blackBandIndex);
678

    
679
        for (int i = 0; i < buffer.getRows(); i++) {
680
            for (int j = 0; j < buffer.getColumns(); j++) {
681
                Number cyanValue = (Number) cyanBand.get(i, j);
682
                Number magentaValue = (Number) magentaBand.get(i, j);
683
                Number yellowValue = (Number) yellowBand.get(i, j);
684
                Number blackValue = (Number) blackBand.get(i, j);
685

    
686

    
687

    
688
                Number[] rgbValues=ColorUtils.fromCMYKtoRGB(
689
                    cyanValue.floatValue(),
690
                    magentaValue.floatValue(),
691
                    yellowValue.floatValue(),
692
                    blackValue.floatValue()
693
                    );
694

    
695
                Integer alphaValue =255;
696
                if (transparency != null) {
697
                    // Apply defined transparency ranges
698

    
699
                    alphaValue = alphaValue.byteValue() & 0xFF;
700
                    int newAlpha =
701
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
702
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
703
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
704

    
705
                    // Apply general transparency
706
                    int transparencyValue = transparency.getAlpha();
707
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
708
                }
709

    
710
                if (filters != null) {
711
                    // TODO Apply filters
712
                }
713

    
714
                int intRGB = 0;
715
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
716
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
717
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
718
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
719
                image.setRGB(j, i, intRGB);
720
            }
721
        }
722
        return image;
723
    }
724

    
725
    private Image drawYCBCRBuffer(Graphics graphics, Buffer buffer,
726
        ColorInterpretation colorInterpretation,Transparency transparency,
727
        OperationList filters) throws BufferOperationException {
728

    
729
        Buffer byteBuffer = convertToByteBuffer(buffer);
730

    
731
        BufferedImage image = null;
732

    
733
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
734
            BufferedImage.TYPE_INT_ARGB);
735

    
736
        int yIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_Y_BAND);
737
        int cbBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CB_BAND);
738
        int crBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CR_BAND);
739

    
740

    
741
        Band yBand = byteBuffer.getBand(yIndex);
742
        Band cbBand = byteBuffer.getBand(cbBandIndex);
743
        Band crBand = byteBuffer.getBand(crBandIndex);
744

    
745
        for (int i = 0; i < buffer.getRows(); i++) {
746
            for (int j = 0; j < buffer.getColumns(); j++) {
747
                Number yValue = (Number) yBand.get(i, j);
748
                Number cbValue = (Number) cbBand.get(i, j);
749
                Number crValue = (Number) crBand.get(i, j);
750

    
751
                Number[] rgbValues=ColorUtils.fromYCBCRtoRGB(
752
                    yValue.floatValue(),
753
                    cbValue.floatValue(),
754
                    crValue.floatValue()
755
                    );
756

    
757
                Integer alphaValue =255;
758
                if (transparency != null) {
759
                    // Apply defined transparency ranges
760

    
761
                    alphaValue = alphaValue.byteValue() & 0xFF;
762
                    int newAlpha =
763
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
764
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
765
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
766

    
767
                    // Apply general transparency
768
                    int transparencyValue = transparency.getAlpha();
769
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
770
                }
771

    
772
                if (filters != null) {
773
                    // TODO Apply filters
774
                }
775

    
776
                int intRGB = 0;
777
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
778
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
779
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
780
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
781
                image.setRGB(j, i, intRGB);
782
            }
783
        }
784
        return image;
785
    }
786

    
787
    /**
788
     * Method to draw gray buffers
789
     * @param graphics
790
     * @param byteBuffer
791
     * @param filters
792
     * @return
793
     * @throws OperationException
794
     */
795
    private Image drawGrayBuffer(Graphics graphics, Buffer buffer, ColorInterpretation colorInterpretation, Transparency transparency, OperationList filters) throws BufferOperationException {
796

    
797
        BufferedImage image = null;
798
        Buffer byteBuffer = convertToByteBuffer(buffer);
799

    
800
        image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(byteBuffer.getColumns(), byteBuffer.getRows(),
801
            BufferedImage.TYPE_INT_ARGB);
802

    
803
        Band grayBand = byteBuffer.getBand(colorInterpretation.getBand(ColorInterpretation.GRAY_BAND));
804

    
805
        for (int i = 0; i < byteBuffer.getRows(); i++) {
806
            for (int j = 0; j < byteBuffer.getColumns(); j++) {
807
                int grayByteValue = 0;
808
                int alphaByteValue = (byte)255;
809
                Number grayValue = (Number) grayBand.get(i, j);
810
                NoData noData = grayBand.getNoData();
811
                if(noData != null){
812
                    if(grayValue.equals(noData.getValue())){
813
                        alphaByteValue = 0;
814
                        grayByteValue = 0;
815
                    } else {
816
                        alphaByteValue = 255;
817
                        grayByteValue = grayValue.byteValue();
818
                    }
819
                } else {
820
                    grayByteValue = grayValue.byteValue();
821
                }
822

    
823
                if (alphaByteValue != 0 && transparency != null) {
824
                    // Apply defined transparency ranges
825

    
826
//                    alphaByteValue = alphaValue.byteValue() & 0xFF;
827
                    int newAlpha = transparency.getTransparencyRangeAlpha(grayByteValue, grayByteValue, grayByteValue);
828
                    alphaByteValue = getNewAlpha(alphaByteValue, newAlpha);
829

    
830
                    // Apply general transparency
831
                    int transparencyValue = transparency.getAlpha();
832
                    alphaByteValue = getNewAlpha(alphaByteValue, transparencyValue);
833
                }
834

    
835
                if (filters != null) {
836
                    // TODO Apply filters
837
                }
838

    
839
                int intARGB = (((byte)alphaByteValue & 0xFF) << 24) | // alpha
840
                    (((byte)grayByteValue & 0xFF)<< 16) | // red
841
                    (((byte)grayByteValue & 0xFF)<< 8) | // green
842
                    (((byte)grayByteValue & 0xFF)); // blue
843

    
844
                image.setRGB(j, i, intARGB);
845
            }
846
        }
847
        return image;
848
    }
849

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

    
870
    private Image drawPaletteBuffer(Graphics graphics, Buffer buffer, ColorInterpretation colorInterpretation,
871
        Transparency transparency, OperationList filters) {
872

    
873
        BufferedImage image = ToolsSwingLocator.getToolsSwingManager().createBufferedImage(buffer.getColumns(), buffer.getRows(),
874
            BufferedImage.TYPE_INT_ARGB);
875

    
876
        for (int i = 0; i < buffer.getRows(); i++) {
877
            for (int j = 0; j < buffer.getColumns(); j++) {
878

    
879
                Object value = buffer.getBand(colorInterpretation.getPaletteBand()).get(i, j);
880
                byte[] rgba = colorInterpretation.getPalette().getRGBA(value);
881

    
882
                if (transparency != null) {
883
                    // Apply defined transparency ranges
884
                    int alpha = rgba[3] & 0xFF;
885
                    int newAlpha =
886
                        transparency.getTransparencyRangeAlpha(rgba[0], rgba[1], rgba[2]);
887
                    alpha = getNewAlpha(alpha, newAlpha);
888

    
889
                    // Apply general transparency
890
                    int transparencyValue = transparency.getAlpha();
891
                    rgba[3] = (byte) getNewAlpha(alpha, transparencyValue);
892
                }
893

    
894
                if (filters != null) {
895
                    // TODO Apply filters
896
                }
897

    
898
                int intARGB = ((rgba[3] & 0xFF) << 24) | // alpha
899
                    ((rgba[0] & 0xFF) << 16) | // red
900
                    ((rgba[1] & 0xFF) << 8) | // green
901
                    ((rgba[2] & 0xFF) << 0); // blue
902

    
903
                image.setRGB(j, i, intARGB);
904
            }
905
        }
906
        return image;
907
    }
908

    
909
    private int getNewAlpha(int alpha, int newAlpha) {
910
        return (int) Math.round(alpha * (newAlpha / 255d));
911
    }
912

    
913
    @Override
914
    public ColorInterpretation getColorInterpretation() {
915
        return this.colorInterpretation;
916
    }
917

    
918
    @Override
919
    public void setColorInterpretation(ColorInterpretation colorInterpretation) {
920
        if (this.colorInterpretation != null) {
921
            this.colorInterpretation.deleteObserver(this);
922
        }
923
        this.colorInterpretation = colorInterpretation;
924
        this.colorInterpretation.addObserver(this);
925
    }
926

    
927
    @Override
928
    public OperationList getFilters() {
929
        if(this.filters == null){
930
            BufferManager bufferManager = BufferLocator.getBufferManager();
931
            this.filters = ((OperationManager)bufferManager).createOperationList();
932
        }
933
        return this.filters;
934
    }
935

    
936
    @Override
937
    public void setFilters(OperationList filterList) {
938
        OperationList oldFilters = this.filters;
939
        this.filters = filterList;
940
        fireColorinterpretationChangedEvent(new ChangeOperationListEvent(oldFilters, this.filters));
941
    }
942

    
943
    /**
944
     *
945
     */
946
    public static void registerPersistence() {
947
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
948
        DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
949
        if (definition == null) {
950
            definition =
951
                manager.addDefinition(DefaultRasterLegend.class, PERSISTENT_NAME,
952
                    PERSISTENT_DESCRIPTION, null, null);
953
            definition.addDynFieldObject(COLOR_INTERPRETATION_PERSISTENCE_FIELD).setMandatory(false)
954
                .setClassOfValue(ColorInterpretation.class);
955
            definition.addDynFieldObject(FILTERS_PERSISTENCE_FIELD).setMandatory(false)
956
                .setClassOfValue(OperationList.class);
957
        }
958
    }
959

    
960
    @Override
961
    public void saveToState(PersistentState state) throws PersistenceException {
962
        state.set(COLOR_INTERPRETATION_PERSISTENCE_FIELD, this.getColorInterpretation());
963
        state.set(FILTERS_PERSISTENCE_FIELD, (Persistent)this.getFilters());
964
    }
965

    
966
    @Override
967
    public void loadFromState(PersistentState state) throws PersistenceException {
968
        this.setColorInterpretation((ColorInterpretation) state
969
            .get(COLOR_INTERPRETATION_PERSISTENCE_FIELD));
970
        this.setFilters((OperationList) state.get(FILTERS_PERSISTENCE_FIELD));
971
    }
972

    
973
    @Override
974
    public void setTransparency(Transparency transparency) {
975
        this.transparency = transparency;
976
    }
977

    
978
    @Override
979
    public Transparency getTransparency() {
980
        return this.transparency;
981
    }
982

    
983
    @Override
984
    public ISymbol getDefaultSymbol() {
985
        return null;
986
    }
987

    
988
    @Override
989
    public Object clone() throws CloneNotSupportedException {
990
        DefaultRasterLegend cloned = (DefaultRasterLegend) super.clone();
991

    
992
        ColorInterpretation clonedColorInterpretation = (ColorInterpretation)this.getColorInterpretation().clone();
993
        cloned.setColorInterpretation(clonedColorInterpretation);
994
        //FIXME:
995
//        cloned.setTransparency((Transparency)this.getTransparency().clone());
996
//        cloned.setFilters(getFilters());
997

    
998
        cloned.setFilters((OperationList)getFilters().clone());
999

    
1000
        return cloned;
1001
    }
1002

    
1003
    @Override
1004
    public ILegend cloneLegend() {
1005
        try {
1006
            return (RasterLegend)this.clone();
1007
        } catch (Exception e) {
1008
            throw new RuntimeException("Can't clone the legend", e);
1009
        }
1010
    }
1011

    
1012

    
1013
    @Override
1014
    public void fireDefaultSymbolChangedEvent(SymbolLegendEvent event) {
1015

    
1016
        for (int i = 0; i < listeners.size(); i++) {
1017
            ((LegendContentsChangedListener) listeners.get(i))
1018
                    .symbolChanged(event);
1019
        }
1020
    }
1021

    
1022
    @Override
1023
    public LegendContentsChangedListener[] getListeners() {
1024
        return (LegendContentsChangedListener[]) listeners
1025
                .toArray(new LegendContentsChangedListener[listeners.size()]);
1026
    }
1027

    
1028

    
1029

    
1030
    @Override
1031
    public void setTransparentNoData(boolean noDataTransparent) {
1032
        this.transparentNoData=noDataTransparent;
1033

    
1034
    }
1035

    
1036
    @Override
1037
    public boolean areTransparentNoData() {
1038
        return this.transparentNoData;
1039
    }
1040

    
1041
    @SuppressWarnings("unchecked")
1042
    @Override
1043
    public void update(Observable observable, Object notification) {
1044
        if (notification instanceof ColorInterpretationNotification) {
1045
            String type = ((ColorInterpretationNotification) notification).getType();
1046
            if(type.equals(ColorInterpretationNotification.CHANGED_COLOR_INTERPRETATION_VALUE)
1047
               || type.equals(ColorInterpretationNotification.ADDED_COLOR_INTERPRETATION)
1048
               || type.equals(ColorInterpretationNotification.COPIED_FROM_COLOR_INTERPRETATION)){
1049
            fireColorinterpretationChangedEvent(new ChangeColorInterpretationEvent(
1050
                (String[])((ColorInterpretationNotification) notification).getValue(0),
1051
                (String[])((ColorInterpretationNotification) notification).getValue(1)));
1052
            }
1053
            if (type.equals(ColorInterpretationNotification.SETTED_PALETTE)) {
1054
                fireColorinterpretationChangedEvent(new ChangePaletteEvent(
1055
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0),
1056
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(1)));
1057
            }
1058
            if (type.equals(ColorInterpretationNotification.CHANGED_PALETTE)) {
1059
                fireColorinterpretationChangedEvent(new ChangePaletteEvent(
1060
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0),
1061
                    (ColorTable) ((ColorInterpretationNotification) notification).getValue(0)));
1062
            }
1063

    
1064
            if (type.equals(ColorInterpretationNotification.SETTED_PALETTE_BAND)) {
1065
                fireColorinterpretationChangedEvent(new ChangePaletteBandEvent(
1066
                    (int) ((ColorInterpretationNotification) notification).getValue(0),
1067
                    (int) ((ColorInterpretationNotification) notification).getValue(1)));
1068
            }
1069
        }
1070
        if (notification instanceof OperationListNotification) {
1071
            fireOperationListChangedEvent(new ChangeOperationListEvent(
1072
                    (List<OperationListEntry>) ((OperationListNotification) notification).getValue(0),
1073
                    (List<OperationListEntry>) ((OperationListNotification) notification).getValue(1)));
1074
        }
1075
    }
1076

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

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

    
1087
    /**
1088
     * @param event
1089
     */
1090
    public void fireOperationListChangedEvent(RasterLegendEvent event) {
1091

    
1092
        for (int i = 0; i < listeners.size(); i++) {
1093
            ((RasterLegendChangedListener) listeners.get(i)).operationListChanged(event);
1094
        }
1095
    }
1096

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

    
1105
    }
1106

    
1107
    @Override
1108
    public void removeLegendListener(LegendContentsChangedListener listener) {
1109
        if(listener instanceof RasterLegendChangedListener){
1110
            removeLegendListener((RasterLegendChangedListener)listener);
1111
            return;
1112
        }
1113
        throw new UnsupportedOperationException("Raster layer can't be listened by a no RasterLegendChangedListener");
1114

    
1115
    }
1116

    
1117
    private void addLegendListener(RasterLegendChangedListener listener) {
1118
        if (listener != null && !listeners.contains(listener))
1119
            listeners.add(listener);
1120
    }
1121

    
1122
    private void removeLegendListener(RasterLegendChangedListener listener) {
1123
        listeners.remove(listener);
1124
    }
1125

    
1126
    @Override
1127
    public void addColorTableOperation(ColorInterpretation colorInterpretation, int index) {
1128

    
1129
        OperationList theFilters = this.getFilters();
1130
        theFilters.removeIfExists(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1131
        theFilters.removeIfExists(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1132

    
1133
        OperationManager operationManager = BufferLocator.getOperationManager();
1134
        Operation colorTableOperation = operationManager.createOperation(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1135
        DynObject colorTableOperationParameters = operationManager.createOperationParameters(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1136
        colorTableOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM, colorInterpretation);
1137
        colorTableOperationParameters.setDynValue(AbstractOperation.COPY_UNPROCESSED_BANDS_PARAM, true);
1138
        OperationListEntry colorTableEntry = operationManager.createOperationListEntry(colorTableOperation, colorTableOperationParameters);
1139
        theFilters.add(index, colorTableEntry);
1140
    }
1141

    
1142
    @Override
1143
    public void addLinearStretchEnhancementOperationIfNeeded(
1144
        ColorInterpretation colorInterpretation,
1145
        List<BandDescriptor> bands, 
1146
        int index) {
1147

    
1148
        OperationList theFilters = this.getFilters();
1149
        
1150
        theFilters.removeIfExists(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1151
        theFilters.removeIfExists(ColoredOperation.COLOR_TABLE_OPERATION_NAME);
1152

    
1153
        if( (!colorInterpretation.isPalette()) &&
1154
            (colorInterpretation.hasAnyColorInterpretationBand() || 
1155
                colorInterpretation.hasAlphaBand() || 
1156
                colorInterpretation.hasAnyGrayBand())) {
1157

    
1158
            List<Integer> bandsToProcess = new ArrayList<>();
1159
            for (int i = 0; i < bands.size(); i++) {
1160
                if ((colorInterpretation.isColorInterpretation(i) || 
1161
                    colorInterpretation.isAlphaInterpretation(i) || 
1162
                    colorInterpretation.isGrayInterpretation(i)) && 
1163
                    (bands.get(i).getDataType() != BufferManager.TYPE_BYTE)) {
1164
                    bandsToProcess.add(i);
1165
                }
1166
            }
1167

    
1168
            if (!bandsToProcess.isEmpty()) {
1169
                OperationManager operationManager = BufferLocator.getOperationManager();
1170
                Operation linearStretchEnhancementOperation = operationManager.createOperation(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1171
                DynObject linearStretchEnhancementOperationParameters =
1172
                    operationManager.createOperationParameters(SpecifiedBandsOperation.LINEAR_STRETCH_ENHANCEMENT_NAME);
1173
                linearStretchEnhancementOperationParameters.setDynValue(
1174
                    AbstractSpecifiedBandsOperation.BANDS_TO_PROCESS_PARAM, bandsToProcess);
1175
                OperationListEntry colorTableEntry =
1176
                    ((OperationManager) operationManager).createOperationListEntry(linearStretchEnhancementOperation,
1177
                        linearStretchEnhancementOperationParameters);
1178
                theFilters.add(index, colorTableEntry);
1179
            }
1180
        }
1181
    }
1182

    
1183
    @Override
1184
    public void addHSLToRGBOperation(ColorInterpretation colorInterpretation) {
1185

    
1186
        OperationManager operationManager = BufferLocator.getOperationManager();
1187
        DynObject hSLToRGBOperationParameters =
1188
            operationManager.createOperationParameters(HSLToRGBOperationFactory.NAME);
1189
        hSLToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM, colorInterpretation);
1190
        Operation hSLToRGBOperation = operationManager.createOperation(HSLToRGBOperationFactory.NAME);
1191

    
1192
        OperationListEntry hSLToRGBOperationEntry =
1193
            operationManager.createOperationListEntry(hSLToRGBOperation, hSLToRGBOperationParameters);
1194
        getFilters().add(hSLToRGBOperationEntry);
1195
    }
1196

    
1197
    @Override
1198
    public void addCMYKToRGBOperation(ColorInterpretation colorInterpretation) {
1199

    
1200
        OperationManager operationManager = BufferLocator.getOperationManager();
1201
        DynObject cmykToRGBOperationParameters =
1202
            operationManager.createOperationParameters(CMYKToRGBOperationFactory.NAME);
1203
        cmykToRGBOperationParameters.setDynValue(ColoredOperation.COLOR_INTERPRETATION_PARAM, colorInterpretation);
1204
        Operation cmykToRGBOperation = operationManager.createOperation(HSLToRGBOperationFactory.NAME);
1205

    
1206
        OperationListEntry cmykToRGBOperationEntry =
1207
            operationManager.createOperationListEntry(cmykToRGBOperation, cmykToRGBOperationParameters);
1208
        getFilters().add(cmykToRGBOperationEntry);
1209
    }
1210

    
1211
    @Override
1212
    public void addYCBCRToRGBOperation(ColorInterpretation colorInterpretation){
1213
        //TODO: Not implemented yet, meanwhile do nothing
1214
    };
1215

    
1216

    
1217
}