Revision 1315

View differences:

org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/DefaultRasterManager.java
49 49
import org.gvsig.fmap.dal.coverage.grid.AbstractROI;
50 50
import org.gvsig.fmap.dal.coverage.grid.Grid;
51 51
import org.gvsig.fmap.dal.coverage.grid.RasterFilterList;
52
import org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer;
52 53
import org.gvsig.fmap.dal.coverage.process.TaskEventManager;
53 54
import org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder;
54 55
import org.gvsig.fmap.dal.coverage.process.vector.Vectorization;
......
84 85
import org.gvsig.raster.impl.datastruct.legend.RasterLegendIO;
85 86
import org.gvsig.raster.impl.grid.GridImpl;
86 87
import org.gvsig.raster.impl.grid.filter.DefaultRasterFilterList;
88
import org.gvsig.raster.impl.grid.render.ImageDrawerImpl;
87 89
import org.gvsig.raster.impl.grid.roi.ROIStatistic;
88 90
import org.gvsig.raster.impl.process.DefaultTaskEventManager;
89 91
import org.gvsig.raster.impl.process.overview.GdalOverviewBuilder;
......
763 765
		
764 766
		return true;
765 767
	}
768
	
769
	/*
770
	 * (non-Javadoc)
771
	 * @see org.gvsig.fmap.dal.coverage.RasterManager#createImageDrawerService()
772
	 */
773
	public ImageDrawer createImageDrawerService() {
774
		return new ImageDrawerImpl();
775
	}
766 776
}
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/grid/render/ImageDrawer.java
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.dataset.Buffer;
28
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
29
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
30
import org.gvsig.raster.impl.DefaultRasterManager;
31
import org.gvsig.raster.impl.process.RasterTask;
32
import org.gvsig.raster.impl.process.RasterTaskQueue;
33
import org.slf4j.LoggerFactory;
34

  
35
/**
36
 * Objeto para la escritura de datos desde un buffer a un objeto Image. En este nivel de
37
 * renderizado no se gestiona extents, ni rotaciones ni coordenadas del mundo, solo la
38
 * escritura desde un buffer hasta otro de tama?o dado. Por medio de par?metros y de objetos
39
 * de estado varia el resultado de la escritura, selecci?n de bandas a escribir desde el buffer
40
 * a RGB, transparencias aplicadas o paletas.
41
 *
42
 * @author Nacho Brodin (nachobrodin@gmail.com)
43
 */
