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

History | View | Annotate | Download (14.3 KB)

1 43803 fdiaz
/* 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.List;
27
28
import org.gvsig.fmap.geom.exception.CreateEnvelopeException;
29
import org.gvsig.raster.lib.buffer.api.Band;
30
import org.gvsig.raster.lib.buffer.api.BufferLocator;
31
import org.gvsig.raster.lib.buffer.api.BufferManager;
32
import org.gvsig.raster.lib.buffer.api.NoData;
33
import org.gvsig.raster.lib.buffer.api.exceptions.BufferException;
34
import org.gvsig.raster.lib.buffer.api.exceptions.BufferOperationException;
35
import org.gvsig.raster.lib.buffer.api.operations.OperationFactory;
36
import org.gvsig.raster.lib.buffer.spi.exceptions.ProcessingOperationException;
37
import org.gvsig.raster.lib.legend.api.RasterLegendLocator;
38
import org.gvsig.raster.lib.legend.api.RasterLegendManager;
39
import org.gvsig.raster.lib.legend.api.colorinterpretation.ColorInterpretation;
40
import org.gvsig.raster.lib.legend.spi.AbstractColoredOperation;
41
import org.gvsig.tools.locator.LocatorException;
42
43
44
/**
45
 * @author fdiaz
46
 *
47
 */
48
public class ColorTableOperation extends AbstractColoredOperation {
49
50
    private RowProcessor rowProcessor;
51
52
53
    /**
54
     * @param factory
55
     *
56
     */
57
    public ColorTableOperation(OperationFactory factory) {
58 43862 jjdelcerro
        super(factory);
59 43803 fdiaz
    }
60
61
    @Override
62
    public void preProcess() throws BufferOperationException {
63
        super.preProcess();
64
        BufferManager manager = BufferLocator.getBufferManager();
65
        RasterLegendManager legendManager = RasterLegendLocator.getRasterLegendManager();
66
67
        try {
68 43862 jjdelcerro
            if (!getInputColorInterpretation().isPalette()) {
69 43803 fdiaz
                throw new UnsupportedOperationException("The color interpretation of input buffer isn't Palette");
70
            }
71
72 43862 jjdelcerro
            int bandType = this.getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand()).getDataType();
73 43803 fdiaz
            switch (bandType) {
74
            case BufferManager.TYPE_BYTE:
75
                rowProcessor = new ByteRowProcessor();
76
                break;
77
            case BufferManager.TYPE_USHORT:
78
                rowProcessor = new UShortRowProcessor();
79
                break;
80
            case BufferManager.TYPE_SHORT:
81
                rowProcessor = new ShortRowProcessor();
82
                break;
83
            case BufferManager.TYPE_INT:
84
                rowProcessor = new IntRowProcessor();
85
                break;
86
            case BufferManager.TYPE_FLOAT:
87
                rowProcessor = new FloatRowProcessor();
88
                break;
89
            case BufferManager.TYPE_DOUBLE:
90
                rowProcessor = new DoubleRowProcessor();
91
                break;
92
            default:
93 43862 jjdelcerro
                throw new IllegalArgumentException("Unknow type of band '"+getInputColorInterpretation().getPaletteBand()+"'");
94 43803 fdiaz
            }
95
96
97 43862 jjdelcerro
            int sourceBands = this.getInputBuffer().getBandCount();
98
            NoData[] sourceNoDatas = this.getInputBuffer().getBandNoData();
99
//            int[] sourceTypes = this.getInputBuffer().getBandTypes();
100 43803 fdiaz
101 43862 jjdelcerro
            List<String> colorInterpretations = new ArrayList<>();
102
            List<NoData> noDatas = new ArrayList<>();
103
            List<Integer> types = new ArrayList<>();
104 43803 fdiaz
105
            colorInterpretations.add(ColorInterpretation.RED_BAND);
106
            colorInterpretations.add(ColorInterpretation.GREEN_BAND);
107
            colorInterpretations.add(ColorInterpretation.BLUE_BAND);
108
            colorInterpretations.add(ColorInterpretation.ALPHA_BAND);
109
110
            types.add(BufferManager.TYPE_BYTE);
111
            types.add(BufferManager.TYPE_BYTE);
112
            types.add(BufferManager.TYPE_BYTE);
113
            types.add(BufferManager.TYPE_BYTE);
114
115
            noDatas.add(null);
116
            noDatas.add(null);
117
            noDatas.add(null);
118
            noDatas.add(null);
119
120 43862 jjdelcerro
//            if (getInputColorInterpretation().hasAlphaBand()) {
121
//                int alphaBand = getInputColorInterpretation().getAlphaBand();
122 43803 fdiaz
//                if(sourceTypes[alphaBand]!=BufferManager.TYPE_BYTE){
123
//                    throw new UnsupportedOperationException("The type of ALPHA band isn't BYTE");
124
//                }
125
//                colorInterpretations.add(ColorInterpretation.ALPHA_BAND);
126
//                types.add(sourceTypes[alphaBand]);
127
//                noDatas.add(sourceNoDatas[alphaBand]);
128
//            }
129
130 43862 jjdelcerro
            if (mustCopyUnprocessedBands()) {
131 43803 fdiaz
                for (int band = 0; band < sourceBands; band++) {
132
                    if (!isProcessableBand(band)) {
133
                        colorInterpretations.add(ColorInterpretation.UNDEFINED_BAND);
134
                        noDatas.add(sourceNoDatas[band]);
135 43862 jjdelcerro
                        types.add(this.getInputBuffer().getBandTypes()[band]);
136 43803 fdiaz
                    }
137
                }
138
            }
139
140 43862 jjdelcerro
            setOutputColorInterpretation(
141
                legendManager.createColorInterpretation(colorInterpretations));
142
            this.setParameter(OUTPUT_COLOR_INTERPRETATION_PARAM, getOutputColorInterpretation());
143 43803 fdiaz
144 43862 jjdelcerro
            this.setOutputBuffer(
145
                manager.createBuffer(
146
                        this.getInputBuffer().getRows(),
147
                        this.getInputBuffer().getColumns(),
148
                        this.getTypesAsArray(types),
149
                        this.getNoDatasAsArray(noDatas),
150
                        this.getInputBuffer().getProjection(),
151
                        this.getInputBuffer().getEnvelope()));
152 43803 fdiaz
        } catch (LocatorException | BufferException | CreateEnvelopeException e) {
153
            throw new ProcessingOperationException(e);
154
        }
155
    }
