/* John Pfeiffer, 2010-07 write out raw bmp files
updated 2010-08
*/
#include <stdio.h>
typedef struct bmpFileHeaderT bmpFileHeader ;
typedef bmpFileHeader* bmpFileHeaderptr;
/* 14 bytes */
struct bmpFileHeaderT
{
char bmIdentifier[2];
char filesize[4];
char reservedA[2];
char reservedB[2];
char dataAddress[4];
};
typedef struct bmpInfoHeaderT bmpInfoHeader ;
typedef bmpInfoHeader* bmpInfoHeaderptr;
/* size is 40 bytes for most compatible Win 3.0 version */
struct bmpInfoHeaderT
{
char bmpInfoHeaderSize[4];
char bmpWidth[4];
char bmpHeight[4];
char colorPlanes[2];
char bitsPerPixel[2];
char bmpCompression[4];
char dataSize[4]; /* 4 bytes for every pixel if uncompressed */
char horizontalResolution[4];
char verticalResolution[4];
char colorsInPalette[4];
char importantColors[4];
};
void WritePixel( FILE** outputfile , char blue , char green , char red )
{
fputc( blue , *outputfile );
fputc( green , *outputfile );
fputc( red , *outputfile );
} /* end WritePixel function */
/* #### MAIN ########################## */
int main(int argc, char* argv[])
{
bmpFileHeader outputFileHeader;
bmpInfoHeader outputInfoHeader;
int fileHeaderSize = 14;
int infoHeaderSize = 40;
int bmpWidth = 3;
int bmpHeight = 5;
int dataSize = bmpWidth * 4 * bmpHeight;
/* 3 bytes per pixel + 1 byte padding for alignment =
4 bytes * width = 12
12 * height = 60
*/
int paddingCount = 0;
int i = 0;
int k = 0;
FILE* ofp;
ofp = fopen( "test.bmp" , "w" );
if( (ofp == NULL) )
{ printf( "Error opening file" );
}
/* #### file header ################################ */
outputFileHeader.bmIdentifier[0] = 'B';
outputFileHeader.bmIdentifier[1] = 'M';
outputFileHeader.filesize[0] = fileHeaderSize + infoHeaderSize + dataSize ;
outputFileHeader.filesize[1] = 0;
outputFileHeader.filesize[2] = 0;
outputFileHeader.filesize[3] = 0;
outputFileHeader.reservedA[0] = 0;
outputFileHeader.reservedA[1] = 0;
outputFileHeader.reservedB[0] = 0;
outputFileHeader.reservedB[1] = 0;
outputFileHeader.dataAddress[0] = fileHeaderSize + infoHeaderSize;
outputFileHeader.dataAddress[1] = 0;
outputFileHeader.dataAddress[2] = 0;
outputFileHeader.dataAddress[3] = 0;
fwrite( outputFileHeader.bmIdentifier , 1 , sizeof( outputFileHeader.bmIdentifier ) , ofp );
fwrite( outputFileHeader.filesize , 1 , sizeof( outputFileHeader.filesize ) , ofp );
fwrite( outputFileHeader.reservedA , 1 , sizeof( outputFileHeader.reservedA ) , ofp );
fwrite( outputFileHeader.reservedB , 1 , sizeof( outputFileHeader.reservedB ) , ofp );
fwrite( outputFileHeader.dataAddress , 1 , sizeof( outputFileHeader.dataAddress ) , ofp );
/* #### info header ################################ */
/* note need func to convert this to 4 bytes */
outputInfoHeader.bmpInfoHeaderSize[0] = infoHeaderSize ;
outputInfoHeader.bmpInfoHeaderSize[1] = 0;
outputInfoHeader.bmpInfoHeaderSize[2] = 0;
outputInfoHeader.bmpInfoHeaderSize[3] = 0;
fwrite( outputInfoHeader.bmpInfoHeaderSize , 1 , sizeof( outputInfoHeader.bmpInfoHeaderSize ) , ofp );
outputInfoHeader.bmpWidth[0] = bmpWidth ;
outputInfoHeader.bmpWidth[1] = 0;
outputInfoHeader.bmpWidth[2] = 0;
outputInfoHeader.bmpWidth[3] = 0;
fwrite( outputInfoHeader.bmpWidth , 1 , sizeof( outputInfoHeader.bmpWidth ) , ofp );
outputInfoHeader.bmpHeight[0] = bmpHeight ;
outputInfoHeader.bmpHeight[1] = 0;
outputInfoHeader.bmpHeight[2] = 0;
outputInfoHeader.bmpHeight[3] = 0;
fwrite( outputInfoHeader.bmpHeight , 1 , sizeof( outputInfoHeader.bmpHeight ) , ofp );
outputInfoHeader.colorPlanes[0] = 1;
outputInfoHeader.colorPlanes[1] = 0;
fwrite( outputInfoHeader.colorPlanes , 1 , sizeof( outputInfoHeader.colorPlanes ) , ofp );
outputInfoHeader.bitsPerPixel[0] = 24;
outputInfoHeader.bitsPerPixel[1] = 0;
fwrite( outputInfoHeader.bitsPerPixel , 1 , sizeof( outputInfoHeader.bitsPerPixel ) , ofp );
outputInfoHeader.bmpCompression[0] = 0;
outputInfoHeader.bmpCompression[1] = 0;
outputInfoHeader.bmpCompression[2] = 0;
outputInfoHeader.bmpCompression[3] = 0;
fwrite( outputInfoHeader.bmpCompression , 1 , sizeof( outputInfoHeader.bmpCompression ) , ofp );
outputInfoHeader.dataSize[0] = dataSize ;
outputInfoHeader.dataSize[1] = 0;
outputInfoHeader.dataSize[2] = 0;
outputInfoHeader.dataSize[3] = 0;
fwrite( outputInfoHeader.dataSize , 1 , sizeof( outputInfoHeader.dataSize ) , ofp );
outputInfoHeader.horizontalResolution[0] = 0;
outputInfoHeader.horizontalResolution[1] = 0;
outputInfoHeader.horizontalResolution[2] = 0;
outputInfoHeader.horizontalResolution[3] = 0;
outputInfoHeader.verticalResolution[0] = 0;
outputInfoHeader.verticalResolution[1] = 0;
outputInfoHeader.verticalResolution[2] = 0;
outputInfoHeader.verticalResolution[3] = 0;
outputInfoHeader.colorsInPalette[0] = 0;
outputInfoHeader.colorsInPalette[1] = 0;
outputInfoHeader.colorsInPalette[2] = 0;
outputInfoHeader.colorsInPalette[3] = 0;
outputInfoHeader.importantColors[0] = 0;
outputInfoHeader.importantColors[1] = 0;
outputInfoHeader.importantColors[2] = 0;
outputInfoHeader.importantColors[3] = 0;
fwrite( outputInfoHeader.horizontalResolution , 1 , sizeof( outputInfoHeader.horizontalResolution ) , ofp );
fwrite( outputInfoHeader.verticalResolution , 1 , sizeof( outputInfoHeader.verticalResolution ) , ofp );
fwrite( outputInfoHeader.colorsInPalette , 1 , sizeof( outputInfoHeader.colorsInPalette ) , ofp );
fwrite( outputInfoHeader.importantColors , 1 , sizeof( outputInfoHeader.importantColors ) , ofp );
/* #### begin bmp data ################################ */
/* from bottom left to bottom right */
/* then start again at the leftmost of the next row up */
/* bottom left = 0,0 -> top right = width, height*/
/* blue 12x2 rectangle
for( k=0 ; k< bmpHeight ; k++ )
{
for( i=0 ; i< bmpWidth ; i++ )
{
WritePixel( &ofp , 255 , 0 , 0 );
}
}
WritePixel( &ofp , 255 , 255 , 255 ); white
*/
/* green? 3x5 rectangle */
for( k=0 ; k< bmpHeight ; k++ )
{
for( i=0 ; i< bmpWidth ; i++ )
{
WritePixel( &ofp , 0 , 255 , 0 );
}
paddingCount = 0 ;
/* if not 4 byte aligned then add padding 0 bytes until */
while( ((bmpWidth + paddingCount) % 4) != 0 )
{
WritePixel( &ofp , 0 , 0 , 0 ); /* black = padding?!?!? */
paddingCount++;
}
}
fclose(ofp);
return 0;
}/* end main */
/* 3 x 2 blue / red
0 255 0
0 255 0
ends with 2 bytes alignment
*/
/* red 3x3 ... but w/ blue top left corner spot
0 0 , 255 bottom left
0 0 , 255
0 0 , 255
0 , 0 , 0
0 0 , 255
0 0 , 255
0 0 , 255
0 0 0
0 0 , 255 255 0 0 = top left
0 0 , 255
0 0 , 255
0 0 0
*/