Skip to content

Instantly share code, notes, and snippets.

@bzdgn
Created May 6, 2016 22:51
Show Gist options
  • Save bzdgn/40638eccd20dac8273fc00bfc5f50ac2 to your computer and use it in GitHub Desktop.
Save bzdgn/40638eccd20dac8273fc00bfc5f50ac2 to your computer and use it in GitHub Desktop.
A Simple Bitmap Writer
// check struct for gcc pragma pop push;
// http://stackoverflow.com/questions/11129138/reading-writing-bmp-files-in-c
#include <stdio.h>
#include <stdint.h> // uint8_t, uint16_t
#include <stdlib.h> // malloc()
#include <string.h>
#define HALF 2 // HALF WORD 2 bytes
#define WORD 4 // WORD 4 bytes
#define NUMBER_OF_COLOR_PLANES 1
#define BITMAP_INFO_HEADER_SIZE 40
#define COMPRESSION_STATE 0
/*
* File Write , check this link : https://www.codingunit.com/c-tutorial-binary-file-io
*
*/
/* For 54 byte header data
*
* http://blog.paphus.com/blog/2012/08/14/write-your-own-bitmaps/
*/
#pragma pack(push,1)
typedef struct BitmapHeaderType {
unsigned char b0; // 0
unsigned char b1; // 1
unsigned int fullFileSize; // 2...5
unsigned int reserved; // 6...9
unsigned int pixelOffset; // 10..13 HEADER SIZE
unsigned int bitmapInfoHeaderSize; // 14..17 BITMAP INFO HEADER SIZE
unsigned int pixelWidth; // 18..21 image width
unsigned int pixelHeight; // 22..25 image height
unsigned short int numberOfColorPlanes; // 26..27 the number of color planes
unsigned short int bitPerPixel; // 28..29 24bit, 32bit, bit size
unsigned int compessionState; // 30..33 compression state, 0 for disable compression
unsigned int sizeOfRawPixel; // 34..37 size of pixel data including paddings (24 bit padding changes data section)
unsigned int horizontalResolution; // 38..41 just leave 2835
unsigned int verticalResolution; // 42..45 just leave 2835
unsigned int numberOfColors; // 46..49 set 0 for default
unsigned int numberOfImportantColors; // 50..53 set 0 for default
} BitmapHeader;
#pragma pack(pop)
typedef struct PixelType{
unsigned char blue;
unsigned char green;
unsigned char red;
}Pixel;
void handleBitmapHeader(BitmapHeader *header, int width, int height);
int closestMultipleOfFour(int num);
void writeToFile(unsigned char* bytes, int len, char fileName[]);
int main()
{
BitmapHeader *header = (BitmapHeader *)malloc(sizeof(BitmapHeader));
handleBitmapHeader(header, 800, 600);
unsigned char *data = (unsigned char *)malloc(header->sizeOfRawPixel);
unsigned char *bitmap = (unsigned char *)malloc(header->fullFileSize);
//// data
//// pixel 1
//*data = 0x00;
//*(data+1) = 0x00;
//*(data+2) = 0xff;
//
//// pixel 2
//*(data+3) = 0xff;
//*(data+4) = 0x00;
//*(data+5) = 0x00;
//
//// pixel padding to multipe of 4
//*(data+6) = 0x00;
//*(data+7) = 0x00;
int k = 0;
for(int j = 0; j < 600; j++)
{
for(int i = j*800*3; i < (j+1)*800*3; i++)
if(i%3 == k)
*(data + i) = 0xff;
else
*(data + i) = 0x00;
k = (k+1)%3;
}
// copy header to bitmap
memcpy(bitmap, header, header->pixelOffset);
// copy data to bitmap
memcpy(bitmap+header->pixelOffset, data, header->fullFileSize);
char fileName[] = "hello3.bmp";
// write
writeToFile((unsigned char *)bitmap , header->fullFileSize, fileName);
free(header);
free(data);
free(bitmap);
//PixelType black;
//black.red = 0;
//black.green = 0;
//black.blue = 0;
//
//PixelType red;
//black.red = 255;
//black.green = 0;
//black.blue = 0;
//writeToFile((unsigned char *)header , sizeof(*header), fileName);
return 0;
}
void handleBitmapHeader(BitmapHeader *header, int width, int height)
{
//int numOfPixels = height * width;
// Calculate row with padding
int rowWithPadding = closestMultipleOfFour(width*3);
int rawSize = height * rowWithPadding;
printf("Row With Padding : %4d\n", rowWithPadding);
printf("Raw Size : Decimal[%4d], Hex[%4x]\n", rawSize, rawSize);
header->b0 = 'B';
header->b1 = 'M';
//header->fullFileSize = 0xFFFFFFFF;
header->fullFileSize = rawSize + 54;
header->reserved = 0x00000000;
header->pixelOffset = 54;
header->bitmapInfoHeaderSize = 40;
//header->pixelWidth = 0x11223344;
//header->pixelHeight = 0x55667788;
header->pixelWidth = (unsigned int)width;
header->pixelHeight = (unsigned int)height;
header->numberOfColorPlanes = 1;
header->bitPerPixel = 24;
header->compessionState = 0;
//header->sizeOfRawPixel = 0xAABBCCDD;
header->sizeOfRawPixel = (unsigned int) rawSize;
header->horizontalResolution = 0x2835;
header->verticalResolution = 0x2835;
header->numberOfColors = 0;
header->numberOfImportantColors = 0;
}
int closestMultipleOfFour(int num)
{
return (num + 3) & ~0x03;
}
void writeToFile(unsigned char* bytes, int len, char fileName[])
{
FILE *filePtr;
filePtr = fopen(fileName, "wb"); // wb for write binary
if(!filePtr)
{
printf("ERROR::writeToFile()::Unable to open file : \"%s\"\n", fileName);
return;
}
fwrite(bytes, len, 1, filePtr);
fclose(filePtr);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment