Archived

This topic is now archived and is closed to further replies.

.bmp file loading is impossible

This topic is 6018 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''ve come to the upsetting conclusion that loading .bmp files is not only frustrating, but not working with Direct Draw. I wrote my own .bmp loader class, and tried to blit my .bmp to my Direct Draw off screen surface, but my surface fails to lock. I tried to load a .bmp with my alternative Direct Draw "ddutil" class that Microsoft wrote, but that is not working either. Is anyone familiar with the "ddutil" class microsoft wrote? I give up. Can anyone help me out? Can anyone post their own .bmp file loading code for me to take a look at. I think my .bmp loading class is working, but when I try to use it with Direct Draw, my surfaces(primary,back,off screen) fail to lock. Please help. Thanx. Edem Attiogbe

Share this post


Link to post
Share on other sites
Ok, here you go:


LPDIRECTDRAWSURFACE7 LoadBmp(LPDIRECTDRAW7 lpDD, TCHAR *file)
{
HDC hdc;
HBITMAP bit;
LPDIRECTDRAWSURFACE7 surf;

// See of it''s a resource or an actual file
bit = (HBITMAP)LoadImage(GetModuleHandle(NULL), file, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE);
if (!bit)
bit = (HBITMAP)LoadImage(NULL, file, IMAGE_BITMAP, 0, 0, LR_DEFAULTSIZE | LR_LOADFROMFILE);

if (!bit)
return NULL;

BITMAP bitmap;
GetObject(bit, sizeof(BITMAP), &bitmap);
int surf_width = bitmap.bmWidth;
int surf_height = bitmap.bmHeight;

// Create Surface
HRESULT hRet;
DDSURFACEDESC2 ddsd;
ZeroMemory(&ddsd, sizeof(DDSURFACEDESC2));
ddsd.dwSize = sizeof(DDSURFACEDESC2);
ddsd.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = surf_width;
ddsd.dwHeight = surf_height;

// Attempt to Create Surface
hRet = lpDD->CreateSurface(&ddsd, &surf, NULL);
if (hRet != DD_OK)
{
DeleteObject(bit);
return NULL;
}
else
{
surf->GetDC(&hdc);
HDC bit_dc = CreateCompatibleDC(hdc);

SelectObject(bit_dc, bit);
BitBlt(hdc, 0, 0, surf_width, surf_height, bit_dc, 0, 0, SRCCOPY);

surf->ReleaseDC(hdc);
DeleteDC(bit_dc);
}

DeleteObject(bit);

return surf;
}


There you go, pretty straightfoward.



"We are the music makers, and we are the dreamers of the dreams."
- Willy Wonka

Share this post


Link to post
Share on other sites
thanx a lot BitBlt. I''ll study your code and compare it to mine. The thing is that I was engineering my .bmp loader to be direct draw independent. anyway, thankx. I will now look at you code.

Edem Attiogbe

Share this post


Link to post
Share on other sites
Hi,

Did you write own bitmap loading program, if so it would be best you scrutinize it well enough, because many a times you want the data and everyone ends up putting & before reading in the data, a silly but non-noticeable mistake and this can cause a lot of problems elsewhere in the program.

I can put in my code but it would be too big so I wouldn''t put it here. But if you do want to see it, just ask and I''ll put it in here.

Share this post


Link to post
Share on other sites
I wrote a BMP loader that was DDraw intependant. I then had a char * to DDSurface function that did the specific changes. The only problems that I ever had were when the bitmaps width where not to the base 2 (ie were not 16,32,64,128 etc). When that happened there where some impossibly strange Skewing problems that seemed to defy logic.

Has somebody had this problem, because no amount of hacking code has ever gotten me closer to figuring out why this happens.

-Chris Bennett of Dwarfsoft - The future of RPGs Thanks to all the goblins in the GDCorner niche

Share this post


Link to post
Share on other sites
Oh, my bad. I didn''t realize that you were trying to load the bitmap in manually. I use my own custom graphics format, so I don''t have any .bmp reading code, well, I may, I''ll check on my hard drive.



"We are the music makers, and we are the dreamers of the dreams."
- Willy Wonka

Share this post


Link to post
Share on other sites
Here''s some code I wrote to load RGB bitmaps with OpenGL. Just rip out all of the engine specific stuff, class variables, and OpenGL stuff, and it should work. Saving bitmaps is a whole lot harder than loading them. I''m still having problems with that .
  
