Skip to main content
gamedev.net
🔒 Locked

Reading bmps - help!

Started by Krynnish Conspiracy Mar 8, 2005 at 2:11 PM 6 replies 1.2k views
Original Post
Krynnish Conspiracy
Krynnish Conspiracy
Well hello, this is my first post... First thing I'm not a newbie to programming, but only recently I've started learning it more seriously and doing programs that are more than simply "wow that's cool now get away". As of now I know C. So my question is: When you read a bitamp file whose widths and heights are not divided by 4, it comes out all streched or just gibberish. I've tried reading the file and then filling rows and columns with pixels I've defined as opaque until it's divided by four, but it doesn't do much change. I've tried a few other things that did absolutly nothing. So, how do I do it? Thanks ahead, and may your compiler never show errors. /// edit: I posted in the beginer forum and it somehow ended up here O-o If you can pass it I'll be grateful.
SuperNerd
SuperNerd
In a Bitmap if the width multipied by bytes per pixel isn't an even number then there is an extra byte that doesn't do anything at the end of every line or row of pixels.
Foot Soldier
Foot Soldier
I had a similar problem with the WORD padding. Here is my code, it took a while to get it right. Just keep paying with it, and you will eventually get it:

    //this is a 24bpp bitmap, so I get the actual pixel width    byteWidth := header.gWdith * 3;    padWidth  := byteWidth;    //i increase the size until it is on a 4 byte boundry    while(padWidth mod 4 <> 0) do      padWidth := padWidth + 1;    //this is the actual image size with no padding    diff := header.gHeight * byteWidth;    //this just sets an array to be the size of the actual image    SetLength(imageData, diff);    SetLength(tempImageData, byteWidth + 1);    header.gSize := diff;        //I set the offset to be the difference between the padded width and the unpadded width    offset := padWidth - byteWidth;    saveCursor := screen.Cursor;    screen.Cursor := crHourGlass;    //loop for every pixel of the image    for index := 0 to (diff - 1) do    begin      //if it is at then end of a line (before the padding), then skip past the padding      if (((index+1) mod (byteWidth)) = 0) then      begin        seek(myFile, filepos(myFile) + (offset));      end;      //read in the byte      BlockRead(myFile, imageData[index], 1);    end;


Sorry that it isn't in C++, but I added in some comments. It shouldn't be hard to convert to C++.
[/source]
Sure is a big 'ol world.
Kippesoep
Kippesoep
This is the so-called "stride" of the bitmap. It means that a scanline in the bitmap must always be a multiple of 4 bytes. When you create a DIB section in Windows, the memory buffer also has this stride. In other words, when you use the DIB routines in Windows itself, you can just load directly without worrying about the padding.

scanlinelength = (width * bitsperpixel) >> 3;stride = (scanlinelength + 3) & ~3;padding = stride - scanlinelength;
Kippesoep
de_matt
de_matt
Aha,

This probably explains why I was having some trouble some time ago when I was working with 24 bit bitmaps. (r (byte), g (byte) b (byte) )

At certain resolutions it worked fine and at others it didn't.

I tried out 32bt (a (byte), r (byte), g (byte) b (byte) ) and that worked because, clearly, it's 4 bytes per pixel.

That's interesting to know.

Sorry for going a bit off-track there "Krynnish Conspiracy"

Matt
Krynnish Conspiracy
Krynnish Conspiracy
Sorry I haven't replied yet, I was busy, but here I am.

Thank you for your replies... I used what SuperNerd said and now it works great (:

Thanks again, I'll be back if I have more question or if I think I know enough to benefit other people.

Until then, farewell, and may none of your programs ever crash!
Kippesoep
Kippesoep
Quote:
Original post by Krynnish Conspiracy
I used what SuperNerd said and now it works great (:


Don't. It's not entirely correct. He assumes the number of bytes must be even (a multiple of two). Rather, it should be a multiple of four (as I posted above).
Kippesoep

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.