Statistics
| Revision:

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

History | View | Annotate | Download (28.6 KB)

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

    
3
import java.awt.Graphics;
4
import java.awt.Image;
5
import java.awt.color.ColorSpace;
6
import java.awt.color.ICC_ColorSpace;
7
import java.awt.color.ICC_Profile;
8
import java.awt.geom.AffineTransform;
9
import java.awt.geom.NoninvertibleTransformException;
10
import java.awt.image.BufferedImage;
11

    
12
import org.apache.log4j.spi.AppenderAttachable;
13
import org.cresques.cts.ICoordTrans;
14
import org.gvsig.fmap.geom.Geometry.SUBTYPES;
15
import org.gvsig.fmap.geom.GeometryLocator;
16
import org.gvsig.fmap.geom.exception.CreateGeometryException;
17
import org.gvsig.fmap.geom.primitive.Envelope;
18
import org.gvsig.fmap.geom.primitive.Point;
19
import org.gvsig.fmap.mapcontext.ViewPort;
20
import org.gvsig.raster.lib.buffer.api.Band;
21
import org.gvsig.raster.lib.buffer.api.Buffer;
22
import org.gvsig.raster.lib.buffer.api.FilterList;
23
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
24
import org.gvsig.raster.lib.legend.api.ColorInterpretation;
25
import org.gvsig.raster.lib.legend.api.ColorTable;
26
import org.gvsig.raster.lib.legend.api.RasterLegend;
27
import org.gvsig.raster.lib.legend.api.Transparency;
28
import org.gvsig.tools.ToolsLocator;
29
import org.gvsig.tools.dynobject.DynStruct;
30
import org.gvsig.tools.persistence.PersistenceManager;
31
import org.gvsig.tools.persistence.PersistentState;
32
import org.gvsig.tools.persistence.exception.PersistenceException;
33
import org.gvsig.tools.task.SimpleTaskStatus;
34
import org.gvsig.tools.task.TaskStatusManager;
35
import org.slf4j.Logger;
36
import org.slf4j.LoggerFactory;
37

    
38
/**
39
 * Default implementation of {@link RasterLegend}. This object can draw buffers
40
 * with a {@link ColorInterpretation}, {@link ColorTable} and {@link FilterList}
41
 *
42
 *
43
 * @author <a href="mailto:lmarques@disid.com">Lluis Marques</a>
44
 *
45
 */
