Bitmap Load Problems!

Started by
2 comments, last by ziplux 24 years, 1 month ago
Hello. I am having trouble with my (actually Andre LaMothe''s) bitmap loading and drawing functions. Whenever I try to load and display a bitmap that is not 16 by 16, my program crashes and/or produces undesired results. My two funtions are as follows:

void Draw_Bitmap16(BITMAP_FILE_PTR bitmap, int x,int y, int width, int height, USHORT *buffer, int lPitch16, int pixel_format)
	{
	// This is an a slow funtion.  Do not call this every frame.
	USHORT pixel; // holds color
	// process each line and copy it into the primary buffer
	for (int index_y = y; index_y < height+y; index_y++)
		{
		for (int index_x = x; index_x < width+x; index_x++)
			{
			// get BGR values, note the scaling down of the channels, so that they
			// fit into the 5.6.5 format
			UCHAR blue  = (bitmap->buffer[index_y*width*3 + index_x*3]) >> 3,
				  green = (bitmap->buffer[index_y*width*3 + index_x*3 + 1]) >> 3,
				  red   = (bitmap->buffer[index_y*width*3 + index_x*3 + 2]) >> 3;
			if(pixel_format == 16)
				{
				// this builds a 16 bit color value in 5.6.5 format (green dominant mode)
				pixel = _RGB16BIT565(red,green,blue);
				}
			else
				{
				// must be 5.5.5 mode
				pixel = _RGB16BIT555(red,green,blue);
				}

			
			// write the pixel
			buffer[index_x + index_y * lPitch16] = pixel;

			} // end for index_x

		} // end for index_y
	}
 
and the loading function...

int Load_Bitmap_File(BITMAP_FILE_PTR bitmap, char *filename)
{
// this function opens a bitmap file and loads the data into bitmap

int file_handle,  // the file handle
    index;        // looping index

UCHAR   *temp_buffer = NULL; // used to convert 24 bit images to 16 bit
OFSTRUCT file_data;          // the file data information

// open the file if it exists
if ((file_handle = OpenFile(filename,&file_data,OF_READ))==-1)
   return(0);

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapfileheader,sizeof(BITMAPFILEHEADER));

// test if this is a bitmap file
if (bitmap->bitmapfileheader.bfType!=BITMAP_ID)
   {
   // close the file
   _lclose(file_handle);

   // return error
   return(0);
   } // end if

// now we know this is a bitmap, so read in all the sections

// first the bitmap infoheader

// now load the bitmap file header
_lread(file_handle, &bitmap->bitmapinfoheader,sizeof(BITMAPINFOHEADER));

// now load the color palette if there is one
if (bitmap->bitmapinfoheader.biBitCount == 8)
   {
   _lread(file_handle, &bitmap->palette,MAX_COLORS_PALETTE*sizeof(PALETTEENTRY));

   // now set all the flags in the palette correctly and fix the reversed 
   // BGR RGBQUAD data format
   for (index=0; index < MAX_COLORS_PALETTE; index++)
       {
       // reverse the red and green fields
       int temp_color                = bitmap->palette[index].peRed;
       bitmap->palette[index].peRed  = bitmap->palette[index].peBlue;
       bitmap->palette[index].peBlue = temp_color;
       
       // always set the flags word to this
       bitmap->palette[index].peFlags = PC_NOCOLLAPSE;
       } // end for index

    } // end if

// finally the image data itself
_lseek(file_handle,-(int)(bitmap->bitmapinfoheader.biSizeImage),SEEK_END);

// now read in the image, if the image is 8 or 16 bit then simply read it
// but if its 24 bit then read it into a temporary area and then convert
// it to a 16 bit image

if (bitmap->bitmapinfoheader.biBitCount==8 // bitmap->bitmapinfoheader.biBitCount==16 // 
    bitmap->bitmapinfoheader.biBitCount==24)
   {
   // delete the last image if there was one
   if (bitmap->buffer)
       free(bitmap->buffer);

   // allocate the memory for the image
   if (!(bitmap->buffer = (UCHAR *)malloc(bitmap->bitmapinfoheader.biSizeImage)))
      {
      // close the file
      _lclose(file_handle);

      // return error
      return(0);
      } // end if

   // now read it in
   _lread(file_handle,bitmap->buffer,bitmap->bitmapinfoheader.biWidth*bitmap->bitmapinfoheader.biHeight*bitmap->bitmapinfoheader.biBitCount);

   } // end if
else
   {
   // serious problem
   return(0);

   } // end else

#if 0
// write the file info out 
printf("\nfilename:%s \nsize=%d \nwidth=%d \nheight=%d \nbitsperpixel=%d \ncolors=%d \nimpcolors=%d",
        filename,
        bitmap->bitmapinfoheader.biSizeImage,
        bitmap->bitmapinfoheader.biWidth,
        bitmap->bitmapinfoheader.biHeight,
		bitmap->bitmapinfoheader.biBitCount,
        bitmap->bitmapinfoheader.biClrUsed,
        bitmap->bitmapinfoheader.biClrImportant);
#endif

// close the file
_lclose(file_handle);

// flip the bitmap
Flip_Bitmap(bitmap->buffer, 
            bitmap->bitmapinfoheader.biWidth*(bitmap->bitmapinfoheader.biBitCount/8), 
            bitmap->bitmapinfoheader.biHeight);

// return success
return(1);

} // end Load_Bitmap_File
 
