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 / operations / colortable / ColorTableOperation.java @ 8682

History | View | Annotate | Download (14.4 KB)

1
/* gvSIG. Desktop Geographic Information System.
2
 *
3
 * Copyright ? 2007-2017 gvSIG Association
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18
 * MA  02110-1301, USA.
19
 *
20
 * For any additional information, do not hesitate to contact us
21
 * at info AT gvsig.com, or visit our website www.gvsig.com.
22
 */
23
package org.gvsig.raster.lib.legend.impl.operations.colortable;
24

    
25
import java.util.ArrayList;
26
import java.util.Iterator;
27
import java.util.List;
28

    
29
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
30
import org.gvsig.raster.lib.buffer.api.Band;
31
import org.gvsig.raster.lib.buffer.api.BufferLocator;
32
import org.gvsig.raster.lib.buffer.api.BufferManager;
33
import org.gvsig.raster.lib.buffer.api.NoData;
34
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
35
import org.gvsig.raster.lib.buffer.api.exceptions.BufferOperationException;
36
import org.gvsig.raster.lib.buffer.api.operations.OperationFactory;
37
import org.gvsig.raster.lib.buffer.spi.exceptions.ProcessingOperationException;
38
import org.gvsig.raster.lib.buffer.spi.operations.AbstractOperation;
39
import org.gvsig.raster.lib.legend.api.RasterLegendLocator;
40
import org.gvsig.raster.lib.legend.api.RasterLegendManager;
41
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
42
import org.gvsig.raster.lib.legend.impl.ColorManager;
43
import org.gvsig.raster.lib.legend.impl.RasterLegendManagerServices;
44
import org.gvsig.raster.lib.legend.spi.AbstractColoredOperation;
45
import org.gvsig.tools.locator.LocatorException;
46

    
47

    
48
/**
49
 * @author fdiaz
50
 *
51
 */
