Statistics
| Revision:

gvsig-raster / org.gvsig.raster.tools / trunk / org.gvsig.raster.tools / org.gvsig.raster.tools.algorithm / org.gvsig.raster.tools.algorithm.maskthreshold / src / main / java / org / gvsig / raster / tools / algorithm / maskthreshold / MaskthresholdProcess.java @ 1312

History | View | Annotate | Download (23.8 KB)

1
/* gvSIG. Geographic Information System of the Valencian Government
2
*
3
* Copyright (C) 2007-2008 Infrastructures and Transports Department
4
* of the Valencian Government (CIT)
5
* 
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* as published by the Free Software Foundation; either version 2
9
* of the License, or (at your option) any later version.
10
* 
11
* This program is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
* GNU General Public License for more details.
15
* 
16
* You should have received a copy of the GNU General Public License
17
* along with this program; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
19
* MA  02110-1301, USA.
20
* 
21
*/
22
package org.gvsig.raster.tools.algorithm.maskthreshold;
23

    
24
import java.awt.geom.Rectangle2D;
25
import java.util.HashMap;
26

    
27
import javax.swing.SwingUtilities;
28

    
29
import org.gvsig.fmap.dal.coverage.RasterLocator;
30
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
31
import org.gvsig.fmap.dal.coverage.datastruct.NoData;
32
import org.gvsig.fmap.dal.coverage.exception.InvalidSetViewException;
33
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
34
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
35
import org.gvsig.fmap.dal.coverage.store.RasterDataStore;
36
import org.gvsig.fmap.dal.coverage.store.RasterQuery;
37
import org.gvsig.i18n.Messages;
38
import org.gvsig.raster.tools.algorithm.base.RasterBaseAlgorithmLibrary;
39
import org.gvsig.raster.tools.algorithm.base.process.ProcessException;
40
import org.gvsig.raster.tools.algorithm.base.process.RasterProcess;
41
import org.gvsig.raster.tools.algorithm.base.util.Operation;
42

    
43
/**
44
 * Process to create a mask using a threshold. This threshold could be a value
45
 * of a pixel or a fixed value.
46
 * 
47
 * Possible use cases:
48
 * <UL>
49
 * <LI>Fixed-oplayer:  A input layer, an operator layer and a fixed value if the condition is satisfied.
50
 * If the condition is not satisfied the value is set to NoData</LI>
51
 * 
52
 * <LI>Fixed-threshold:  A input layer, a threshold and a fixed value if the condition is satisfied.
53
 * If the condition is not satisfied the value is set to NoData</LI>
54
 *
55
 * <LI>Replicate-oplayer:  A input layer, an operator layer and a output layer. If the condition is satisfied.
56
 * the result layer replicates the output bands. If the condition is not satisfied the values is set to NoData</LI>
57
 * 
58
 * <LI>Replicate-threshold:  A input layer, a threshold layer and a output layer. If the condition is satisfied.
59
 * the result layer replicates the output bands. If the condition is not satisfied the values is set to NoData</LI>
60
 * 
61
 * <LI>Transparent-oplayer: A input layer, an operator layer and a RGB output layer. If the condition is satisfied
62
 * the layer result replicates the output RGB with transparency values. If the condition is not satisfied 
63
 * the layer result only replicates the output RGB.</LI>
64
 * 
65
 * <LI>Transparent-threshold: A input layer, a threshold and a RGB output layer. If the condition is satisfied
66
 * the layer result replicates the output RGB with transparency values. If the condition is not satisfied 
67
 * the layer result only replicates the output RGB.</LI>
68
 * 
69
 * <LI>Opacity-oplayer: A input layer, an operator layer, a RGB output layer. If the condition is satisfied
70
 * the layer result replicates the output layer values and if not this pixels are set to transparent </LI>
71
 * 
72
 * <LI>Opacity-threshold: A input layer, an operator layer, a threshold. If the condition is satisfied
73
 * the layer result replicates the output layer values and if not this pixels are set to transparent </LI>
74
 * </UL>
75
 * 
76
 *
77
 * 10/12/2007
78
 * @author Nacho Brodin nachobrodin@gmail.com
79
 */