46
public class DefaultRasterLegend implements RasterLegend {
47

    
48
    private static final Logger LOG = LoggerFactory.getLogger(DefaultRasterLegend.class);
49

    
50
    private ColorInterpretation colorInterpretation;
51
    private ColorTable colorTable;
52
    private Transparency transparency;
53
    private FilterList filters;
54

    
55
    /**
56
     * Persistence definition name
57
     */
58
    public static final String PERSISTENT_NAME = "RasterLegendPersistence";
59
    /**
60
     * Description of persistence definition
61
     */
62
    public static final String PERSISTENT_DESCRIPTION = "Persistence definition of raster legend";
63

    
64
    private final static String COLOR_TABLE_PERSISTENCE_FIELD = "colorTable";
65
    private final static String COLOR_INTERPRETATION_PERSISTENCE_FIELD = "colorInterpretation";
66
    private final static String FILTERS_PERSISTENCE_FIELD = "filters";
67

    
68
    /**
69
     * Empty constructor
70
     */
71
    public DefaultRasterLegend() {
72

    
73
    }
74

    
75
    /**
76
     * Default {@link RasterLegend} constructor
77
     *
78
     * @param colorInterpretation
79
     *            Color interpretation of legend
80
     */
81
    public DefaultRasterLegend(ColorInterpretation colorInterpretation) {
82
        this.colorInterpretation = colorInterpretation;
83
    }
84

    
85
    /**
86
     * Default {@link RasterLegend} constructor
87
     *
88
     * @param colorTable
89
     *            Color table of legend
90
     * @param colorInterpretation
91
     *            Color interpretation of legend
92
     * @param transparency
93
     *            Transparency of legend
94
     * @param filters
95
     *            Filters of legend
96
     */
97
    public DefaultRasterLegend(ColorInterpretation colorInterpretation, ColorTable colorTable,
98
        Transparency transparency, FilterList filters) {
99
        this.colorInterpretation = colorInterpretation;
100
        this.colorTable = colorTable;
101
        this.transparency = transparency;
102
        this.filters = filters;
103
    }
104

    
105
    @Override
106
    public void draw(Graphics graphics, Buffer buffer, ViewPort viewPort,
107
        SimpleTaskStatus taskStatus) {
108

    
109
        boolean isMyTask = false;
110
        if (taskStatus == null) {
111
            TaskStatusManager taskStatusManager = ToolsLocator.getTaskStatusManager();
112
            taskStatus =
113
                taskStatusManager.createDefaultSimpleTaskStatus("_drawing_buffer_XxellipsisxX");
114
            taskStatus.setAutoremove(true);
115
            taskStatus.add();
116
            isMyTask = true;
117
        } else {
118
            taskStatus.push();
119
        }
120

    
121
        taskStatus.setIndeterminate();
122

    
123
        if (this.colorInterpretation == null || !this.colorInterpretation.hasInterpretation()
124
            || this.colorInterpretation.isUndefined()) {
125
            taskStatus.abort();
126
            throw new IllegalStateException(
127
                "To draw buffer, raster legend has to have a color interpretation");
128
        }
129

    
130
        if ((this.colorInterpretation.isRGB() || this.colorInterpretation.isBGR() || this.colorInterpretation
131
            .isRGBA()) && this.colorTable != null) {
132
            taskStatus.abort();
133
            throw new IllegalStateException(
134
                "If color interpretation is RGB, RGBA or BGR, raster legend can not have a color table");
135
        }
136

    
137
        // Check if viewport projection is the same as buffer projection
138
        Buffer bufferToDraw = null;
139
        if (!viewPort.getProjection().equals(buffer.getProjection())) {
140

    
141
            // Convert extension to check if envelopes intersect
142
            ICoordTrans coordTrans = viewPort.getProjection().getCT(buffer.getProjection());
143
            Envelope convertedEnvelope = viewPort.getAdjustedEnvelope().convert(coordTrans);
144
            if (!convertedEnvelope.intersects(buffer.getEnvelope())) {
145
                return;
146
            }
147
            try {
148
                // Clip buffer with doubled converted envelope
149
                bufferToDraw = buffer.clip(convertedEnvelope);
150

    
151
                // Convert interpolated clipped buffer
152
                bufferToDraw = bufferToDraw.convert(coordTrans.getInverted(), taskStatus);
153

    
154
                double widthPixel =
155
                    getWidthPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(0)
156
                        / viewPort.getImageWidth());
157
                double heightPixel =
158
                    getHeightPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(1)
159
                        / viewPort.getImageHeight());
160

    
161
                bufferToDraw =
162
                    bufferToDraw.createInterpolated((int) Math.floor(heightPixel),
163
                        (int) Math.floor(widthPixel), Buffer.INTERPOLATION_NearestNeighbour,
164
                        taskStatus);
165

    
166
            } catch (BufferException e) {
167
                LOG.warn("Buffer can not be clipped, converted or interpolated", e);
168
                taskStatus.abort();
169
                return;
170
            }
171
        } else if (viewPort.getAdjustedEnvelope().intersects(buffer.getEnvelope())) {
172

    
173
            double widthPixel = 0;
174
            double heightPixel = 0;
175
            try {
176
                // Clip and interpolate buffer with view port envelope
177
                if(buffer.getEnvelope().equals(viewPort.getAdjustedEnvelope())){
178
                    bufferToDraw = buffer;
179
                } else {
180
                    bufferToDraw = buffer.clip(viewPort.getAdjustedEnvelope());
181
                }
182
                widthPixel =
183
                    getWidthPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(0)
184
                        / viewPort.getImageWidth());
185
                heightPixel =
186
                    getHeightPixel(bufferToDraw.getEnvelope(), viewPort.getAdjustedEnvelope().getLength(1)
187
                        / viewPort.getImageHeight());
188

    
189
                bufferToDraw =
190
                    bufferToDraw.createInterpolated((int) Math.floor(heightPixel),
191
                        (int) Math.floor(widthPixel), Buffer.INTERPOLATION_NearestNeighbour,
192
                        taskStatus);
193
            } catch (BufferException e) {
194
                LOG.warn(
195
                    "Buffer can not be interpolated with [rows: {} , columns: {}, method: {}]",
196
                    new String[] { String.valueOf((int) Math.floor(heightPixel)),
197
                        String.valueOf((int) Math.floor(widthPixel)),
198
                        String.valueOf(Buffer.INTERPOLATION_NearestNeighbour) });
199
                taskStatus.abort();
200
                return;
201
            }
