|
||
|
GP Mailing List
ATXGPSIG List
|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: The Windows BMP File Format
Hey, guess what! I forgot to attach BMP.H! Sorry, I'm just an idiot. -Ender Wiggin
unsigned char *VGA=(unsigned char *)0xA0000000L; /* this points to video memory. */
struct Picture {
unsigned short x,y;
unsigned char *picture;
unsigned char *palette;
} Pict;
struct BMP1 {
/******FILE HEADER****************/
unsigned short bfType; // Must be set to 'BM'
unsigned long bfSize; // The size of the file in bytes
unsigned short bfReserved1; // Reserved for future expansion
unsigned short bfReserved2; // Reserved for future expansion
unsigned long bfOffBits; // The number of bytes before bitmap
};
struct BMP1 BMPFILEHEADER;
struct BMP2 {
/******BITMAP HEADER**************/
unsigned long biSize; // The size of this header: 40
unsigned long biWidth; // The width in pixels
unsigned long biHeight; // The height in pixels
unsigned short biPlanes; // The number of planes (1)
unsigned short biBitCount; // The number of bits per pixel
unsigned long biCompression; // The type of compression
unsigned long biSizeImage; // Size of image in bytes when compressed
unsigned long biXPelsPerMeter;// The horizontal number of pix/meter
unsigned long biYPelsPerMeter;// The vertical number of pix/meter
unsigned long biClrUsed; // The number of colors that are used
unsigned long biClrImportant;// The number of important colors
} BMPINFOHEADER;
struct BMP3 {
/******OS/2 BITMAP HEADER*********/
unsigned long bcSize; // The size of this header: 12
unsigned short bcWidth; // The width in pixels
unsigned short bcHeight; // The height in pixels
unsigned short bcPlanes; // The number of planes (1)
unsigned short bcBitCount; // The number of bits per pixel
} BMPCOREINFO;
#define fskip(fp,n) { \
int i; \
for(i=0;i<n;i++) \
fgetc(fp); \
}
void WaitRetrace() {
asm mov dx,3DAh
l1:
asm {
in al,dx
and al,08h
jnz l1
}
l2:
asm {
in al,dx
and al,08h
jz l2
}
}
void inline DrawPixelXY(short x,unsigned char y,unsigned char color) {
VGA[(y<<8)+(y<<6)+x]=color;
}
unsigned char inline GetPixelXY(short x, unsigned char y) {
return VGA[(y<<8)+(y<<6)+x];
}
void inline DrawPixelRaw(unsigned short a, unsigned char color) {
VGA[a]=color;
}
void DrawPicture(unsigned short xoffset, unsigned short yoffset, Picture &P) {
unsigned short pos=0;
for(unsigned short y=0;y<P.y;y++)
for(unsigned short x=0;x<P.x;x++) {
DrawPixelXY(x+xoffset,y+yoffset,P.picture[pos]);
pos++;
}
}
void DrawPictureRGB(unsigned short xoffset, unsigned short yoffset, Picture &P, unsigned char which) {
unsigned long pos=which;
for(unsigned short y=0;y<P.y;y++)
for(unsigned short x=0;x<P.x;x++) {
DrawPixelXY(x+xoffset,y+yoffset,P.picture[pos]);
pos+=3;
}
}
int LoadBMP(char *file, Picture *P) {
FILE *fp;
long index;
int x,type,cnt,c,d; // type: 0=OS/2, 1=Windows
double a,b;
unsigned char reed;
if((fp=fopen(file,"rb"))==NULL) {
return 1; // Error opening file
}
fread(&BMPFILEHEADER,sizeof(BMPFILEHEADER),1,fp);
fread(&BMPINFOHEADER.biSize,sizeof(BMPINFOHEADER.biSize),1,fp);
if(BMPINFOHEADER.biSize==40) { // Windows
fread(&BMPINFOHEADER.biWidth,36,1,fp); // 36 = 40 - 4
P->x=BMPINFOHEADER.biWidth;
P->y=BMPINFOHEADER.biHeight;
type=1;
}
if(BMPINFOHEADER.biSize==12) { // OS/2
BMPCOREINFO.bcSize=BMPINFOHEADER.biSize; // 12
fread(&BMPCOREINFO.bcWidth,8,1,fp); // 8 = 12 - 4
P->x=BMPCOREINFO.bcWidth;
P->y=BMPCOREINFO.bcHeight;
type=0;
}
if((BMPINFOHEADER.biSize!=40)&&(BMPINFOHEADER.biSize!=12))
return 5; // Unknown BMP type or corrupted header
if(((!type)&&(BMPCOREINFO.bcBitCount==8))||(type)&&(BMPINFOHEADER.biBitCount==8)) { // Test for 8 bit
if((P->picture=new unsigned char[P->x*P->y])==NULL) {
fclose(fp);
return 3; // Not enough memory for picture
}
if((P->palette=new unsigned char[256*3])==NULL) {
fclose(fp);
return 4; // Not enough memory for palette
}
for(index=0;index<256;index++) {
P->palette[(int)(index*3+2)]=fgetc(fp)>>2;
P->palette[(int)(index*3+1)]=fgetc(fp)>>2;
P->palette[(int)(index*3+0)]=fgetc(fp)>>2;
if(type) x=fgetc(fp);
}
if(((type)&&(!BMPINFOHEADER.biCompression))||(!type)) { // Test for compressed
for(index=(P->y-1)*P->x;index>=0;index-=P->x)
for(x=0;x<P->x;x++)
P->picture[(index+x)]=(unsigned char)fgetc(fp);
}
if((type)&&(BMPINFOHEADER.biCompression)) {
index=(P->y-1)*P->x;
while(index>=0) {
x=0;
while(x<P->x) {
reed=fgetc(fp);
if(!reed) { // Literal or special
c=fgetc(fp);
if(c==2) {
x+=fgetc(fp);
index-=(P->x*fgetc(fp));
}
if((c!=0)&&(c!=1)&&(c!=2)) {
for(cnt=0;cnt<c;cnt++) {
P->picture[index+x]=(unsigned char)fgetc(fp);
x++;
}
a=(float)c;
if(modf(a/2,&b)) {
d=fgetc(fp); // even byte padding
}
}
} else { // RLE
d=fgetc(fp); // what to store
for(cnt=0;cnt<reed;cnt++) {
P->picture[index+x]=(unsigned char)d;
x++;
}
}
}
index-=P->x;
}
}
}
if(((!type)&&(BMPCOREINFO.bcBitCount==24))||((type)&&(BMPINFOHEADER.biBitCount==24))) { // Test for 24 bit
if((P->picture=new unsigned char[P->x*P->y*3])==NULL) {
fclose(fp);
return 3; // Not enough memory for picture
}
for(index=P->y;index>=0;index--)
for(x=0;x<P->x;x++) {
P->picture[(index*P->x+x)*3+2]=fgetc(fp);
P->picture[(index*P->x+x)*3+1]=fgetc(fp);
P->picture[(index*P->x+x)*3+0]=fgetc(fp);
}
}
if (((!type)&&(BMPCOREINFO.bcBitCount!=24)&&(BMPCOREINFO.bcBitCount!=8))||
((type)&&(BMPINFOHEADER.biBitCount!=24)&&(BMPINFOHEADER.biBitCount!=8)))
return 2; // Unsupported number of bits per pixel
fclose(fp);
return 0; // No error, successful
}
void UnDrawPicture(unsigned short xoffset, unsigned short yoffset, Picture &P, unsigned char color) {
unsigned short pos=0;
for(unsigned short y=0;y<P.y;y++)
for(unsigned short x=0;x<P.x;x++) {
DrawPixelXY(x+xoffset,y+yoffset,color);
pos++;
}
}
void set_palette(unsigned char *palette) {
int i;
outp(0x3c8,0); /* tell the VGA that palette data
is coming. */
for(i=0;i<256*3;i++)
outp(0x3c9,palette[i]); /* write the data */
}
|
|