80
public class MaskthresholdProcess extends RasterProcess {
81
        //Possible input parameters
82
        public static String      RASTER_STORE1    = "RasterStore1";
83
        public static String      RASTER_STORE2    = "RasterStore2";
84
        public static String      RASTER_STORE3    = "RasterStore3";
85
        public static String      RASTER_BUFFER1   = "Buffer1";
86
        public static String      RASTER_BUFFER2   = "Buffer2";
87
        public static String      RASTER_BUFFER3   = "Buffer3";
88
        public static String      BAND1            = "Band1";
89
        public static String      BAND2            = "Band2";
90
        public static String      BAND3            = "Band3";
91
        public static String      THRESHOLD        = "Threshold";
92
        public static String      FIXED_VALUE      = "FixedValue";
93
        public static String      OPERATION        = "Operation";
94
        public static String      SATISFY_METHOD   = "Satisfy_Method";
95
        public static String      PATH             = "Path";
96
        
97
        //Possible output parameters
98
        public static String      BUFFER           = "Buffer";
99
        public static String      FILENAME         = "FileName";
100
        public static String      TIME             = "Time";
101
        
102
        public static String[]    MASK_OPERATIONS  = new String[]{"Greater", "Lower", 
103
                                                                      "GreaterOrEquals", "LoweOrEquals"};
104
        public static String[]    OUTPUT_METHODS   = new String[]{"NoData", "FixedValue", 
105
                                                                      "Transparency", "Opacity", 
106
                                                                      "LayerAndBandsSelected", "LayerAndBandsSelectedInverse"};
107
        
108
        private RasterDataStore   inputStore       = null;
109
        private RasterDataStore   operationStore   = null;
110
        private RasterDataStore   outputStore      = null;
111
        private Buffer            inputBuffer      = null;
112
        private Buffer            operationBuffer  = null;
113
        private Buffer            outputBuffer     = null;
114
        private int               band1            = 0;
115
        private int               band2            = 0;
116
        private int               band3            = 0; //-1 All
117
        private int               resultNumBands   = 0;
118
        
119
        private String            filename         = null; //If is null only returns a buffer
120
        private double            threshold        = 0;
121
        private double            fixedValue       = 0;
122
        private NoData            nodata           = null;
123
        private AbstractOperation operation        = null;
124
        private AbstractOperation opSatisfy        = null;
125
        private AbstractOperation opNotSatisfy     = null;
126
        private long              milis            = 0;
127
        private int               percent          = 0;
128
        private Buffer            resultBuffer     = null;
129
        
130
        public static void registerParameters() {
131
                RASTER_STORE1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE1, RasterDataStore.class);
132
                RASTER_STORE2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE2, RasterDataStore.class);
133
                RASTER_STORE3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_STORE3, RasterDataStore.class);
134
                
135
                RASTER_BUFFER1 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER1, Buffer.class);
136
                RASTER_BUFFER2 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER2, Buffer.class);
137
                RASTER_BUFFER3 = RasterBaseAlgorithmLibrary.registerInputParameter(RASTER_BUFFER3, Buffer.class);
138
                
139
                BAND1 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND1, Integer.class);
140
                BAND2 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND2, Integer.class);
141
                BAND3 = RasterBaseAlgorithmLibrary.registerInputParameter(BAND3, Integer.class);
142
                
143
                SATISFY_METHOD = RasterBaseAlgorithmLibrary.registerInputParameter(SATISFY_METHOD, Integer.class);
144
                
145
                THRESHOLD = RasterBaseAlgorithmLibrary.registerInputParameter(THRESHOLD, Double.class);
146
                FIXED_VALUE = RasterBaseAlgorithmLibrary.registerInputParameter(FIXED_VALUE, Double.class);
147
                OPERATION = RasterBaseAlgorithmLibrary.registerInputParameter(OPERATION, Integer.class);
148
                
149
                PATH = RasterBaseAlgorithmLibrary.registerInputParameter(PATH, String.class);
150
                FILENAME = RasterBaseAlgorithmLibrary.registerOutputParameter(FILENAME, String.class);