202
        } else {
203
            // Do nothing view port envelope does not intersect with buffer
204
            return;
205
        }
206

    
207
        // Draw buffer
208
        Image image = null;
209
        if (this.colorInterpretation.isGray()){
210
             // Draw buffer with gray scale
211
            image = drawGrayBuffer(graphics, bufferToDraw, transparency, filters);
212
        }else if ( this.colorInterpretation.isPalette() && this.colorTable != null ) {
213
            // Draw buffer with table color
214
            image = drawPaletteBuffer(graphics, bufferToDraw, colorTable, transparency, filters);
215
        } else if (this.colorInterpretation.isRGBA() || this.colorInterpretation.isRGB()
216
            || this.colorInterpretation.isBGR()) {
217
            // Draw RGB, RGBA or BGR buffer without color table
218
            image = drawRGBBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
219
        }else if (this.colorInterpretation.isHSL()) {
220
            // Draw HSL buffer without color table
221
            image = drawHSLBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
222
        }else if (this.colorInterpretation.isCMYK()) {
223
            // Draw CMYK buffer without color table
224
            image = drawCMYKBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
225
        }else if (this.colorInterpretation.isYCBCR()) {
226
            // Draw YCBCR buffer without color table
227
            image = drawYCBCRBuffer(graphics, bufferToDraw, colorInterpretation, transparency, filters);
228
        }
229

    
230
        // Calculate where image has to be drawn
231
        double x = bufferToDraw.getEnvelope().getMinimum(0);
232
        double y = bufferToDraw.getEnvelope().getMaximum(1);
233
        AffineTransform affineTransform =
234
            calculateAffineTransform(viewPort.getAdjustedEnvelope(), viewPort.getImageWidth(),
235
                viewPort.getImageHeight());
236

    
237
        Point point;
238
        try {
239
            point = GeometryLocator.getGeometryManager().createPoint(x, y, SUBTYPES.GEOM2D);
240
            point.transform(affineTransform.createInverse());
241
            graphics.drawImage(image, (int) Math.floor(point.getX()),
242
                (int) Math.floor(point.getY()), null);
243
        } catch (CreateGeometryException | NoninvertibleTransformException e) {
244
            LOG.warn("Can not calculate the point of buffer in viewport image", e);
245
            taskStatus.abort();
246
            return;
247
        }
248

    
249
        if (!isMyTask) {
250
            taskStatus.pop();
251
        }
252
    }
253

    
254
    private AffineTransform calculateAffineTransform(Envelope envelope, double imageWidth,
255
        double imageHeight) {
256
        double pixelSizeX = envelope.getLength(0) / imageWidth;
257
        double rotationX = 0;
258
        double x = envelope.getMinimum(0);
259
        double rotationY = 0;
260
        double pixelSizeY = -envelope.getLength(1) / imageHeight;
261
        double y = envelope.getMaximum(1);
262
        return new AffineTransform(pixelSizeX, rotationY, rotationX, pixelSizeY, x, y);
263
    }
264

    
265
    private double getWidthPixel(Envelope envelope, double dist1pixel) {
266
        double widthEnvelope = envelope.getLength(0);
267
        return widthEnvelope / dist1pixel;
268
    }
269

    
270
    private double getHeightPixel(Envelope envelope, double dist1pixel) {
271
        double heightEnvelope = envelope.getLength(1);
272
        return heightEnvelope / dist1pixel;
273
    }
