Statistics
| Revision:

gvsig-raster / org.gvsig.raster / branches / org.gvsig.raster_dataaccess_refactoring / org.gvsig.raster.lib / org.gvsig.raster.lib.impl / src / main / java / org / gvsig / raster / impl / grid / render / ImageDrawerImpl.java @ 2338

History | View | Annotate | Download (12.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.exception.FileNotOpenException;
30
import org.gvsig.fmap.dal.coverage.exception.FilterTypeException;
31
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
32
import org.gvsig.fmap.dal.coverage.exception.RasterDriverException;
33
import org.gvsig.fmap.dal.coverage.filter.FilterLoader;
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.grid.filter.enhancement.DefaultLinearStretchParams;
40
import org.gvsig.raster.impl.grid.filter.enhancement.EnhancementStretchListManager;
41
import org.gvsig.raster.impl.process.RasterTask;
42
import org.gvsig.raster.impl.process.RasterTaskQueue;
43
import org.slf4j.Logger;
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 Logger        log                   = LoggerFactory.getLogger(ImageDrawerImpl.class);
57
        private Buffer        rasterBuf             = null;
58
        private double[]      step                  = null;
59
        private int           width                 = -1;
60
        private int           height                = -1;
61
        private double        scaleX                = 1; //rate between input and output buffer
62
        private double        scaleY                = 1; 
63
        private Transparency  transparency          = null;
64
        
65
        public ImageDrawerImpl() {
66
        }
67
        
68
        public void setLastTransparency(Transparency t) {
69
                this.transparency = t;
70
        }
71

    
72
        public Image drawBufferOverImageObject() throws ProcessInterruptedException {
73
                if (rasterBuf == null)
74
                        return null;
75

    
76
                try { // Temporal para la traza de un error aleatorio
77
                        boolean supersamplingOn = false;
78
                        BufferedImage image = null;
79
                        if(width <= 0 && height <= 0) {
80
                                width = rasterBuf.getWidth();
81
                                height = rasterBuf.getHeight();
82
                                scaleX = scaleY = 1;
83
                        } else {
84
                                scaleX = rasterBuf.getWidth() / width;
85
                                scaleY = rasterBuf.getHeight() / height;
86
                        }
87
                        image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
88
                        
89
                        if(step != null) {
90
                                supersamplingOn = true;
91
                        }
92

    
93
                        //En el caso de que llegue un buffer que no sea byte es que no se ha aplicado 
94
                        //filtro de realce por lo que habr? que hacer una conversi?n a byte de cualquier manera
95
                        //para que se muestre algo.
96
                        if (rasterBuf.getDataType() != Buffer.TYPE_BYTE)
97
                                rasterBuf = convertToByte(rasterBuf);
98

    
99
                        if (transparency != null && transparency.isTransparencyActive()) {
100
                                drawWithTransparency(image, supersamplingOn, transparency);
101
                        } else
102
                                drawByte(image, supersamplingOn);
103

    
104
                        step = null;
105
                        return image;
106
                } catch (OutOfMemoryError error) { // Temporal para la traza de un error
107
                                                                                        // aleatorio
108
                        log.debug("Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , error);
109
                }
110
                return null;
111
        }
112

    
113
        /**
114
         * Calcula los vectores de desplazamiento en pixels en X e Y cuando se supersamplea.
115
         * @param r Array de desplazamientos para las filas. Debe tener espacio reservado
116
         * @param c Array de desplazamientos para las columnas. Debe tener espacio reservado
117
         * cargados.
118
         */
119
        private void calcSupersamplingStepsArrays(int[] r, int[] c) {
120
                double pos = step[1];
121
                for(int row = 0; row < r.length; row ++) {
122
                        r[row] = (int)(pos / step[3]);
123
                        pos ++;
124
                }
125
                pos = step[0];
126
                for(int col = 0; col < c.length; col ++) {
127
                        c[col] = (int)(pos / step[2]);
128
                        pos ++;
129
                }
130
        }
131

    
132
        /**
133
         * Dibuja un raster sobre un BufferedImage
134
         * @param image BufferedImage sobre el que se dibuja
135
         * @param data buffer vacio. Se trata de un array de bytes donde cada elemento representa una banda.
136
         * @param supersampling true si se necesita supersamplear y false si no se necesita
137
         * @throws ProcessInterruptedException
138
         */
139
        private void drawByte(BufferedImage image, boolean supersampling) throws ProcessInterruptedException {
140
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
141
                try {
142
                        byte[] data = new byte[rasterBuf.getBandCount()];
143
                        
144
                        if (supersampling) {
145
                                int[] r = new int[height];
146
                                int[] c = new int[width];
147
                                calcSupersamplingStepsArrays(r, c);
148
                                for (int row = 0; row < height; row++) {
149
                                        for (int col = 0; col < width; col++)
150
                                                try {
151
                                                        rasterBuf.getElemByte(r[row], c[col], data);
152
                                                        image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
153
                                                                        + ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
154
                                                } catch (ArrayIndexOutOfBoundsException e) {
155
                                                        log.info("== Size Image:" + image.getWidth() + " " + image.getHeight());
156
                                                        log.info("== Position required:" + col + " " + row);
157
                                                        break;
158
                                                }
159
                                                if (task.getEvent() != null)
160
                                                        task.manageEvent(task.getEvent());
161
                                }
162
                        } else {
163
                                for (int row = 0; row < height; row++) {
164
                                        for (int col = 0; col < width; col++) {
165
                                                try {
166
                                                        rasterBuf.getElemByte((int)(row * scaleY), (int)(col * scaleX), data);
167
                                                        image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
168
                                                                        + ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
169
                                                } catch (ArrayIndexOutOfBoundsException ex) {
170
                                                        log.info("== Size Image:" + image.getWidth() + " " + image.getHeight());
171
                                                        log.info("== Position required:" + (int)(col * scaleX) + " " + (int)(row * scaleY));
172
                                                        break;
173
                                                }
174
                                        }
175
                                        if (task.getEvent() != null)
176
                                                task.manageEvent(task.getEvent());
177
                                }
178
                        }
179
                } catch (Exception e) {
180
                        LoggerFactory.getLogger(this.getClass()).info(
181
                                        "Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , e);
182
                }
183
        }
184

    
185
        /**
186
         * Dibuja un raster sobre un BufferedImage con las propiedades de paleta y transparencia
187
         * @param image BufferedImage sobre el que se dibuja
188
         * @param data buffer vacio. Se trata de un array de bytes donde cada elemento representa una banda.
189
         * @param supersampling true si se necesita supersamplear y false si no se necesita
190
         * @throws ProcessInterruptedException
191
         */
192
        private void drawWithTransparency(BufferedImage image, 
193
                        boolean supersampling,
194
                        Transparency t) throws ProcessInterruptedException {
195
                RasterTask task = RasterTaskQueue.get(Thread.currentThread().getId() + "");
196
                int value = 0;
197
                byte[] data = new byte[rasterBuf.getBandCount()];
198
                try {
199
                        if (supersampling) {
200
                                int[] r = new int[height];
201
                                int[] c = new int[width];
202
                                calcSupersamplingStepsArrays(r, c);
203
                                for (int row = 0; row < height; row++) {
204
                                        for (int col = 0; col < width; col++)
205
                                                try {
206
                                                        rasterBuf.getElemByte(r[row], c[col], data);
207
                                                        value = t.processRGB(data[0] & 0xff, data[1] & 0xff, data[2] & 0xff, r[row], c[col], rasterBuf);
208
                                                        image.setRGB(col, row, value);
209
                                                } catch (ArrayIndexOutOfBoundsException e) {
210
                                                        log.info("== Size Image:" + image.getWidth() + " " + image.getHeight());
211
                                                        log.info("== Position required:" + col + " " + row);
212
                                                        break;
213
                                                }
214
                                                if (task.getEvent() != null)
215
                                                        task.manageEvent(task.getEvent());
216
                                }
217
                        } else {
218
                                for (int row = 0; row < height; row++) {
219
                                        for (int col = 0; col < width; col++) {
220
                                                try {
221
                                                        int r = (int)(row * scaleY);
222
                                                        int c = (int)(col * scaleX);
223
                                                        rasterBuf.getElemByte(r, c, data);
224
                                                        value = t.processRGB(data[0] & 0xff, data[1] & 0xff, data[2] & 0xff, r, c, rasterBuf);
225
                                                        image.setRGB(col, row, value);
226
                                                } catch (ArrayIndexOutOfBoundsException e) {
227
                                                        log.info("== Size Image:" + image.getWidth() + " " + image.getHeight());
228
                                                        log.info("== Position required:" + col + " " + row);
229
                                                        break;
230
                                                }  //catch (Exception e) {
231
                                                //System.out.println("Row:" + (int)(row * scaleY) + " Col:" + (int)(col * scaleX) + " " + rasterBuf.getBandCount() + " " + data.length);
232
                                                //}
233
                                        }
234
                                        if (task.getEvent() != null)
235
                                                task.manageEvent(task.getEvent());
236
                                }
237

    
238
                        }
239
                } catch (Exception e) {
240
                        LoggerFactory.getLogger(this.getClass()).info(
241
                                        "Buffer: " + rasterBuf.getWidth() + " " + rasterBuf.getHeight() , e);
242
                }
243
        }        
244

    
245
        /**
246
         * Converts a Buffer object into a byte
247
         * @param buf
248
         * @return
249
         */
250
        private Buffer convertToByte(Buffer buf) {
251
                Buffer b = DefaultRasterManager.getInstance().createBuffer(Buffer.TYPE_BYTE, buf.getWidth(), buf.getHeight(), buf.getBandCount(), true);
252
                if(buf.getDataType() == Buffer.TYPE_SHORT)
253
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
254
                                for (int row = 0; row < buf.getHeight(); row++)
255
                                        for (int col = 0; col < buf.getWidth(); col++)
256
                                                b.setElem(row, col, nBand, (byte)(buf.getElemShort(row, col, nBand) & 0xffff));
257
                if(buf.getDataType() == Buffer.TYPE_INT)
258
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
259
                                for (int row = 0; row < buf.getHeight(); row++)
260
                                        for (int col = 0; col < buf.getWidth(); col++)
261
                                                b.setElem(row, col, nBand, (byte)(buf.getElemInt(row, col, nBand) & 0xffffffff));
262
                if(buf.getDataType() == Buffer.TYPE_FLOAT)
263
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
264
                                for (int row = 0; row < buf.getHeight(); row++)
265
                                        for (int col = 0; col < buf.getWidth(); col++)
266
                                                b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemFloat(row, col, nBand))));
267
                if(buf.getDataType() == Buffer.TYPE_DOUBLE)
268
                        for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
269
                                for (int row = 0; row < buf.getHeight(); row++)
270
                                        for (int col = 0; col < buf.getWidth(); col++)
271
                                                b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemDouble(row, col, nBand))));
