Loading BMPs

I'm trying to edit my BMP loader function to make it load bitmaps with less than 24 bpp, and with positive height. Right now I'm trying to load a 24-bit bitmap, and the draw function is returning 0 (meaning it failed). I'm almost positive it has to do with the loader. So, can anyone help me figure this out?

What I have so far (It was working before I added the big switch statement)

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;}
Well, I guess it is a lot of code to go over for no real gain... Can anyone give some sample code for loading a 24-bit bitmap even if height>0? I could probably build off of that.
Topic archived. No new replies allowed.