Direct9+VS2005 读取bmp位图时,_lseek()函数断言报错分析

在使用Direct9+VS2005进行游戏编程时,读取bmp位图时可能会遇到_lseek()函数断言错误。问题源于《游戏脚本高级编程》中的bmp加载函数,错误发生在_lseek调用,导致程序中断。通过查看_lseek函数源码,发现fh文件句柄与_nhandle不匹配。解决方案是将_lseek替换为_llseek或使用SetFilePointer。微软官方建议使用SetFilePointer代替_lseek。
摘要由CSDN通过智能技术生成

    这是个很古老的问题,因为游戏编程常常需要载入bmp图像到屏幕中,虽然对位图的载入函数有很多版本,但是大体操作都一样,会用到一般的文件操作如open,read,wirte,seek。而在VS2005中,编译这种带lseek的函数,常常出现如下错误对话框:

                               

图1断言错误

    下面是《游戏脚本高级编程》的载入bmp位图的函数版本:

 

/**************************************************************************************

*

*	W_LoadImage ()

*

*	Loads a BMP file to a Wrappuh image.

*/



bool W_LoadImage ( char * pstrBMPFilename, W_Image * Image )

{

	HFILE hFile;

	OFSTRUCT FileData;

	

	BITMAPFILEHEADER BMPFileHeader;

	BITMAPINFOHEADER BMPImageHeader;

	

	if ( ( hFile = OpenFile ( pstrBMPFilename, & FileData, OF_READ ) ) == -1 )

		return FALSE;

	

	_lread ( hFile, & BMPFileHeader, sizeof ( BITMAPFILEHEADER ) );

	if ( BMPFileHeader.bfType != 0x4D42 )

	{

		_lclose ( hFile );

		return FALSE;

	}

	

	_lread ( hFile, & BMPImageHeader, sizeof ( BITMAPINFOHEADER ) );

	if ( BMPImageHeader.biBitCount != 24 )

	{

		_lclose ( hFile );

		return FALSE;

	}

	

	int iScanlineByteSize = BMPImageHeader.biWidth * 3;

	

	GetNextMul4 ( iScanlineByteSize );

	

	int iScanlinePad = iScanlineByteSize - ( BMPImageHeader.biWidth * 3 );

	int iBMPFileImageByteSize = ( BMPImageHeader.biWidth * 3 + iScanlinePad ) * BMPImageHeader.biHeight;

	

	_lseek ( hFile, BMPFileHeader.bfOffBits, SEEK_SET );

	

	UCHAR * pImageBuffer = NULL;

	if ( ! ( pImageBuffer = ( UCHAR * ) malloc ( iBMPFileImageByteSize ) ) )

	{

		_lclose ( hFile );

		return FALSE;

	}

	

	_lread ( hFile, pImageBuffer, iBMPFileImageByteSize );

	

	int iCurrSourcePixelOffs = 0;

	RGBTriad CurrSourcePixelTriad;

	

	InitWin32Struct ( g_DDSrfcDesc );

	

	g_DDSrfcDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_CKSRCBLT;

	

	int iXRes = BMPImageHeader.biWidth;

	GetNextMul4 ( iXRes );

	

	g_DDSrfcDesc.dwWidth = iXRes;

	g_DDSrfcDesc.dwHeight = BMPImageHeader.biHeight;

	

	switch ( g_VideoContext.iColorDepth )

	{

				case 15:

					{

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceLowValue = DEF_IMAGE_MASK_COLOR_15;

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceHighValue = DEF_IMAGE_MASK_COLOR_15;

						break;

					}

					

				case 16:

					{

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceLowValue = DEF_IMAGE_MASK_COLOR_16;

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceHighValue = DEF_IMAGE_MASK_COLOR_16;

						break;

					}

					

				case 32:

					{

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceLowValue = DEF_IMAGE_MASK_COLOR_32;

						g_DDSrfcDesc.ddckCKSrcBlt.dwColorSpaceHighValue = DEF_IMAGE_MASK_COLOR_32;

						break;

					}

	}

	

	Image->iXRes = BMPImageHeader.biWidth;

	Image->iYRes = g_DDSrfcDesc.dwHeight;

	Image->iXMax = Image->iXRes - 1;

	Image->iYMax = Image->iYRes - 1;

	

	g_DDSrfcDesc.ddsCaps.dwCaps = DDSCAPS_OFFSCREENPLAIN | DDSCAPS_SYSTEMMEMORY;

	

	if ( FAILED ( g_pDDIntrfc4->CreateSurface ( & g_DDSrfcDesc, & Image->pDDSrfc, NULL ) ) )

		return FALSE;

	

	InitWin32Struct ( g_DDSrfcDesc );

	if ( FAILED ( Image->pDDSrfc->Lock ( NULL, & g_DDSrfcDesc, DDLOCK_SURFACEMEMORYPTR | DDLOCK_WAIT, NULL ) ) )

		return FALSE;

	

	Image->iPitch = g_DDSrfcDesc.lPitch;

	

	Pixel15 * pSrfcBuffer15 = ( Pixel15 * ) g_DDSrfcDesc.lpSurface;

	Pixel16 * pSrfcBuffer16 = ( Pixel16 * ) g_DDSrfcDesc.lpSurface;

	Pixel32 * pSrfcBuffer32 = ( Pixel32 * ) g_DDSrfcDesc.lpSurface;

	

	int iX,

		iY;

	

	for ( iY = BMPImageHeader.biHeight - 1; iY >= 0; -- iY )

	{

		for ( iX = 0; iX < BMPImageHeader.biWidth; ++ iX )

		{

			CurrSourcePixelTriad.R = pImageBuffer [ iCurrSourcePixelOffs + 2 ];

			CurrSourcePixelTriad.G = pImageBuffer [ iCurrSourcePixelOffs + 1 ];

			CurrSourcePixelTriad.B = pImageBuffer [ iCurrSourcePixelOffs ];

			

			if ( EncodePixel32 ( CurrSourcePixelTriad.R, CurrSourcePixelTriad.G, CurrSourcePixelTriad.B ) == DEF_IMAGE_MASK_COLOR_32 )

			{

				switch ( g_VideoContext.iColorDepth )

				{

				case 15:

					pSrfcBuffer15 [ iY * ( g_DDSrfcDesc.lPitch >> 1 ) + iX ] = ( Pixel15 ) DEF_IMAGE_MASK_COLOR_15;

					break;

					

				case 16:

					pSrfcBuffer16 [ iY * ( g_DDSrfcDesc.lPitch >> 1 ) + iX ] = ( Pixel16 ) DEF_IMAGE_MASK_COLOR_16;

					break;

					

				case 32:

					pSrfcBuffer32 [ iY * ( g_DDSrfcDesc.lPitch >> 2 ) + iX ] = ( Pixel32 ) DEF_IMAGE_MASK_COLOR_32;

					break;

				}

			}

			else

			{

				switch ( g_VideoContext.iColorDepth )

				{

				case 15:

					CurrSourcePixelTriad.R >>= 3;

					CurrSourcePixelTriad.G >>= 3;

					CurrSourcePixelTriad.B >>= 3;

					pSrfcBuffer15 [ iY * ( g_DDSrfcDesc.lPitch >> 1 ) + iX ] = ( Pixel15 ) EncodePixel15 ( CurrSourcePixelTriad.R, CurrSourcePixelTriad.G, CurrSourcePixelTriad.B );

					break;

					

				case 16:

					CurrSourcePixelTriad.R >>= 3;

					CurrSourcePixelTriad.G >>= 3;

					CurrSourcePixelTriad.B >>= 3;

					pSrfcBuffer16 [ iY * ( g_DDSrfcDesc.lPitch >> 1 ) + iX ] = ( Pixel16 ) EncodePixel16 ( CurrSourcePixelTriad.R, CurrSourcePixelTriad.G, CurrSourcePixelTriad.B );

					break;

					

				case 32:

					pSrfcBuffer32 [ iY * ( g_DDSrfcDesc.lPitch >> 2 ) + iX ] = ( Pixel32 ) EncodePixel32 ( CurrSourcePixelTriad.R, CurrSourcePixelTriad.G, CurrSourcePixelTriad.B );

					break;

				}

			}

			

			iCurrSourcePixelOffs += 3;

		}

		iCurrSourcePixelOffs += iScanlinePad;

	}

	

	int iClipFound;

	W_Rect ClipRect;

	ClipRect.iX0 = 0;

	ClipRect.iY0 = 0;

	ClipRect.iX1 = Image->iXMax;

	ClipRect.iY1 = Image->iYMax;

	

	
评论 16
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值