151
                BUFFER = RasterBaseAlgorithmLibrary.registerOutputParameter(BUFFER, Buffer.class);
152
        }
153
        
154
        /*
155
         * (non-Javadoc)
156
         * @see org.gvsig.rastertools.RasterProcess#init()
157
         */
158
        public void init() {
159
                inputStore = getParam(RASTER_STORE1) != null ? (RasterDataStore)getParam(RASTER_STORE1) : null; //M
160
                operationStore = getParam(RASTER_STORE2) != null ? (RasterDataStore)getParam(RASTER_STORE2) : null; //Default Null
161
                outputStore = getParam(RASTER_STORE3) != null ? (RasterDataStore)getParam(RASTER_STORE3) : null; //Default Null
162
                
163
                inputBuffer = getParam(RASTER_BUFFER1) != null ? (Buffer)getParam(RASTER_BUFFER1) : null;
164
                operationBuffer = getParam(RASTER_BUFFER2) != null ? (Buffer)getParam(RASTER_BUFFER2) : null;
165
                outputBuffer = getParam(RASTER_BUFFER3) != null ? (Buffer)getParam(RASTER_BUFFER3) : null;
166
                
167
                band1 = (Integer)getIntParam(BAND1); //Default 0
168
                band2 = (Integer)getIntParam(BAND2); //Default 0
169
                band3 = (Integer)getIntParam(BAND3); //Default 0
170
                
171
                int satisfy = (Integer)getIntParam(SATISFY_METHOD); //Default 0
172
                
173
                if(satisfy == 0) {
174
                        opSatisfy = new NoDataOp();
175
                        opNotSatisfy = new FixedValueOp();
176
                        resultNumBands = 1;
177
                }
178
                if(satisfy == 1) {
179
                        opSatisfy = new FixedValueOp();
180
                        opNotSatisfy = new NoDataOp();
181
                        resultNumBands = 1;
182
                }
183
                if(satisfy == 2) {
184
                        opSatisfy = new TransparencyOp();
185
                        opNotSatisfy = new OpacityOp();
186
                        resultNumBands = 4;
187
                }
188
                if(satisfy == 3) {
189
                        opSatisfy = new OpacityOp();
190
                        opNotSatisfy = new TransparencyOp();
191
                        resultNumBands = 4;
192
                }
193
                if(satisfy == 4) {
194
                        opSatisfy = new LayerOp();
195
                        opNotSatisfy = new NoDataOp();
196
                }
197
                if(satisfy == 5) {
198
                        opSatisfy = new NoDataOp();
199
                        opNotSatisfy = new LayerOp();
200
                }
201
                if(satisfy == 4 || satisfy == 5) {
202
                        if(outputStore != null)
203
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputStore.getBandCount();
204
                        if(outputBuffer != null)
205
                                resultNumBands = band3 >= 0 ? band3 + 1 : outputBuffer.getBandCount();
206
                }
207
                
208
                int op = (Integer)getIntParam(OPERATION); //Default 0
209
                if(op == 0)
210
                        operation = new Greater();
211
                if(op == 1)
212
                        operation = new Lower();
213
                if(op == 2)
214
                        operation = new GreaterOrEquals();
215
                if(op == 3)
216
                        operation = new LowerOrEquals();
217
                threshold = (Double)getDoubleParam(THRESHOLD); //Default 0
218
                fixedValue = (Double)getDoubleParam(FIXED_VALUE); //Default 0
219
                
220
                filename = getStringParam(PATH);
221
        }
222
        
223
        /**
224
         * M?todo donde se ejecutar? el Thread, aqu? se reproyecta el raster.
225
         */
