You’re reading the header wrong I think. The first member of the structure, bfType, is an unsigned int, not an unsigned short. This means you’re only reading two bytes before the size, when it should actually be four.
To get the size of your image, read in the BITMAPINFOHEADER directly after the BITMAPFILEHEADER and look at the biSizeImage member of the BITMAPINFOHEADER struct. This will contain the size of the bitmap data (minus the header stuff).
You can read in these two structures, then move the file pointer to BITMAPFILEHEADER.bfOffBits and read BITMAPINFOHEADER.biSizeImage bytes, which will be the actual image.
In the case where biSizeImage is zero (happens with some paint programs) you have to manually calculate the size of the image, based on its width, height, and colordepth.
It is also possible that you’re running into an alignment problem. If the program that wrote out the bitmap file did something like:
fwrite(&bfh , sizeof(BITMAPFILEHEADER), 1, fp)
then there may be a couple of extra bytes between the bfType member and the bfSize since MS likes to align struct members on 4 byte boundaries. It is also possible that the reverse problem is true. i.e. the BITMAPFILE header was written out a member at a time, but you’re trying to read the whole thing in at once. i.e.
Anyway, I believe the correct way to read and write the BMP structures is to do it a member at a time to avoid alignment problems.
The only place you are likely to run into alignment problems is in the actual image data. For example, say you have a 24bpp image that has a width of 257. Each line in the image would take 771 bytes, which would get padded an additional byte to make it align on a 4byte boundary (772/4 = 193 4byte chunks).
If you were to do something like flip this bitmap line by line, you would have to make sure you account for the padding bytes on the end of each line or else (in this case) the information in the blue channel would get “pushed” into the green channel (since they are right next to each other in memory).
This also has to be taken into account if you manually calculate the image size instead of using BITMAPINFOHEADER.biSizeImage.
All of this alignment stuff only really applies to 1, 4, 8, 16, 24 bit BMP’s. 32bpp images are 4bytes per pixel so they are automatically aligned.
jup, it’s an alignment problem, you read th bytes 4 till 7 instead of 2 till 5
the bytes are:
xx xx 07 00 00 00
the first 4 are the size (the 07 00 result from the about 465k file size) the trailing 00 00 is the reserved (always 00)
Originally posted by Olumide:
(For Geeks and Bitmap Phreaks)
Ever wondered why an unsigned short (bfType) is tested against ‘MB’ (which looks like a string)? …
Well, I did too; for a while, till I disovered that since:
‘M’ = 0100 1101
‘B’ = 0100 0010
‘BM’ is a concatenatation of ‘M’ and ‘B’ (as shown below):
‘BM’ = 0100 1101 0100 0010 = 19778 = 0x4D42
(Dont tell me these numbers dont look familair …)[/b]
in fact it is not a string (“MB”), it’s a a 2 byte charachter literal (‘MB’)
but this is NOT portable! e.g. try it with MinGW and it will fail, because MinGW compiles this the other way round, so you have to test against ‘BM’
always test against the hex-number (and write a nice comment to explain g)
i learned that the hard way when i changed from borland compiler (what a f*** stupid optimizer) to MinGW and wondered why my image class failed loading a simple BMP…