Hi,
I'm writing a class that controls Bitmap I/O. here's the working code:

#ifndef __linux__
#include <windows.h>
#endif

#include  <stdio.h>

// Our functions



class FEN
{
int not_defined_yet;      
};

class fileBITMAP
{
public:
BITMAPFILEHEADER file_header;
BITMAPINFOHEADER info_header;
RGBTRIPLE* image_data;



fileBITMAP (int width, int height);


int writetodisk(FILE* handle)
{

printf("writing header...");
fwrite(&file_header,sizeof(BITMAPFILEHEADER),1,handle);
printf("done\nwriting info...");
fwrite(&info_header,sizeof(BITMAPINFOHEADER),1,handle);
printf("done\nwriting data...");
fwrite(image_data,sizeof(RGBTRIPLE), info_header.biWidth*info_header.biHeight,handle);
printf("done.");
}

int readfromdisk(FILE* handle)
{
fread(&file_header,1, sizeof(BITMAPFILEHEADER),handle);
fread(&info_header,1, sizeof(BITMAPINFOHEADER),handle);
fread(image_data,sizeof(RGBTRIPLE), info_header.biWidth*info_header.biHeight,handle);
}

RGBTRIPLE get_pixel(int x,int y)
{
 return image_data[(info_header.biHeight-1-y)*info_header.biWidth+x];
}

void set_pixel(int x,int y, RGBTRIPLE &color)
{
 image_data[(info_header.biHeight-1-y)*info_header.biWidth+x] = color;
}


};

fileBITMAP::fileBITMAP(int width, int height)
{
  file_header.bfType = 'M'*256+'B';                 
  file_header.bfSize=sizeof(BITMAPFILEHEADER);
  file_header.bfReserved1=0;
  file_header.bfReserved2=0;
  file_header.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
           
  info_header.biSize=sizeof(BITMAPINFOHEADER); 
  info_header.biWidth=width; 
  info_header.biHeight=height;
  info_header.biPlanes=1;        
  info_header.biBitCount=24;     
  info_header.biCompression=0;   
  info_header.biSizeImage=sizeof(RGBTRIPLE)*width*height; 
  info_header.biXPelsPerMeter=2400;
  info_header.biYPelsPerMeter=2400;
  info_header.biClrUsed=0;       
  info_header.biClrImportant=0;  
  image_data=new RGBTRIPLE [info_header.biWidth*info_header.biHeight];
}


fileBITMAP build_board ( FEN position );







int main () 
{
FILE* h;

fileBITMAP x(320,320);

int i,j;

RGBTRIPLE black, white;
black.rgbtBlue=170;
black.rgbtGreen=160;
black.rgbtRed=10;

white.rgbtBlue=255;
white.rgbtGreen=255;
white.rgbtRed=255;

for (i=0;i<320;i++) for(j=0;j<320;j++) 

{
 //printf("%d,%d \n",i,j);
 x.set_pixel(i,j,black);

    
}     
printf("all ok!");

h=fopen ("c:\\a.bmp","wb");
if (!h) printf("uh oh");

x.writetodisk(h);     

fclose(h);

return 1;
}

in short, this makes a bitmap file named "a.bmp" on root of drive C, which is a 24-bit uncompressed bitmap of plain color "0AA0AA" (something between blue and green)
it's using struct definitions from windows.h, since it's being compiled on windows.

now, I went into windows.h and related headers, and extracted those struct definitions, and put them directly into the code. then removed the include line of windows.h. this is the resulting code:

#include  <stdio.h>

// Things we need from windows.h header


typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef unsigned char BYTE;
typedef long LONG;









typedef struct tagRGBTRIPLE {
	BYTE rgbtBlue;
	BYTE rgbtGreen;
	BYTE rgbtRed;
} RGBTRIPLE,*LPRGBTRIPLE;



typedef struct tagBITMAPFILEHEADER {
	WORD	bfType;
	DWORD	bfSize;
	WORD	bfReserved1;
	WORD	bfReserved2;
	DWORD	bfOffBits;
} BITMAPFILEHEADER,*LPBITMAPFILEHEADER,*PBITMAPFILEHEADER;



typedef struct tagBITMAPINFOHEADER{
	DWORD	biSize;
	LONG	biWidth;
	LONG	biHeight;
	WORD	biPlanes;
	WORD	biBitCount;
	DWORD	biCompression;
	DWORD	biSizeImage;
	LONG	biXPelsPerMeter;
	LONG	biYPelsPerMeter;
	DWORD	biClrUsed;
	DWORD	biClrImportant;
} BITMAPINFOHEADER,*LPBITMAPINFOHEADER,*PBITMAPINFOHEADER;



// Our functions



class FEN
{
int not_defined;      
};