226
        public void process() throws ProcessInterruptedException, ProcessException {
227
                long t1 = new java.util.Date().getTime();
228
                insertLineLog(Messages.getText("maskthreshold"));
229
                
230
                try {
231
                        if(inputStore != null)
232
                                checkStore();
233
                        else
234
                                checkBuffer();
235
                        
236
                        Rectangle2D[] pxBBox = null;
237
                        
238
                        if(inputStore != null) {
239
                                inputBuffer = readROBuffer(inputStore, band1);
240
                                RasterDataStore[] storeList = new RasterDataStore[]{inputStore, operationStore, outputStore};
241
                                pxBBox = getIntersectionInPxCoords(storeList);
242
                        } else {
243
                                pxBBox = new Rectangle2D[]{
244
                                        new Rectangle2D.Double(0, 0, inputBuffer.getWidth(), inputBuffer.getHeight())
245
                                        };
246
                        }
247
                        
248
                        if(operationStore != null) 
249
                                operationBuffer = readROBuffer(operationStore, band2);
250
                        
251
                        int dataType = Buffer.TYPE_DOUBLE;
252
                        
253
                        if(outputStore != null) { 
254
                                outputBuffer = readROBuffer(outputStore, band3);
255
                                dataType = outputBuffer.getDataType();
256
                        }
257
                        
258
                        resultBuffer = RasterLocator.getManager().createBuffer(
259
                                        dataType, 
260
                                        (int)pxBBox[0].getWidth(), 
261
                                        (int)pxBBox[0].getHeight(), 
262
                                        resultNumBands, true);
263
                        
264
                        write(resultBuffer, pxBBox);
265
                        
266
                        if(filename != null)
267
                                exportRaster(filename, resultBuffer, inputStore.getCellSize(), 
268
                                                inputStore.getExtent().getULX(), inputStore.getExtent().getULY());
269

    
270
                        long t2 = new java.util.Date().getTime();
271
                        milis = t2 - t1;
272
                        
273
                        SwingUtilities.invokeLater(new Runnable() {
274
                                public void run() {
275
                                        if (externalActions != null) {
276
                                                HashMap<String, Object> map = new HashMap<String, Object>();
277
                                                map.put(FILENAME, filename);
278
                                                map.put(BUFFER, resultBuffer);
279
                                                map.put(TIME, new Long(milis));
280
                                                externalActions.end(map);
281
                                        }
282
                                }
283
                        });
284
                } catch (MaskthresholdException e) {
285
                        if (incrementableTask != null)
286
                                incrementableTask.processFinalize();
287
                        messageBoxError("error_reprojecting", this, e);
288
                } finally {
289
                        if (incrementableTask != null) {
290
                                incrementableTask.processFinalize();
291
                                setProgressActive(false);
292
                        }
293
                }
294
        }
295
        
296
        /**
297
         * Checks input parameters for DataStores
298
         * @throws MaskthresholdException
299
         */
300
        private void checkStore() throws MaskthresholdException {
301
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
302
                                (outputStore == null || outputStore.getBandCount() < 3 || outputStore.getDataType()[0] != Buffer.TYPE_BYTE)) {
303
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
304
                }
305

    
306
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
307
                                outputStore == null)
308
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
309

    
310
                if (inputStore == null)
311
                        throw new MaskthresholdException("Layer not valid");
312
                
313
                if(operationStore != null) {
314
                        if(!inputStore.getExtent().intersects(operationStore.getExtent()))
315
                                throw new MaskthresholdException("Extents don't intersect");
316
                        if(inputStore.getCellSize() != operationStore.getCellSize())
317
                                throw new MaskthresholdException("Cell sizes are not equal");
318
                }
319
        }
320
        
321
        /**
322
         * Checks input parameters for Buffers
323
         * @throws MaskthresholdException
324
         */
325
        private void checkBuffer() throws MaskthresholdException {
326
                if(opSatisfy instanceof TransparencyOp || opSatisfy instanceof OpacityOp && 
327
                                (outputBuffer == null || outputBuffer.getBandCount() < 3 || outputBuffer.getDataType() != Buffer.TYPE_BYTE)) {
328
                        throw new MaskthresholdException("Not valid parameters. Transparency method have 3 output bands");
329
                }
330

    
331
                if((opSatisfy instanceof LayerOp || opNotSatisfy instanceof LayerOp) && 
332
                                outputBuffer == null)
333
                        throw new MaskthresholdException("Not valid parameters. Layer method have output data store");
334

    
335
                if (inputBuffer == null)
336
                        throw new MaskthresholdException("Layer not valid");
337
                
338
                if(outputBuffer != null && 
339
                  ((inputBuffer.getWidth() != outputBuffer.getWidth()) || 
340
                   (inputBuffer.getHeight() != outputBuffer.getHeight()) ||
341
                   (inputStore.getCellSize() != outputStore.getCellSize())) )
342
                        throw new MaskthresholdException("Buffer sizes not valid");
343
        }
