[cp-patches] fix image handling on big endian systems

Andreas Tobler toa at pop.agri.ch
Tue Jun 27 19:12:11 UTC 2006


Hello all,

this patch brings the image handling back to work on big endian systems.

Please check on a little endian system!

I hope the comments in the code are ok.

Ok to commit?

Andreas

2006-06-27  Andreas Tobler  <a.tobler at schweiz.ch>

	* gnu/java/awt/peer/gtk/CairoSurface.java: Swap the data from the
	GdkPixbuf correctly on big endian systems. Fix a typo in the little
	endian swapping code.

	* native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
	(Java_gnu_java_awt_peer_gtk_GtkImage_getPixels): Swap the pixeldata
	without alpha information correctly on big endian systems.
-------------- next part --------------
Index: gnu/java/awt/peer/gtk/CairoSurface.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/awt/peer/gtk/CairoSurface.java,v
retrieving revision 1.10
diff -u -r1.10 CairoSurface.java
--- gnu/java/awt/peer/gtk/CairoSurface.java	13 Jun 2006 15:59:36 -0000	1.10
+++ gnu/java/awt/peer/gtk/CairoSurface.java	27 Jun 2006 17:35:29 -0000
@@ -52,6 +52,7 @@
 import java.awt.image.DirectColorModel;
 import java.io.File;
 import java.io.IOException;
+import java.nio.ByteOrder;
 import java.util.Hashtable;
 import java.util.Vector;
 import java.io.ByteArrayOutputStream;
@@ -177,28 +178,51 @@
     height = image.height;
 
     create(width, height, width);
-    
+
     if(surfacePointer == 0 || bufferPointer == 0)
       throw new Error("Could not allocate bitmap.");
-    
+
     // Copy the pixel data from the GtkImage.
     int[] data = image.getPixels();
 
     // Swap ordering from GdkPixbuf to Cairo
     for(int i = 0; i < data.length; i++ )
       {
-	int alpha = (data[i] & 0xFF000000) >> 24;
-	if( alpha == 0 ) // I do not know why we need this, but it works.
-	  data[i] = 0;
+	if (ByteOrder.nativeOrder() == ByteOrder.BIG_ENDIAN)
+	  {
+	    // On a big endian system we get a RRGGBBAA data array.
+	    int alpha = (data[i] & 0xFF);
+	    if( alpha == 0 ) // I do not know why we need this, but it works.
+	      data[i] = 0;
+	    else
+	      {
+		int r = (((data[i] & 0xFF000000) >> 24));
+		int g = (((data[i] & 0x00FF0000) >> 16));
+		int b = (((data[i] & 0x0000FF00) >> 8));
+		// Cairo needs a ARGB32 native array.
+		data[i] = (( alpha << 24 ) & 0xFF000000)
+		  | (( r << 16 ) & 0x00FF0000)
+		  | (( g << 8 )  & 0x0000FF00)
+		  | ( b  & 0x000000FF);
+	      }
+	  }
 	else
 	  {
-	    int r = (((data[i] & 0x00FF0000) >> 16) );
-	    int g = (((data[i] & 0x0000FF00) >> 8) );
-	    int b = ((data[i] & 0x000000FF) );
-	    data[i] = (( alpha << 24 ) & 0xFF000000) 
-	      | (( b << 16 ) & 0x00FF0000)
-	      | (( g << 8 )  & 0x0000FF00)
-	      | ( r  & 0x000000FF);
+	    // On a little endian system we get a AABBGGRR data array.
+	    int alpha = (data[i] & 0xFF000000) >> 24;
+	    if( alpha == 0 ) // I do not know why we need this, but it works.
+	      data[i] = 0;
+	    else
+	      {
+		int b = (((data[i] & 0x00FF0000) >> 16));
+		int g = (((data[i] & 0x0000FF00) >> 8));
+		int r = ((data[i] & 0x000000FF));
+		// Cairo needs a ARGB32 native array.
+		data[i] = (( alpha << 24 ) & 0xFF000000)
+		  | (( r << 16 ) & 0x00FF0000)
+		  | (( g << 8 )  & 0x0000FF00)
+		  | ( b  & 0x000000FF);
+	      }
 	  }
       }
 
Index: native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c
===================================================================
RCS file: /cvsroot/classpath/classpath/native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c,v
retrieving revision 1.25
diff -u -r1.25 gnu_java_awt_peer_gtk_GtkImage.c
--- native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c	14 Jun 2006 13:00:09 -0000	1.25
+++ native/jni/gtk-peer/gnu_java_awt_peer_gtk_GtkImage.c	27 Jun 2006 17:35:29 -0000
@@ -189,13 +189,27 @@
 	  pixeldata += rowstride;
 	}
     } else {
+
+    /* Add a default alpha value of 0xFF to the pixeldata without alpha
+       information and keep it in the same format as the pixeldata with alpha
+       information. On Little Endian systems: AABBGGRR and on Big Endian
+       systems: RRGGBBAA.  */
+
       for(i = 0; i < height; i++)
 	{
 	  for(j = 0; j < width; j++)
-	    dst[j] = 0xFF000000 |
-	      (pixeldata[j*3 + 2] & 0xFF) << 16 |
-	      (pixeldata[j*3 + 1] & 0xFF) << 8 |
-	      (pixeldata[j*3] & 0xFF);
+
+#ifndef WORDS_BIGENDIAN
+	    dst[j] = 0xFF000000
+	      | (pixeldata[j*3 + 2] & 0xFF) << 16
+	      | (pixeldata[j*3 + 1] & 0xFF) << 8
+	      | (pixeldata[j*3] & 0xFF);
+#else
+	    dst[j] = (pixeldata[j*3] & 0xFF) << 24
+	      | (pixeldata[j*3 + 1] & 0xFF) << 16
+	      | (pixeldata[j*3 + 2] & 0xFF) << 8
+	      | 0xFF;
+#endif
 	  dst += width;
 	  pixeldata += rowstride;
 	}


More information about the Classpath-patches mailing list