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 @ 1319

History | View | Annotate | Download (24 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.io.File;
26
import java.util.HashMap;
27

    
28
import javax.swing.SwingUtilities;
29

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

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

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

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

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

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

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

    
385
                opSatisfy.fixedValue = opNotSatisfy.fixedValue = fixedValue;
386
                opSatisfy.result = opNotSatisfy.result = result;
387
                opSatisfy.outBuffer = opNotSatisfy.outBuffer = outputBuffer;
388
                opSatisfy.band = opNotSatisfy.band = band3;
389

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

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

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

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

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

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

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

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

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