Jump to content
  • Advertisement

Archived

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

Qoy

Bitmap problem

This topic is 6930 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 am having a problem with my bitmap loading and drawing functions. I wanted to ask first, to see if anyone has had the same problem, but if it''s too undescriptive, I''ll post code (or a link to code) and maybe some pictures tomorrow. The problem is that when the bitmap file is of certain dimensions (not the rect I''m drawing, but the whole file) the output is skewed. As in, it slants to the right on the top. When I change the dimensions to certain dimensions, the file is not skewed. I''m loading a 24 bit file and converting it to 16 bit for drawing. I know I''m not being very specific, but before I take the time to write a specific post, I wanted to see if maybe anyone else has had this problem, and knows about it. If nobody responds in like a day or so, I''ll post another, more specific post with code. Thank! ------------------------------ Jonathan Little invader@hushmail.com http://www.crosswinds.net/~uselessknowledge

Share this post


Link to post
Share on other sites
Advertisement
Have you checked both the picture''s and primary/back- buffers lPitch ??

Sometimes the pitch are not the same as the width.

/maq

Share this post


Link to post
Share on other sites
The picture''s pitch could be different from the width?? I don''t know if that would make any difference anyway, though. As it happens, I''m always drawing from a RECT in the source picture.

And as far as I know, the picture''s width is always the picture''s width. It''s also stored in a single dimensional array..

But yes I check the backbuffer. When one of the picture''s is the wrong size, and is drawn skewed, the others still draw correctly, so it''s something that only effects certain widths of bitmaps.

Share this post


Link to post
Share on other sites
Do you take care of the extra bytes after each line in the bmp file? After each horizontal line bmp puts in a couple of empty bytes to make it dividable by four... I know most numbers are dividable by four but I hope you see what I mean...


Edited by - Geradian on 5/1/00 3:52:47 AM

Share this post


Link to post
Share on other sites
I was unaware that the format put extra bytes at the end.. I think this could describe the problem, but where can I find more info on this?

Share this post


Link to post
Share on other sites
We saw the same thing here by looking at the data through a hex editor.

"... you act as if stupidity were a virtue."
-- Flight of the Phoenix

Share this post


Link to post
Share on other sites
Guest Anonymous Poster

It''s called zero padding and many image formats do it. You have to
calculate the correct number of bytes for a single scanline of the bitmap.
If I had a 32x32 pixel 24-bit bitmap, a single scanline would be 32*3 = 96 bytes.
If I had a 31x31 pixel 24-bit bitmap, you would probably incorrectly
calculate it as 31*3 = 93 bytes. This is wrong. It is really 96 bytes.

But, what''s the purpose of loading this bitmap anyway? Does it have to do
with DirectX and surfaces? If so, just forget about doing it yourself and
use the function DDLoadBitmap from ddutil.cpp. It will load a bitmap onto
a DD surface. It will do the loading and conversion for you.


IDirectDrawSurface7*
DDLoadBitmap( IDirectDraw7* pdd, LPCSTR szBitmap, int dx, int dy)
{
HBITMAP hbm;
BITMAP bm;
DDSURFACEDESC2 ddsd;
IDirectDrawSurface7 *pdds;

//
// Try to load the bitmap as a resource, if that fails, try it as a file
//
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), szBitmap, IMAGE_BITMAP, dx,
dy, LR_CREATEDIBSECTION);
if (hbm == NULL)
hbm = (HBITMAP) LoadImage(NULL, szBitmap, IMAGE_BITMAP, dx, dy,
LR_LOADFROMFILE / LR_CREATEDIBSECTION);
if (hbm == NULL)
return NULL;
//
// Get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm);
//
// Create a DirectDrawSurface for this bitmap
//
ZeroMemory(&ddsd, sizeof(ddsd));
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_CAPS / DDSD_HEIGHT / DDSD_WIDTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN;
ddsd.dwWidth = bm.bmWidth;
ddsd.dwHeight = bm.bmHeight;
if (pdd->CreateSurface(&ddsd, &pdds, NULL) != DD_OK)
return NULL;
DDCopyBitmap(pdds, hbm, 0, 0, 0, 0);
DeleteObject(hbm);
return pdds;
}


