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 / grayscale / GrayScaleOperation.java @ 43803

History | View | Annotate | Download (10.1 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.grayscale;
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.spi.AbstractColoredOperation;
43
import org.gvsig.tools.locator.LocatorException;
44

    
45

    
46
/**
47
 * @author fdiaz
48
 *
49
 */
50
public class GrayScaleOperation extends AbstractColoredOperation {
51

    
52
    /**
53
     * @param factory
54
     *
55
     */
56
    public GrayScaleOperation(OperationFactory factory) {
57
        this.factory = factory;
58
    }
59

    
60
    @Override
61
    public void preProcess() throws BufferOperationException {
62
        super.preProcess();
63
        BufferManager manager = BufferLocator.getBufferManager();
64
        RasterLegendManager legendManager = RasterLegendLocator.getRasterLegendManager();
65

    
66
        try {
67

    
68
            if (!(colorInterpretation.hasAnyRGBBand() || colorInterpretation.hasAnyGrayBand())) {
69
                throw new UnsupportedOperationException(
70
                    "The color interpretation of input buffer isn't RGB nor GRAYSCALE");
71
            }
72

    
73
            int[] inputBandTypes = buffer.getBandTypes();
74
            if (colorInterpretation.hasAnyRGBBand()) {
75
                if ((colorInterpretation.getBand(ColorInterpretation.RED_BAND)>=0 && inputBandTypes[colorInterpretation.getBand(ColorInterpretation.RED_BAND)] != BufferManager.TYPE_BYTE)
76
                    || (colorInterpretation.getBand(ColorInterpretation.GREEN_BAND)>=0 && inputBandTypes[colorInterpretation.getBand(ColorInterpretation.GREEN_BAND)] != BufferManager.TYPE_BYTE)
77
                    || (colorInterpretation.getBand(ColorInterpretation.BLUE_BAND)>=0 && inputBandTypes[colorInterpretation.getBand(ColorInterpretation.BLUE_BAND)] != BufferManager.TYPE_BYTE)) {
78
                    throw new UnsupportedOperationException("The type of bands isn't BYTE");
79
                }
80
            } else if (colorInterpretation.hasAnyGrayBand()) {
81
                if ((colorInterpretation.getBand(ColorInterpretation.GRAY_BAND)>=0 && inputBandTypes[colorInterpretation.getBand(ColorInterpretation.GRAY_BAND)] != BufferManager.TYPE_BYTE)) {
82
                    throw new UnsupportedOperationException("The type of band gray isn't BYTE");
83
                }
84
            } else {
85
                throw new UnsupportedOperationException(
86
                    "The color interpretation of input buffer isn't RGB nor GRAYSCALE");
87
            }
88

    
89
            int sourceBands = this.buffer.getBandCount();
90
            NoData[] sourceNoDatas = this.buffer.getBandNoData();
91
            int[] sourceTypes = this.buffer.getBandTypes();
92

    
93
            List<String> colorInterpretations = new ArrayList<String>();
94
            List<NoData> noDatas = new ArrayList<NoData>();
95
            List<Integer> types = new ArrayList<Integer>();
96

    
97
            colorInterpretations.add(ColorInterpretation.GRAY_BAND);
98
            types.add(BufferManager.TYPE_BYTE);
99
            noDatas.add(null);
100

    
101
            if (colorInterpretation.hasAlphaBand()) {
102
                if(sourceTypes[colorInterpretation.getAlphaBand()]!=BufferManager.TYPE_BYTE){
103
                    throw new UnsupportedOperationException("The type of ALPHA band isn't BYTE");
104
                }
105
                colorInterpretations.add(ColorInterpretation.ALPHA_BAND);
106
                types.add(sourceTypes[colorInterpretation.getAlphaBand()]);
107
                noDatas.add(sourceNoDatas[colorInterpretation.getAlphaBand()]);
108
            }
109

    
110
            if (copyUnprocessedBands) {
111
                for (int band = 0; band < sourceBands; band++) {
112
                    if (!isProcessableBand(band) && !colorInterpretation.isAlphaInterpretation(band)) {
113
                        colorInterpretations.add(colorInterpretation.get(band));
114
                        noDatas.add(sourceNoDatas[band]);
115
                        types.add(this.buffer.getBandTypes()[band]);
116
                    }
117
                }
118
            }
119
            outputColorInterpretation =
120
                legendManager.createColorInterpretation(colorInterpretations.toArray(new String[0]));
121
            this.parameters.setDynValue(OUTPUT_COLOR_INTERPRETATION_PARAM, outputColorInterpretation);
122
            int[] typesInt = new int[types.size()];
123
            for (Iterator<Integer> iterator = types.iterator(); iterator.hasNext();) {
124
                int i = 0;
125
                Integer type = (Integer) iterator.next();
126
                typesInt[i] = type.intValue();
127
            }
128
            this.outputBuffer =
129
                manager.createBuffer(this.buffer.getRows(), this.buffer.getColumns(), typesInt,
130
                    noDatas.toArray(new NoData[0]), this.buffer.getProjection(), this.buffer.getEnvelope());
131
        } catch (LocatorException | BufferException | CreateEnvelopeException e) {
132
            throw new ProcessingOperationException(e);
133
        }
134
    }
135

    
136
    @Override
137
    public void process() throws ProcessingOperationException {
138
        try {
139
            super.process();
140
            List<Integer> bandsToProcess = new ArrayList<Integer>();
141

    
142
            Band outputBufferBand = outputBuffer.getBand(0);
143
            boolean processed = false;
144
            if (copyUnprocessedBands) {
145
                int bands = this.buffer.getBandCount();
146
                int outBand = colorInterpretation.hasAlphaBand() ? 2 : 1;
147
                for (int band = 0; band < bands; band++) {
148
                    if (isProcessableBand(band)) {
149
                        if (colorInterpretation.isGrayInterpretation(band)) {
150
                            outputBufferBand.copyFrom(this.buffer.getBand(band));
151
                            processed = true;
152
                        } else {
153
                            bandsToProcess.add(band);
154
                        }
155
                    } else if (colorInterpretation.isAlphaInterpretation(band)) {
156
                        outputBuffer.getBand(outputColorInterpretation.getAlphaBand()).copyFrom(
157
                            this.buffer.getBand(band));
158
                    } else {
159
                        outputBuffer.getBand(outBand).copyFrom(
160
                            this.buffer.getBand(band));
161
                        outBand++;
162
                    }
163
                }
164
            }
165

    
166
            if (!processed) {
167
                Object[] rowBandsBuffer = new Object[bandsToProcess.size()];
168
                for (int row = 0; row < this.buffer.getRows(); row++) {
169
                    for (int i = 0; i < bandsToProcess.size(); i++) {
170
                        Integer band = bandsToProcess.get(i);
171
                        if (isProcessableBand(band)) {
172
                            Band bufferBand = buffer.getBand(band);
173
                            rowBandsBuffer[i] = bufferBand.createRowBuffer();
174
                            bufferBand.fetchRow(row, rowBandsBuffer[i]);
175
                        }
176
                    }
177
                    Object outputRowBuffer = outputBufferBand.createRowBuffer();
178
                    processRow(rowBandsBuffer, outputRowBuffer);
179
                    outputBufferBand.putRow(row, outputRowBuffer);
180
                }
181
            }
182
        } catch (Exception e) {
183
            throw new ProcessingOperationException(e);
184
        }
185
    }
186

    
187
    /**
188
     * @param band
189
     * @return
190
     */
191
    private boolean isProcessableBand(int band) {
192
        return isRGBorGrayBand(band) && this.buffer.getBandTypes()[band] == BufferManager.TYPE_BYTE;
193
    }
194

    
195
    private boolean isRGBorGrayBand(int band) {
196
        String bandColorInterpretation = colorInterpretation.get(band);
197
        return (bandColorInterpretation.equals(ColorInterpretation.RED_BAND)
198
            || bandColorInterpretation.equals(ColorInterpretation.GREEN_BAND)
199
            || bandColorInterpretation.equals(ColorInterpretation.BLUE_BAND) || bandColorInterpretation
200
                .equals(ColorInterpretation.GRAY_BAND));
201
    }
202

    
203
    @Override
204
    public void postProcess() throws BufferOperationException {
205
        super.postProcess();
206
    }
207

    
208
    private void processRow(Object[] inputRows, Object outputRow) {
209
        byte[][] inputByteRows = new byte[inputRows.length][((byte[]) inputRows[0]).length];
210
        for (int i = 0; i < inputRows.length; i++) {
211
            inputByteRows[i] = (byte[]) inputRows[i];
212
        }
213
        byte[] outputByteRow = (byte[]) outputRow;
214
        for (int i = 0; i < inputByteRows[0].length; i++) {
215

    
216
            int tmp = 0;
217

    
218
            for (int band = 0; band < inputRows.length; band++) {
219
                tmp += 0xFF & ((Byte) inputByteRows[band][i]).byteValue();
220
            }
221
            outputByteRow[i] = (byte) (tmp / inputRows.length);
222
        }
223
    }
224
}