Image drawing issue

I set up a simple program to load and draw a 24/32-bit BMP file, but it isn't being drawn to the screen. Unfortunately, I can't for the life of me figure out why. Here is my code:

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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
#include <vector>
#include <iostream>
#include <stdexcept>
#include <windows.h>
using namespace std;

#define SHOWERR(x) MessageBox(0,x,"ERROR",MB_OK|MB_ICONEXCLAMATION)

typedef uint8_t uint8;

//this structure holds the rgba values of a color (standard bmp color order)
struct color{
	uint8 b,g,r,x;
	color(uint8 R,uint8 G,uint8 B,uint8 X=255):b(B),g(G),r(R),x(X){}
	color():b(0),g(0),r(0),x(255){}
	color(RGBQUAD rgb):b(rgb.rgbBlue),g(rgb.rgbGreen),r(rgb.rgbRed),x(rgb.rgbReserved){}}c_trans(0,0,0,0);

//this structure holds the necessary code and variables for image-handling
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()){
		throw std::out_of_range("surface::draw(x,y,HDC,frame=0)");}
	return SetDIBitsToDevice(hdc,x,y,width,height,0,0,0,height,(void*)data[frame],bmi,DIB_RGB_COLORS);}

color& surface::operator()(int x,int y,unsigned frame=0){
	if(x>width || y>height || frame>data.size()){
		throw std::out_of_range("surface::operator()(x,y,frame=0)");}
	return data[frame][y*width+x];}

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;
	unsigned 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=0;
	int 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){
		//--- I have other bit count cases here, but they're not finished yet
		case 24:
		case 32:
			size=bih.biSizeImage/4;
			data=new color[size];
			for(z=0;z<bih.biHeight;++z){
				ReadFile(file,data+z*bih.biWidth+x,bih.biWidth*sizeof(color)+bpr,&read,NULL);
				if(bih.biHeight>0){
					SetFilePointer(file,-(bpr+bih.biWidth)*2,NULL,FILE_CURRENT);}}
			break;}
	//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;}

char* get_ext(char* fname,char* ext,unsigned len=0){
	if(len==0){
		len=strlen(fname);}
	--len;
	unsigned x;
	for(x=len;fname[x]!='.' && x>0;--x){}
	++x;
	ext=new char[len-x+1];
	memcpy(ext,fname+x,len-x+1);
	return ext;}

bool surface::load(char* fname){
	HANDLE file=CreateFile(fname,GENERIC_READ,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);
	if(file==INVALID_HANDLE_VALUE){
		SHOWERR("ERROR: Couldn't load image file");
		return false;}
	char* ext=NULL;
	ext=get_ext(fname,ext);
	bool loaded=false;
	if(!memcmp(ext,"bmp",3)){
		loaded=load_bmp(file,*this);}
	else{
		SHOWERR("ERROR: File format not supported.\n\nSupported file formats:\n\t.BMP");
		return false;}
	delete[] ext;
	CloseHandle(file);
	return loaded;}

LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
PAINTSTRUCT ps;
HDC hdc;
surface img;

int WINAPI WinMain(HINSTANCE hinst,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow){
	MSG	msg;
	WNDCLASS wc={0};
	wc.lpszClassName=TEXT("Center");
	wc.hInstance=hinst;
	wc.hbrBackground=GetSysColorBrush(COLOR_3DFACE);
	wc.lpfnWndProc= WndProc;
	wc.hCursor=LoadCursor(0,IDC_ARROW);
	RegisterClass(&wc);
	HWND hwnd=CreateWindow(wc.lpszClassName,TEXT("Center"),WS_OVERLAPPEDWINDOW|WS_VISIBLE,100,100,250,150,0,0,hinst,0);
	HANDLE file=OPENFILER("mybmp.bmp");
	if(file==INVALID_HANDLE_VALUE){
		SHOWERR("ERROR: Failed to load BMP file");
		exit(1);}
	if(!load_bmp(file,img)){
		exit(2);}
	InvalidateRect(hwnd,NULL,false);
	while(GetMessage(&msg,NULL,0,0)){
		TranslateMessage(&msg);
		DispatchMessage(&msg);}
	return msg.wParam;}

LRESULT CALLBACK WndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam){
	switch(msg){
		case WM_DESTROY:
			PostQuitMessage(0);
			return 0;
		case WM_PAINT:
			hdc=BeginPaint(hwnd,&ps);
			img.draw(0,0,hdc,0);
			EndPaint(hwnd,&ps);
			return 0;}
	return DefWindowProc(hwnd,msg,wParam,lParam);}
Bump
The load_bmp function does not work for me.
Crashes.
I've narrowed it down to this part of the function:
1
2
3
4
5
6
7
8
9
            
for(z=0;z<bih.biHeight;++z)
{
      ReadFile(file,data+z*bih.biWidth+x,bih.biWidth*sizeof(color)+bpr,&read,NULL);
      if(bih.biHeight>0)
      {
             SetFilePointer(file,-(bpr+bih.biWidth)*2,NULL,FILE_CURRENT);
       }
}
Topic archived. No new replies allowed.