I am trying to read a bitmap (.bmp) image header into a struct
in c.
typedef unsigned short WORD;
typedef unsigned long DWORD;
typedef struct _BIT
When reading this kind of files I think a good approach is to first read them as a stream of bytes (unsigned char
) and then, if and when needed, to interpret part of the file contents according to the proper data types.
In your case, for instance, I would define the BITMAPFILEHEADER
struct like this:
typedef struct _BITMAPFILEHEADER {
unsigned char Type[ 2 ];
unsigned int Size; // Size of the BMP file in bytes
unsigned char Reserved1[ 2 ];
unsigned char Reserved2[ 2 ];
unsigned int OffBits; // Starting address of the pixel array
} BITMAPFILEHEADER;
Then I would read the header contents as a block of 14 bytes and, at last, I would go on to fill the BITMAPFILEHEADER
struct properly.
Below you can find a simple program that reads the header of a BMP file and prints it onto the screen.
int main
(
)
{
// Defines a few variables
FILE* fp = 0;
unsigned char h[ 14 ];
// Opens the BMP file
fp = fopen( "img.bmp", "rb" );
if ( fp == NULL )
{
printf( "Cannot open file\n" );
return -1;
}
// Reads the BMP header (14 bytes)
fread( h, 14, 1, fp );
// Prints the header contents
printf( "Type: %02x%02x\n", h[ 0 ], h[ 1 ] );
printf( "Size: %02x%02x%02x%02x\n", h[ 2 ], h[ 3 ], h[ 4 ], h[ 5 ] );
printf( "Reserved: %02x%02x\n", h[ 6 ], h[ 7 ] );
printf( "Reserved: %02x%02x\n", h[ 8 ], h[ 9 ] );
printf( "Offset: %02x%02x%02x%02x\n", h[ 10 ], h[ 11 ], h[ 12 ], h[ 13 ] );
return 0;
}
NOTE 1 - Padding: From the BMP file format specification, we know that the header is 14-byte long while a printf( "%d", sizeof(BITMAPFILEHEADER) )
will show a different (greater!) number due to padding (see comments to your question).
NOTE 2 - Endiannes: When writing 2 or 4 bytes into a short or long respectively, you have to take into account endiannes. This means that you have to know how values are written into the file (as for the Bitmap header, they are represented using little endian notation) and how they are treated by your machine (probably in little endian notation).