Import GNU Classpath (20121202).
[official-gcc.git] / libjava / classpath / native / jni / gtk-peer / gnu_java_awt_peer_gtk_GtkImage.c
blob0b0dbec4bdbea2859a027132d5c60ac724d101dd
1 /* gtkimage.c
2 Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
38 #include "jcl.h"
39 #include "gtkpeer.h"
41 #include "gnu_java_awt_peer_gtk_GtkImage.h"
43 /* The constant fields in java.awt.Image */
44 #define SCALE_DEFAULT 1
45 #define SCALE_FAST 2
46 #define SCALE_SMOOTH 4
47 #define SCALE_REPLICATE 8
48 #define SCALE_AREA_AVERAGING 16
50 /* local stuff */
51 static GdkInterpType mapHints(jint hints);
52 static void createRawData (JNIEnv * env, jobject obj, void *ptr);
53 static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height);
55 /**
56 * Loads a pixbuf from a file.
58 JNIEXPORT jboolean JNICALL
59 Java_gnu_java_awt_peer_gtk_GtkImage_loadPixbuf
60 (JNIEnv *env, jobject obj, jstring name)
62 const char *filename;
63 int width, height;
64 GdkPixbuf *pixbuf;
66 /* Don't use the JCL convert function because it throws an exception
67 on failure */
68 filename = (*env)->GetStringUTFChars (env, name, 0);
70 if (filename == NULL)
71 return JNI_FALSE;
73 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
74 if (pixbuf == NULL)
76 (*env)->ReleaseStringUTFChars (env, name, filename);
77 return JNI_FALSE;
80 width = gdk_pixbuf_get_width (pixbuf);
81 height = gdk_pixbuf_get_height (pixbuf);
83 createRawData (env, obj, pixbuf);
84 setWidthHeight(env, obj, width, height);
85 (*env)->ReleaseStringUTFChars (env, name, filename);
87 return JNI_TRUE;
91 * Creates the image from an array of java bytes.
93 JNIEXPORT jboolean JNICALL
94 Java_gnu_java_awt_peer_gtk_GtkImage_loadImageFromData
95 (JNIEnv *env, jobject obj, jbyteArray data)
97 jbyte *src;
98 GdkPixbuf* pixbuf;
99 GdkPixbufLoader* loader;
100 int len;
101 int width;
102 int height;
104 src = (*env)->GetByteArrayElements (env, data, NULL);
105 len = (*env)->GetArrayLength (env, data);
107 loader = gdk_pixbuf_loader_new ();
109 gdk_pixbuf_loader_write (loader, (guchar *)src, len, NULL);
110 gdk_pixbuf_loader_close (loader, NULL);
112 (*env)->ReleaseByteArrayElements (env, data, src, 0);
114 pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
116 if (pixbuf == NULL)
118 g_object_unref (loader);
119 createRawData (env, obj, NULL);
120 return JNI_FALSE;
123 g_object_ref (pixbuf);
124 g_object_unref (loader);
126 width = gdk_pixbuf_get_width (pixbuf);
127 height = gdk_pixbuf_get_height (pixbuf);
129 createRawData (env, obj, pixbuf);
130 setWidthHeight(env, obj, width, height);
132 return JNI_TRUE;
135 JNIEXPORT void JNICALL
136 Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf
137 (JNIEnv *env, jobject obj)
139 int width, heigth;
140 GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
141 width = gdk_pixbuf_get_width (pixbuf);
142 heigth = gdk_pixbuf_get_height (pixbuf);
143 setWidthHeight(env, obj, width, heigth);
147 * Returns a copy of the pixel data as a java array.
149 JNIEXPORT jintArray JNICALL
150 Java_gnu_java_awt_peer_gtk_GtkImage_getPixels(JNIEnv *env, jobject obj)
152 GdkPixbuf *pixbuf;
153 int width, height, rowstride;
154 guchar *pixeldata;
155 jintArray result_array;
156 jint *result_array_iter, *dst;
157 int i,j;
159 gdk_threads_enter ();
161 pixbuf = cp_gtk_image_get_pixbuf (env, obj);
162 width = gdk_pixbuf_get_width (pixbuf);
163 height = gdk_pixbuf_get_height (pixbuf);
164 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
166 result_array = (*env)->NewIntArray (env, (width * height));
167 if (result_array == NULL)
169 gdk_threads_leave ();
170 return NULL;
173 dst = result_array_iter =
174 (*env)->GetIntArrayElements (env, result_array, NULL);
177 pixeldata = gdk_pixbuf_get_pixels (pixbuf);
179 g_assert (gdk_pixbuf_get_bits_per_sample (pixbuf) == 8);
181 if (gdk_pixbuf_get_has_alpha (pixbuf))
183 for(i = 0 ; i < height; i++)
185 memcpy(dst, (void *)pixeldata, width * 4);
186 dst += width;
187 pixeldata += rowstride;
189 } else {
191 /* Add a default alpha value of 0xFF to the pixeldata without alpha
192 information and keep it in the same format as the pixeldata with alpha
193 information. On Little Endian systems: AABBGGRR and on Big Endian
194 systems: RRGGBBAA. */
196 for(i = 0; i < height; i++)
198 for(j = 0; j < width; j++)
200 #ifndef WORDS_BIGENDIAN
201 dst[j] = 0xFF000000
202 | (pixeldata[j*3 + 2] & 0xFF) << 16
203 | (pixeldata[j*3 + 1] & 0xFF) << 8
204 | (pixeldata[j*3] & 0xFF);
205 #else
206 dst[j] = (pixeldata[j*3] & 0xFF) << 24
207 | (pixeldata[j*3 + 1] & 0xFF) << 16
208 | (pixeldata[j*3 + 2] & 0xFF) << 8
209 | 0xFF;
210 #endif
211 dst += width;
212 pixeldata += rowstride;
216 (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
218 gdk_threads_leave ();
219 return result_array;
223 * Returns a copy of the pixel data as a java array.
224 * (GdkPixbuf only)
226 JNIEXPORT void JNICALL
227 Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
228 jintArray pixels)
230 GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
231 int width, height, rowstride;
232 guchar *pixeldata;
233 jint *src_array_iter, *src;
234 int i;
236 width = gdk_pixbuf_get_width (pixbuf);
237 height = gdk_pixbuf_get_height (pixbuf);
238 rowstride = gdk_pixbuf_get_rowstride (pixbuf);
240 src = src_array_iter =
241 (*env)->GetIntArrayElements (env, pixels, NULL);
243 pixeldata = gdk_pixbuf_get_pixels (pixbuf);
244 for(i = 0 ; i < height; i++)
246 memcpy((void *)pixeldata, (void *)src, width * 4);
247 src += width;
248 pixeldata += rowstride;
251 (*env)->ReleaseIntArrayElements (env, pixels, src_array_iter, 0);
255 * Allocates a Gtk Pixbuf
257 JNIEXPORT void JNICALL
258 Java_gnu_java_awt_peer_gtk_GtkImage_createPixbuf(JNIEnv *env, jobject obj)
260 int width, height;
261 jclass cls;
262 jfieldID field;
264 cls = (*env)->GetObjectClass (env, obj);
265 field = (*env)->GetFieldID (env, cls, "width", "I");
266 g_assert (field != 0);
267 width = (*env)->GetIntField (env, obj, field);
269 field = (*env)->GetFieldID (env, cls, "height", "I");
270 g_assert (field != 0);
271 height = (*env)->GetIntField (env, obj, field);
273 createRawData (env, obj, gdk_pixbuf_new (GDK_COLORSPACE_RGB,
274 TRUE,
276 width,
277 height));
281 * Allocates a Gtk Pixbuf
283 JNIEXPORT void JNICALL
284 Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer(JNIEnv *env, jobject obj,
285 jlong bufferPointer)
287 int width, height;
288 jclass cls;
289 jfieldID field;
290 GdkPixbuf *pixbuf;
291 const guchar *bp = JLONG_TO_PTR(const guchar, bufferPointer);
293 g_assert(bp != NULL);
294 cls = (*env)->GetObjectClass( env, obj );
295 field = (*env)->GetFieldID( env, cls, "width", "I" );
296 g_assert( field != 0 );
297 width = (*env)->GetIntField( env, obj, field );
299 field = (*env)->GetFieldID( env, cls, "height", "I" );
300 g_assert( field != 0 );
301 height = (*env)->GetIntField( env, obj, field );
303 pixbuf = gdk_pixbuf_new_from_data( bp,
304 GDK_COLORSPACE_RGB, TRUE, 8,
305 width, height, width * 4, NULL, NULL );
306 g_assert( pixbuf != NULL );
307 createRawData( env, obj, pixbuf );
311 * Frees the Gtk Pixbuf.
313 JNIEXPORT void JNICALL
314 Java_gnu_java_awt_peer_gtk_GtkImage_freePixbuf(JNIEnv *env, jobject obj)
316 g_object_unref (cp_gtk_image_get_pixbuf (env, obj));
320 * Sets this to a scaled version of the original pixbuf
321 * width and height of the destination GtkImage must be set.
323 JNIEXPORT void JNICALL
324 Java_gnu_java_awt_peer_gtk_GtkImage_createScaledPixbuf(JNIEnv *env,
325 jobject destination,
326 jobject source,
327 jint hints)
329 GdkPixbuf* dst;
330 int width, height;
331 jclass cls;
332 jfieldID field;
334 GdkPixbuf *pixbuf;
336 cls = (*env)->GetObjectClass (env, destination);
337 field = (*env)->GetFieldID (env, cls, "width", "I");
338 g_assert (field != 0);
339 width = (*env)->GetIntField (env, destination, field);
341 field = (*env)->GetFieldID (env, cls, "height", "I");
342 g_assert (field != 0);
343 height = (*env)->GetIntField (env, destination, field);
345 pixbuf = cp_gtk_image_get_pixbuf (env, source);
347 dst = gdk_pixbuf_scale_simple(pixbuf,
348 width, height,
349 mapHints(hints));
351 createRawData (env, destination, (void *)dst);
355 * Used by GtkFramePeer
357 GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj)
359 jclass cls;
360 jfieldID data_fid;
361 jobject data;
363 cls = (*env)->GetObjectClass (env, obj);
364 data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
365 "Lgnu/classpath/Pointer;");
366 g_assert (data_fid != 0);
367 data = (*env)->GetObjectField (env, obj, data_fid);
369 if (data == NULL)
370 return NULL;
372 return (GdkPixbuf *)JCL_GetRawData (env, data);
376 * Maps java.awt.Image scaling hints to the native GDK ones.
378 static GdkInterpType mapHints(jint hints)
380 switch ( hints )
382 /* For FAST, we use the nearest-neighbor. Fastest and lowest quality. */
383 case SCALE_FAST:
384 case SCALE_REPLICATE:
385 return GDK_INTERP_NEAREST;
387 /* Hyperbolic for smooth. Slowest too. */
388 case SCALE_SMOOTH:
389 return GDK_INTERP_HYPER;
391 /* the inbetweenish method */
392 case SCALE_AREA_AVERAGING:
393 return GDK_INTERP_TILES;
395 /* default to bilinear */
397 return GDK_INTERP_BILINEAR;
400 /* Sets the width and height fields of a GtkImage object. */
401 static void setWidthHeight (JNIEnv * env, jobject obj, int width, int height)
403 jclass cls;
404 jfieldID field;
406 cls = (*env)->GetObjectClass (env, obj);
407 g_assert (cls != 0);
408 field = (*env)->GetFieldID (env, cls, "width", "I");
409 g_assert (field != 0);
410 (*env)->SetIntField (env, obj, field, (jint)width);
412 field = (*env)->GetFieldID (env, cls, "height", "I");
413 g_assert (field != 0);
414 (*env)->SetIntField (env, obj, field, (jint)height);
417 /* Store and get the pixbuf pointer */
418 static void
419 createRawData (JNIEnv * env, jobject obj, void *ptr)
421 jclass cls;
422 jobject data;
423 jfieldID data_fid;
425 cls = (*env)->GetObjectClass (env, obj);
426 data_fid = (*env)->GetFieldID (env, cls, "pixbuf",
427 "Lgnu/classpath/Pointer;");
428 g_assert (data_fid != 0);
430 data = JCL_NewRawDataObject (env, ptr);
432 (*env)->SetObjectField (env, obj, data_fid, data);