Statistics
| Revision:

gvsig-raster / org.gvsig.raster / tags / 2.0.0 / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / grid / render / ImageDrawerImpl.java @ 1708

History | View | Annotate | Download (15.7 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.impl.grid.render;
23

    
24
import java.awt.Image;
25
import java.awt.image.BufferedImage;
26

    
27
import org.gvsig.fmap.dal.coverage.RasterLocator;
28
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
29
import org.gvsig.fmap.dal.coverage.datastruct.Extent;
30
import org.gvsig.fmap.dal.coverage.exception.FileNotOpenException;
31
import org.gvsig.fmap.dal.coverage.exception.FilterTypeException;
32
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
33
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
34
import org.gvsig.fmap.dal.coverage.grid.RasterFilterList;
35
import org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer;
36
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
37
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
38
import org.gvsig.raster.impl.DefaultRasterManager;
39
import org.gvsig.raster.impl.buffer.RasterBuffer;
40
import org.gvsig.raster.impl.grid.filter.enhancement.DefaultLinearStretchParams;
41
import org.gvsig.raster.impl.grid.filter.enhancement.EnhancementStretchListManager;
42
import org.gvsig.raster.impl.process.RasterTask;
43
import org.gvsig.raster.impl.process.RasterTaskQueue;
44
import org.slf4j.LoggerFactory;
45

    
46
/**
47
 * Objeto para la escritura de datos desde un buffer a un objeto Image. En este nivel de
48
 * renderizado no se gestiona extents, ni rotaciones ni coordenadas del mundo, solo la
49
 * escritura desde un buffer hasta otro de tama?o dado. Por medio de par?metros y de objetos
50
 * de estado varia el resultado de la escritura, selecci?n de bandas a escribir desde el buffer
51
 * a RGB, transparencias aplicadas o paletas.
52
 *
53
 * @author Nacho Brodin (nachobrodin@gmail.com)
54
 */
55
public class ImageDrawerImpl implements ImageDrawer {
56
        private Buffer        rasterBuf             = null;
57
        private double[]      step                  = null;
58
        private int           width                 = -1;
59
        private int           height                = -1;
60
        private double        scaleX                = 1; //rate between input and output buffer
61
        private double        scaleY                = 1; 
62
        private Transparency  transparency          = null;
63
        
64
        public ImageDrawerImpl() {
65
        }
66
        
67
        /*
68
         * (non-Javadoc)
69
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setLastTransparency(org.gvsig.fmap.dal.coverage.store.props.Transparency)
70
         */
71
        public void setLastTransparency(Transparency t) {
72
                this.transparency = t;
73
        }
74

    
75
        /*
76
         * (non-Javadoc)
77
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#drawBufferOverImageObject()
78
         */
79
        public Image drawBufferOverImageObject() throws ProcessInterruptedException {
80
                if (rasterBuf == null)
81
                        return null;
82

    
83
                try { // Temporal para la traza de un error aleatorio
84
                        boolean supersamplingOn = false;
85
                        BufferedImage image = null;
86
                        if(width <= 0 && height <= 0) {
87
                                width = rasterBuf.getWidth();
88
                                height = rasterBuf.getHeight();
89
                                scaleX = scaleY = 1;
90
                        } else {
91
                                scaleX = rasterBuf.getWidth() / width;
92
                                scaleY = rasterBuf.getHeight() / height;
93
                        }
94
                        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
95
                        
96
                        if(step != null) {
97
                                supersamplingOn = true;
98
                        }
99

    
100
                        if (rasterBuf.getDataType() != Buffer.TYPE_BYTE)
101
                                rasterBuf = convertToByte(rasterBuf);
102

    
103
                        byte[] data = new byte[rasterBuf.getBandCount()];
104

    
105
                        if (transparency != null && transparency.isTransparencyActive()) {
106
                                if (transparency.existAlphaBand() && 
107
                                        transparency.getAlphaBand() != null && 
108
                                        transparency.getAlphaBand().getDataType() != Buffer.TYPE_BYTE) {
109
                                        transparency.setAlphaBand(convertToByte(transparency.getAlphaBand()));
110
                                }
111
                                drawWithTransparency(image, data, supersamplingOn, transparency);
112
                        } else
113
                                drawByte(image, data, supersamplingOn);
114

    
115
                        step = null;
116
                        return image;
117
                } catch (OutOfMemoryError error) { // Temporal para la traza de un error
118
                                                                                        // aleatorio
119
                        LoggerFactory.getLogger(this.getClass()).debug(
120
                                        "Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , error);
121
                }
122
                return null;
123
        }
124

    
125
        /**
126
         * Calcula los vectores de desplazamiento en pixels en X e Y cuando se supersamplea.
127
         * @param r Array de desplazamientos para las filas. Debe tener espacio reservado
128
         * @param c Array de desplazamientos para las columnas. Debe tener espacio reservado
129
         * cargados.
130
         */
131
        private void calcSupersamplingStepsArrays(int[] r, int[] c) {
132
                double pos = step[1];
133
                for(int row = 0; row < r.length; row ++) {
134
                        r[row] = (int)(pos / step[3]);
135
                        pos ++;
136
                }
137
                pos = step[0];
138
                for(int col = 0; col < c.length; col ++) {
139
                        c[col] = (int)(pos / step[2]);
140
                        pos ++;
141
                }
142
        }
143

    
144
        /**
145
         * Dibuja un raster sobre un BufferedImage
146
         * @param image BufferedImage sobre el que se dibuja
147
         * @param data buffer vacio. Se trata de un array de bytes donde cada elemento representa una banda.
148
         * @param supersampling true si se necesita supersamplear y false si no se necesita
149
         * @throws ProcessInterruptedException
150
         */
151
        private void drawByte(BufferedImage image, byte[] data, boolean supersampling) throws ProcessInterruptedException {
152
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
153
                try {
154
                        if (supersampling) {
155
                                int[] r = new int[height];
156
                                int[] c = new int[width];
157
                                calcSupersamplingStepsArrays(r, c);
158
                                for (int row = 0; row < height; row++) {
159
                                        for (int col = 0; col < width; col++)
160
                                                try {
161
                                                        rasterBuf.getElemByte(r[row], c[col], data);
162
                                                        image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
163
                                                                        + ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
164
                                                } catch (ArrayIndexOutOfBoundsException e) {
165
                                                        System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
166
                                                        System.err.println("== Position required:" + col + " " + row);
167
                                                        break;
168
                                                }
169
                                                if (task.getEvent() != null)
170
                                                        task.manageEvent(task.getEvent());
171
                                }
172
                        } else {
173
                                /*Old code
174
                          for (int row = 0; row < rasterBuf.getHeight(); row++) {
175
                                for (int col = 0; col < rasterBuf.getWidth(); col++)
176
                                        try {
177
                                                rasterBuf.getElemByte(row, col, data);
178
                                                image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
179
                                                                + ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
180
                                        } catch (ArrayIndexOutOfBoundsException ex) {
181
                                                System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
182
                                                System.err.println("== Position required:" + col + " " + row);
183
                                                break;
184
                                        }
185
                                if (task.getEvent() != null)
186
                                        task.manageEvent(task.getEvent());
187
                        }*/
188
                                for (int row = 0; row < height; row++) {
189
                                        for (int col = 0; col < width; col++) {
190
                                                try {
191
                                                        rasterBuf.getElemByte((int)(row * scaleY), (int)(col * scaleX), data);
192
                                                        image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
193
                                                                        + ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
194
                                                } catch (ArrayIndexOutOfBoundsException ex) {
195
                                                        System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
196
                                                        System.err.println("== Position required:" + (int)(col * scaleX) + " " + (int)(row * scaleY));
197
                                                        break;
198
                                                }
199
                                        }
200
                                        if (task.getEvent() != null)
201
                                                task.manageEvent(task.getEvent());
202
                                }
203
                        }
204
                } catch (Exception e) {
205
                        LoggerFactory.getLogger(this.getClass()).info(
206
                                        "Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , e);
207
                }
208
        }
209

    
210
        /**
211
         * Dibuja un raster sobre un BufferedImage con las propiedades de paleta y transparencia
212
         * @param image BufferedImage sobre el que se dibuja
213
         * @param data buffer vacio. Se trata de un array de bytes donde cada elemento representa una banda.
214
         * @param supersampling true si se necesita supersamplear y false si no se necesita
215
         * @throws ProcessInterruptedException
216
         */
217
        private void drawWithTransparency(BufferedImage image, 
218
                        byte[] data, 
219
                        boolean supersampling,
220
                        Transparency t) throws ProcessInterruptedException {
221
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
222
                int value = 0;
223
                try {
224
                        if (supersampling) {
225
                                int[] r = new int[height];
226
                                int[] c = new int[width];
227
                                calcSupersamplingStepsArrays(r, c);
228
                                for (int row = 0; row < height; row++) {
229
                                        for (int col = 0; col < width; col++)
230
                                                try {
231
                                                        rasterBuf.getElemByte(r[row], c[col], data);
232
                                                        value = t.processRGB(data[0] & 0xff, data[1] & 0xff, data[2] & 0xff, r[row], c[col]);
233
                                                        image.setRGB(col, row, value);
234
                                                } catch (ArrayIndexOutOfBoundsException e) {
235
                                                        System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
236
                                                        System.err.println("== Position required:" + col + " " + row);
237
                                                        break;
238
                                                }
239
                                                if (task.getEvent() != null)
240
                                                        task.manageEvent(task.getEvent());
241
                                }
242
                        } else {
243
                                /*Old code
244
                        for (int row = 0; row < rasterBuf.getHeight(); row++) {
245
                                for (int col = 0; col < rasterBuf.getWidth(); col++)
246
                                        try {
247
                                                rasterBuf.getElemByte(row, col, data);
248
                                                value = t.processRGB(data[0] & 0xff, data[1] & 0xff, data[2] & 0xff, row, col);
249
                                                image.setRGB(col, row, value);
250
                                        } catch (ArrayIndexOutOfBoundsException e) {
251
                                                System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
252
                                                System.err.println("== Position required:" + col + " " + row);
253
                                                break;
254
                                        }
255
                                if (task.getEvent() != null)
256
                                        task.manageEvent(task.getEvent());
257
                        }
258
                                 */
259
                                for (int row = 0; row < height; row++) {
260
                                        for (int col = 0; col < width; col++) {
261
                                                try {
262
                                                        int r = (int)(row * scaleY);
263
                                                        int c = (int)(col * scaleX);
264
                                                        rasterBuf.getElemByte(r, c, data);
265
                                                        value = t.processRGB(data[0] & 0xff, data[1] & 0xff, data[2] & 0xff, r, c);
266
                                                        image.setRGB(col, row, value);
267
                                                } catch (ArrayIndexOutOfBoundsException e) {
268
                                                        System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
269
                                                        System.err.println("== Position required:" + col + " " + row);
270
                                                        break;
271
                                                }  //catch (Exception e) {
272
                                                //System.out.println("Row:" + (int)(row * scaleY) + " Col:" + (int)(col * scaleX) + " " + rasterBuf.getBandCount() + " " + data.length);
273
                                                //}
274
                                        }
275
                                        if (task.getEvent() != null)
276
                                                task.manageEvent(task.getEvent());
277
                                }
278

    
279
                        }
280
                } catch (Exception e) {
281
                        LoggerFactory.getLogger(this.getClass()).info(
282
                                        "Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , e);
283
                }
284
        }        
285

    
286
        /**
287
         * Converts a Buffer object into a byte
288
         * @param buf
289
         * @return
290
         */
291
        private Buffer convertToByte(Buffer buf) {
292
                Buffer b = DefaultRasterManager.getInstance().createBuffer(Buffer.TYPE_BYTE, buf.getWidth(), buf.getHeight(), buf.getBandCount(), true);
293
                if(buf.getDataType() == Buffer.TYPE_SHORT)
294
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
295
                                for (int row = 0; row < buf.getHeight(); row++)
296
                                        for (int col = 0; col < buf.getWidth(); col++)
297
                                                b.setElem(row, col, nBand, (byte)(buf.getElemShort(row, col, nBand) & 0xffff));
298
                if(buf.getDataType() == Buffer.TYPE_INT)
299
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
300
                                for (int row = 0; row < buf.getHeight(); row++)
301
                                        for (int col = 0; col < buf.getWidth(); col++)
302
                                                b.setElem(row, col, nBand, (byte)(buf.getElemInt(row, col, nBand) & 0xffffffff));
303
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
304
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
305
                                for (int row = 0; row < buf.getHeight(); row++)
306
                                        for (int col = 0; col < buf.getWidth(); col++)
307
                                                b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemFloat(row, col, nBand))));
308
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
309
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
310
                                for (int row = 0; row < buf.getHeight(); row++)
311
                                        for (int col = 0; col < buf.getWidth(); col++)
312
                                                b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemDouble(row, col, nBand))));
