I'm trying to read the header of BMP files in c manually. I've used some images to test it out but find that the biSize
from the BITMAPINFOHEADER
of the images are exceedingly huge.
Firstly, I am unfortunately not on a windows machine, therefore I have to define the data types (such as WORD
, DWORD
, LONG
and BYTE
) according to the MS-DTYP documents. Maybe this could lead to some problems.
Secondly, I think I am not fully aware of how the numbers are stored and formatted when being output in c. Hence, the result might be right but it's just me who can not understand it.
Lastly, I have discovered that the size of struct BITMAPFILEHEADER
is not 14 bytes as the sum of the sizes of the members in the struct. Therefore, is it possible that the fread()
reads more bytes to the struct than it should have?
Code
typedef unsigned long DWORD;
typedef long LONG;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef struct tagBITMAPFILEHEADER {
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits; // bit from the beginning of this struct to bitmap
} BITMAPFILEHEADER, *LPBITMAPFILEHEADER, *PBITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
DWORD biSize;
LONG biWidth; // width of image in pixels
LONG biHeight; // height of image in pixels
WORD biPlanes;
WORD biBitCount; // size of each pixel in bits
DWORD biCompression;
DWORD biSizeImage;
LONG biXPelsPerMeter;
LONG biYPelsPerMeter;
DWORD biClrUsed;
DWORD biClrImportant;
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;
bool
ReadBmp(char *path){
/*
parameter:
char *path: the path (string) to the target bmp
return:
True: if success
False: if failed
*/
// get the pointer of the bmp file
FILE * f_ptr;
if((f_ptr = fopen(path, "rb"))==NULL){
perror("ReadBmp failed when reading bmp: ");
return false;
}
// load file header to fhead
BITMAPFILEHEADER fhead; // file header
fread(&fhead, sizeof(BITMAPFILEHEADER), 1, f_ptr);
// load the DIB into dib
BITMAPINFOHEADER dib;
fread(&dib, sizeof(BITMAPINFOHEADER), 1, f_ptr);
printf("size: %lu\n", dib.biSize);
}
int
main(void){
ReadBmp("../imgs/master_yoda.bmp");
return 0;
}
Result
size: 1063975552894894080
While the actual size of master_yoda.bmp
is 2.2MB. I've also check the bfType
from BITMAPFILEHEADER
and it works fine with a return of 19778
== 0x4D42
, which is the identifier for bmp files.