crystal/bmp.c

94 lines
2.8 KiB
C

/**
* copied from
* https://stackoverflow.com/questions/2654480/writing-bmp-image-in-pure-c-c-without-other-libraries
**/
#include<stdio.h>
#include "bmp.h"
/* void generate_bitmap(unsigned char* image, int h, int w, char* file_name); */
/* unsigned char* create_bitmap_file_header(int h, int stride); */
/* unsigned char* create_bitmap_info_header(int h, int w); */
void generate_bitmap(unsigned char* image, int h, int w, char* file_name)
{
int width_in_bytes = w * BPP;
unsigned char padding[3] = {0, 0, 0};
int padding_size = (4 - (width_in_bytes) % 4) % 4;
int stride = (width_in_bytes) + padding_size;
FILE* image_file = fopen(file_name, "wb");
unsigned char* file_header = create_bitmap_file_header(h, stride);
fwrite(file_header, 1, FILE_HEADER_SIZE, image_file);
unsigned char* info_header = create_bitmap_info_header(h, w);
fwrite(info_header, 1, INFO_HEADER_SIZE, image_file);
for(int i=0;i<h;++i)
{
fwrite(image + (i*width_in_bytes), BPP, w, image_file);
fwrite(padding, 1, padding_size, image_file);
}
fclose(image_file);
}
unsigned char* create_bitmap_file_header(int h, int stride)
{
int file_size = FILE_HEADER_SIZE + INFO_HEADER_SIZE + (stride * h);
static unsigned char file_header[] =
{
0,0, /*signature*/
0,0,0,0, /*image file size in bytes*/
0,0,0,0, /*reserved*/
0,0,0,0, /*start of pixel array*/
};
file_header[0] = (unsigned char)('B');
file_header[1] = (unsigned char)('M');
file_header[2] = (unsigned char)(file_size);
file_header[3] = (unsigned char)(file_size >> 8);
file_header[4] = (unsigned char)(file_size >> 16);
file_header[5] = (unsigned char)(file_size >> 24);
file_header[10] = (unsigned char)(FILE_HEADER_SIZE + INFO_HEADER_SIZE);
return file_header;
}
unsigned char* create_bitmap_info_header(int h, int w)
{
static unsigned char info_header[] =
{
0,0,0,0, /*header size*/
0,0,0,0, /*image width*/
0,0,0,0, /*image height*/
0,0, /*number of color planes*/
0,0, /*bits per pixel*/
0,0,0,0, /*compression*/
0,0,0,0, /*image size*/
0,0,0,0, /*horizontal resolution*/
0,0,0,0, /*vertical resolution*/
0,0,0,0, /*colors in color table*/
0,0,0,0, /*important color count*/
};
info_header[ 0] = (unsigned char)(INFO_HEADER_SIZE);
info_header[ 4] = (unsigned char)(w);
info_header[ 5] = (unsigned char)(w >> 8);
info_header[ 6] = (unsigned char)(w >> 16);
info_header[ 7] = (unsigned char)(w >> 24);
info_header[ 8] = (unsigned char)(h);
info_header[ 9] = (unsigned char)(h >> 8);
info_header[10] = (unsigned char)(h >> 16);
info_header[11] = (unsigned char)(h >> 24);
info_header[12] = (unsigned char)(1);
info_header[14] = (unsigned char)(BPP*8);
return info_header;
}