272
                return b;
273
        }
274

    
275
        public void setBuffer(Buffer b) {
276
                this.rasterBuf = b;
277
        }
278

    
279
        public void setSupersamplingOn(double[] step) {
280
                this.step = step;
281
        }
282

    
283
        public void setOutputSize(int w, int h) {
284
                this.width = w;
285
                this.height = h;
286
        }
287
        
288
        public void dispose() {
289
                if(rasterBuf != null)
290
                        rasterBuf.dispose();
291
                if(transparency != null)
292
                        transparency.dispose();
293
                try {
294
                        finalize();
295
                } catch (Throwable e) {
296
                }
297
        }
298
        
299
        public Buffer addEnhanced(Statistics stats) {
300
                return addEnhanced(stats, true, 0.0);
301
        }
302

    
303
        public Buffer addEnhanced(Statistics stats, boolean tailTrim, double tailTrimValue) {
304
                RasterFilterList filterList = RasterLocator.getManager().createEmptyFilterList(rasterBuf.getDataType());
305

    
306
                try {
307
                        EnhancementStretchListManager enhancementManager = (EnhancementStretchListManager) filterList.getManagerByClass(EnhancementStretchListManager.class);
308
                        int[] renderBands = new int[rasterBuf.getBandCount()];
309
                        for (int i = 0; i < renderBands.length; i++) {
310
                                renderBands[i] = i;
311
                        }
312
                        enhancementManager.addEnhancedStretchFilter(
313
                                        DefaultLinearStretchParams.createStandardParam(new int[] { 0, 1, 2 }, tailTrimValue, stats, true), 
314
                                        stats, 
315
                                        renderBands, 
316
                                        tailTrim);
317
                } catch (FilterTypeException e1) {
318
                } catch (FileNotOpenException e) {
319
                } catch (RasterDriverException e) {
320
                }
321

    
322
                if(filterList != null) {
323
                        FilterLoader filterLoader = RasterLocator.getManager().createFilterLoader(filterList);
324
                        filterLoader.addSrcBandCount(rasterBuf.getBandCount());
325
                        filterLoader.addSrcDataType(rasterBuf.getDataType());
326
                        filterLoader.addSrcStatistics(stats);
327
                        filterLoader.addTransparency(transparency);
328
                        filterLoader.addSrcHistogram(rasterBuf.getHistogramComputer());
329
                        filterLoader.applyFilters(rasterBuf);
330
                        rasterBuf = filterLoader.getBufferResult();
331
                }
332
                return rasterBuf;
333
        }
334
        
335
        protected void finalize() throws Throwable {
336
                step        = null;
337
                rasterBuf   = null;
338
                transparency = null;
339
                super.finalize();
340
        }
341

    
342
}