274

    
275

    
276

    
277
    private Image drawRGBBuffer(Graphics graphics, Buffer buffer,
278
        ColorInterpretation colorInterpretation, Transparency transparency, FilterList filters) {
279

    
280
        BufferedImage image = null;
281

    
282
        if (colorInterpretation.isRGB() || colorInterpretation.isRGBA()) {
283
            image =
284
                new BufferedImage(buffer.getColumns(), buffer.getRows(),
285
                    BufferedImage.TYPE_INT_ARGB);
286
        } else if (colorInterpretation.isBGR()) {
287
            image =
288
                new BufferedImage(buffer.getColumns(), buffer.getRows(), BufferedImage.TYPE_INT_BGR);
289
        }
290

    
291
        if (image == null) {
292
            throw new IllegalStateException(
293
                "Color interpretation is not RGB,RGBA or BGR and buffer was be drawn without color table");
294
        }
295

    
296
        int redBandIndex = colorInterpretation.getBand(ColorInterpretation.RED_BAND);
297
        int greenBandIndex = colorInterpretation.getBand(ColorInterpretation.GREEN_BAND);
298
        int blueBandIndex = colorInterpretation.getBand(ColorInterpretation.BLUE_BAND);
299

    
300
        Band redBand = buffer.getBand(redBandIndex);
301
        Band greenBand = buffer.getBand(greenBandIndex);
302
        Band blueBand = buffer.getBand(blueBandIndex);
303
        Band alphaBand = null;
304
        if (colorInterpretation.hasAlphaBand()) {
305
            int alphaBandIndex =
306
                colorInterpretation.getBand(ColorInterpretation.ALPHA_BAND);
307
            alphaBand = buffer.getBand(alphaBandIndex);
308
        }
309

    
310
        for (int i = 0; i < buffer.getRows(); i++) {
311
            for (int j = 0; j < buffer.getColumns(); j++) {
312
                Number redValue = (Number) redBand.get(i, j);
313
                Number blueValue = (Number) blueBand.get(i, j);
314
                Number greenValue = (Number) greenBand.get(i, j);
315

    
316
                Number alphaValue = 255;
317
                if (alphaBand != null) {
318
                    alphaValue = (Number) alphaBand.get(i, j);
319
                }
320

    
321
                if (transparency != null) {
322
                    // Apply defined transparency ranges
323

    
324
                    alphaValue = alphaValue.byteValue() & 0xFF;
325
                    int newAlpha =
326
                        transparency.getTransparencyRangeAlpha(redValue.byteValue(),
327
                            greenValue.byteValue(), blueValue.byteValue());
328
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
329

    
330
                    // Apply general transparency
331
                    int transparencyValue = transparency.getAlpha();
332
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
333
                }
334

    
335
                if (filters != null) {
336
                    // TODO Apply filters
337
                }
338

    
339
                int intRGB = 0;
340
                if (colorInterpretation.isRGB() || colorInterpretation.isRGBA()) {
341
                    intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
342
                        ((redValue.byteValue() & 0xFF) << 16) | // red
343
                        ((greenValue.byteValue() & 0xFF) << 8) | // green
344
                        ((blueValue.byteValue() & 0xFF) << 0); // blue
345
                } else if (colorInterpretation.isBGR()) {
346
                    intRGB = ((blueValue.byteValue() & 0xFF) << 16 | // blue
347
                        ((greenValue.byteValue() & 0xFF) << 8) | // green
348
                        ((redValue.byteValue() & 0xFF) << 0)); // red
349

    
350
                }
351
                image.setRGB(j, i, intRGB);
352
            }
353
        }
354
        return image;
355
    }
356

    
357

    
358
    private Image drawHSLBuffer(Graphics graphics, Buffer buffer,
359
        ColorInterpretation colorInterpretation,Transparency transparency,
360
        FilterList filters) {
361

    
362
        BufferedImage image = null;
363

    
364
        image =
365
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
366
                BufferedImage.TYPE_INT_ARGB);
367

    
368
        int hueBandIndex = colorInterpretation.getBand(ColorInterpretation.HUE_BAND);
369
        int saturationBandIndex = colorInterpretation.getBand(ColorInterpretation.SATURATION_BAND);
370
        int lightBandIndex = colorInterpretation.getBand(ColorInterpretation.LIGHTNESS_BAND);
371

    
372

    
373
        Band hueBand = buffer.getBand(hueBandIndex);
374
        Band saturationBand = buffer.getBand(saturationBandIndex);
375
        Band lightBand = buffer.getBand(lightBandIndex);
