1

I'm trying to generate a bitmap using C.

So far I managed to write this code that is generating an image for me of size 10x10 pixels.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>


#pragma pack(push, 1)
typedef struct {             // Total: 54 bytes
  char bitmapSignatureBytes[2];
  uint32_t  size;             // File size in bytes
  uint16_t  reserved1;        // Not used
  uint16_t  reserved2;        // Not used
  uint32_t  offset;           // Offset to image data in bytes from beginning of file (54 bytes)
  uint32_t  dib_header_size;  // DIB Header size in bytes (40 bytes)
  int32_t   width;         // Width of the image
  int32_t   height;        // Height of image
  uint16_t  num_planes;       // Number of color planes
  uint16_t  bits_per_pixel;   // Bits per pixel
  uint32_t  compression;      // Compression type
  uint32_t  image_size_bytes; // Image size in bytes
  int32_t   x_resolution_ppm; // Pixels per meter
  int32_t   y_resolution_ppm; // Pixels per meter
  uint32_t  num_colors;       // Number of colors  
  uint32_t  important_colors; // Important colors 
} BMPHeader;
#pragma pack(pop)

const int32_t image_width = 10;
const int32_t image_height = 10;

const int32_t bitcount = 24;//<- 24-bit bitmap
const int32_t width_in_bytes = ((image_width * bitcount + 31) / 32) * 4;
const uint32_t imagesize = width_in_bytes * image_height;   //total image size
BMPHeader bmpHeader = {"BM", 54+imagesize, 0, 0, 54, 40, image_width, image_height, 1, 24, 0, imagesize, 100, 100, 0, 0};

 // porque usar pragma:  https://stackoverflow.com/questions/3318410/pragma-pack-effect

typedef struct 
{
    uint8_t blue;
    uint8_t green;
    uint8_t red; 
    
}pixel;

pixel pixelConfig = {255, 255, 255};

int main(void)
{




    FILE *file = fopen("my_first_image.bmp", "wb");

    // Print (write) strings to file
    fwrite(&bmpHeader, sizeof(bmpHeader), 1, file);


    int size = bmpHeader.width*bmpHeader.height;
    for (int i = 0; i < size; ++i)
    {
        fwrite(&pixelConfig, sizeof(pixelConfig), 1, file);
    }

    // Close file
    fclose(file);
}

My problem is that the final file seems to be damaged and always the first row pixels appear with random colors. And other following lines are ok.

I can't find the error in my code. Maybe someone will tell me what's going on?

I suppose it is something with my fileHeader and infoHeader. I tried to check adding the size of the two and it gave 54bytes, as expected.

Another hypothesis is to try to deal with the padding (I think this is the most likely to solve the problem), but I couldn't understand how I need to work with it.

Please, help me understand why my image is corrupted. I am sending an example with the image that I can generate with the code above.

The result image of code above

andrii_ufu
  • 47
  • 7

1 Answers1

1

There was no padding, which made the file too short. It's not clear to me why the other colors appeared. Adding the padding made the problem go away though. For example,

uint8_t zero[4] = { 0 };
int size = bmpHeader.width * bmpHeader.height;
for (int i = 0; i < bmpHeader.height; ++i)
{
    for (int j = 0; j < bmpHeader.width; j++)
        fwrite(&pixelConfig, sizeof(pixelConfig), 1, file);
    int32_t width_in_bytes_unrounded = bmpHeader.width * 3;
    fwrite(zero, 1, width_in_bytes - width_in_bytes_unrounded, file);
}
harold
  • 61,398
  • 6
  • 86
  • 164