44
public class ImageDrawer {
45
	/**
46
	 * Fuente de datos para el renderizado
47
	 */
48
	private Buffer        rasterBuf = null;
49
	private double[]      step      = null;
50
	/**
51
	 * Ancho y alto del objeto image
52
	 */
53
	private int           width     = 0;
54
	private int           height    = 0;
55
	private DefaultRender rendering = null;
56
	
57
	public ImageDrawer(DefaultRender rendering) {
58
		this.rendering = rendering;
59
	}
60

  
61
	/**
62
	 * Dibuja el buffer sobre un objeto Image de java.awt y devuelve el resultado.
63
	 *
64
	 * @param replicateBand Flag de comportamiento del renderizado. Al renderizar el buffer
65
	 * este obtiene la primera banda del buffer y la asigna al R, la segunda al G y la tercera
66
	 * al B. Este flag no es tomado en cuenta en caso de que existan 3 bandas en el buffer.
67
	 * Si no hay tres bandas, por ejemplo una y el flag es true esta ser? replicada
68
	 * en R, G y B, en caso de ser false la banda ser? dibujada en su posici?n (R, G o B)
69
	 * y en las otras bandas se rellenar? con 0.
70
	 *
71
	 * @param transparentBand. Si es true la banda 4 es alpha y si es false no lo es.
72
	 *
73
	 * @return java.awt.Image con el buffer dibujado.
74
	 * @throws ProcessInterruptedException
75
	 */
76
	public Image drawBufferOverImageObject() throws ProcessInterruptedException {
77
		if (rasterBuf == null || width == 0 || height == 0)
78
			return null;
79

  
80
		try { // Temporal para la traza de un error aleatorio
81
			BufferedImage image = new BufferedImage(width, height,
82
					BufferedImage.TYPE_INT_ARGB);
83

  
84
			// Dibujado de raster de 1 o 2 bandas.
85
			// adaptBufferToRender(replicateBand, renderBands);
86

  
87
			if (rasterBuf.getDataType() != Buffer.TYPE_BYTE)
88
				rasterBuf = convertToByte(rasterBuf);
89

  
90
			// Asigna la banda de transparencia si existe esta.
91
			// assignTransparencyBand(renderBands);
92

  
93
			byte[] data = new byte[rasterBuf.getBandCount()];
94

  
95
			Transparency transparency = rendering.getLastTransparency();
96
			if (transparency != null && transparency.isTransparencyActive()) {
97
				if (transparency.existAlphaBand()
98
						&& transparency.getAlphaBand() != null
99
						&& (transparency.getAlphaBand().getDataType() != Buffer.TYPE_BYTE))
100
					transparency.setAlphaBand(convertToByte(transparency
101
							.getAlphaBand()));
102
				drawWithTransparency(image, data, (step != null));
103
			} else
104
				drawByte(image, data, (step != null));
105

  
106
			step = null;
107
			return image;
108
		} catch (OutOfMemoryError error) { // Temporal para la traza de un error
109
											// aleatorio
110
			LoggerFactory.getLogger(this.getClass()).debug(
111
					"Buffer: " + width + " " + height , error);
112
		}
113
		return null;
114
	}
115

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

  
135
	/**
136
	 * Dibuja un raster sobre un BufferedImage
137
	 * @param image BufferedImage sobre el que se dibuja
138
	 * @param data buffer vacio. Se trata de un array de bytes donde cada elemento representa una banda.
139
	 * @param supersampling true si se necesita supersamplear y false si no se necesita
140
	 * @throws ProcessInterruptedException
141
	 */
142
	private void drawByte(BufferedImage image, byte[] data, boolean supersampling) throws ProcessInterruptedException {
143
		RasterTask task = RasterTaskQueue.get(Thread.currentThread().toString());
144

  
145
		if (supersampling) {
146
			int[] r = new int[height];
147
			int[] c = new int[width];
148
			calcSupersamplingStepsArrays(r, c);
149
			for (int row = 0; row < height; row++) {
150
				for (int col = 0; col < width; col++)
151
					try {
152
						rasterBuf.getElemByte(r[row], c[col], data);
153
						image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
154
								+ ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
155
					} catch (ArrayIndexOutOfBoundsException e) {
156
						System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
157
						System.err.println("== Position required:" + col + " " + row);
158
						break;
159
					}
160
				if (task.getEvent() != null)
161
					task.manageEvent(task.getEvent());
162
			}
163
		} else
164
			for (int row = 0; row < rasterBuf.getHeight(); row++) {
165
				for (int col = 0; col < rasterBuf.getWidth(); col++)
166
					try {
167
						rasterBuf.getElemByte(row, col, data);
168
						image.setRGB(col, row, (0xff000000 + ((data[0] & 0xff) << 16)
169
								+ ((data[1] & 0xff) << 8) + (data[2] & 0xff)));
170
					} catch (ArrayIndexOutOfBoundsException ex) {
171
						System.err.println("== Size Image:" + image.getWidth() + " " + image.getHeight());
172
						System.err.println("== Position required:" + col + " " + row);
173
						break;
174
					}
175
				if (task.getEvent() != null)
176
					task.manageEvent(task.getEvent());
177
			}
178
	}
179

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

  
227
	/**
228
	 * Converts a Buffer object into a byte
229
	 * @param buf
230
	 * @return
231
	 */
232
	private Buffer convertToByte(Buffer buf) {
233
		Buffer b = DefaultRasterManager.getInstance().createBuffer(Buffer.TYPE_BYTE, buf.getWidth(), buf.getHeight(), buf.getBandCount(), true);
234
		if(buf.getDataType() == Buffer.TYPE_SHORT)
235
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
236
				for (int row = 0; row < buf.getHeight(); row++)
237
					for (int col = 0; col < buf.getWidth(); col++)
238
						b.setElem(row, col, nBand, (byte)(buf.getElemShort(row, col, nBand) & 0xffff));
239
		if(buf.getDataType() == Buffer.TYPE_INT)
240
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
241
				for (int row = 0; row < buf.getHeight(); row++)
242
					for (int col = 0; col < buf.getWidth(); col++)
243
						b.setElem(row, col, nBand, (byte)(buf.getElemInt(row, col, nBand) & 0xffffffff));
244
		if(buf.getDataType() == Buffer.TYPE_FLOAT)
245
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
246
				for (int row = 0; row < buf.getHeight(); row++)
247
					for (int col = 0; col < buf.getWidth(); col++)
248
						b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemFloat(row, col, nBand))));