376

    
377

    
378
        for (int i = 0; i < buffer.getRows(); i++) {
379
            for (int j = 0; j < buffer.getColumns(); j++) {
380
                Number hueValue = (Number) hueBand.get(i, j);
381
                Number saturationValue = (Number) saturationBand.get(i, j);
382
                Number lightValue = (Number) lightBand.get(i, j);
383

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

    
386
                Integer alphaValue =rgbaValues[3].intValue();
387
                if (transparency != null) {
388
                    // Apply defined transparency ranges
389

    
390
                    alphaValue = alphaValue.byteValue() & 0xFF;
391
                    int newAlpha =
392
                        transparency.getTransparencyRangeAlpha(rgbaValues[0].byteValue(),
393
                            rgbaValues[1].byteValue(), rgbaValues[2].byteValue());
394
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
395

    
396
                    // Apply general transparency
397
                    int transparencyValue = transparency.getAlpha();
398
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
399
                }
400

    
401
                if (filters != null) {
402
                    // TODO Apply filters
403
                }
404

    
405
                int intRGB = 0;
406
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
407
                    ((rgbaValues[0].byteValue() & 0xFF) << 16) | // red
408
                    ((rgbaValues[1].byteValue() & 0xFF) << 8) | // green
409
                    ((rgbaValues[2].byteValue() & 0xFF) << 0); // blue
410
                image.setRGB(j, i, intRGB);
411
            }
412
        }
413
        return image;
414
    }
415

    
416
    private Image drawCMYKBuffer(Graphics graphics, Buffer buffer,
417
        ColorInterpretation colorInterpretation,Transparency transparency,
418
        FilterList filters) {
419

    
420
        BufferedImage image = null;
421

    
422
        image =
423
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
424
                BufferedImage.TYPE_INT_ARGB);
425

    
426
        int cyanBandIndex = colorInterpretation.getBand(ColorInterpretation.CYAN_BAND);
427
        int magentaBandIndex = colorInterpretation.getBand(ColorInterpretation.MAGENTA_BAND);
428
        int yellowBandIndex = colorInterpretation.getBand(ColorInterpretation.YELLOW_BAND);
429
        int blackBandIndex = colorInterpretation.getBand(ColorInterpretation.BLACK_BAND);
430

    
431

    
432
        Band cyanBand = buffer.getBand(cyanBandIndex);
433
        Band magentaBand = buffer.getBand(magentaBandIndex);
434
        Band yellowBand = buffer.getBand(yellowBandIndex);
435
        Band blackBand = buffer.getBand(blackBandIndex);
436

    
437
        for (int i = 0; i < buffer.getRows(); i++) {
438
            for (int j = 0; j < buffer.getColumns(); j++) {
439
                Number cyanValue = (Number) cyanBand.get(i, j);
440
                Number magentaValue = (Number) magentaBand.get(i, j);
441
                Number yellowValue = (Number) yellowBand.get(i, j);
442
                Number blackValue = (Number) blackBand.get(i, j);
443

    
444

    
445

    
446
                Number[] rgbValues=ColorUtils.fromCMYKtoRGB(
447
                    cyanValue.floatValue(),
448
                    magentaValue.floatValue(),
449
                    yellowValue.floatValue(),
450
                    blackValue.floatValue()
451
                    );
452

    
453
                Integer alphaValue =255;
454
                if (transparency != null) {
455
                    // Apply defined transparency ranges
456

    
457
                    alphaValue = alphaValue.byteValue() & 0xFF;
458
                    int newAlpha =
459
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
460
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
461
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
462

    
463
                    // Apply general transparency
464
                    int transparencyValue = transparency.getAlpha();
465
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
466
                }
467

    
468
                if (filters != null) {
469
                    // TODO Apply filters
470
                }
471

    
472
                int intRGB = 0;
473
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
474
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
475
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
476
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
477
                image.setRGB(j, i, intRGB);
478
            }
479
        }
480
        return image;
481
    }
482

    
483
    private Image drawYCBCRBuffer(Graphics graphics, Buffer buffer,
484
        ColorInterpretation colorInterpretation,Transparency transparency,
485
        FilterList filters) {
486

    
487
        BufferedImage image = null;
488

    
489
        image =
490
            new BufferedImage(buffer.getColumns(), buffer.getRows(),
491
                BufferedImage.TYPE_INT_ARGB);
492

    
493
        int yIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_Y_BAND);
494
        int cbBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CB_BAND);
495
        int crBandIndex = colorInterpretation.getBand(ColorInterpretation.YCBCR_CR_BAND);
496

    
497

    
498
        Band yBand = buffer.getBand(yIndex);
499
        Band cbBand = buffer.getBand(cbBandIndex);
500
        Band crBand = buffer.getBand(crBandIndex);
