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 @ 43862

History | View | Annotate | Download (54.3 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.api.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
    public DefaultRasterLegend(ColorInterpretation colorInterpretation,
138
        Transparency transparency, OperationList filters) {
139
        this.transparency = transparency;
140
        this.filters = filters;
141
        setColorInterpretation(colorInterpretation);
142
    }
143

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

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

    
160
        taskStatus.setIndeterminate();
161

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

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

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

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

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

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

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

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

    
214
                        bufferToDraw = interpolated2;
215

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

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

    
239
                        interpolated =
240
                            bufferToDraw.createInterpolated((int) Math.floor(heightPixel),
241
                                (int) Math.floor(widthPixel), Buffer.INTERPOLATION_Bilinear, taskStatus);
242
                        DisposeUtils.disposeQuietly(clip);
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
                // Calculate where image has to be drawn
265
                double x = bufferToDraw.getEnvelope().getMinimum(0);
266
                double y = bufferToDraw.getEnvelope().getMaximum(1);
267
                AffineTransform affineTransform =
268
                    calculateAffineTransform(viewPort.getAdjustedEnvelope(), viewPort.getImageWidth(),
269
                        viewPort.getImageHeight());
270

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

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

    
291
                    getFilters().setDefaultParameters(defaultParameters);
292

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

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

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

    
387

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

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

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

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

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

    
443

    
444

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

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

    
451
        BufferedImage image = null;
452

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
601
        Buffer byteBuffer = convertToByteBuffer(buffer);
602

    
603
        BufferedImage image = null;
604

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

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

    
612

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

    
617

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

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

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

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

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

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

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

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

    
660
        Buffer byteBuffer = convertToByteBuffer(buffer);
661

    
662
        BufferedImage image = null;
663

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

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

    
672

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

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

    
685

    
686

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

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

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

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

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

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

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

    
728
        Buffer byteBuffer = convertToByteBuffer(buffer);
729

    
730
        BufferedImage image = null;
731

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

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

    
739

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
999
        return cloned;
1000
    }
1001

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

    
1011

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

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

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

    
1027

    
1028

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

    
1033
    }
1034

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

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

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

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

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

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

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

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

    
1104
    }
1105

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

    
1114
    }
1115

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1215

    
1216
}