• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*******************************************************************************
2  * Copyright 2011 See AUTHORS file.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  ******************************************************************************/
16 
17 package com.badlogic.gdx.graphics.g2d;
18 
19 import java.io.ByteArrayOutputStream;
20 import java.io.IOException;
21 import java.io.InputStream;
22 import java.nio.ByteBuffer;
23 
24 import com.badlogic.gdx.graphics.GL20;
25 import com.badlogic.gdx.utils.Disposable;
26 import com.badlogic.gdx.utils.GdxRuntimeException;
27 
28 /** @author mzechner */
29 public class Gdx2DPixmap implements Disposable {
30 	public static final int GDX2D_FORMAT_ALPHA = 1;
31 	public static final int GDX2D_FORMAT_LUMINANCE_ALPHA = 2;
32 	public static final int GDX2D_FORMAT_RGB888 = 3;
33 	public static final int GDX2D_FORMAT_RGBA8888 = 4;
34 	public static final int GDX2D_FORMAT_RGB565 = 5;
35 	public static final int GDX2D_FORMAT_RGBA4444 = 6;
36 
37 	public static final int GDX2D_SCALE_NEAREST = 0;
38 	public static final int GDX2D_SCALE_LINEAR = 1;
39 
40 	public static final int GDX2D_BLEND_NONE = 0;
41 	public static final int GDX2D_BLEND_SRC_OVER = 1;
42 
toGlFormat(int format)43 	public static int toGlFormat (int format) {
44 		switch (format) {
45 		case GDX2D_FORMAT_ALPHA:
46 			return GL20.GL_ALPHA;
47 		case GDX2D_FORMAT_LUMINANCE_ALPHA:
48 			return GL20.GL_LUMINANCE_ALPHA;
49 		case GDX2D_FORMAT_RGB888:
50 		case GDX2D_FORMAT_RGB565:
51 			return GL20.GL_RGB;
52 		case GDX2D_FORMAT_RGBA8888:
53 		case GDX2D_FORMAT_RGBA4444:
54 			return GL20.GL_RGBA;
55 		default:
56 			throw new GdxRuntimeException("unknown format: " + format);
57 		}
58 	}
59 
toGlType(int format)60 	public static int toGlType (int format) {
61 		switch (format) {
62 		case GDX2D_FORMAT_ALPHA:
63 		case GDX2D_FORMAT_LUMINANCE_ALPHA:
64 		case GDX2D_FORMAT_RGB888:
65 		case GDX2D_FORMAT_RGBA8888:
66 			return GL20.GL_UNSIGNED_BYTE;
67 		case GDX2D_FORMAT_RGB565:
68 			return GL20.GL_UNSIGNED_SHORT_5_6_5;
69 		case GDX2D_FORMAT_RGBA4444:
70 			return GL20.GL_UNSIGNED_SHORT_4_4_4_4;
71 		default:
72 			throw new GdxRuntimeException("unknown format: " + format);
73 		}
74 	}
75 
76 	long basePtr;
77 	int width;
78 	int height;
79 	int format;
80 	ByteBuffer pixelPtr;
81 	long[] nativeData = new long[4];
82 
83 	static {
84 		setBlend(GDX2D_BLEND_SRC_OVER);
85 		setScale(GDX2D_SCALE_LINEAR);
86 	}
87 
Gdx2DPixmap(byte[] encodedData, int offset, int len, int requestedFormat)88 	public Gdx2DPixmap (byte[] encodedData, int offset, int len, int requestedFormat) throws IOException {
89 		pixelPtr = load(nativeData, encodedData, offset, len);
90 		if (pixelPtr == null) throw new IOException("Error loading pixmap: " + getFailureReason());
91 
92 		basePtr = nativeData[0];
93 		width = (int)nativeData[1];
94 		height = (int)nativeData[2];
95 		format = (int)nativeData[3];
96 
97 		if (requestedFormat != 0 && requestedFormat != format) {
98 			convert(requestedFormat);
99 		}
100 	}
101 
Gdx2DPixmap(InputStream in, int requestedFormat)102 	public Gdx2DPixmap (InputStream in, int requestedFormat) throws IOException {
103 		ByteArrayOutputStream bytes = new ByteArrayOutputStream(1024);
104 		byte[] buffer = new byte[1024];
105 		int readBytes = 0;
106 
107 		while ((readBytes = in.read(buffer)) != -1) {
108 			bytes.write(buffer, 0, readBytes);
109 		}
110 
111 		buffer = bytes.toByteArray();
112 		pixelPtr = load(nativeData, buffer, 0, buffer.length);
113 		if (pixelPtr == null) throw new IOException("Error loading pixmap: " + getFailureReason());
114 
115 		basePtr = nativeData[0];
116 		width = (int)nativeData[1];
117 		height = (int)nativeData[2];
118 		format = (int)nativeData[3];
119 
120 		if (requestedFormat != 0 && requestedFormat != format) {
121 			convert(requestedFormat);
122 		}
123 	}
124 
125 	/** @throws GdxRuntimeException if allocation failed. */
Gdx2DPixmap(int width, int height, int format)126 	public Gdx2DPixmap (int width, int height, int format) throws GdxRuntimeException {
127 		pixelPtr = newPixmap(nativeData, width, height, format);
128 		if (pixelPtr == null) throw new GdxRuntimeException("Error loading pixmap.");
129 
130 		this.basePtr = nativeData[0];
131 		this.width = (int)nativeData[1];
132 		this.height = (int)nativeData[2];
133 		this.format = (int)nativeData[3];
134 	}
135 
Gdx2DPixmap(ByteBuffer pixelPtr, long[] nativeData)136 	public Gdx2DPixmap (ByteBuffer pixelPtr, long[] nativeData) {
137 		this.pixelPtr = pixelPtr;
138 		this.basePtr = nativeData[0];
139 		this.width = (int)nativeData[1];
140 		this.height = (int)nativeData[2];
141 		this.format = (int)nativeData[3];
142 	}
143 
convert(int requestedFormat)144 	private void convert (int requestedFormat) {
145 		Gdx2DPixmap pixmap = new Gdx2DPixmap(width, height, requestedFormat);
146 		pixmap.drawPixmap(this, 0, 0, 0, 0, width, height);
147 		dispose();
148 		this.basePtr = pixmap.basePtr;
149 		this.format = pixmap.format;
150 		this.height = pixmap.height;
151 		this.nativeData = pixmap.nativeData;
152 		this.pixelPtr = pixmap.pixelPtr;
153 		this.width = pixmap.width;
154 	}
155 
156 	@Override
dispose()157 	public void dispose () {
158 		free(basePtr);
159 	}
160 
clear(int color)161 	public void clear (int color) {
162 		clear(basePtr, color);
163 	}
164 
setPixel(int x, int y, int color)165 	public void setPixel (int x, int y, int color) {
166 		setPixel(basePtr, x, y, color);
167 	}
168 
getPixel(int x, int y)169 	public int getPixel (int x, int y) {
170 		return getPixel(basePtr, x, y);
171 	}
172 
drawLine(int x, int y, int x2, int y2, int color)173 	public void drawLine (int x, int y, int x2, int y2, int color) {
174 		drawLine(basePtr, x, y, x2, y2, color);
175 	}
176 
drawRect(int x, int y, int width, int height, int color)177 	public void drawRect (int x, int y, int width, int height, int color) {
178 		drawRect(basePtr, x, y, width, height, color);
179 	}
180 
drawCircle(int x, int y, int radius, int color)181 	public void drawCircle (int x, int y, int radius, int color) {
182 		drawCircle(basePtr, x, y, radius, color);
183 	}
184 
fillRect(int x, int y, int width, int height, int color)185 	public void fillRect (int x, int y, int width, int height, int color) {
186 		fillRect(basePtr, x, y, width, height, color);
187 	}
188 
fillCircle(int x, int y, int radius, int color)189 	public void fillCircle (int x, int y, int radius, int color) {
190 		fillCircle(basePtr, x, y, radius, color);
191 	}
192 
fillTriangle(int x1, int y1, int x2, int y2, int x3, int y3, int color)193 	public void fillTriangle (int x1, int y1, int x2, int y2, int x3, int y3, int color) {
194 		fillTriangle(basePtr, x1, y1, x2, y2, x3, y3, color);
195 	}
196 
drawPixmap(Gdx2DPixmap src, int srcX, int srcY, int dstX, int dstY, int width, int height)197 	public void drawPixmap (Gdx2DPixmap src, int srcX, int srcY, int dstX, int dstY, int width, int height) {
198 		drawPixmap(src.basePtr, basePtr, srcX, srcY, width, height, dstX, dstY, width, height);
199 	}
200 
drawPixmap(Gdx2DPixmap src, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight)201 	public void drawPixmap (Gdx2DPixmap src, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth,
202 		int dstHeight) {
203 		drawPixmap(src.basePtr, basePtr, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight);
204 	}
205 
newPixmap(InputStream in, int requestedFormat)206 	public static Gdx2DPixmap newPixmap (InputStream in, int requestedFormat) {
207 		try {
208 			return new Gdx2DPixmap(in, requestedFormat);
209 		} catch (IOException e) {
210 			return null;
211 		}
212 	}
213 
newPixmap(int width, int height, int format)214 	public static Gdx2DPixmap newPixmap (int width, int height, int format) {
215 		try {
216 			return new Gdx2DPixmap(width, height, format);
217 		} catch (IllegalArgumentException e) {
218 			return null;
219 		}
220 	}
221 
getPixels()222 	public ByteBuffer getPixels () {
223 		return pixelPtr;
224 	}
225 
getHeight()226 	public int getHeight () {
227 		return height;
228 	}
229 
getWidth()230 	public int getWidth () {
231 		return width;
232 	}
233 
getFormat()234 	public int getFormat () {
235 		return format;
236 	}
237 
getGLInternalFormat()238 	public int getGLInternalFormat () {
239 		return toGlFormat(format);
240 	}
241 
getGLFormat()242 	public int getGLFormat () {
243 		return getGLInternalFormat();
244 	}
245 
getGLType()246 	public int getGLType () {
247 		return toGlType(format);
248 	}
249 
getFormatString()250 	public String getFormatString () {
251 		switch (format) {
252 		case GDX2D_FORMAT_ALPHA:
253 			return "alpha";
254 		case GDX2D_FORMAT_LUMINANCE_ALPHA:
255 			return "luminance alpha";
256 		case GDX2D_FORMAT_RGB888:
257 			return "rgb888";
258 		case GDX2D_FORMAT_RGBA8888:
259 			return "rgba8888";
260 		case GDX2D_FORMAT_RGB565:
261 			return "rgb565";
262 		case GDX2D_FORMAT_RGBA4444:
263 			return "rgba4444";
264 		default:
265 			return "unknown";
266 		}
267 	}
268 
269 	// @off
270 	/*JNI
271 	#include <gdx2d/gdx2d.h>
272 	#include <stdlib.h>
273 	 */
274 
load(long[] nativeData, byte[] buffer, int offset, int len)275 	private static native ByteBuffer load (long[] nativeData, byte[] buffer, int offset, int len); /*MANUAL
276 		const unsigned char* p_buffer = (const unsigned char*)env->GetPrimitiveArrayCritical(buffer, 0);
277 		gdx2d_pixmap* pixmap = gdx2d_load(p_buffer + offset, len);
278 		env->ReleasePrimitiveArrayCritical(buffer, (char*)p_buffer, 0);
279 
280 		if(pixmap==0)
281 			return 0;
282 
283 		jobject pixel_buffer = env->NewDirectByteBuffer((void*)pixmap->pixels, pixmap->width * pixmap->height * gdx2d_bytes_per_pixel(pixmap->format));
284 		jlong* p_native_data = (jlong*)env->GetPrimitiveArrayCritical(nativeData, 0);
285 		p_native_data[0] = (jlong)pixmap;
286 		p_native_data[1] = pixmap->width;
287 		p_native_data[2] = pixmap->height;
288 		p_native_data[3] = pixmap->format;
289 		env->ReleasePrimitiveArrayCritical(nativeData, p_native_data, 0);
290 
291 		return pixel_buffer;
292 	 */
293 
newPixmap(long[] nativeData, int width, int height, int format)294 	private static native ByteBuffer newPixmap (long[] nativeData, int width, int height, int format); /*MANUAL
295 		gdx2d_pixmap* pixmap = gdx2d_new(width, height, format);
296 		if(pixmap==0)
297 			return 0;
298 
299 		jobject pixel_buffer = env->NewDirectByteBuffer((void*)pixmap->pixels, pixmap->width * pixmap->height * gdx2d_bytes_per_pixel(pixmap->format));
300 		jlong* p_native_data = (jlong*)env->GetPrimitiveArrayCritical(nativeData, 0);
301 		p_native_data[0] = (jlong)pixmap;
302 		p_native_data[1] = pixmap->width;
303 		p_native_data[2] = pixmap->height;
304 		p_native_data[3] = pixmap->format;
305 		env->ReleasePrimitiveArrayCritical(nativeData, p_native_data, 0);
306 
307 		return pixel_buffer;
308 	 */
309 
free(long pixmap)310 	private static native void free (long pixmap); /*
311 		gdx2d_free((gdx2d_pixmap*)pixmap);
312 	 */
313 
clear(long pixmap, int color)314 	private static native void clear (long pixmap, int color); /*
315 		gdx2d_clear((gdx2d_pixmap*)pixmap, color);
316 	 */
317 
setPixel(long pixmap, int x, int y, int color)318 	private static native void setPixel (long pixmap, int x, int y, int color); /*
319 		gdx2d_set_pixel((gdx2d_pixmap*)pixmap, x, y, color);
320 	 */
321 
getPixel(long pixmap, int x, int y)322 	private static native int getPixel (long pixmap, int x, int y); /*
323 		return gdx2d_get_pixel((gdx2d_pixmap*)pixmap, x, y);
324 	 */
325 
drawLine(long pixmap, int x, int y, int x2, int y2, int color)326 	private static native void drawLine (long pixmap, int x, int y, int x2, int y2, int color); /*
327 		gdx2d_draw_line((gdx2d_pixmap*)pixmap, x, y, x2, y2, color);
328 	 */
329 
drawRect(long pixmap, int x, int y, int width, int height, int color)330 	private static native void drawRect (long pixmap, int x, int y, int width, int height, int color); /*
331 		gdx2d_draw_rect((gdx2d_pixmap*)pixmap, x, y, width, height, color);
332 	 */
333 
drawCircle(long pixmap, int x, int y, int radius, int color)334 	private static native void drawCircle (long pixmap, int x, int y, int radius, int color); /*
335 		gdx2d_draw_circle((gdx2d_pixmap*)pixmap, x, y, radius, color);
336 	 */
337 
fillRect(long pixmap, int x, int y, int width, int height, int color)338 	private static native void fillRect (long pixmap, int x, int y, int width, int height, int color); /*
339 		gdx2d_fill_rect((gdx2d_pixmap*)pixmap, x, y, width, height, color);
340 	 */
341 
fillCircle(long pixmap, int x, int y, int radius, int color)342 	private static native void fillCircle (long pixmap, int x, int y, int radius, int color); /*
343 		gdx2d_fill_circle((gdx2d_pixmap*)pixmap, x, y, radius, color);
344 	 */
345 
fillTriangle(long pixmap, int x1, int y1, int x2, int y2, int x3, int y3, int color)346 	private static native void fillTriangle (long pixmap, int x1, int y1, int x2, int y2, int x3, int y3, int color); /*
347 		gdx2d_fill_triangle((gdx2d_pixmap*)pixmap, x1, y1, x2, y2, x3, y3, color);
348 	 */
349 
drawPixmap(long src, long dst, int srcX, int srcY, int srcWidth, int srcHeight, int dstX, int dstY, int dstWidth, int dstHeight)350 	private static native void drawPixmap (long src, long dst, int srcX, int srcY, int srcWidth, int srcHeight, int dstX,
351 		int dstY, int dstWidth, int dstHeight); /*
352 		gdx2d_draw_pixmap((gdx2d_pixmap*)src, (gdx2d_pixmap*)dst, srcX, srcY, srcWidth, srcHeight, dstX, dstY, dstWidth, dstHeight);
353 		 */
354 
setBlend(int blend)355 	public static native void setBlend (int blend); /*
356 		gdx2d_set_blend(blend);
357 	 */
358 
setScale(int scale)359 	public static native void setScale (int scale); /*
360 		gdx2d_set_scale(scale);
361 	 */
362 
getFailureReason()363 	public static native String getFailureReason (); /*
364      return env->NewStringUTF(gdx2d_get_failure_reason());
365 	 */
366 }
367