Thanks in advance for any help. I know my problem is in one of these two snippets. BTW I have a 5.6.5 card and am in 16 bit color mode. The load function converts from 24bit color to 16bit color.
My Geekcode: "GCS d s: a14 C++$ P+(++) L+ E-- W+++$ K- w++(+++) O---- M-- Y-- PGP- t XR- tv+ b++ DI+(+++) D- G e* h!"Decode my geekcode!Geekcode.com
Visit our web site:Asylum Entertainment
Advertisement
1) I''ve heard some complaints from a few people about the bitmap loading of Lathe''s book. I recommend the LoadBitMap functions of the MS SDK DD Example3 except you LOADFROMFILE

I just modified DD Example 3 and it makes no difference what bit format you use. They use ddutil.cpp ddutil.h ddutil2.h. Check it out.

2) Also LaMothe''s code does not address the 565 problem with 16bit surfaces and vidcards

3) Search also in the GameDev forums(using the GameDev search button) for the exact same problem.

//----------------------------------------------------------
// Global variables
//----------------------------------------------------------
LPDIRECTDRAW4 g_pDD; // DirectDraw object
LPDIRECTDRAWSURFACE4 g_pDDSPrimary;// DirectDraw primary surface
LPDIRECTDRAWSURFACE4 g_pDDSBack; // DirectDraw back surface
LPDIRECTDRAWSURFACE4 g_pDDSOne; // Offscreen surface 1
LPDIRECTDRAWSURFACE4 g_pDDSTwo; // Offscreen surface 2
LPDIRECTDRAWSURFACE4 g_pDDSHexMap; // JT surface
LPDIRECTDRAWSURFACE4 g_pDDSHexBackGround; // JT surface
LPDIRECTDRAWSURFACE4 g_pDDSText; // JT surface
LPDIRECTDRAWSURFACE4 g_pDDSHexTiles; // JT surface
LPDIRECTDRAWPALETTE g_pDDPal; // The primary surface palette
BOOL g_bActive; // Is application active?
LPDIRECTSOUND g_pDS = NULL;
;
int g_x;
int g_y;

//-----------------------------------------------------------------------------
// Name: InitSurfaces(void)
// Desc: This function reads the bitmap file FRNTBACK.BMP and stores half of it
// in offscreen surface 1 and the other half in offscreen surface 2.
// Globals: g_pDDSOne, g_pDDSTwo, g_pDDSHexMap, g_pDDSText, g_pDDSHexMapBackground
//-----------------------------------------------------------------------------
BOOL InitSurfaces(void)
{
HBITMAP hbm;
HBITMAP working;
HBITMAP combatsource;

// Load our bitmap resource.
hbm = (HBITMAP) LoadImage(GetModuleHandle(NULL), "frntback.bmp", IMAGE_BITMAP, 0,
0, LR_LOADFROMFILE / LR_CREATEDIBSECTION);
if (hbm == NULL) return FALSE;

DDCopyBitmap(g_pDDSOne, hbm, 0, 0, 640, 480);
DDCopyBitmap(g_pDDSTwo, hbm, 0, 480, 640, 480);
DeleteObject(hbm);

working = (HBITMAP) LoadImage(GetModuleHandle(NULL), "pcscreen.bmp", IMAGE_BITMAP, 0,
0, LR_LOADFROMFILE / LR_CREATEDIBSECTION);
DDCopyBitmap(g_pDDSText, working, 0, 0, 640, 480);
DeleteObject(working);

combatsource = (HBITMAP) LoadImage(GetModuleHandle(NULL), "combat.bmp", IMAGE_BITMAP, 0,
0, LR_LOADFROMFILE / LR_CREATEDIBSECTION);
DDCopyBitmap(g_pDDSHexMap, combatsource, 0, 0, 640, 480);
DeleteObject(combatsource);

combatsource = (HBITMAP) LoadImage(GetModuleHandle(NULL), "hextile.bmp", IMAGE_BITMAP, 0,
0, LR_LOADFROMFILE / LR_CREATEDIBSECTION);
DDCopyBitmap(g_pDDSHexTiles, combatsource, 0, 0, 640, 480);
DeleteObject(combatsource);

DDSetColorKey(g_pDDSTwo, RGB(0,0,0));
DDSetColorKey(g_pDDSHexMap, RGB(255,255,255));
DDSetColorKey(g_pDDSHexTiles, RGB(255,255,255));
DDSetColorKey(g_pDDSHexBackGround, RGB(255,255,255));
DDSetColorKey(g_pDDSText, RGB(255,255,255));
if (hbm == NULL) return FALSE;
return TRUE;
}

ZoomBoy
A 2D RPG with skills, weapons, and adventure.
See my character editor, Tile editor and diary at
Check out my web-site
I know he doesn''t address the 5.6.5 problem, but I do in my draw bitmap function. I would just like to know why this doesn''t work all of a sudden.
My Geekcode: "GCS d s: a14 C++$ P+(++) L+ E-- W+++$ K- w++(+++) O---- M-- Y-- PGP- t XR- tv+ b++ DI+(+++) D- G e* h!"Decode my geekcode!Geekcode.com
Visit our web site:Asylum Entertainment
I had the same problem with the load-bitmap function. As a work-around, I just made it into a big (as Lamothe puts it) BOB and used Load_BOB and Draw_BOB for display.

Good luck,
Felix

This topic is closed to new replies.

Advertisement