156
157
    @Override
158
    public void process() throws ProcessingOperationException {
159
        super.process();
160
        try {
161
162
            // List<Integer> bandsToProcess = new ArrayList<Integer>();
163
164 43862 jjdelcerro
            if (mustCopyUnprocessedBands()) {
165
                int bands = this.getInputBuffer().getBandCount();
166
                int outBand = 4; //getInputColorInterpretation().hasAlphaBand() ? 4 : 3;
167 43803 fdiaz
                for (int band = 0; band < bands; band++) {
168
                    if (!isProcessableBand(band)) {
169 43862 jjdelcerro
                        getOutputBuffer().getBand(outBand).copyFrom(this.getInputBuffer().getBand(band));
170 43803 fdiaz
                        outBand++;
171
                    }
172
                }
173
            }
174
175 43862 jjdelcerro
            for (int row = 0; row < this.getInputBuffer().getRows(); row++) {
176
                Band bufferPaletteBand = getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand());
177 43803 fdiaz
                Object rowBandBuffer = bufferPaletteBand.createRowBuffer();
178
                bufferPaletteBand.fetchRow(row, rowBandBuffer);
179
180 43862 jjdelcerro
                List<Object> outputRowBuffers = new ArrayList<>();
181 43803 fdiaz
                for (int band = 0; band < 4; band++) {
182 43862 jjdelcerro
                    Band outputBufferBand = getOutputBuffer().getBand(band);
183 43803 fdiaz
                    Object outputRowBuffer = outputBufferBand.createRowBuffer();
184
                    outputRowBuffers.add(outputRowBuffer);
185
                }
186
187
                rowProcessor.processRow(rowBandBuffer, outputRowBuffers);
188
189
                for (int band = 0; band < 4; band++) {
190 43862 jjdelcerro
                    Band outputBufferBand = getOutputBuffer().getBand(band);
191 43803 fdiaz
                    outputBufferBand.putRow(row, outputRowBuffers.get(band));
192
                }
193
194
            }
195
        } catch (Exception e) {
196
            throw new ProcessingOperationException(e);
197
        }
198
199
    }
200
201
    @Override
202
    public void postProcess() throws BufferOperationException {
203
        super.postProcess();
204
    }
205
206
    /**
207
     * @param band
208
     * @return
209
     */
210 43862 jjdelcerro
    @Override
211
    protected boolean isProcessableBand(int band) {
212 43803 fdiaz
        return isPaletteBand(band);
213
    }
214
215
    private boolean isPaletteBand(int band) {
216 43862 jjdelcerro
        return (getInputColorInterpretation().getPaletteBand() == band);
217 43803 fdiaz
    }
218
219
220
221
    interface RowProcessor {
222
        void processRow(Object inputRow, List outputRows);
223
        byte[] processValue(Object value);
224
    };
225
226
    private abstract class AbstractRowProcessor implements RowProcessor {
227
        NoData noData;
228
229
        public AbstractRowProcessor() {
230 43862 jjdelcerro
            noData = getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand()).getNoData();
231 43803 fdiaz
        }
232
    }