344
        
345
        /**
346
         * Reads a band of a buffer
347
         * @param store
348
         * @param band
349
         * @return
350
         * @throws MaskthresholdException
351
         * @throws ProcessInterruptedException
352
         */
353
        private Buffer readROBuffer(RasterDataStore store, int band) throws MaskthresholdException, ProcessInterruptedException {
354
                RasterQuery query = RasterLocator.getManager().createQuery();
355
                if(band >= 0 && band < store.getBandCount())
356
                        query.setDrawableBands(new int[]{band});
357
                else
358
                        query.setAllDrawableBands();
359
                query.setReadOnly(true);
360
                query.setAreaOfInterest();
361
                
362
                try {
363
                        return store.query(query);
364
                } catch (RasterDriverException e) {
365
                        throw new MaskthresholdException("Error reading input raster.");
366
                } catch (InvalidSetViewException e) {
367
                        throw new MaskthresholdException("Error reading input raster.");
368
                }
369
        }
370
        
371
        private void write(Buffer result, Rectangle2D[] pxBbox) {
372
                if(nodata == null)
373
                        nodata = RasterLocator.getManager().getDataStructFactory().createDefaultNoData(1, result.getDataType());
374
                int colSource = (int)pxBbox[0].getX();
375
                int rowSource = (int)pxBbox[0].getY();
376
                int colOperation = colSource;
377
                int rowOperation = rowSource;
378
                if(pxBbox.length > 1) {
379
                        colOperation = (int)pxBbox[1].getX();
380
                        rowOperation = (int)pxBbox[1].getY();
381
                }
382

    
383
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
384
                opSatisfy.result = opNotSatisfy.result = result;
385
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
386
                opSatisfy.band = opNotSatisfy.band = band3;
387

    
388
                for (int row = 0; row < result.getHeight(); row++) {
389
                        if(pxBbox.length > 1) {
390
                                colOperation = (int)pxBbox[1].getX();
391
                                colSource = (int)pxBbox[0].getX();
392
                        }
393
                        colSource = 0;
394
                        for (int col = 0; col < result.getWidth(); col++) {
395
                                double op1 = getValue(inputBuffer, rowSource, colSource);
396
                                double op2 = getValue(operationBuffer, rowOperation, colOperation);
397
                                if(operation.compare(op1, op2)) {
398
                                        opSatisfy.row = row;
399
                                        opSatisfy.col = col;
400
                                        opSatisfy.invoke();
401
                                } else {
402
                                        opNotSatisfy.row = row;
403
                                        opNotSatisfy.col = col;
404
                                        opNotSatisfy.invoke();
405
                                }
406
                                colSource ++;
407
                                colOperation++;
408
                        }
409
                        rowSource ++;
410
                        rowOperation ++;
411
                        percent = (int)((row * 100) / result.getHeight());
412
                }
413
        }
414

    
415
        /**
416
         * Gets the operation value in using a double value. If there is a operation data store then
417
         * returns the value of the pixel in this position else it returns a threshold value
418
         * @param operationBuffer
419
         * @param rowOperation
420
         * @param colOperation
421
         * @return
422
         */
423
        private double getValue(Buffer buf, int rowOperation, int colOperation) {
424
                if(buf == null)
425
                        return threshold;
426
                if(buf.getDataType() == Buffer.TYPE_BYTE)
427
                        return buf.getElemByte(rowOperation, colOperation, 0);
428
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
429
                        return buf.getElemFloat(rowOperation, colOperation, 0);
430
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
431
                        return buf.getElemDouble(rowOperation, colOperation, 0);
432
                if(buf.getDataType() == Buffer.TYPE_SHORT)
433
                        return buf.getElemShort(rowOperation, colOperation, 0);
434
                if(buf.getDataType() == Buffer.TYPE_INT)
435
                        return buf.getElemInt(rowOperation, colOperation, 0);
436
                return 0;
437
        }