249
		if(buf.getDataType() == Buffer.TYPE_DOUBLE)
250
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
251
				for (int row = 0; row < buf.getHeight(); row++)
252
					for (int col = 0; col < buf.getWidth(); col++)
253
						b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemDouble(row, col, nBand))));
254
		return b;
255
	}
256

  
257
	/**
258
	 * Asigna el buffer a renderizar
259
	 * @param b Buffer a renderizar
260
	 */
261
	public void setBuffer(Buffer b) {
262
		this.rasterBuf = b;
263
	}
264

  
265
	/**
266
	 * Asigna la paleta asociada al grid
267
	 * @param palette
268
	 */
269
	/*public void setPalette(GridPalette palette) {
270
		this.palette = palette;
271
	}*/
272

  
273
	/**
274
	 * Asigna el desplazamiento en pixeles desde la esquina superior izquierda. Si es null se considera que esta
275
	 * funci?n la ha hecho el driver quedando desactivada en el renderizador. Si es as? no debe variar el resultado
276
	 * en la visualizacion.
277
	 * Si Supersamplea el renderizador se cargar? una matriz de datos 1:1 por lo que se podr? aplicar un filtro
278
	 * a este buffer de datos leidos independientemente del zoom que tengamos.
279
	 * @param step Desplazamiento
280
	 */
281
	public void setStep(double[] step) {
282
		this.step = step;
283
	}
284

  
285
	/**
286
	 * Asigna el ancho y el alto del BufferedImage. Esto es util para cuando hay supersampling
287
	 * que el tama?o del objeto Image no coincide con el buffer con los datos raster.
288
	 * @param w Ancho
289
	 * @param h Alto
290
	 */
291
	public void setBufferSize(int w, int h) {
292
		this.width = w;
293
		this.height = h;
294
	}
295
	
296
	public void dispose() {
297
		if(rasterBuf != null)
298
			rasterBuf.dispose();
299
		try {
300
			finalize();
301
		} catch (Throwable e) {
302
		}
303
	}
304
	
305
	/*
306
	 * (non-Javadoc)
307
	 * @see java.lang.Object#finalize()
308
	 */
309
	protected void finalize() throws Throwable {
310
		step        = null;
311
		rendering   = null;
312
		rasterBuf   = null;
313
		super.finalize();
314
	}
315

  
316
}
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/grid/render/DefaultRender.java
111 111
	 */
112 112
	private int[]            renderBands              = { 0, 1, 2 };
113 113

  
114
	private ImageDrawer      drawer                   = null;
114
	private ImageDrawerImpl      drawer                   = null;