313
                return b;
314
        }
315

    
316
        /*
317
         * (non-Javadoc)
318
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setBuffer(org.gvsig.fmap.dal.coverage.dataset.Buffer)
319
         */
320
        public void setBuffer(Buffer b) {
321
                this.rasterBuf = b;
322
        }
323

    
324
        /*
325
         * (non-Javadoc)
326
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setSupersamplingOn(double[], int, int)
327
         */
328
        public void setSupersamplingOn(double[] step) {
329
                this.step = step;
330
        }
331

    
332
        /*
333
         * (non-Javadoc)
334
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setOutPutSize(int, int)
335
         */
336
        public void setOutputSize(int w, int h) {
337
                this.width = w;
338
                this.height = h;
339
        }
340
        
341
        /*
342
         * (non-Javadoc)
343
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#dispose()
344
         */
345
        public void dispose() {
346
                if(rasterBuf != null)
347
                        rasterBuf.dispose();
348
                if(transparency != null)
349
                        transparency.dispose();
350
                try {
351
                        finalize();
352
                } catch (Throwable e) {
353
                }
354
        }
355
        
356
        /*
357
         * (non-Javadoc)
358
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#addEnhanced(org.gvsig.fmap.dal.coverage.store.props.Statistics)
359
         */
360
        public Buffer addEnhanced(Statistics stats) {
361
                return addEnhanced(stats, true, 0.0);
362
        }