501

    
502
        for (int i = 0; i < buffer.getRows(); i++) {
503
            for (int j = 0; j < buffer.getColumns(); j++) {
504
                Number yValue = (Number) yBand.get(i, j);
505
                Number cbValue = (Number) cbBand.get(i, j);
506
                Number crValue = (Number) crBand.get(i, j);
507

    
508
                Number[] rgbValues=ColorUtils.fromYCBCRtoRGB(
509
                    yValue.floatValue(),
510
                    cbValue.floatValue(),
511
                    crValue.floatValue()
512
                    );
513

    
514
                Integer alphaValue =255;
515
                if (transparency != null) {
516
                    // Apply defined transparency ranges
517

    
518
                    alphaValue = alphaValue.byteValue() & 0xFF;
519
                    int newAlpha =
520
                        transparency.getTransparencyRangeAlpha(rgbValues[0].byteValue(),
521
                            rgbValues[1].byteValue(), rgbValues[2].byteValue());
522
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
523

    
524
                    // Apply general transparency
525
                    int transparencyValue = transparency.getAlpha();
526
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
527
                }
528

    
529
                if (filters != null) {
530
                    // TODO Apply filters
531
                }
532

    
533
                int intRGB = 0;
534
                intRGB = ((alphaValue.byteValue() & 0xFF) << 24) | // alpha
535
                    ((rgbValues[0].byteValue() & 0xFF) << 16) | // red
536
                    ((rgbValues[1].byteValue() & 0xFF) << 8) | // green
537
                    ((rgbValues[2].byteValue() & 0xFF) << 0); // blue
538
                image.setRGB(j, i, intRGB);
539
            }
540
        }
541
        return image;
542
    }
543

    
544
    /**
545
     * Method to draw gray buffers
546
     * @param graphics
547
     * @param buffer
548
     * @param filters
549
     * @return
550
     */
551
    private Image drawGrayBuffer(Graphics graphics, Buffer buffer, Transparency transparency, FilterList filters) {
552

    
553
        BufferedImage image = null;
554

    
555
        image =
556
            new BufferedImage(buffer.getColumns(), buffer.getRows(), BufferedImage.TYPE_INT_ARGB);
557

    
558
        Band greyBand = buffer.getBand(0);
559

    
560
        for (int i = 0; i < buffer.getRows(); i++) {
561
            for (int j = 0; j < buffer.getColumns(); j++) {
562
                Number greyValue = (Number) greyBand.get(i, j);
563

    
564
                Integer alphaValue =255;
565
                if (transparency != null) {
566
                    // Apply defined transparency ranges
567

    
568
                    alphaValue = alphaValue.byteValue() & 0xFF;
569
                    int newAlpha =
570
                        transparency.getTransparencyRangeAlpha(greyValue.byteValue(),
571
                            greyValue.byteValue(), greyValue.byteValue());
572
                    alphaValue = getNewAlpha(alphaValue.intValue(), newAlpha);
573

    
574
                    // Apply general transparency
575
                    int transparencyValue = transparency.getAlpha();
576
                    alphaValue = getNewAlpha(alphaValue.intValue(), transparencyValue);
577
                }
578

    
579
                if (filters != null) {
580
                    // TODO Apply filters
581
                }
582

    
583
                int intARGB = ((alphaValue.byteValue()  & 0xFF) << 24) | // alpha
584
                    ((greyValue.byteValue() & 0xFF) << 16) | // red
585
                    ((greyValue.byteValue() & 0xFF) << 8) | // green
586
                    ((greyValue.byteValue() & 0xFF) << 0); // blue
587

    
588
                image.setRGB(j, i, intARGB);
589
            }
590
        }
591
        return image;
592
    }
593

    
594
    private Image drawPaletteBuffer(Graphics graphics, Buffer buffer, ColorTable colorTable,
595
        Transparency transparency, FilterList filters) {
596

    
597
        BufferedImage image =
598
            new BufferedImage(buffer.getColumns(), buffer.getRows(), BufferedImage.TYPE_INT_ARGB);
599

    
600
        for (int i = 0; i < buffer.getRows(); i++) {
601
            for (int j = 0; j < buffer.getColumns(); j++) {
602

    
603
                Object value = buffer.getBand(0).get(i, j);
604
                byte[] rgba = colorTable.getRGBA(value);
605

    
606
                if (transparency != null) {
607
                    // Apply defined transparency ranges
608
                    int alpha = rgba[3] & 0xFF;
609
                    int newAlpha =
610
                        transparency.getTransparencyRangeAlpha(rgba[0], rgba[1], rgba[2]);
611
                    alpha = getNewAlpha(alpha, newAlpha);
612

    
613
                    // Apply general transparency
614
                    int transparencyValue = transparency.getAlpha();
615
                    rgba[3] = (byte) getNewAlpha(alpha, transparencyValue);
616
                }
617

    
618
                if (filters != null) {
619
                    // TODO Apply filters
620
                }
621

    
622
                int intARGB = ((rgba[3] & 0xFF) << 24) | // alpha
623
                    ((rgba[0] & 0xFF) << 16) | // red
624
                    ((rgba[1] & 0xFF) << 8) | // green
625
                    ((rgba[2] & 0xFF) << 0); // blue
626

    
627
                image.setRGB(j, i, intARGB);
628
            }
629
        }
630
        return image;
631
    }
