Hey,
Here's a patch which might be of use..

I created a GtkImage.getBufferedImage() method which returns a
BufferedImage backed by the GtkImage. (Only works for the pixbuf
GtkImages at the moment though, so it's not terribly useful.)

Attached is a small demo too. Works on my machine.

/Sven


Index: gnu/java/awt/Buffers.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/Buffers.java,v
retrieving revision 1.5
diff -U3 -r1.5 Buffers.java
--- gnu/java/awt/Buffers.java	2 Jul 2005 20:32:10 -0000	1.5
+++ gnu/java/awt/Buffers.java	21 May 2006 07:12:56 -0000
@@ -208,7 +208,10 @@
       }
     else
       {
-	throw new ClassCastException("Unknown data buffer type");
+	if( dest == null ) dest = new int[length + destOffset];
+	for(int i = 0; i < length; i++)
+	  ((int[])dest)[destOffset + i] = src.getElem(0, srcOffset + i);
+	return dest;
       }
     
     System.arraycopy(from, srcOffset, dest, destOffset, length);
Index: gnu/java/awt/peer/gtk/GtkImage.java
===================================================================
RCS file: /sources/classpath/classpath/gnu/java/awt/peer/gtk/GtkImage.java,v
retrieving revision 1.28
diff -U3 -r1.28 GtkImage.java
--- gnu/java/awt/peer/gtk/GtkImage.java	6 May 2006 21:10:11 -0000	1.28
+++ gnu/java/awt/peer/gtk/GtkImage.java	21 May 2006 07:12:56 -0000
@@ -41,12 +41,15 @@
 import java.awt.Graphics;
 import java.awt.Color;
 import java.awt.Image;
+import java.awt.Point;
 import java.awt.image.ColorModel;
+import java.awt.image.DataBuffer;
 import java.awt.image.DirectColorModel;
 import java.awt.image.MemoryImageSource;
 import java.awt.image.ImageConsumer;
 import java.awt.image.ImageObserver;
 import java.awt.image.ImageProducer;
+import java.awt.image.*;
 import java.io.File;
 import java.io.IOException;
 import java.util.Hashtable;
@@ -116,9 +119,9 @@
    * The 32-bit AABBGGRR format the GDK uses.
    */
   static ColorModel nativeModel = new DirectColorModel(32, 
-						       0x000000FF,
-						       0x0000FF00,
 						       0x00FF0000,
+						       0x0000FF00,
+						       0x000000FF,
 						       0xFF000000);
 
   /**
@@ -669,4 +672,52 @@
       }
     return false;
   }
+
+
+  public BufferedImage getBufferedImage()
+  {
+    if(offScreen)
+      throw new IllegalArgumentException("Pixbuf only");
+
+    WritableRaster raster = Raster.createPackedRaster
+      (new NativeDataBuffer(this), width, height,
+       width, new int[]{ 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000 },
+       new Point(0,0));
+
+    return new BufferedImage(nativeModel, raster, false, new Hashtable());
+  }
+
+  /**
+   * Provides access to pixel data - PIXBUF ONLY.
+   */
+  private native int getElem(int i);
+
+  /**
+   * Provides access to pixel data - PIXBUF ONLY.
+   */
+  private native void setElem(int i, int val);
+
+  /**
+   * Provides access to pixel data - PIXBUF ONLY.
+   */
+  public class NativeDataBuffer extends DataBuffer
+  {
+    private GtkImage image;
+
+    public NativeDataBuffer(GtkImage image)
+    {
+      super(DataBuffer.TYPE_INT, image.width * image.height);
+      this.image = image;
+    }
+    
+    public int getElem(int bank, int i)
+    {
+      return image.getElem(i);
+    }
+    
+    public void setElem(int bank, int i, int val)
+    {
+      image.setElem(i, val);
+    }
+  }
 }
