1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141
|
struct surface{
vector<color*> data;
int bpp;//bits per pixel
int bpr;//bytes per row (including alignment)
int transparent;
int transparency;
int delay;
int width,height;
RGBQUAD* palette;
BITMAPINFO* bmi;
surface():bpp(0),width(0),height(0),palette(NULL),bmi(NULL){}
~surface();
int draw(int,int,HDC,unsigned);
bool load(char*);
color& operator()(int,int,unsigned);};
surface::~surface(){
int x=0,size=data.size();
for(;x<size;++x){
delete[] data[x];}
delete[] palette;
delete bmi;}
int surface::draw(int x,int y,HDC hdc,unsigned frame=0){
if(frame>=data.size()){
frame=data.size()-1;}
return SetDIBitsToDevice(hdc,x,y,width,height,0,0,0,height,(void*)&data[frame],bmi,0);}
bool load_bmp(HANDLE file,surface& img){
//---All this stuff is exactly as it was before
DWORD read;
//load file header
BITMAPFILEHEADER bfh;
ReadFile(file,&bfh,sizeof(BITMAPFILEHEADER),&read,NULL);
if(read!=sizeof(BITMAPFILEHEADER)){
SHOWERR("ERROR: Failed to read the BMP file header");
return false;}
if(bfh.bfType!=0x4D42){//'BM'
SHOWERR("ERROR: BMP file is invalid");
return false;}
//load info header
BITMAPINFOHEADER bih;
ReadFile(file,&bih,sizeof(BITMAPINFOHEADER),&read,NULL);
if(read!=sizeof(BITMAPINFOHEADER)){
SHOWERR("ERROR: Failed to read the BMP file header");
return false;}
if(bih.biCompression!=0){
SHOWERR("ERROR: BMP file uses an unsupported form of compression");
return false;}
//---New stuff starts here
RGBQUAD* color_table=NULL;
int size=0;
if(bih.biBitCount<16){
if(bih.biClrUsed==0){
size=1<<bih.biBitCount;
color_table=new RGBQUAD[size];}
else{
size=bih.biClrUsed;
color_table=new RGBQUAD[bih.biClrUsed];}
ReadFile(file,color_table,size,&read,NULL);}
//load data
color* data;
char byte;
short word;
unsigned x,y,z;
unsigned bpr=(bih.biBitCount*bih.biWidth)>>8;
//integer alignment
bpr+=(4-bpr%4)%4;
//support for multiple bpp values
if(bih.biHeight>0){
SetFilePointer(file,bih.biSizeImage-bpr,NULL,FILE_CURRENT);}
switch(bih.biBitCount){
case 1:
data=new color[bih.biSizeImage<<3];
for(z=0;z<bih.biHeight;++z){
for(x=0;x<bih.biWidth;++x){
ReadFile(file,&byte,sizeof(char),&read,NULL);
for(y=0;y<8;++y){
data[(z*bih.biWidth+x)<<3+y]=color_table[GETBIT(byte,y)];}}
//skip end of line buffering
if(bih.biHeight<0){
SetFilePointer(file,bpr-bih.biWidth,NULL,FILE_CURRENT);}
else{
SetFilePointer(file,-bpr-bih.biWidth,NULL,FILE_CURRENT);}}
break;
case 2:
data=new color[bih.biSizeImage<<2];
for(x=0;x<bih.biSizeImage;++x){
ReadFile(file,&byte,sizeof(char),&read,NULL);
for(y=0;y<4;++y){
data[x<<2+y]=color_table[GET2BIT(byte,y)];}}
break;
case 4:
data=new color[bih.biSizeImage<<1];
for(x=0;x<bih.biSizeImage;++x){
ReadFile(file,&byte,sizeof(char),&read,NULL);
data[x<<1]=color_table[HINIBBLE(byte)];
data[x<<1+1]=color_table[LONIBBLE(byte)];}
break;
case 8:
data=new color[bih.biSizeImage];
for(x=0;x<bih.biSizeImage;++x){
ReadFile(file,&byte,sizeof(char),&read,NULL);
data[x]=color_table[byte];}
break;
case 16:
data=new color[bih.biSizeImage>>1];
for(x=0;x<bih.biSizeImage;x+=2){
ReadFile(file,&word,sizeof(short),&read,NULL);
data[x]=wtoc24(word);}
break;
//---Case that is currently being tested
case 24:
case 32:
size=bih.biSizeImage>>2;
data=new color[size];
for(z=0;z<bih.biHeight;++z){
for(x=0;x<bih.biWidth;++x){
ReadFile(file,data+z*bih.biWidth+x,sizeof(color),&read,NULL);}
//skip end of line buffering
ReadFile(file,data+z*bih.biWidth+x,bpr-bih.biWidth,&read,NULL);
if(bih.biHeight>0){
SetFilePointer(file,(-bpr-bih.biWidth)<<1,NULL,FILE_CURRENT);}}
//old
/*size=bih.biSizeImage>>2;
data=new color[size];
ReadFile(file,data,size,&read,NULL);*/
break;
default:
SHOWERR("ERROR: BMP has unsupported BPP value\n\nSupported BPP values:\n\t1\n\t2\n\t4\n\t8\n\t16\n\t24\n\t32");
break;}
//---This stuff was pretty much the same before, too
//fill surface with data
img.bmi=new BITMAPINFO;
img.bmi->bmiHeader=bih;
img.data.push_back(data);
img.bpp=32;
img.width=bih.biWidth;
img.height=(bih.biHeight>0?-bih.biHeight:bih.biHeight);
return true;}
|