Jael
Jael

Reputation: 11

C Function to create BMP file header from width and height

I need help filling out a BMP file based on the width and height of an image.

What I am working with:

struct BMP_Header { 
    char signature[2]; 
    int size; 
    short reserved1; 
    short reserved2; 
    int offset; 
}; 

struct DIB_Header { 
    int size; 
    int width; 
    int height; 
    short planes; 
    short bit_count; 
    int compression; 
    int size_image; 
    int x_ppm; 
    int y_ppm; 
    int clr_used; 
    int clr_important; 
};
* @param header: Pointer to the destination DIB header
* @param width: Width of the image
* @param height: Height of the image
void makeBMPHeader(struct BMP_Header* header, int width, int height){
    //header->size = ???; 
    //header->offset = ???; 
}

* @param header: Pointer to the destination DIB header
* @param width: Width of the image 
* @param height: Height of the image 
void makeDIBHeader(struct DIB_Header* header, int width, int height) {
    //header->size = ???; 
    //header-> width = ???; 
    //header->height = ???; 
    //header-> bits_per_pixel = ???; 
    //header-> size_image = ???; 

}

I used default values for most components I just need assistance calculating the values for the components above.

Upvotes: 1

Views: 192

Answers (1)

Cem Polat
Cem Polat

Reputation: 701

Here is an example to create a .bmp file in Windows. BITMAPINFOHEADER and BITMAPFILEHEADER structures are defined in wingdi.h (accessed from windows.h). This example creates a 24 bit RGB bitmap.

#include <windows.h>
#include <stdint.h>
#include <stdio.h>

void CreateBMPFile(const char* filename, int width, int height, uint32_t color) {
    // Calculate the row size in bytes (including padding)
    int row_size = (width * 3 + 3) & ~3; // Round up to the nearest multiple of 4

    // Calculate the size of the pixel data
    int pixel_data_size = row_size * height;

    // Create and initialize the BITMAPINFOHEADER structure (DIB header)
    BITMAPINFOHEADER bih = { sizeof(BITMAPINFOHEADER), width, height, 1, 24, BI_RGB, pixel_data_size, 0, 0, 0, 0 };

    // Create and initialize the BITMAPFILEHEADER structure (BMP header)
    BITMAPFILEHEADER bfh = { 'B' + ('M' << 8), sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + pixel_data_size, 0, 0, sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) };

    // Create the BMP file and write the headers
    FILE* file = fopen(filename, "wb");
    if (!file) {
        return; // Error handling: Unable to create the file
    }

    // Write the BMP and DIB headers to the file
    fwrite(&bfh, sizeof(BITMAPFILEHEADER), 1, file);
    fwrite(&bih, sizeof(BITMAPINFOHEADER), 1, file);

    // Write the pixel data (in BGR format) row by row
    uint8_t pixel[3] = { color & 0xFF, (color >> 8) & 0xFF, (color >> 16) & 0xFF };
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            fwrite(pixel, 3, 1, file);
        }
        // Add padding bytes (if needed) to align rows to a multiple of 4
        for (int p = 0; p < row_size - width * 3; p++) {
            uint8_t padByte = 0;
            fwrite(&padByte, 1, 1, file);
        }
    }

    fclose(file);
}

int main() {
    
    CreateBMPFile("f://output.bmp", 640, 480, 0x0000FF); // blue
    return 0;
}

Upvotes: 1

Related Questions