438
        
439
        /*
440
         * (non-Javadoc)
441
         * @see org.gvsig.raster.tools.app.basic.raster.process.RasterProcess#getResult()
442
         */
443
        public Object getResult() {
444
                HashMap<String, Object> map = new HashMap<String, Object>();
445
                map.put(FILENAME, filename);
446
                map.put(BUFFER, resultBuffer);
447
                map.put(TIME, new Long(milis));
448
                return map;
449
        }
450

    
451
        /*
452
         * (non-Javadoc)
453
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getPercent()
454
         */
455
        public int getPercent() {
456
                return percent;
457
        }
458

    
459
        /*
460
         * (non-Javadoc)
461
         * @see org.gvsig.gui.beans.incrementabletask.IIncrementable#getTitle()
462
         */
463
        public String getTitle() {
464
                return Messages.getText("maskthreshold");
465
        }
466
        
467
        abstract class AbstractOperation implements Operation {
468
                public int       row          = 0;
469
                public int       col          = 0;
470
                public Buffer    result       = null;
471
                public double    fixedValue   = 0;
472
                public Buffer    outBuffer   = null;
473
                public int       band         = 0;
474
                
475
                public void invoke() {
476
                        
477
                }
478
                public boolean compare(double a, double b) {
479
                        return false;
480
                }
481
        }
482
        
483
        class LayerOp extends AbstractOperation {
484
                public void invoke() {
485
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
486
                                if(band < 0) {
487
                                        for (int i = 0; i < result.getBandCount(); i++) {
488
                                                byte vSource = outBuffer.getElemByte(row, col, i);
489
                                                result.setElem(row, col, i, vSource);
490
                                        }
491
                                } else {
492
                                        byte vSource = outBuffer.getElemByte(row, col, band);
493
                                        result.setElem(row, col, band, vSource);
494
                                }
495
                        } else if(result.getDataType() == Buffer.TYPE_FLOAT) {
496
                                if(band < 0) {
497
                                        for (int i = 0; i < result.getBandCount(); i++) {
498
                                                float vSource = outBuffer.getElemFloat(row, col, i);
499
                                                result.setElem(row, col, i, vSource);
500
                                        }
501
                                } else {
502
                                        float vSource = outBuffer.getElemFloat(row, col, band);
503
                                        result.setElem(row, col, band, vSource);
504
                                }
505
                        } else if(result.getDataType() == Buffer.TYPE_DOUBLE) {
506
                                if(band < 0) {
507
                                        for (int i = 0; i < result.getBandCount(); i++) {
508
                                                double vSource = outBuffer.getElemDouble(row, col, i);
509
                                                result.setElem(row, col, i, vSource);
510
                                        }
511
                                } else {
512
                                        double vSource = outBuffer.getElemDouble(row, col, band);
513
                                        result.setElem(row, col, band, vSource);
514
                                }
515
                        } else if(result.getDataType() == Buffer.TYPE_SHORT) {
516
                                if(band < 0) {
517
                                        for (int i = 0; i < result.getBandCount(); i++) {
518
                                                float vSource = outBuffer.getElemShort(row, col, i);
519
                                                result.setElem(row, col, i, vSource);
520
                                        }
521
                                } else {
522
                                        float vSource = outBuffer.getElemShort(row, col, band);
523
                                        result.setElem(row, col, band, vSource);
524
                                }
525
                        } else if(result.getDataType() == Buffer.TYPE_INT) {
526
                                if(band < 0) {
527
                                        for (int i = 0; i < result.getBandCount(); i++) {
528
                                                int vSource = outBuffer.getElemInt(row, col, i);
529
                                                result.setElem(row, col, i, vSource);
530
                                        }
531
                                } else {
532
                                        int vSource = outBuffer.getElemInt(row, col, band);
533
                                        result.setElem(row, col, band, vSource);
534
                                }
535
                        }
536
                }
537
        }
538
        