115 115
	/**
116 116
	 * Ultima transparencia aplicada en la visualizaci?n que es obtenida desde el
117 117
	 * grid
......
197 197
		if(dataStore.getDataType() == null)
198 198
			return;
199 199

  
200
		drawer = new ImageDrawer(this);
200
		drawer = new ImageDrawerImpl();
201 201

  
202 202
		if (dataStore == null) {
203 203
			setRenderBands(new int[] { 0, 1, 2 });
......
442 442
		//Buffer filtrado para renderizar
443 443
		lastRenderBuffer = grid.getRasterBuf();
444 444
		drawer.setBuffer(lastRenderBuffer); // Buffer de datos a renderizar
445
		drawer.setStep(step); // Desplazamiento para supersampleo
446
		drawer.setBufferSize((int)Math.round(widthImage), (int)Math.round(heightImage)); // Ancho y alto del buffer
445
		drawer.setSupersamplingOn(step); // Desplazamiento para supersampleo
446
		drawer.setOutputSize((int)Math.round(widthImage), (int)Math.round(heightImage)); // Ancho y alto del buffer
447
		drawer.setLastTransparency(getLastTransparency());
447 448
		Image geoImage = drawer.drawBufferOverImageObject(); // Acci?n de renderizado
448 449

  
449 450
		// Borramos el buffer de transparencia para que siempre se tenga que regenerar.
......
562 563
			double tileScaleH = e.height() / (double)buf.getHeight();
563 564
			double scaleH = viewScaleH / tileScaleH;
564 565

  
565
			ImageDrawer d = new ImageDrawer(this);
566
			ImageDrawerImpl d = new ImageDrawerImpl();
566 567
			d.setBuffer(buf);
567
			d.setStep(null);
568
			d.setBufferSize(buf.getWidth(), buf.getHeight());
568
			d.setSupersamplingOn(null);
569
			d.setOutputSize(buf.getWidth(), buf.getHeight());
570
			d.setLastTransparency(getLastTransparency());
569 571
			Image geoImage;
570 572
			try {
571 573
				geoImage = d.drawBufferOverImageObject();
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/grid/render/ImageDrawerImpl.java
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().toString());
153

  
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
	}
205

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

  
275
	/**
276
	 * Converts a Buffer object into a byte
277
	 * @param buf
278
	 * @return
279
	 */
280
	private Buffer convertToByte(Buffer buf) {
281
		Buffer b = DefaultRasterManager.getInstance().createBuffer(Buffer.TYPE_BYTE, buf.getWidth(), buf.getHeight(), buf.getBandCount(), true);
282
		if(buf.getDataType() == Buffer.TYPE_SHORT)
283
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
284
				for (int row = 0; row < buf.getHeight(); row++)
285
					for (int col = 0; col < buf.getWidth(); col++)
286
						b.setElem(row, col, nBand, (byte)(buf.getElemShort(row, col, nBand) & 0xffff));
287
		if(buf.getDataType() == Buffer.TYPE_INT)
288
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
289
				for (int row = 0; row < buf.getHeight(); row++)
290
					for (int col = 0; col < buf.getWidth(); col++)
291
						b.setElem(row, col, nBand, (byte)(buf.getElemInt(row, col, nBand) & 0xffffffff));
292
		if(buf.getDataType() == Buffer.TYPE_FLOAT)
293
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
294
				for (int row = 0; row < buf.getHeight(); row++)
295
					for (int col = 0; col < buf.getWidth(); col++)
296
						b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemFloat(row, col, nBand))));
297
		if(buf.getDataType() == Buffer.TYPE_DOUBLE)
298
			for (int nBand = 0; nBand < buf.getBandCount(); nBand++)
299
				for (int row = 0; row < buf.getHeight(); row++)
300
					for (int col = 0; col < buf.getWidth(); col++)
301
						b.setElem(row, col, nBand, (byte)(Math.round(buf.getElemDouble(row, col, nBand))));
302
		return b;
303
	}
304

  
305
	/*
306
	 * (non-Javadoc)
307
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setBuffer(org.gvsig.fmap.dal.coverage.dataset.Buffer)
308
	 */
309
	public void setBuffer(Buffer b) {
310
		this.rasterBuf = b;
311
	}
312

  
313
	/*
314
	 * (non-Javadoc)
315
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setSupersamplingOn(double[], int, int)
316
	 */
317
	public void setSupersamplingOn(double[] step) {
318
		this.step = step;
319
	}
320

  
321
	/*
322
	 * (non-Javadoc)
323
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#setOutPutSize(int, int)
324
	 */
325
	public void setOutputSize(int w, int h) {
326
		this.width = w;
327
		this.height = h;
328
	}
329
	
330
	/*
331
	 * (non-Javadoc)
332
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#dispose()
333
	 */
334
	public void dispose() {
335
		if(rasterBuf != null)
336
			rasterBuf.dispose();
337
		try {
338
			finalize();
339
		} catch (Throwable e) {
340
		}
341
	}
342
	
343
	/*
344
	 * (non-Javadoc)
345
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#addEnhanced(org.gvsig.fmap.dal.coverage.store.props.Statistics)
346
	 */