Index: include/gnu_java_awt_peer_gtk_GtkImage.h
===================================================================
RCS file: /sources/classpath/classpath/include/gnu_java_awt_peer_gtk_GtkImage.h,v
retrieving revision 1.6
diff -U3 -r1.6 gnu_java_awt_peer_gtk_GtkImage.h
--- include/gnu_java_awt_peer_gtk_GtkImage.h	30 Apr 2006 10:37:36 -0000	1.6
+++ include/gnu_java_awt_peer_gtk_GtkImage.h	21 May 2006 07:12:57 -0000
@@ -20,6 +20,8 @@
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaled (JNIEnv *env, jobject, jobject, jint, jint, jint, jint, jint, jint, jint, jboolean);
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_drawPixelsScaledFlipped (JNIEnv *env, jobject, jobject, jint, jint, jint, jboolean, jboolean, jint, jint, jint, jint, jint, jint, jint, jint, jboolean);
 JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_createFromPixbuf (JNIEnv *env, jobject);
+JNIEXPORT jint JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_getElem(JNIEnv *env, jobject, jint);
+JNIEXPORT void JNICALL Java_gnu_java_awt_peer_gtk_GtkImage_setElem(JNIEnv *env, jobject, jint, jint);
 
 #ifdef __cplusplus
 }
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
===================================================================
RCS file: /sources/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c,v
retrieving revision 1.19
diff -U3 -r1.19 gnu_java_awt_peer_gtk_GtkImage.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c	13 May 2006 15:05:12 -0000	1.19
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c	21 May 2006 07:12:57 -0000
@@ -505,6 +505,62 @@
   gdk_threads_leave ();
 }
 
+
+/**
+ * Gets a pixel
+ */
+JNIEXPORT jint JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkImage_getElem(JNIEnv *env, jobject obj, jint i)
+{
+  GdkPixbuf *pixbuf;
+  jint *pixeldata, rval;
+
+  if (offScreen (env, obj) != JNI_FALSE)
+    return 0;
+
+  pixbuf = (GdkPixbuf *)getData (env, obj);
+
+  if( pixbuf == NULL )
+    return 0;
+
+  gdk_threads_enter ();
+
+  pixeldata = (jint *)gdk_pixbuf_get_pixels( pixbuf );
+
+  rval = pixeldata[i];
+
+  gdk_threads_leave ();
+  
+  return rval;
+}
+
+/**
+ * Sets a pixel
+ */
+JNIEXPORT void JNICALL 
+Java_gnu_java_awt_peer_gtk_GtkImage_setElem(JNIEnv *env, jobject obj, 
+					    jint i, jint val)
+{
+  GdkPixbuf *pixbuf;
+  jint *pixeldata;
+
+  if (offScreen (env, obj) != JNI_FALSE)
+    return;
+
+  pixbuf = (GdkPixbuf *)getData (env, obj);
+
+  if( pixbuf == NULL )
+    return;
+
+  gdk_threads_enter ();
+
+  pixeldata = (jint *)gdk_pixbuf_get_pixels( pixbuf );
+
+  pixeldata[i] = val;
+
+  gdk_threads_leave ();
+}
+
 /**
  * Used by GtkFramePeer
  */
import java.awt.*;
import java.net.URL;
import gnu.java.awt.peer.gtk.GtkImage;
import java.awt.event.*;
import java.awt.image.*;

public class TestGtk extends Frame implements ActionListener
{
  Image image;
  BufferedImage bi = null;

  public TestGtk()
  {
    image = Toolkit.getDefaultToolkit().createImage("jfig.gif");
    setLayout(new BorderLayout());
    Button b = new Button("Test");
    add(b, BorderLayout.SOUTH);
    b.addActionListener(this);
    setSize(300,300);
    setVisible(true);
  }


  public void actionPerformed(ActionEvent e)
  {
    System.out.println(image);
    bi = ((GtkImage)image).getBufferedImage();
  }

  public void paint( Graphics g ) 
  {
    g.setColor( Color.gray );
    g.fillRect( 0, 0, getSize().width, getSize().height );
    g.setColor( Color.red );
    g.fillRect( 0, 0, 10, 10 );
    g.drawImage( image, 10, 10, null );
    if( bi != null)
      g.drawImage( bi, 200, 10, null );
  }

  public static void main( String args[] )
  {
    new TestGtk();
  }

}

Reply via email to