632

    
633
    private int getNewAlpha(int alpha, int newAlpha) {
634
        return (int) Math.round(alpha * (newAlpha / 255d));
635
    }
636

    
637
    public ColorTable getColorTable() {
638
        return this.colorTable;
639
    }
640

    
641
    @Override
642
    public void setColorTable(ColorTable colorTable) {
643
        ColorInterpretation colorInterpretation = this.getColorInterpretation();
644

    
645
        if (colorInterpretation != null
646
            && (colorInterpretation.isRGB() || colorInterpretation.isBGR() || colorInterpretation
647
                .isRGBA())) {
648
            throw new IllegalArgumentException(
649
                "Can not set color table when color interpretation is RGB, BGR or RGBA");
650
        }
651

    
652
        this.colorTable = colorTable;
653
    }
654

    
655
    @Override
656
    public ColorInterpretation getColorInterpretation() {
657
        return this.colorInterpretation;
658
    }
659

    
660
    @Override
661
    public void setColorInterpretation(ColorInterpretation colorInterpretation) {
662

    
663
        if (this.colorTable != null
664
            && (colorInterpretation.isRGB() || colorInterpretation.isBGR() || colorInterpretation
665
                .isRGBA())) {
666
            throw new IllegalArgumentException(
667
                "Can not set color interpreation RGB, RGBA or BGR if legend has a color table specifed");
668
        }
669

    
670
        this.colorInterpretation = colorInterpretation;
671
    }
672

    
673
    @Override
674
    public FilterList getFilters() {
675
        return this.filters;
676
    }
677

    
678
    @Override
679
    public void setFilters(FilterList filterList) {
680
        this.filters = filterList;
681
    }
682

    
683
    /**
684
     *
685
     */
686
    public static void registerDefinition() {
687
        PersistenceManager manager = ToolsLocator.getPersistenceManager();
688
        DynStruct definition = manager.getDefinition(PERSISTENT_NAME);
689
        if (definition == null) {
690
            definition =
691
                manager.addDefinition(DefaultRasterLegend.class, PERSISTENT_NAME,
692
                    PERSISTENT_DESCRIPTION, null, null);
693
            definition.addDynField(COLOR_TABLE_PERSISTENCE_FIELD).setMandatory(false)
694
                .setClassOfValue(ColorTable.class);
695
            definition.addDynField(COLOR_INTERPRETATION_PERSISTENCE_FIELD).setMandatory(false)
696
                .setClassOfValue(ColorInterpretation.class);
697
            definition.addDynField(FILTERS_PERSISTENCE_FIELD).setMandatory(false)
698
                .setClassOfValue(FilterList.class);
699
        }
700
    }
701

    
702
    @Override
703
    public void saveToState(PersistentState state) throws PersistenceException {
704
        state.set(COLOR_TABLE_PERSISTENCE_FIELD, this.getColorTable());
705
        state.set(COLOR_INTERPRETATION_PERSISTENCE_FIELD, this.getColorInterpretation());
706
        state.set(FILTERS_PERSISTENCE_FIELD, this.filters);
707
    }
708

    
709
    @Override
710
    public void loadFromState(PersistentState state) throws PersistenceException {
711
        this.setColorTable((ColorTable) state.get(COLOR_TABLE_PERSISTENCE_FIELD));
712
        this.setColorInterpretation((ColorInterpretation) state
713
            .get(COLOR_INTERPRETATION_PERSISTENCE_FIELD));
714
        this.setFilters((FilterList) state.get(FILTERS_PERSISTENCE_FIELD));
715
    }
716

    
717
}