233
234
235
    private class ByteRowProcessor extends AbstractRowProcessor {
236
237
238
        public ByteRowProcessor() {
239
            super();
240
        }
241
242
        @Override
243
        public void processRow(Object inputRow, List outputRows) {
244
            byte[] inputByteRow = (byte[])inputRow;
245
246
            for (int i = 0; i < inputByteRow.length; i++) {
247
                byte[] rgb = processValue(inputByteRow[i]);
248
                for (int band = 0; band < outputRows.size(); band++) {
249
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
250
                }
251
            }
252
253
        }
254
255
        @Override
256
        public byte[] processValue(Object value) {
257
            if (noData.isDefined()) {
258
                if (noData.getValue().equals(value)) {
259
                    byte result[] = { 0, 0, 0, 0 };
260
                    return result;
261
                }
262
            }
263
264 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(0xFF & (byte)value);
265 43803 fdiaz
        }
266
267
    }
268
269
    private class ShortRowProcessor extends AbstractRowProcessor {
270
271
        public ShortRowProcessor() {
272
            super();
273
        }
274
275
        @Override
276
        public void processRow(Object inputRow, List outputRows) {
277
            short[] inputByteRow = (short[])inputRow;
278
279
            for (int i = 0; i < inputByteRow.length; i++) {
280
                byte[] rgb = processValue(inputByteRow[i]);
281
                for (int band = 0; band < outputRows.size(); band++) {
282
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
283
                }
284
            }
285
        }
286
287
        @Override
288
        public byte[] processValue(Object value) {
289
            if(noData.isDefined() && noData.getValue().equals(value)){
290
                byte result[] = {0,0,0,0};
291
                return result;
292
            }
293
294 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(value);
295 43803 fdiaz
        }
296
297
    }
298
299
    private class UShortRowProcessor extends AbstractRowProcessor {
300
301
        public UShortRowProcessor() {
302
            super();
303
        }
304
305
        @Override
306
        public void processRow(Object inputRow, List outputRows) {
307
            short[] inputByteRow = (short[])inputRow;
308
309
            for (int i = 0; i < inputByteRow.length; i++) {
310
                byte[] rgb = processValue(inputByteRow[i]);
311
                for (int band = 0; band < outputRows.size(); band++) {
312
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
313
                }
314
            }
315
        }
316
317
        @Override
318
        public byte[] processValue(Object value) {
319
            if(noData.isDefined() && noData.getValue().equals(value)){
320
                byte result[] = {0,0,0,0};
321
                return result;
322
            }
323
324 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(0xFFFF & (byte)value);
325 43803 fdiaz
        }
326
327
    }
328
329
    private class IntRowProcessor extends AbstractRowProcessor {
330
331
        public IntRowProcessor() {
332
            super();
333
        }
334
335
        @Override
336
        public void processRow(Object inputRow, List outputRows) {
337
            int[] inputByteRow = (int[])inputRow;
338
339
            for (int i = 0; i < inputByteRow.length; i++) {
340
                byte[] rgb = processValue(inputByteRow[i]);
341
                for (int band = 0; band < outputRows.size(); band++) {
342
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
343
                }
344
            }
345
        }
346
347
        @Override
348
        public byte[] processValue(Object value) {
349
            if(noData.isDefined() && noData.getValue().equals(value)){
350
                byte result[] = {0,0,0,0};
351
                return result;
352
            }
353
354 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(value);
355 43803 fdiaz
        }
356
357
    }
358
    private class FloatRowProcessor extends AbstractRowProcessor {
359
360
        public FloatRowProcessor() {
361
            super();
362
        }
363
364
        @Override
365
        public void processRow(Object inputRow, List outputRows) {
366
            float[] inputByteRow = (float[])inputRow;
367
368
            for (int i = 0; i < inputByteRow.length; i++) {
369
                byte[] rgb = processValue(inputByteRow[i]);
370
                for (int band = 0; band < outputRows.size(); band++) {
371
                    ((byte[])(outputRows.get(band)))[i] = rgb[band];
372
                }
373
            }
374
        }
375
376
        @Override
377
        public byte[] processValue(Object value) {
378
            if(noData.isDefined() && noData.getValue().equals(value)){
379
                byte result[] = {0,0,0,0};
380
                return result;
381
            }
382
383 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(value);
384 43803 fdiaz
        }
385
386
    }
387
    private class DoubleRowProcessor extends AbstractRowProcessor {
388
389
390
        public DoubleRowProcessor() {
391
            super();
392
        }
393
394
        @Override
395
        public void processRow(Object inputRow, List outputRows) {
396
            double[] inputByteRow = (double[])inputRow;
397
398
            for (int i = 0; i < inputByteRow.length; i++) {
399
                byte[] rgb = processValue(inputByteRow[i]);
400
                for (int band = 0; band < outputRows.size(); band++) {
401
                    byte[] bs = (byte[])(outputRows.get(band));
402
                    bs[i] = rgb[band];
403
                }
404
            }
405
        }
406
407
        @Override
408
        public byte[] processValue(Object value) {
409
            if(noData.isDefined() && noData.getValue().equals(value)){
410
                byte result[] = {0,0,0,0};
411
                return result;
412
            }
413
414 43862 jjdelcerro
            return getInputColorInterpretation().getPalette().getRGBA(value);
415 43803 fdiaz
        }
416
417
    }
418
419
}