loading bmp

Started by
3 comments, last by karwosts 13 years, 4 months ago
I'm trying to load a bitmap into memory by myself and I think I have it down but there are a few things that are confusing me a bit. I don't know if this is right or not.

In my function "format24BMP" there is an if statement "x == byteWidth"... it should enter it 100 times but it appears to only enter it once.

Here are my relevant functions to loading the bitmap:

bool Bitmap::readBMP(char* fn){	fname = fn;	ifstream inf(fname,ios::binary|ios::in);		if(!inf.is_open()){		return false;	}	//read in BITMAPFILEHEADER	inf.read((char*)&bmfh->bfType,2);		if(bmfh->bfType!=BITMAP_ID){		return false;	}		inf.read((char*)&bmfh->bfSize,4);	inf.read((char*)&bmfh->bfReserved1,2);	inf.read((char*)&bmfh->bfReserved2,2);	inf.read((char*)&bmfh->bfOffBits,4);	//read in BITMAPINFOHEADER	inf.read((char*)&bmih->biSize,4);	inf.read((char*)&bmih->biWidth,4);	inf.read((char*)&bmih->biHeight,4);	inf.read((char*)&bmih->biPlanes,2);	inf.read((char*)&bmih->biBitCount,2);	inf.read((char*)&bmih->biCompression,4);	inf.read((char*)&bmih->biSizeImage,4);	inf.read((char*)&bmih->biXPelsPerMeter,4);	inf.read((char*)&bmih->biYPelsPerMeter,4);	inf.read((char*)&bmih->biClrUsed,4);	inf.read((char*)&bmih->biClrImportant,4);	//has no color table and 3 bytes represents 1 pixel	if(bmih->biBitCount == 24){		byteWidth = bmih->biWidth*3;		//get the length of the padded byte rows		if(bmih->biWidth%4!=0){			padWidth = byteWidth;			padWidth = (int)((padWidth/4)+1);			padWidth *= 4;		}		//no padded bytes		else{			padWidth = byteWidth;		}		//get the absolute value of height		if(bmih->biHeight < 0)		{			byteHeight = (bmih->biHeight*-1);		}		else		{			byteHeight = (bmih->biHeight);		}		pImgSize = bmfh->bfSize - bmfh->bfOffBits;		imgSize = byteWidth*byteHeight;		//get the number of padded bytes per row		padBytes = padWidth - byteWidth;		//read in unformated data		char* tPData = new char[pImgSize];		inf.read(tPData,pImgSize);		//now format pixel data		format24BMP(tPData); //stores formatted data in aColors	}	return true;}



void Bitmap::format24BMP(char* tPData){	aColors = new char[imgSize];	//if bmih->biHeight is positive, the pixel data is backwards	if(bmih->biHeight > 0){		int end = imgSize - 3;		for(int x = 0; x < pImgSize; x+=3){						if(x == byteWidth){				x+=padBytes; //skip the padded bytes			}			aColors[end] = tPData[x+2];			aColors[end+1] = tPData[x+1];			aColors[end+2] = tPData[x];			end -= 3;		}		}	else{			}}


I admit I followed one of the tutorials on gamedev but I tried to do most of it on my own. Right now I'm only trying to get it to work with 24bpp and I have a specific file I'm working with just trying to make sure it works with it and I know it won't go into the empty else statement etc.

I didn't pack my structures so I had to read my data in the way I did in my function.
Advertisement
Have you tried following this in your debugger? This would be a good exercise to learn on if you don't know how. I would think that stepping through you should be able to identify the problems without too much trouble.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
karwosts' suggestion is good. Also, you can make your code much more readable (and easier to maintain) if you read in each of the headers in one statement, rather than reading in each variable by itself.

E.g.,
inf.read((unsigned char*)&bmfh,sizeof(BITMAPFILEHEADER));//...inf.read((unsigned char*)&bmih,sizeof(BITMAPINFOHEADER));//...

Please don't PM me with questions. Post them in the forums for everyone's benefit, and I can embarrass myself publicly.

You don't forget how to play when you grow old; you grow old when you forget how to play.

Ok, I've done some debugging (not with an IDE but some useful results)

I created a 2x2 24bpp bmp file. It's structure was like this:

 (50,50,50)      (100,100,100)(200,200,200)    (255,255,255)


Now below are the results I printed out. They aren't in the right order and for some reason I'm getting 255's and 200's as negatives (like they were too large to fit but they weren't)

All the other data is right... the size of padding of bytes in the file is 2. I checked with my hexeditor...

Basically... it seems as though the problem is with the logic of my for loop in format24BMP()

If you guys can see it please let me know. I'll continue trying to tweak it.

My Results

|=========================================||           Bitmap Calculations           ||=========================================|padWidth: 8padBytes: 2byteHeight: 2byteWidth: 6|=========================================||                Pixel Data               ||=========================================|100	100	100	50	50	50	-1	-1	-1	-56	-56	-56|=================================||       Bitmap File Header        ||=================================|bfType: 19778bfSize: 70bfReserved1: 0bfReserved2: 0bfOffBits: 54|================================||       Bitmap Info Header       ||================================|biSize: 40biWidth: 2biHeight: 2biPlanes: 1biBitCount: 24biCompression: 0biSizeImage: 16biXPelsPerMeter: 2835biYPelsPerMeter: 2835biClrUsed: 0biClrImportant: 0


Quote:Ok, I've done some debugging (not with an IDE but some useful results)


You need to learn to use your IDE, you'll be able to solve this much faster that way. It's built for situations like this.

That aside, the reason you see negative numbers is because a char ranges from -128 to 127, so a 255 wraps around to become -1. Their binary representation is exactly the same though (both are represented by 8'b11111111), so that's probably not the source of your problem.

Use unsigned char if you want to range from 0 to 255.
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game

This topic is closed to new replies.

Advertisement