PDA

View Full Version : Things don't add up :(



jbich
04-15-2005, 10:24 AM
Something is really confusing me, and you guys have been so nice, so I thought I'd post my question here.

I'm trying to manually load a bitmap file. Yep, I know about SDL, but I wanna actually learn how to do it ;)

Anyway. I've got the specs for the format, but the file info always comes out wrong. The references on the net use windows TypeDefs (like DWORD and WORD) which I've tentatively translated to int and char[2] respectively, but something doesn't add up.

typedef struct tagBITMAPFILEHEADER {
char Type[2];
int Size;
char Reserved1[2];
char Reserved2[2];
int OffBits;
} BITMAPFILEHEADER;

That should equal 14 bytes, but sizeof reports it as 16, and I don't understand why. Every time I see this on a windows programmers explaination of how to load a bitmap, they say the FILEINFO struct actually SHOULD be 16 bytes... *blink* wtf?

In SDL's actual SOURCE for loading a bitmap it SAYS:
/* The Win32 BMP file header (14 bytes) */
char magic[2];
Uint32 bfSize;
Uint16 bfReserved1;
Uint16 bfReserved2;
Uint32 bfOffBits;

When I load the indiviudal struct members using fseek and fread for each member, it loads correctly, but when I try to load the whole thing at once (which is kinda the point isn't it?), it gets all messed up.

So my question is, why does the BITMAPFILEHEADER struct I just layed out have a sizeof() of 16 when if you actually count the bytes, it equals 14?!?

I'm thinking that if I can answer that question, things will become a lot easier...

Thanks very much for any insight you can provide.

*scratches his head*

j

04-15-2005, 11:54 AM
Your compiler will add two padding bytes after

char Type[2];to ensure that


int Size;starts at a 4 byte boundary and no missaligned access to Size will take place. You can change the default packing behavior however.

In case your using MS Visual Studio you can use the


#pragma pack(x)directive, where x can be 1,2,4,8,16. If you dont specify a value for x the default packing will be selected (which is 8).

Instead of:


char Type[2]I recommend using this declaration:

[CODE]
#pragma pack(2)
typedef struct tagBITMAPFILEHEADER {
unsigned short Type;
unsigned int Size;
unsigned short Reserved1;
unsigned short Reserved2;
unsigned int OffBits;
} BITMAPFILEHEADER;
#pragma pack()
[CODE]

jbich
04-16-2005, 07:58 AM
You're a godsend.
Thank you!

GreatRedShark
04-16-2005, 02:43 PM
You may also want to check out:
http://www.gamedev.net/reference/articles/article1966.asp

Download the example source if you're still stuck. It works great on Linux... don't know about Windows.

04-18-2005, 01:58 AM
Originally posted by jbich:
You're a godsend.
Thank you!Hehehe, you're welcome! :)