Sign in to follow this  

loading bmp

This topic is 2545 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.

Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites
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));
//...

Share this post


Link to post
Share on other sites
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: 19778
bfSize: 70
bfReserved1: 0
bfReserved2: 0
bfOffBits: 54

|================================|
| Bitmap Info Header |
|================================|

biSize: 40
biWidth: 2
biHeight: 2
biPlanes: 1
biBitCount: 24
biCompression: 0
biSizeImage: 16
biXPelsPerMeter: 2835
biYPelsPerMeter: 2835
biClrUsed: 0
biClrImportant: 0


Share this post


Link to post
Share on other sites
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.

Share this post


Link to post
Share on other sites

This topic is 2545 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this