I want to load a bmp file into memory in C. I’ve found many different types of BmpFileHeader and BmpInfoHeader structures. The last one that I’ve taken it from msdn.microsoft.com but it still does not read properly from binary file. With test file lena
Image Size: -1076791624
Memory could not be allocated
What’s the point I am missing? Thanks.
#include <stdio.h>
#include <stdlib.h>
typedef struct tagBITMAPFILEHEADER {
unsigned short bfType;
unsigned int bfSize;
short bfReserved1;
short bfReserved2;
unsigned int bfOffBits;
} BITMAPFILEHEADER;
typedef struct tagBITMAPINFOHEADER {
unsigned int biSize;
int biWidth;
int biHeight;
short biPlanes;
short biBitCount;
unsigned int biCompression;
unsigned int biSizeImage;
int biXPelsPerMeter;
int biYPelsPerMeter;
unsigned int biClrUsed;
unsigned int biClrImportant;
} BITMAPINFOHEADER;
int main(int argc, char *argv[])
{
if(argc != 2)
{
printf("Usage: %s input.bmp\n", argv[0]);
exit(-1);
}
FILE *filePtr;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bitmapInfoHeader;
unsigned char *bitmapImage;
int imageIdx=0;
unsigned char tempRGB;
filePtr = fopen(argv[1],"rb");
if (filePtr == NULL)
{
printf("File could not opened\n");
exit(-1);
}
//read the bitmap file header
fread(&bitmapFileHeader, sizeof(bitmapFileHeader), 1, filePtr);
if (bitmapFileHeader.bfType !=0x4D42)
{
fclose(filePtr);
printf("Not a bmp file\n");
exit(-1);
}
fseek(filePtr, bitmapFileHeader.bfOffBits, SEEK_SET);
bitmapImage = (unsigned char*)malloc(sizeof(unsigned char)*bitmapInfoHeader.biSizeImage);
printf("Image Size: %d\n", bitmapInfoHeader.biSizeImage);
if (!bitmapImage)
{
free(bitmapImage);
fclose(filePtr);
printf("Memory could not be allocated\n");
exit(-1);
}
//swap the r and b values to get RGB (bitmap is BGR)
for (imageIdx = 0; imageIdx < bitmapInfoHeader.biSizeImage; imageIdx+=3)
{
tempRGB = bitmapImage[imageIdx];
bitmapImage[imageIdx] = bitmapImage[imageIdx + 2];
bitmapImage[imageIdx + 2] = tempRGB;
}
int i;
for(i = 0; i < bitmapInfoHeader.biSizeImage; i+=3){
printf("R: %c G: %c B: %c\n", bitmapImage[i], bitmapImage[i + 1], bitmapImage[i + 2]);
}
fclose(filePtr);
return 0;
}
The first thing that I would do is to find an authoritative statement on the byte layout of these headers and then, assuming that you want to continue to use the structs that you have defined, add some asserts on the field offsets, for example:
Chances are that your use of unsigned int, short, etc plus your compiler options (especially structure packing) might mean that your struct fields do not match the actual BMP file data (in offset, and maybe in length).