HRESULT
DDCopyBitmap(IDirectDrawSurface7* pdds, HBITMAP hbm, int x, int y,
int dx, int dy)
{
HDC hdcImage;
HDC hdc;
BITMAP bm;
DDSURFACEDESC2 ddsd;
HRESULT hr;

if (hbm == NULL // pdds == NULL)
return E_FAIL;
//
// Make sure this surface is restored.
//
pdds->Restore();
//
// Select bitmap into a memoryDC so we can use it.
//
hdcImage = CreateCompatibleDC(NULL);
if (!hdcImage)
OutputDebugString("createcompatible dc failed\n");
SelectObject(hdcImage, hbm);
//
// Get size of the bitmap
//
GetObject(hbm, sizeof(bm), &bm);
dx = dx == 0 ? bm.bmWidth : dx; // Use the passed size, unless zero
dy = dy == 0 ? bm.bmHeight : dy;
//
// Get size of surface.
//
ddsd.dwSize = sizeof(ddsd);
ddsd.dwFlags = DDSD_HEIGHT / DDSD_WIDTH;
pdds->GetSurfaceDesc(&ddsd);

if ((hr = pdds->GetDC(&hdc)) == DD_OK)
{
StretchBlt(hdc, 0, 0, ddsd.dwWidth, ddsd.dwHeight, hdcImage, x, y,
dx, dy, SRCCOPY);
pdds->ReleaseDC(hdc);
}
DeleteDC(hdcImage);
return hr;
}

Share this post


Link to post
Share on other sites
Here is a part of my reading routine. It supposes that the file has already been read into
memory. I am currently only supporting 1 bit and 24 bit modes. Mainly because I can''t manage
to create a bmp file in 32 bit and 16 bit . Why I don''t have 8 bit is because I am lazy!

HRESULT clsSurface::ReadBMPFromMemory(char *Offset)
{
HRESULT hr;
LPBITMAPFILEHEADER BMPFileHeader;
LPBITMAPINFOHEADER BMPInfoHeader;
clsColor Color;
clsColor Palette[255]; //Used when reading in palette. Max is 256 entries.
int X,
Y,
Mod,
Mod2; //Sometime I need two mods...
unsigned char Counter;

//Get the file header.
BMPFileHeader = (LPBITMAPFILEHEADER) Offset;

//Check so this is a window bitmap.
if(BMPFileHeader->bfType != 19778)
return -1;

//Get the info header.
BMPInfoHeader = (LPBITMAPINFOHEADER) (Offset + 14);

//Make sure this size is a windows bitmap.
if(BMPInfoHeader->biSize != 40)
return -1;

//Make sure it ain''t compressed.
if(BMPInfoHeader->biCompression != 0)
return -1;

//Create the surface.
hr = Create(BMPInfoHeader->biWidth, BMPInfoHeader->biHeight);
if FAILED(hr)
return hr;

//Check the bit depth.
switch(BMPInfoHeader->biBitCount)
{
case 1:
//Read in the palette.
for(Counter = 0; Counter < BMPInfoHeader->biClrUsed; Counter++)
{
Palette[Counter].Blue = (int) *(Offset + 54 + (Counter * 4) );
Palette[Counter].Green = (int) *(Offset + 54 + (Counter * 4) + 1);
Palette[Counter].Red = (int) *(Offset + 54 + (Counter * 4) + 2);
}

//Run through all pixels.
Offset += BMPFileHeader->bfOffBits;
Mod = Width % 8;
Mod2 = ((Mod + Width) / 8) % 4;
for(Y = Height - 1; Y >= 0; Y--)
{
for(X = 0; X < Width
{
Counter = 128;
//Run through each byte in this line
do
{
if( (* (Offset + X/8) ) & Counter )
Color.Color = 1;
else
Color.Color = 0;

Color.Red = Palette[ Color.Color ].Red;
Color.Green = Palette[ Color.Color ].Green;
Color.Blue = Palette[ Color.Color ].Blue;
DrawPixel(X, Y, Color);
X++;

if(Counter == 1)
Counter = 0;
else
Counter -= (Counter/2);
} while(Counter > 0);
}
Offset += ((Width + Mod)/8) + Mod2;
}

break;
case 16:
break;
case 24:
Mod = Width % 4;
Offset += BMPFileHeader->bfOffBits ;

//Run through all the pixels.
for(Y = Height - 1; Y >= 0; Y--)
{
for(X = 0; X < Width; X++)
{
//Extract the red, green and blue component.
Color.Red = (char) *Offset;
Color.Green = (char) *(Offset + 1);
Color.Blue = (char) *(Offset + 2);

hr = DrawPixel(X, Y, Color);
if FAILED(hr)
return hr;

Offset += 3;
}
Offset += Mod;
}

break;
case 32:
break;
}

return 0;
}

Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!