#include <dos.h>
#include <stdio.h>
#include <alloc.h>
#include <stdlib.h>
#define PALETTE_READ 0x3C7 /*VGA系统调色板读端口*/
#define PALETTE_WRITE 0x3C8 /*VGA系统调色板写端口*/
#define PALETTE_DATA 0x3C9 /*VGA系统调色板数据端口*/
/*第一部分为位图文件头BITMAPFILEHEADER,其定义如下:*/
typedef struct tagBITMAPFILEHEADER
{
unsigned int bfType; /*指定文件类型,*.bmp文件的头两个字节都是"BM"*/
unsigned long bfSize; /*指定文件大小,包括这14个字节*/
unsigned int Reserved1; /*为保留字,不用考虑*/
unsigned int reserved2; /*为保留字,不用考虑*/
unsigned long bfOffset; /*为从文件头到实际的位图数据的偏移字节数,前三个部分的长度之和。*/
}BITMAPFILEHEADER;
/*第二部分为位图信息头BITMAPINFOHEADER,这个结构的长度是固定的,为40个字节其定义如下:*/
typedef struct tagBITMAPINFOHEADER
{
unsigned long biSize; /*指定这个结构的长度,为40*/
unsigned long biWidth; /*指定图象的宽度,单位是象素*/
unsigned long biHeight; /*指定图象的高度,单位是象素*/
unsigned int biPlanes; /*必须是1,不用考虑*/
unsigned int biBitCount; /*指定表示颜色时要用到的位数,常用的值为1(黑白二色图),4(16色图),8(256色),24(真彩色图)*/
unsigned long biCompression; /*指定位图是否压缩,有效的值为BI_RGB,BI_RLE8,BI_RLE4,BI_BITFIELDS*/
unsigned long biSizeImage; /*指定实际的位图数据占用的字节数*/
unsigned long biXpolsPerMeter; /*指定目标设备的水平分辨率,单位是每米的象素个数。*/
unsigned long biYpelsPerMeter; /*指定目标设备的垂直分辨率,单位同上。*/
unsigned long biClrUsed; /*指定本图象实际用到的颜色数,如果该值为零,则用到的颜色数为2的biBitCount次方。*/
unsigned long biClrImportant; /*指定本图象中重要的颜色数,如果该值为零,则认为所有的颜色都是重要的。*/
}BITMAPINFOHEADER;
typedef struct tagRGBQUAD /*用于读取256色BMP图片调色板信息*/
{
unsigned char rgbBlue;
unsigned char rgbGreen;
unsigned char rgbRed;
unsigned char Reserved;
}RGBQUAD;
typedef struct tagRGB
{
unsigned char b;
unsigned char g;
unsigned char r;
}RGB;
typedef RGB PALETTE[256];
typedef unsigned char BOOL;
/////////////////////////////////////////////////////////////////////////////////////////////////
//设置单个调色板
/////////////////////////////////////////////////////////////////////////////////////////////////
void SetPalette(unsigned char i, unsigned char r, unsigned char g, unsigned char b)
{
outportb(PALETTE_WRITE,i);
outportb(PALETTE_DATA,r);
outportb(PALETTE_DATA,g);
outportb(PALETTE_DATA,b);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//取得单个调色板
/////////////////////////////////////////////////////////////////////////////////////////////////
void GetPalette(unsigned char i, unsigned char *r, unsigned char *g, unsigned char *b)
{
outportb(PALETTE_READ,i);
*r = inportb(PALETTE_DATA);
*g = inportb(PALETTE_DATA);
*b = inportb(PALETTE_DATA);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
//BMP图显示函数
/////////////////////////////////////////////////////////////////////////////////////////////////
void ShowBMP_256(char *File_Name, int x, int y)
{
int i, j, width;
unsigned char *buffer;
RGB *RGB_buffer;
FILE *fp;
RGBQUAD *bmp_rgb; // depth=8时的调色板信息
BITMAPFILEHEADER *FileHead; // 位图文件头
BITMAPINFOHEADER *InfoHead; // 位图信息头
if ((bmp_rgb = (RGBQUAD *)malloc(sizeof(RGBQUAD))) == NULL)
return;
if ((FileHead = (BITMAPFILEHEADER *)malloc(sizeof(BITMAPFILEHEADER))) == NULL)
return;
if ((InfoHead = (BITMAPINFOHEADER*)malloc(sizeof(BITMAPINFOHEADER))) == NULL)
return;
if ((fp=fopen(File_Name,"rb")) == NULL)
return;
fread(FileHead,sizeof(BITMAPFILEHEADER),1,fp);
if (FileHead->bfType!='BM')
return;
fread(InfoHead,sizeof(BITMAPINFOHEADER),1,fp);
if (InfoHead->biCompression !=0 || (InfoHead->biBitCount!=8 && InfoHead->biBitCount!=24))
{
fclose(fp);
return;
}
if ((int)InfoHead->biBitCount == 8) // 色深=8
{
for (i = 0 ; i < 256 ; i++)
{
fread(bmp_rgb,sizeof(RGBQUAD),1,fp);
SetPalette(i,bmp_rgb->rgbRed>>2,bmp_rgb->rgbGreen>>2,bmp_rgb->rgbBlue>>2);
}
width =((int)InfoHead->biWidth+3)/4*4; // 每行字节数--4的整数倍
if ((buffer = (unsigned char *)malloc(width)) == NULL)
{
fclose(fp);
return;
}
for (j = (int)InfoHead->biHeight-1 ; j >= 0 ; j--)
{
fread(buffer,width,sizeof(unsigned char),fp);
for(i = 0; i < width; i++)
PutPixel(i+x,j+y,buffer[i]);
}
free(buffer);
}
/////////////////////////////////////////////////////////////////////////////////////////////////
// 目前BMP真彩色显示还未搞清原理
/////////////////////////////////////////////////////////////////////////////////////////////////
else if ((int)InfoHead->biBitCount == 24) // 色深=24
{
}
free(FileHead);
free(InfoHead);
free(bmp_rgb);
}