347
	public Buffer addEnhanced(Statistics stats) {
348
		return addEnhanced(stats, true, 0.0);
349
	}
350

  
351
	/*
352
	 * (non-Javadoc)
353
	 * @see org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer#addEnhanced(org.gvsig.fmap.dal.coverage.store.props.Statistics)
354
	 */
355
	public Buffer addEnhanced(Statistics stats, boolean tailTrim, double tailTrimValue) {
356
		RasterFilterList filterList = RasterLocator.getManager().createEmptyFilterList(rasterBuf.getDataType());
357

  
358
		try {
359
			/*RasterFilterListManager enhancementManager = filterList.getManagerByID("EnhancementStretch");
360
			Params params = filterList.createEmptyFilterParams();
361
			params.setParam("stats", stats);
362
			params.setParam("remove", new Boolean(false));
363
			int[] renderBands = new int[rasterBuf.getBandCount()];
364
			for (int i = 0; i < renderBands.length; i++) {
365
				renderBands[i] = i;
366
			}
367
			params.setParam("renderBands", renderBands);
368
			params.setParam("stretchs", null);//coge el LinearStretchParams por defecto
369
			params.setParam("rgb", new Boolean(true));
370

  
371
			enhancementManager.addFilter(params);
372
			 */
373
			EnhancementStretchListManager enhancementManager = (EnhancementStretchListManager) filterList.getManagerByClass(EnhancementStretchListManager.class);
374
			int[] renderBands = new int[rasterBuf.getBandCount()];
375
			for (int i = 0; i < renderBands.length; i++) {
376
				renderBands[i] = i;
377
			}
378
			enhancementManager.addEnhancedStretchFilter(
379
					DefaultLinearStretchParams.createStandardParam(new int[] { 0, 1, 2 }, tailTrimValue, stats, true), 
380
					stats, 
381
					renderBands, 
382
					tailTrim);
383
		} catch (FilterTypeException e1) {
384
		} catch (FileNotOpenException e) {
385
		} catch (RasterDriverException e) {
386
		}
387

  
388
		if(filterList != null) {
389
			Extent ext = RasterLocator.getManager().getDataStructFactory().
390
				createExtent(rasterBuf.getDataExtent());
391
			filterList.addEnvParam("IStatistics", stats);
392
			filterList.addEnvParam("Transparency", transparency);
393
			filterList.addEnvParam("GridExtent", ext);
394
			filterList.addEnvParam("WindowExtent", ext);
395
			filterList.setInitRasterBuf(rasterBuf);
396
			try {
397
				filterList.execute();
398
			} catch (ProcessInterruptedException e) {
399
				return rasterBuf;
400
			}
401
			rasterBuf = (RasterBuffer) filterList.getResult();
402
		}
403
		return rasterBuf;
404
	}
405
	
406
	/*
407
	 * (non-Javadoc)
408
	 * @see java.lang.Object#finalize()
409
	 */
410
	protected void finalize() throws Throwable {
411
		step        = null;
412
		rasterBuf   = null;
413
		super.finalize();
414
	}
415

  
416
}
0 417

  
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.impl/src/main/java/org/gvsig/raster/impl/grid/GridImpl.java
1141 1141

  
1142 1142
		filterList.setInitRasterBuf(rasterBuf);
1143 1143

  
1144
		filterList.getEnv().put("GridExtent", getGridExtent());
1145
		filterList.getEnv().put("WindowExtent", getWindowExtent());
1144
		filterList.addEnvParam("GridExtent", getGridExtent());
1145
		filterList.addEnvParam("WindowExtent", getWindowExtent());
1146 1146

  
1147 1147
		filterList.execute();
1148 1148
		rasterBuf = (RasterBuffer) filterList.getResult();
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.api/src/main/java/org/gvsig/fmap/dal/coverage/RasterManager.java
41 41
import org.gvsig.fmap.dal.coverage.grid.AbstractROI;
42 42
import org.gvsig.fmap.dal.coverage.grid.Grid;
43 43
import org.gvsig.fmap.dal.coverage.grid.RasterFilterList;
44
import org.gvsig.fmap.dal.coverage.grid.render.ImageDrawer;
44 45
import org.gvsig.fmap.dal.coverage.process.TaskEventManager;
45 46
import org.gvsig.fmap.dal.coverage.process.overview.OverviewBuilder;
46 47
import org.gvsig.fmap.dal.coverage.process.warp.Warp;
......
429 430
	 * @return
