Reputation: 13
The code can read the width correctly but the height wrong and because of this, the program crashes. The file it needs to read is an 8x8 pixel 24 bit BMP file. The file also needs to work for every 8fold number.
some info: breedte = width hoogte = height
#include <stdio.h>
#include <stdlib.h>
#define __DEBUG
#define BMPINPUTFILE "test.bmp"
int main()
{
#ifdef __DEBUG
printf("DEBUG info: BMP transformer\n");
#endif
FILE* inputFilePointer = fopen(BMPINPUTFILE, "rb"); //maak een file pointer naar de afbeelding
if(inputFilePointer == NULL) //Test of het open van de file gelukt is!
{
printf("Something went wrong while trying to open %s\n", BMPINPUTFILE);
exit(EXIT_FAILURE);
}
#ifdef __DEBUG
printf("DEBUG info: Opening File OK: %s\n", BMPINPUTFILE);
#endif
unsigned char bmpHeader[54]; // voorzie een array van 54-bytes voor de BMP Header
fread(bmpHeader, sizeof(unsigned char), 54, inputFilePointer); // lees de 54-byte header
//Informatie uit de header (wikipedia)
// haal de hoogte en breedte uit de header
int breedte = *(int*)&bmpHeader[18];
int hoogte = *(int*)&bmpHeader[22];
#ifdef __DEBUG
printf("DEBUG info: breedte = %d\n", breedte);
printf("DEBUG info: hoogte = %d\n", hoogte);
#endif
int imageSize = 3 * breedte * hoogte; //ieder pixel heeft 3 byte data: rood, groen en blauw (RGB)
unsigned char* inputPixels = (unsigned char *) calloc(imageSize, sizeof(unsigned char)); // allocate een array voor alle pixels
fread(inputPixels, sizeof(unsigned char), imageSize, inputFilePointer); // Lees alle pixels (de rest van de file
for(int i =0; i < imageSize-2; i+=3)
{
printf("pixel %d: B= %d, G=%d, R=%d\n", i, inputPixels[i], inputPixels[i+1], inputPixels[i+2]);
}
fclose(inputFilePointer);
free(inputPixels);
return 0;
}
Upvotes: 0
Views: 603
Reputation: 4862
While you don't seem to need the file header (only the info header), I'd suggest you read the BMPFileHeader
anyway just to keep things simple, then read the BMPInfoHeader
since it comes after the file header in the BMP file.
Structure documentation: https://learn.microsoft.com/en-us/windows/win32/gdi/bitmap-storage
Working example:
#include <stdio.h>
#include <stdlib.h>
#pragma pack(push, 1)
typedef struct _tag_BMPFileHeader {
unsigned short file_type; // File type always BM which is 0x4D42
unsigned int file_size; // Size of the file (in bytes)
unsigned short reserved1; // Reserved, always 0
unsigned short reserved2; // Reserved, always 0
unsigned int offset_data; // Start position of pixel data (bytes from the beginning of the file)
} BMPFILEHEADER, *LPBMPFILEHEADER;
typedef struct _tag_BMPInfoHeader {
unsigned int size; // Size of this header (in bytes)
int width; // width of bitmap in pixels
int height; // width of bitmap in pixels
// (if positive, bottom-up, with origin in lower left corner)
// (if negative, top-down, with origin in upper left corner)
unsigned short planes; // No. of planes for the target device, this is always 1
unsigned short bit_count; // No. of bits per pixel
unsigned int compression; // 0 or 3 - uncompressed. THIS PROGRAM CONSIDERS ONLY UNCOMPRESSED BMP images
unsigned int size_image; // 0 - for uncompressed images
int x_pixels_per_meter;
int y_pixels_per_meter;
unsigned int colors_used; // No. color indexes in the color table. Use 0 for the max number of colors allowed by bit_count
unsigned int colors_important; // No. of colors used for displaying the bitmap. If 0 all colors are required
} BMPINFOHEADER, *LPBMPINFOHEADER;
#pragma pack(pop)
int main()
{
FILE* inputFilePointer = fopen("c:\\bitmap.bmp", "rb");
if (inputFilePointer == NULL)
{
return 0;
}
BMPFILEHEADER fileHeader;
BMPINFOHEADER infoHeader;
fread(&fileHeader, sizeof(BMPFILEHEADER), 1, inputFilePointer);
fread(&infoHeader, sizeof(BMPINFOHEADER), 1, inputFilePointer);
printf("Width: %d, Height: %d\n", infoHeader.width, infoHeader.height);
fclose(inputFilePointer);
}
...and the working example output:
As mentioned by someone in the comments, if you are using Windows then you should just include wingdi.h and use the structures defined there.
Upvotes: 1