riBool riTexture::LoadBitmap(FILE *File) {
struct {
riUShort Type;
riInt Size;
riShort Res1, Res2;
riInt OffBits;
} BitmapFileHeader;
struct {
riInt Size;
riInt Width;
riInt Height;
riShort Planes;
riShort BitCount;
riInt Compression;
riInt SizeImage;
riInt XPelsPerMeter;
riInt YPelsPerMeter;
riInt ClrUsed;
riInt ClrImportant;
} BitmapInfoHeader;

riUInt BitCheck = 0x00000001;

BitCheck &= fread(&BitmapFileHeader,14,1,File);
BitCheck &= fread(&BitmapInfoHeader,40,1,File);

if(BitCheck != 0x00000001) return RI_FALSE;
if(BitmapFileHeader.Type != 0x4D42 || BitmapInfoHeader.BitCount != 24) return RI_FALSE;
if(BitmapFileHeader.OffBits != 0) fseek(File,14+BitmapFileHeader.OffBits,SEEK_SET);

riUInt Width = BitmapInfoHeader.Width * 3;
riByte *Data = new riByte[Width * BitmapInfoHeader.Height];
riInt Shift = Width % 4;

riAssert(Data);

if(Shift != 0) {
// Load with (evil) padding considered

riByte *At = Data;
for(riInt a=0; a<BitmapInfoHeader.Height; a++) {
fread(At,Width,1,File);
fseek(File,Shift,SEEK_CUR);
At += BitmapInfoHeader.Width;
}
} else {
// Load without considering padding

fread(Data, 3, BitmapInfoHeader.Width * BitmapInfoHeader.Height, File);
}

glGenTextures(1,&TexID);

glBindTexture(GL_TEXTURE_2D, TexID);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, BitmapInfoHeader.Width, BitmapInfoHeader.Height, 0, GL_RGB, GL_UNSIGNED_BYTE, Data);

delete [] Data;
return RI_TRUE;
}


[Resist Windows XP''s Invasive Production Activation Technology!]

Share this post


Link to post
Share on other sites
If you plan on using Windows, you really don''t need to write a bitmap loader per say. The LoadImage function in the Win32 API will create a valid HBITMAP handle for any .bmp image. Once you have this handle, you now have a DIB (Device Independant Bitmap) and this can be used to draw onto a DirectDraw Surface, output back to a JPEG (using Intel''s JPEG Library) and so on. Just a suggestion.

Kevin

-----------------------------
kevin@mayday-anime.com
http://dainteractive.mayday-anime.com

Share this post


Link to post
Share on other sites
The funny thing about my bitmap loader was that I reverted it back to being 100% copied off Andre LaMothe (to see if it would still work) and it worked fine in his programs but it didn''t in mine. Stupid! Something strange to ponder on, but it should work for all and not just the image width of a base 2...

-Chris Bennett of Dwarfsoft - The future of RPGs Thanks to all the goblins in the GDCorner niche

Share this post


Link to post
Share on other sites
quote:
Original post by dwarfsoft
I wrote a BMP loader that was DDraw intependant. I then had a char * to DDSurface function that did the specific changes. The only problems that I ever had were when the bitmaps width where not to the base 2 (ie were not 16,32,64,128 etc). When that happened there where some impossibly strange Skewing problems that seemed to defy logic.

Has somebody had this problem, because no amount of hacking code has ever gotten me closer to figuring out why this happens.



It''s a rather simple problem. Not always that evident if you don''t know about it, but very easy to solve. To put it straight, all scanlines in the bitmap are dword aligned. End of story, problem fixed


"This album was written, recorded and edited at Gröndal, Stockholm in the year of 2000. At this point in time money still ruled the world. Capitalistic thoughts were wide spread. From the sky filled with the fumes of a billionarie''s cigar to the deepest abyss drenched in nuclear waste. A rich kid was a happy kid, oh..dirty, filthy times. Let this be a reminder."
- Fireside, taken from back of the Elite album

Share this post


Link to post
Share on other sites
This topic hits close to home.

I was writig my image classes recently, and GDI was fidling with my 8bit file colours, so i switched BitBlt to memcpy to fix that, but then GDI on Win2K was doing the weird skewing thingie.

Turns out (after muchos debugging), strange thing is GDI wasn''t handling the DWORD padding properly on Win2K, but it was on Win98SE. I got so fed up up with it I wrote my own BMP loader class that uses fopen().

Works great, and can load weird sized BMP''s (e.g. 127 pixels wide), of any colour depth.

It''s a last-ditch solution, but it''s the most educational, flexible, and IMHO best.

Now....to fix the BMP file format so it''s less stupid.
(Custom file formats anyone?) :D
Right....not inverted
Colour components not reversed
Kill any irrelevent header info
The list goes on....


Waassaap!!

Share this post


Link to post
Share on other sites
quote:
Original post by mr_jrt

Now....to fix the BMP file format so it's less stupid.
(Custom file formats anyone?) :D
Right....not inverted
Colour components not reversed
Kill any irrelevent header info
The list goes on....


I just made my engine expect ALL textures to be inverted, it's easier than flipping the inverted targas and bitmaps I'm loading (I forgot to bring that up, but my bitmap code doesn't flip it, since my engine likes its inverted textures ).

[EDIT: Third edit, hopefully my grammar is finally fixed]

[Resist Windows XP's Invasive Production Activation Technology!]

Edited by - Null and Void on June 22, 2001 7:18:09 AM

Share this post


Link to post
Share on other sites