Created
May 6, 2016 22:51
-
-
Save bzdgn/40638eccd20dac8273fc00bfc5f50ac2 to your computer and use it in GitHub Desktop.
A Simple Bitmap Writer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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