539
        class TransparencyOp extends AbstractOperation {
540
                public void invoke() {
541
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
542
                                for (int i = 0; i < 3; i++) {
543
                                        byte vSource = outBuffer.getElemByte(row, col, i);
544
                                        result.setElem(row, col, i, vSource);
545
                                }
546
                                result.setElem(row, col, 4, (byte)0);
547
                        }
548
                }
549
        }
550
        
551
        class OpacityOp extends AbstractOperation {
552
                public void invoke() {
553
                        if(result.getDataType() == Buffer.TYPE_BYTE) {
554
                                for (int i = 0; i < 3; i++) {
555
                                        byte vSource = outBuffer.getElemByte(row, col, i);
556
                                        result.setElem(row, col, i, vSource);
557
                                }
558
                                result.setElem(row, col, 4, (byte)255);
559
                        }
560
                }
561
        }
562

    
563
        class FixedValueOp extends AbstractOperation {
564
                public void invoke() {
565
                        if(result.getDataType() == Buffer.TYPE_BYTE)
566
                                result.setElem(row, col, 0, (byte)fixedValue);
567
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
568
                                result.setElem(row, col, 0, (float)fixedValue);
569
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
570
                                result.setElem(row, col, 0, fixedValue);
571
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
572
                                result.setElem(row, col, 0, (short)fixedValue);
573
                        else if(result.getDataType() == Buffer.TYPE_INT)
574
                                result.setElem(row, col, 0, (int)fixedValue);
575
                }
576
        }
577
        
578
        class NoDataOp extends AbstractOperation {
579
                public void invoke() {
580
                        if(result.getDataType() == Buffer.TYPE_BYTE)
581
                                if(band < 0) {
582
                                        for (int i = 0; i < result.getBandCount(); i++) {
583
                                                result.setElem(row, col, i, nodata.getValue().byteValue());
584
                                        }
585
                                } else {
586
                                        result.setElem(row, col, band, nodata.getValue().byteValue());
587
                                }
588
                        else if(result.getDataType() == Buffer.TYPE_FLOAT)
589
                                if(band < 0) {
590
                                        for (int i = 0; i < result.getBandCount(); i++) {
591
                                                result.setElem(row, col, i, nodata.getValue().floatValue());
592
                                        }
593
                                } else {
594
                                        result.setElem(row, col, band, nodata.getValue().floatValue());
595
                                }
596
                        else if(result.getDataType() == Buffer.TYPE_DOUBLE)
597
                                if(band < 0) {
598
                                        for (int i = 0; i < result.getBandCount(); i++) {
599
                                                result.setElem(row, col, i, nodata.getValue().doubleValue());
600
                                        }
601
                                } else {
602
                                        result.setElem(row, col, band, nodata.getValue().doubleValue());
603
                                }
604
                        else if(result.getDataType() == Buffer.TYPE_SHORT)
605
                                if(band < 0) {
606
                                        for (int i = 0; i < result.getBandCount(); i++) {
607
                                                result.setElem(row, col, i, nodata.getValue().shortValue());
608
                                        }
609
                                } else {
610
                                        result.setElem(row, col, band, nodata.getValue().shortValue());
611
                                }
612
                        else if(result.getDataType() == Buffer.TYPE_INT)
613
                                if(band < 0) {
614
                                        for (int i = 0; i < result.getBandCount(); i++) {
615
                                                result.setElem(row, col, i, nodata.getValue().intValue());
616
                                        }
617
                                } else {
618
                                        result.setElem(row, col, band, nodata.getValue().intValue());
619
                                }
620
                }
621
        }
622

    
623
        class Greater extends AbstractOperation {
624
                public boolean compare(double a, double b) {
625
                        return a > b;
626
                }
627
        }
628

    
629
        class Lower extends AbstractOperation {
630
                public boolean compare(double a, double b) {
631
                        return a < b;
632
                }
633
        }
634

    
635
        class GreaterOrEquals extends AbstractOperation {
636
                public boolean compare(double a, double b) {
637
                        return a >= b;
638
                }
639
        }
640

    
641
        class LowerOrEquals extends AbstractOperation {
642
                public boolean compare(double a, double b) {
643
                        return a <= b;
644
                }
645
        }
646
}