xsnk
xsnk

Reputation: 43

Difficulty Writing to a Bitmap File

I started following Casey Muratori's excellent Handmade Hero Stream, and got recently inspired to write a BMP image loader from scratch.

I created a single structure to fill out the values of a Bitmap Header

#pragma pack(push, 1)
struct bitmap_header {
  uint16_t FType;
  uint32_t FSize;
  uint16_t Reserved_1;
  uint16_t Reserved_2;
  uint32_t BitmapOffset;
  uint32_t Size;
  int32_t Width;
  int32_t Height;
  uint16_t Planes;
  uint16_t BitsPerPixel;
  uint32_t Compression;
  uint32_t SizeOfBMP;
  int32_t HorzResolution;
  int32_t VertResolution;
  uint32_t ColorsUsed;
  uint32_t ColorsImportant;
};
#pragma pack(pop)

And then I filled out the values at entry point

bitmap_header Header = {};
Header.FType = 0x4D42; // Magic Value Here
Header.FSize = sizeof(Header) + OutputPixelSize; // entire file size
Header.BitmapOffset = sizeof(Header);
Header.Size = sizeof(Header) - 14;  // Size of the Header exluding the above
Header.Width = OutputWidth;
Header.Height = -(int32_t)OutputHeight;
Header.Planes = 1;
Header.BitsPerPixel = 24;
Header.Compression= 0;
Header.SizeOfBMP = OutputPixelSize; 
Header.HorzResolution = 0;
Header.VertResolution = 0; 
Header.ColorsUsed = 0;
Header.ColorsImportant = 0;

I created a 32 bit unsigned integer pointer to store the pixel data, and then write the pixel data with a color.

uint32_t OutputPixelSize = sizeof(uint32_t) * OutputWidth * OutputHeight;
uint32_t *OutputPixels = (uint32_t *)malloc(OutputPixelSize);

uint32_t *Out = OutputPixels;
for (uint32_t Y = 0; Y < OutputHeight; ++Y) {
    for (uint32_t X = 0; X < OutputWidth; ++X) {
        *Out++ = 0xFF0000FF;
    }
}

Finally, I wrote the data into a bmp file using standard fwrite() function

FILE* OutFile = fopen("test.bmp", "wb");
if (OutFile) {
    fwrite(&Header, sizeof(Header), 1, OutFile);
    fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);
    fclose(OutFile);  
}

The program runs, and a file is created; But the aforementioned file is not recognized by any programs. I compared it's header with a valid bmp file, and they are similar except for the file size. I do not know if I am writing the data correctly into the file or not?

Upvotes: 1

Views: 176

Answers (1)

MFisherKDX
MFisherKDX

Reputation: 2866

OutputPixelSize is an uint32_t. And sizeof(OutputPixelSize) will therefore be 4. So

fwrite(&OutputPixels, sizeof(OutputPixelSize), 1, OutFile);

only writes 4 bytes to the file.

Additionally &OutputPixels is the address of the pointer to the data, not the pointer to the data. You should pass OutputPixels to fwrite instead. Try:

fwrite(OutputPixels, 1, OutputPixelSize, OutFile);

Upvotes: 0

Related Questions