From ebeb676cf1f36d9b9ab74559c46bb13451e8de82 Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Mon, 10 Jun 2002 16:50:10 +0000 Subject: [PATCH] New functions to fetch 32 or 16-bit little-endian values starting at a 2002-06-07 Federico Mena Quintero * 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. --- gdk-pixbuf/ChangeLog | 9 +++++++++ gdk-pixbuf/io-bmp.c | 39 ++++++++++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 11 deletions(-) diff --git a/gdk-pixbuf/ChangeLog b/gdk-pixbuf/ChangeLog index e81f8ab48b..acedc80343 100644 --- a/gdk-pixbuf/ChangeLog +++ b/gdk-pixbuf/ChangeLog @@ -1,3 +1,12 @@ +2002-06-07 Federico Mena Quintero + + * 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 * gdk-pixbuf-io.c (pixbuf_check_xbm): Accept xbms starting diff --git a/gdk-pixbuf/io-bmp.c b/gdk-pixbuf/io-bmp.c index b8f9ee2bb0..21150428b7 100644 --- a/gdk-pixbuf/io-bmp.c +++ b/gdk-pixbuf/io-bmp.c @@ -233,14 +233,31 @@ static GdkPixbuf *gdk_pixbuf__bmp_image_load(FILE * f, GError **error) 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 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, 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 @@ static gboolean DecodeHeader(unsigned char *BFH, unsigned char *BIH, 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;