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)
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
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
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. */
41 #include "gnu_java_awt_peer_gtk_GtkImage.h"
43 /* The constant fields in java.awt.Image */
44 #define SCALE_DEFAULT 1
46 #define SCALE_SMOOTH 4
47 #define SCALE_REPLICATE 8
48 #define SCALE_AREA_AVERAGING 16
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);
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)
66 /* Don't use the JCL convert function because it throws an exception
68 filename = (*env)->GetStringUTFChars (env, name, 0);
73 pixbuf = gdk_pixbuf_new_from_file (filename, NULL);
76 (*env)->ReleaseStringUTFChars (env, name, filename);
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);
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)
99 GdkPixbufLoader* loader;
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);
118 g_object_unref (loader);
119 createRawData (env, obj, NULL);
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);
135 JNIEXPORT void JNICALL
136 Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf
137 (JNIEnv *env, jobject obj)
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)
153 int width, height, rowstride;
155 jintArray result_array;
156 jint *result_array_iter, *dst;
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 ();
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);
187 pixeldata += rowstride;
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
202 | (pixeldata[j*3 + 2] & 0xFF) << 16
203 | (pixeldata[j*3 + 1] & 0xFF) << 8
204 | (pixeldata[j*3] & 0xFF);
206 dst[j] = (pixeldata[j*3] & 0xFF) << 24
207 | (pixeldata[j*3 + 1] & 0xFF) << 16
208 | (pixeldata[j*3 + 2] & 0xFF) << 8
212 pixeldata += rowstride;
216 (*env)->ReleaseIntArrayElements (env, result_array, result_array_iter, 0);
218 gdk_threads_leave ();
223 * Returns a copy of the pixel data as a java array.
226 JNIEXPORT void JNICALL
227 Java_gnu_java_awt_peer_gtk_GtkImage_setPixels(JNIEnv *env, jobject obj,
230 GdkPixbuf *pixbuf = cp_gtk_image_get_pixbuf (env, obj);
231 int width, height, rowstride;
233 jint *src_array_iter, *src;
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);
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)
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,
281 * Allocates a Gtk Pixbuf
283 JNIEXPORT void JNICALL
284 Java_gnu_java_awt_peer_gtk_GtkImage_initFromBuffer(JNIEnv *env, jobject obj,
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 gdk_pixbuf_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,
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,
351 createRawData (env, destination, (void *)dst);
355 * Used by GtkFramePeer
357 GdkPixbuf *cp_gtk_image_get_pixbuf (JNIEnv *env, jobject obj)
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);
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)
382 /* For FAST, we use the nearest-neighbor. Fastest and lowest quality. */
384 case SCALE_REPLICATE:
385 return GDK_INTERP_NEAREST;
387 /* Hyperbolic for smooth. Slowest too. */
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)
406 cls = (*env)->GetObjectClass (env, obj);
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 */
419 createRawData (JNIEnv * env, jobject obj, void *ptr)
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);