Patch for #84083 - alignment issues in io-bmp.c



Hello,

The BMP loader in gdk-pixbuf will not work on machines that require
loads to be aligned in memory (sparc, alpha, etc.).  The patch attached
to http://bugzilla.gnome.org/show_bug.cgi?id=84083 fixes it.  Is it OK
to apply?  I would put it in the gdk-pixbuf stable branch, the gtk-2-0
branch, and HEAD.

  Federico


Index: gdk-pixbuf/ChangeLog
===================================================================
RCS file: /cvs/gnome/gtk+/gdk-pixbuf/ChangeLog,v
retrieving revision 1.414
diff -u -r1.414 ChangeLog
--- gdk-pixbuf/ChangeLog	31 May 2002 23:42:33 -0000	1.414
+++ gdk-pixbuf/ChangeLog	8 Jun 2002 02:13:18 -0000
@@ -1,3 +1,12 @@
+2002-06-07  Federico Mena Quintero  <federico ximian com>
+
+	* io-bmp.c (lsb_32):
+	(lsb_16): New functions to fetch 32 or 16-bit little-endian values
+	starting at a specific memory location.  We do this instead of
+	GINT32_FROM_LE() as the latter is simply dereferences a cast,
+	which doesn't work on platforms with alignment requirements.
+	Fixes #84083.
+
 2002-06-01  Matthias Clasen  <maclas gmx de>
 
 	* gdk-pixbuf-io.c (pixbuf_check_xbm): Accept xbms starting
Index: gdk-pixbuf/io-bmp.c
===================================================================
RCS file: /cvs/gnome/gtk+/gdk-pixbuf/io-bmp.c,v
retrieving revision 1.28
diff -u -r1.28 io-bmp.c
--- gdk-pixbuf/io-bmp.c	12 Mar 2002 19:49:03 -0000	1.28
+++ gdk-pixbuf/io-bmp.c	8 Jun 2002 02:13:18 -0000
@@ -233,14 +233,31 @@
 	return pb;
 }
 
+/* Picks up a 32-bit little-endian integer starting at the specified location.
+ * Does it by hand instead of dereferencing a simple (gint *) cast due to
+ * alignment constraints many platforms.
+ */
+static int
+lsb_32 (guchar *src)
+{
+	return src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
+}
+
+/* Same as above, but for 16-bit little-endian integers. */
+static short
+lsb_16 (guchar *src)
+{
+	return src[0] | (src[1] << 8);
+}
+
 static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH,
                              struct bmp_progressive_state *State,
                              GError **error)
 {
         /* FIXME this is totally unrobust against bogus image data. */
 
-	if (State->BufferSize < GUINT32_FROM_LE (* (guint32 *) &BIH[0]) + 14) {
-		State->BufferSize = GUINT32_FROM_LE (* (guint32 *) &BIH[0]) + 14;
+	if (State->BufferSize < lsb_32 (&BIH[0]) + 14) {
+		State->BufferSize = lsb_32 (&BIH[0]) + 14;
 		State->buff = g_try_realloc (State->buff, State->BufferSize);
 		if (State->buff == NULL) {
 			g_set_error (error,
@@ -257,16 +274,16 @@
 	DumpBIH(BIH);
 #endif
 
-	State->Header.size = GUINT32_FROM_LE (* (guint32 *) &BIH[0]);
+	State->Header.size = lsb_32 (&BIH[0]);
 	if (State->Header.size == 40) {
-		State->Header.width = GINT32_FROM_LE (* (gint32 *) &BIH[4]);
-		State->Header.height = GINT32_FROM_LE (* (gint32 *) &BIH[8]);
-		State->Header.depth = GUINT16_FROM_LE (* (guint16 *) &BIH[14]);
-		State->Compressed = GUINT32_FROM_LE (* (guint32 *) &BIH[16]);
+		State->Header.width = lsb_32 (&BIH[4]);
+		State->Header.height = lsb_32 (&BIH[8]);
+		State->Header.depth = lsb_16 (&BIH[14]);
+		State->Compressed = lsb_32 (&BIH[16]);
 	} else if (State->Header.size == 12) {
-		State->Header.width = GUINT16_FROM_LE (* (guint16 *) &BIH[4]);
-		State->Header.height = GUINT16_FROM_LE (* (guint16 *) &BIH[6]);
-		State->Header.depth = GUINT16_FROM_LE (* (guint16 *) &BIH[10]);
+		State->Header.width = lsb_16 (&BIH[4]);
+		State->Header.height = lsb_16 (&BIH[6]);
+		State->Header.depth = lsb_16 (&BIH[10]);
 		State->Compressed = BI_RGB;
 	} else {
 		g_set_error (error,
@@ -368,7 +385,7 @@
 	State->BufferDone = 0;
 	if (State->Type <= 8) {
 		State->read_state = READ_STATE_PALETTE;
-		State->BufferSize = GUINT32_FROM_LE (* (guint32 *) &BFH[10]) - 14 - State->Header.size;
+		State->BufferSize = lsb_32 (&BFH[10]) - 14 - State->Header.size;
 	} else if (State->Compressed == BI_RGB) {
 		State->read_state = READ_STATE_DATA;
 		State->BufferSize = State->LineWidth;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]