class fileBITMAP
{
public:
BITMAPFILEHEADER file_header;
BITMAPINFOHEADER info_header;
RGBTRIPLE* image_data;



fileBITMAP (int width, int height);


int writetodisk(FILE* handle)
{

printf("writing header...");
fwrite(&file_header,sizeof(BITMAPFILEHEADER),1,handle);
printf("done\nwriting info...");
fwrite(&info_header,sizeof(BITMAPINFOHEADER),1,handle);
printf("done\nwriting data...");
fwrite(image_data,sizeof(RGBTRIPLE), info_header.biWidth*info_header.biHeight,handle);
printf("done.");
}

int readfromdisk(FILE* handle)
{
fread(&file_header,1, sizeof(BITMAPFILEHEADER),handle);
fread(&info_header,1, sizeof(BITMAPINFOHEADER),handle);
fread(image_data,sizeof(RGBTRIPLE), info_header.biWidth*info_header.biHeight,handle);
}

RGBTRIPLE get_pixel(int x,int y)
{
 return image_data[(info_header.biHeight-1-y)*info_header.biWidth+x];
}

void set_pixel(int x,int y, RGBTRIPLE &color)
{
 image_data[(info_header.biHeight-1-y)*info_header.biWidth+x] = color;
}


};

fileBITMAP::fileBITMAP(int width, int height)
{
  file_header.bfType = 'M'*256+'B';                 
  file_header.bfSize=sizeof(BITMAPFILEHEADER);
  file_header.bfReserved1=0;
  file_header.bfReserved2=0;
  file_header.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
           
  info_header.biSize=sizeof(BITMAPINFOHEADER); 
  info_header.biWidth=width; 
  info_header.biHeight=height;
  info_header.biPlanes=1;        
  info_header.biBitCount=24;     
  info_header.biCompression=0;   
  info_header.biSizeImage=sizeof(RGBTRIPLE)*width*height; 
  info_header.biXPelsPerMeter=2400;
  info_header.biYPelsPerMeter=2400;
  info_header.biClrUsed=0;       
  info_header.biClrImportant=0;  
  image_data=new RGBTRIPLE [info_header.biWidth*info_header.biHeight];
}


fileBITMAP build_board ( FEN position );







int main () 
{
FILE* h;

fileBITMAP x(320,320);

int i,j;

RGBTRIPLE black, white;
black.rgbtBlue=170;
black.rgbtGreen=160;
black.rgbtRed=10;

white.rgbtBlue=255;
white.rgbtGreen=255;
white.rgbtRed=255;

for (i=0;i<320;i++) for(j=0;j<320;j++) 

{
 //printf("%d,%d \n",i,j);
 x.set_pixel(i,j,black);

    
}     
printf("all ok!");

h=fopen ("c:\\a.bmp","wb");
if (!h) printf("uh oh");

x.writetodisk(h);     

fclose(h);

return 1;
}

this also compiles successfully. but the problem is, the resulting bitmap file is not of the standard format.

I've compared the former bitmap with this new one, and I found something strange:

header of standard bitmap created by the first program:

42 4D 0E 00 00 00 00 00 00 00 36 00 00 00 28 00 00 00 40 01 00 00 40 01 00 00 01 00 18 00 00 00 00 00 00 B0 04 00 60 09 00 00 60 09 00 00 00 00 00 00 00 00 00 00

header of the non standard one created by second program:

42 4D 10 08 28 00 00 00 00 00 00 00 38 00 00 00 28 00 00 00 40 01 00 00 40 01 00 00 01 00 18 00 00 00 00 00 00 B0 04 00 60 09 00 00 60 09 00 00 00 00 00 00 00 00 00 00

the second one is two bytes longer. the green hex values confirm this fact. (first one is sizeof(BITMAPFILEHEADER) and second one is sizeof(BITMAPINFOHEADER)+sizeof(BITMAPFILEHEADER) ) those red hex values are the extra bytes. I have no idea where do they came from, and, the definitions of BITMAPFILEHEADER struct and DWORD, WORD and BYTE exactly match their definitions in windows.h header. what do you think I did wrong here?

ok, here's another strange thing:

in first program, sizeof(BITMAPFILEHEADER) returns 14,
in second program, sizeof(BITMAPFILEHEADER) returns 16,

and BITMAPFILEHEADER is defined exactly the same in both!! the only difference is that in first program, it loads the struct from wingdi.h, and in second one, it is implemented in the code.

now, I went into windows.h and related headers, and extracted those struct definitions, and put them directly into the code. then removed the include line of windows.h.

Honestly, why did you do this? It's possible that some of the windows code uses defined values that may be modified outside of those files.

Example

file a has code in it, some of the code uses a define called MAX_NUMBER and it is set to 5. When the end of the file is reached MAX_NUMBER has the value 7. If you're using the same code as file a in a different file where MAX_NUMBER is 7, you'll get different results.

Extracting code from one file to migrate into your own is dangerous, because some of the definitions may have different values (or no value?)

This article has been dead for over six months. Start a new discussion instead.