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
/* 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
        super(factory);
59
    }
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
            if (!getInputColorInterpretation().isPalette()) {
69
                throw new UnsupportedOperationException("The color interpretation of input buffer isn't Palette");
70
            }
71

    
72
            int bandType = this.getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand()).getDataType();
73
            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
                throw new IllegalArgumentException("Unknow type of band '"+getInputColorInterpretation().getPaletteBand()+"'");
94
            }
95

    
96

    
97
            int sourceBands = this.getInputBuffer().getBandCount();
98
            NoData[] sourceNoDatas = this.getInputBuffer().getBandNoData();
99
//            int[] sourceTypes = this.getInputBuffer().getBandTypes();
100

    
101
            List<String> colorInterpretations = new ArrayList<>();
102
            List<NoData> noDatas = new ArrayList<>();
103
            List<Integer> types = new ArrayList<>();
104

    
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
//            if (getInputColorInterpretation().hasAlphaBand()) {
121
//                int alphaBand = getInputColorInterpretation().getAlphaBand();
122
//                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
            if (mustCopyUnprocessedBands()) {
131
                for (int band = 0; band < sourceBands; band++) {
132
                    if (!isProcessableBand(band)) {
133
                        colorInterpretations.add(ColorInterpretation.UNDEFINED_BAND);
134
                        noDatas.add(sourceNoDatas[band]);
135
                        types.add(this.getInputBuffer().getBandTypes()[band]);
136
                    }
137
                }
138
            }
139

    
140
            setOutputColorInterpretation(
141
                legendManager.createColorInterpretation(colorInterpretations));
142
            this.setParameter(OUTPUT_COLOR_INTERPRETATION_PARAM, getOutputColorInterpretation());
143

    
144
            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
        } 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
            if (mustCopyUnprocessedBands()) {
165
                int bands = this.getInputBuffer().getBandCount();
166
                int outBand = 4; //getInputColorInterpretation().hasAlphaBand() ? 4 : 3;
167
                for (int band = 0; band < bands; band++) {
168
                    if (!isProcessableBand(band)) {
169
                        getOutputBuffer().getBand(outBand).copyFrom(this.getInputBuffer().getBand(band));
170
                        outBand++;
171
                    }
172
                }
173
            }
174

    
175
            for (int row = 0; row < this.getInputBuffer().getRows(); row++) {
176
                Band bufferPaletteBand = getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand());
177
                Object rowBandBuffer = bufferPaletteBand.createRowBuffer();
178
                bufferPaletteBand.fetchRow(row, rowBandBuffer);
179

    
180
                List<Object> outputRowBuffers = new ArrayList<>();
181
                for (int band = 0; band < 4; band++) {
182
                    Band outputBufferBand = getOutputBuffer().getBand(band);
183
                    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
                    Band outputBufferBand = getOutputBuffer().getBand(band);
191
                    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
    @Override
211
    protected boolean isProcessableBand(int band) {
212
        return isPaletteBand(band);
213
    }
214

    
215
    private boolean isPaletteBand(int band) {
216
        return (getInputColorInterpretation().getPaletteBand() == band);
217
    }
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
            noData = getInputBuffer().getBand(getInputColorInterpretation().getPaletteBand()).getNoData();
231
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(0xFF & (byte)value);
265
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(value);
295
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(0xFFFF & (byte)value);
325
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(value);
355
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(value);
384
        }
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
            return getInputColorInterpretation().getPalette().getRGBA(value);
415
        }
416

    
417
    }
418

    
419
}