430 431
	 */
431 432
	public boolean isExtensionSupported(String ext);
433
	
434
	/**
435
	 * Creates a service to render a buffer on a java Image object
436
	 * @return
437
	 */
438
	public ImageDrawer createImageDrawerService();
432 439
}
org.gvsig.raster/trunk/org.gvsig.raster/org.gvsig.raster.lib/org.gvsig.raster.lib.api/src/main/java/org/gvsig/fmap/dal/coverage/grid/render/ImageDrawer.java
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.fmap.dal.coverage.grid.render;
23

  
24
import java.awt.Image;
25

  
26
import org.gvsig.fmap.dal.coverage.dataset.Buffer;
27
import org.gvsig.fmap.dal.coverage.exception.ProcessInterruptedException;
28
import org.gvsig.fmap.dal.coverage.store.props.Statistics;
29
import org.gvsig.fmap.dal.coverage.store.props.Transparency;
30

  
31
/**
32
 * Writes data from a buffer on a Image object. At this level neither bounding box nor
33
 * rotations nor world coordinates are managed.
34
 *
35
 * @author Nacho Brodin (nachobrodin@gmail.com)
36
 */
37
public interface ImageDrawer {
38
	
39
	/**
40
	 * Sets the buffer to render
41
	 */
42
	public void setBuffer(Buffer b);
43

  
44
	/**
45
	 * Assigns the buffer transparency
46
	 * @param t
47
	 */
48
	public void setLastTransparency(Transparency t);
49
	
50
	/**
51
	 * Sets the shift in pixels from the upper left corner. It is useful when we need supersampling to render
52
	 * the image. If the step is null then the supersampling is deactivated else the size of the output
53
	 * buffer will be width X height pixels. This size should be set with setOutPutSize method.
54
	 * 
55
	 * Exists supersampling when the zoom to draw is greater than 1:1. To draw a pixel will be necessary
56
	 * more than one pixel in the output buffer. 
57
	 * 
58
	 * @param step Desplazamiento
59
	 */
60
	public void setSupersamplingOn(double[] step);
61
	
62
	/**
63
	 * Sets the size of the output buffer. This is useful to reescale the output buffer
64
	 * @param width Ancho
65
	 * @param h Alto
66
	 */
67
	public void setOutputSize(int width, int height);
68
	
69
	/**
70
	 * Releases the link to the buffer.
71
	 */
72
	public void dispose();
73
	
74
	/**
75
	 * Adds a enhanced filter to the buffer
76
	 * @param stats
77
	 * @return
78
	 */
79
	public Buffer addEnhanced(Statistics stats);
80
	
81
	/**
82
	 * Adds a enhanced filter to the buffer
83
	 * @param stats
84
	 * @return
85
	 */
86
	public Buffer addEnhanced(Statistics stats, boolean tailTrim, double tailTrimValue);
87
	
88
	/**
89
	 * Dibuja el buffer sobre un objeto Image de java.awt y devuelve el resultado.
90
	 *
91
	 * @param replicateBand Flag de comportamiento del renderizado. Al renderizar el buffer
92
	 * este obtiene la primera banda del buffer y la asigna al R, la segunda al G y la tercera
93
	 * al B. Este flag no es tomado en cuenta en caso de que existan 3 bandas en el buffer.
94
	 * Si no hay tres bandas, por ejemplo una y el flag es true esta ser? replicada
95
	 * en R, G y B, en caso de ser false la banda ser? dibujada en su posici?n (R, G o B)
96
	 * y en las otras bandas se rellenar? con 0.
97
	 *
98
	 * @param transparentBand. Si es true la banda 4 es alpha y si es false no lo es.
99
	 *
100
	 * @return java.awt.Image con el buffer dibujado.
101
	 * @throws ProcessInterruptedException
102
	 */
103
	public Image drawBufferOverImageObject() throws ProcessInterruptedException;
104
}
0 105

  

Also available in: Unified diff