363

    
364
        /*
365
         * (non-Javadoc)
366
         * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#addEnhanced(org.gvsig.fmap.dal.coverage.store.props.Statistics)
367
         */
368
        public Buffer addEnhanced(Statistics stats, boolean tailTrim, double tailTrimValue) {
369
                RasterFilterList filterList = RasterLocator.getManager().createEmptyFilterList(rasterBuf.getDataType());
370

    
371
                try {
372
                        /*RasterFilterListManager enhancementManager = filterList.getManagerByID("EnhancementStretch");
373
                        Params params = filterList.createEmptyFilterParams();
374
                        params.setParam("stats", stats);
375
                        params.setParam("remove", new Boolean(false));
376
                        int[] renderBands = new int[rasterBuf.getBandCount()];
377
                        for (int i = 0; i < renderBands.length; i++) {
378
                                renderBands[i] = i;
379
                        }
380
                        params.setParam("renderBands", renderBands);
381
                        params.setParam("stretchs", null);//coge el LinearStretchParams por defecto
382
                        params.setParam("rgb", new Boolean(true));
383

384
                        enhancementManager.addFilter(params);
385
                         */
386
                        EnhancementStretchListManager enhancementManager = (EnhancementStretchListManager) filterList.getManagerByClass(EnhancementStretchListManager.class);
387
                        int[] renderBands = new int[rasterBuf.getBandCount()];
388
                        for (int i = 0; i < renderBands.length; i++) {
389
                                renderBands[i] = i;
390
                        }
391
                        enhancementManager.addEnhancedStretchFilter(
392
                                        DefaultLinearStretchParams.createStandardParam(new int[] { 0, 1, 2 }, tailTrimValue, stats, true), 
393
                                        stats, 
394
                                        renderBands, 
395
                                        tailTrim);
396
                } catch (FilterTypeException e1) {
397
                } catch (FileNotOpenException e) {
398
                } catch (RasterDriverException e) {
399
                }
400

    
401
                if(filterList != null) {
402
                        Extent ext = RasterLocator.getManager().getDataStructFactory().
403
                                createExtent(rasterBuf.getDataExtent());
404
                        filterList.addEnvParam("IStatistics", stats);
405
                        filterList.addEnvParam("Transparency", transparency);
406
                        filterList.addEnvParam("GridExtent", ext);
407
                        filterList.addEnvParam("WindowExtent", ext);
408
                        filterList.setInitRasterBuf(rasterBuf);
409
                        try {
410
                                filterList.execute();
411
                        } catch (ProcessInterruptedException e) {
412
                                return rasterBuf;
413
                        }
414
                        rasterBuf = (RasterBuffer) filterList.getResult();
415
                }
416
                return rasterBuf;
417
        }
418
        
419
        /*
420
         * (non-Javadoc)
421
         * @see java.lang.Object#finalize()
422
         */
423
        protected void finalize() throws Throwable {
424
                step        = null;
425
                rasterBuf   = null;
426
                transparency = null;
427
                super.finalize();
428
        }
429

    
430
}