52
public class ColorTableOperation extends AbstractColoredOperation {
53

    
54
    private RowProcessor rowProcessor;
55

    
56

    
57
    /**
58
     * @param factory
59
     *
60
     */
61
    public ColorTableOperation(OperationFactory factory) {
62
        this.factory = factory;
63
    }
64

    
65
    @Override
66
    public void preProcess() throws BufferOperationException {
67
        super.preProcess();
68
        BufferManager manager = BufferLocator.getBufferManager();
69
        RasterLegendManager legendManager = RasterLegendLocator.getRasterLegendManager();
70

    
71
        try {
72
            if (!colorInterpretation.isPalette()) {
73
                throw new UnsupportedOperationException("The color interpretation of input buffer isn't Palette");
74
            }
75

    
76
            int bandType = this.buffer.getBand(colorInterpretation.getPaletteBand()).getDataType();
77
            switch (bandType) {
78
            case BufferManager.TYPE_BYTE:
79
                rowProcessor = new ByteRowProcessor();
80
                break;
81
            case BufferManager.TYPE_USHORT:
82
                rowProcessor = new UShortRowProcessor();
83
                break;
84
            case BufferManager.TYPE_SHORT:
85
                rowProcessor = new ShortRowProcessor();
86
                break;
87
            case BufferManager.TYPE_INT:
88
                rowProcessor = new IntRowProcessor();
89
                break;
90
            case BufferManager.TYPE_FLOAT:
91
                rowProcessor = new FloatRowProcessor();
92
                break;
93
            case BufferManager.TYPE_DOUBLE:
94
                rowProcessor = new DoubleRowProcessor();
95
                break;
96
            default:
97
                throw new IllegalArgumentException("Unknow type of band '"+colorInterpretation.getPaletteBand()+"'");
98
            }
99

    
100

    
101
            int sourceBands = this.buffer.getBandCount();
102
            NoData[] sourceNoDatas = this.buffer.getBandNoData();
103
            int[] sourceTypes = this.buffer.getBandTypes();
104

    
105
            List<String> colorInterpretations = new ArrayList<String>();
106
            List<NoData> noDatas = new ArrayList<NoData>();
107
            List<Integer> types = new ArrayList<Integer>();
108

    
109
            colorInterpretations.add(ColorInterpretation.RED_BAND);
110
            colorInterpretations.add(ColorInterpretation.GREEN_BAND);
111
            colorInterpretations.add(ColorInterpretation.BLUE_BAND);
112
            colorInterpretations.add(ColorInterpretation.ALPHA_BAND);
113

    
114
            types.add(BufferManager.TYPE_BYTE);
115
            types.add(BufferManager.TYPE_BYTE);
116
            types.add(BufferManager.TYPE_BYTE);
117
            types.add(BufferManager.TYPE_BYTE);
118

    
119
            noDatas.add(null);
120
            noDatas.add(null);
121
            noDatas.add(null);
122
            noDatas.add(null);
123

    
124
//            if (colorInterpretation.hasAlphaBand()) {
125
//                int alphaBand = colorInterpretation.getAlphaBand();
126
//                if(sourceTypes[alphaBand]!=BufferManager.TYPE_BYTE){
127
//                    throw new UnsupportedOperationException("The type of ALPHA band isn't BYTE");
128
//                }
129
//                colorInterpretations.add(ColorInterpretation.ALPHA_BAND);
130
//                types.add(sourceTypes[alphaBand]);
131
//                noDatas.add(sourceNoDatas[alphaBand]);
132
//            }
133

    
134
            if (copyUnprocessedBands) {
135
                for (int band = 0; band < sourceBands; band++) {
136
                    if (!isProcessableBand(band)) {
137
                        colorInterpretations.add(ColorInterpretation.UNDEFINED_BAND);
138
                        noDatas.add(sourceNoDatas[band]);
139
                        types.add(this.buffer.getBandTypes()[band]);
140
                    }
141
                }
142
            }
143

    
144
            outputColorInterpretation =
145
                legendManager.createColorInterpretation(colorInterpretations.toArray(new String[0]));
146
            this.parameters.setDynValue(OUTPUT_COLOR_INTERPRETATION_PARAM, outputColorInterpretation);
147
            int[] typesInt = new int[types.size()];
148
            for (Iterator<Integer> iterator = types.iterator(); iterator.hasNext();) {
149
                int i = 0;
150
                Integer type = (Integer) iterator.next();
151
                typesInt[i] = type.intValue();
152
            }
153

    
154
            this.outputBuffer =
155
                manager.createBuffer(this.buffer.getRows(), this.buffer.getColumns(), typesInt,
156
                    noDatas.toArray(new NoData[0]), this.buffer.getProjection(), this.buffer.getEnvelope());
157
        } catch (LocatorException | BufferException | CreateEnvelopeException e) {
158
            throw new ProcessingOperationException(e);
159
        }
160
    }
161

    
162
    @Override
163
    public void process() throws ProcessingOperationException {
164
        super.process();
165
        try {
166

    
167
            // List<Integer> bandsToProcess = new ArrayList<Integer>();
168

    
169
            if (copyUnprocessedBands) {
170
                int bands = this.buffer.getBandCount();
171
                int outBand = 4; //colorInterpretation.hasAlphaBand() ? 4 : 3;
172
                for (int band = 0; band < bands; band++) {
173
                    if (!isProcessableBand(band)) {
174
                        outputBuffer.getBand(outBand).copyFrom(this.buffer.getBand(band));
175
                        outBand++;
176
                    }
177
                }
178
            }
179

    
180
            for (int row = 0; row < this.buffer.getRows(); row++) {
181
                Band bufferPaletteBand = buffer.getBand(colorInterpretation.getPaletteBand());
182
                Object rowBandBuffer = bufferPaletteBand.createRowBuffer();
183
                bufferPaletteBand.fetchRow(row, rowBandBuffer);
184

    
185
                List<Object> outputRowBuffers = new ArrayList<Object>();
186
                for (int band = 0; band < 4; band++) {
187
                    Band outputBufferBand = outputBuffer.getBand(band);
188
                    Object outputRowBuffer = outputBufferBand.createRowBuffer();
189
                    outputRowBuffers.add(outputRowBuffer);
190
                }
191

    
192
                rowProcessor.processRow(rowBandBuffer, outputRowBuffers);
193

    
194
                for (int band = 0; band < 4; band++) {
195
                    Band outputBufferBand = outputBuffer.getBand(band);
196
                    outputBufferBand.putRow(row, outputRowBuffers.get(band));
197
                }
198

    
199
            }
200
        } catch (Exception e) {
201
            throw new ProcessingOperationException(e);
202
        }
203

    
204
    }
205

    
206
    @Override
207
    public void postProcess() throws BufferOperationException {
208
        super.postProcess();
209
    }
210

    
211
    /**
212
     * @param band
213
     * @return
214
     */
215
    private boolean isProcessableBand(int band) {
216
        return isPaletteBand(band);
217
    }
218

    
219
    private boolean isPaletteBand(int band) {
220
        return (colorInterpretation.getPaletteBand() == band);
221
    }
222

    
223

    
224

    
225
    interface RowProcessor {
226
        void processRow(Object inputRow, List outputRows);
227
        byte[] processValue(Object value);
228
    };
229

    
230
    private abstract class AbstractRowProcessor implements RowProcessor {
231
        NoData noData;
232

    
233
        public AbstractRowProcessor() {
234
            noData = buffer.getBand(colorInterpretation.getPaletteBand()).getNoData();
235
        }
236
    }
237

    
238

    
239
    private class ByteRowProcessor extends AbstractRowProcessor {
240

    
241

    
242
        public ByteRowProcessor() {
243
            super();
244
        }
245

    
246
        @Override
247
        public void processRow(Object inputRow, List outputRows) {
248
            byte[] inputByteRow = (byte[])inputRow;
249

    
250
            for (int i = 0; i < inputByteRow.length; i++) {
251
                byte[] rgb = processValue(inputByteRow[i]);
252
                for (int band = 0; band < outputRows.size(); band++) {
253
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
254
                }
255
            }
256

    
257
        }
258

    
259
        @Override
260
        public byte[] processValue(Object value) {
261
            if (noData.isDefined()) {
262
                if (noData.getValue().equals(value)) {
263
                    byte result[] = { 0, 0, 0, 0 };
264
                    return result;
265
                }
266
            }
267

    
268
            return colorInterpretation.getPalette().getRGBA(0xFF & (byte)value);
269
        }
270

    
271
    }
272

    
273
    private class ShortRowProcessor extends AbstractRowProcessor {
274

    
275
        public ShortRowProcessor() {
276
            super();
277
        }
278

    
279
        @Override
280
        public void processRow(Object inputRow, List outputRows) {
281
            short[] inputByteRow = (short[])inputRow;
282

    
283
            for (int i = 0; i < inputByteRow.length; i++) {
284
                byte[] rgb = processValue(inputByteRow[i]);
285
                for (int band = 0; band < outputRows.size(); band++) {
286
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
287
                }
288
            }
289
        }
290

    
291
        @Override
292
        public byte[] processValue(Object value) {
293
            if(noData.isDefined() && noData.getValue().equals(value)){
294
                byte result[] = {0,0,0,0};
295
                return result;
296
            }
297

    
298
            return colorInterpretation.getPalette().getRGBA(value);
299
        }
300

    
301
    }
302

    
303
    private class UShortRowProcessor extends AbstractRowProcessor {
304

    
305
        public UShortRowProcessor() {
306
            super();
307
        }
308

    
309
        @Override
310
        public void processRow(Object inputRow, List outputRows) {
311
            short[] inputByteRow = (short[])inputRow;
312

    
313
            for (int i = 0; i < inputByteRow.length; i++) {
314
                byte[] rgb = processValue(inputByteRow[i]);
315
                for (int band = 0; band < outputRows.size(); band++) {
316
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
317
                }
318
            }
319
        }
320

    
321
        @Override
322
        public byte[] processValue(Object value) {
323
            if(noData.isDefined() && noData.getValue().equals(value)){
324
                byte result[] = {0,0,0,0};
325
                return result;
326
            }
327

    
328
            return colorInterpretation.getPalette().getRGBA(0xFFFF & (byte)value);
329
        }
330

    
331
    }
332

    
333
    private class IntRowProcessor extends AbstractRowProcessor {
334

    
335
        public IntRowProcessor() {
336
            super();
337
        }
338

    
339
        @Override
340
        public void processRow(Object inputRow, List outputRows) {
341
            int[] inputByteRow = (int[])inputRow;
342

    
343
            for (int i = 0; i < inputByteRow.length; i++) {
344
                byte[] rgb = processValue(inputByteRow[i]);
345
                for (int band = 0; band < outputRows.size(); band++) {
346
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
347
                }
348
            }
349
        }
350

    
351
        @Override
352
        public byte[] processValue(Object value) {
353
            if(noData.isDefined() && noData.getValue().equals(value)){
354
                byte result[] = {0,0,0,0};
355
                return result;
356
            }
357

    
358
            return colorInterpretation.getPalette().getRGBA(value);
359
        }
360

    
361
    }
362
    private class FloatRowProcessor extends AbstractRowProcessor {
363

    
364
        public FloatRowProcessor() {
365
            super();
366
        }
367

    
368
        @Override
369
        public void processRow(Object inputRow, List outputRows) {
370
            float[] inputByteRow = (float[])inputRow;
371

    
372
            for (int i = 0; i < inputByteRow.length; i++) {
373
                byte[] rgb = processValue(inputByteRow[i]);
374
                for (int band = 0; band < outputRows.size(); band++) {
375
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
376
                }
377
            }
378
        }
379

    
380
        @Override
381
        public byte[] processValue(Object value) {
382
            if(noData.isDefined() && noData.getValue().equals(value)){
383
                byte result[] = {0,0,0,0};
384
                return result;
385
            }
386

    
387
            return colorInterpretation.getPalette().getRGBA(value);
388
        }
389

    
390
    }
391
    private class DoubleRowProcessor extends AbstractRowProcessor {
392

    
393

    
394
        public DoubleRowProcessor() {
395
            super();
396
        }
397

    
398
        @Override
399
        public void processRow(Object inputRow, List outputRows) {
400
            double[] inputByteRow = (double[])inputRow;
401

    
402
            for (int i = 0; i < inputByteRow.length; i++) {
403
                byte[] rgb = processValue(inputByteRow[i]);
404
                for (int band = 0; band < outputRows.size(); band++) {
405
                    byte[] bs = (byte[])(outputRows.get(band));
406
                    bs[i] = rgb[band];
407
                }
408
            }
409
        }
410

    
411
        @Override
412
        public byte[] processValue(Object value) {
413
            if(noData.isDefined() && noData.getValue().equals(value)){
414
                byte result[] = {0,0,0,0};
415
                return result;
416
            }
417

    
418
            return colorInterpretation.getPalette().getRGBA(value);
419
        }
420

    
421
    }
422

    
423
}