summaryrefslogtreecommitdiff
path: root/gdk-pixbuf/io-bmp.c
diff options
context:
space:
mode:
authorFederico Mena Quintero <federico@ximian.com>2002-06-10 16:50:10 +0000
committerFederico Mena Quintero <federico@src.gnome.org>2002-06-10 16:50:10 +0000
commitebeb676cf1f36d9b9ab74559c46bb13451e8de82 (patch)
treebb0e01d19aa96baa2338b3b0b40f802961d9cdee /gdk-pixbuf/io-bmp.c
parent3d5f7b0cbf352662d6bba90eb70e6c7d62297817 (diff)
downloadgtk+-ebeb676cf1f36d9b9ab74559c46bb13451e8de82.tar.gz
New functions to fetch 32 or 16-bit little-endian values starting at a
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.
Diffstat (limited to 'gdk-pixbuf/io-bmp.c')
-rw-r--r--gdk-pixbuf/io-bmp.c39
1 files changed, 28 insertions, 11 deletions
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;