⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageobj.c

📁 深圳市微逻辑电子有限公司 巨果&#8226 Kingmos&reg 系统核心
💻 C
📖 第 1 页 / 共 4 页
字号:
/******************************************************
Copyright(c) 版权所有,1998-2005微逻辑。保留所有权利。
******************************************************/


/*****************************************************
文件说明:对图形对象进行管理(brush,bitmap,pen,font,region,palette)
版本号:3.0.0
开发时期:1999
作者:李林
修改记录:
	2004-02-21: WinGdi_CreateDIBSection  用 hgwmeProcess 代替 GetCurrentProcess
     2003-05-14 : CreateBitmap 为避免Heap的碎片化 对bitmap,
	             当其所用缓存大小 大于 某大小时, 用VirtualAlloc
				 当bmType = 1, 用VirtualAlloc;否则用,malloc
    2003-05-07: LN:将CreateBitmap的默认值由白改为黑
******************************************************/

#include <eframe.h>
#include <eapisrv.h>
#include <bheap.h>

#include <epwin.h>
#include <gdc.h>
#include <winsrv.h>
#include <gdisrv.h>

#define MALLOC_SIZE_LIMIT  (4 * 1024)

static LPOBJLIST _lpGdiObjList = NULL;
static CRITICAL_SECTION csGdiObjList;

BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner );
BOOL RemoveFromObjMgr( LPOBJLIST lpObj );

extern HBITMAP WINAPI WinGdi_CreateCompatibleBitmap(HDC hdc, int iWidth, int iHeight);
extern int _WinGdi_ConvertImageColorValue( 
									_LPCDISPLAYDRV lpDrv,
								    _LPBITMAP_DIB lpDestImage,  // dest image data
									LPCRECT lprcDestClip,
									CONST BITMAPINFO * lpbi,// src image info
									LPCRECT lprcSrcClip,
								    DWORD dwStartScanLine,  // src start scan line
                                    DWORD dwScanLineNum, 
                                    DWORD dwScanLineWidth,
                                    LPCBYTE lpbData,// src bitmap bits data
								    int fuColorUse   // use src's RGB or PAL
									);


// **************************************************
// 声明:BOOL __InitialGdiObjMgr( void )
// 参数:
// 	无
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	初始化 GDI 图形对象管理器
// 引用: 
//	
// ************************************************

BOOL _InitialGdiObjMgr( void )
{
	InitializeCriticalSection( &csGdiObjList );
	csGdiObjList.lpcsName = "CS-GOM";
	
	return TRUE;
}

// **************************************************
// 声明:void __DeInitialGdiObjMgr( void )
// 参数:
// 	无
// 返回值:
//	无
// 功能描述:
//	与 __InitialGdiObjMgr相反,释放图形对象管理器
// 引用: 
//	
// ************************************************

void _DeInitialGdiObjMgr( void )
{
	DeleteCriticalSection( &csGdiObjList );
}

// **************************************************
// 声明:BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner )
// 参数:
// 	IN lpObj - OBJLIST 结构指针
//	IN objType - 对象类型
//	IN hOwner - 对象拥有者进程
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	将对象加入对象链表
// 引用: 
//	
// ************************************************

BOOL AddToObjMgr( LPOBJLIST lpObj, DWORD objType, ULONG hOwner )
{
	BOOL bRetv;

	EnterCriticalSection( &csGdiObjList );

	bRetv = ObjList_Init( &_lpGdiObjList, lpObj, objType, (ULONG)hOwner );

	LeaveCriticalSection( &csGdiObjList );
	return bRetv;
}

// **************************************************
// 声明:BOOL RemoveFromObjMgr( LPOBJLIST lpObj )
// 参数:
// 	IN lpObj - OBJLIST 结构指针
// 返回值:
//	假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
//	与 AddToObjMgr 相反,将对象移出对象链表
// 引用: 
//	
// ************************************************

BOOL RemoveFromObjMgr( LPOBJLIST lpObj )
{
	EnterCriticalSection( &csGdiObjList );
	ObjList_Remove( &_lpGdiObjList, lpObj );
	LeaveCriticalSection( &csGdiObjList );
	return TRUE;
}


// **************************************************
// 声明:HBITMAP _GetShareBitmapObj( HINSTANCE hInst, DWORD dwName )
// 参数:
// 	IN hInst - 实例句柄
//	IN dwName - 对象名
// 返回值:
//	假如成功,返回位图对象句柄;否则,返回 NULL
// 功能描述:
//	得到共享对象句柄
// 引用: 
//	
// ************************************************

HBITMAP _GetShareBitmapObj( HINSTANCE hInst, DWORD dwName )
{
	HBITMAP hRetv = NULL;
	LPOBJLIST lpObjList;

	EnterCriticalSection( &csGdiObjList );
	
	lpObjList = _lpGdiObjList;
	while( lpObjList )
	{
		if( ( (WORD)lpObjList->objType ) == OBJ_BITMAP )
		{
			_LPBITMAP_SHARE lpBitmap = (_LPBITMAP_SHARE)lpObjList;
			if( lpBitmap->bitmap.bmFlags & BF_SHARE )
			{
				if( hInst == lpBitmap->hInst &&
					dwName == lpBitmap->szName )
				{
					lpObjList->iRefCount++;
					hRetv = (HBITMAP)PTR_TO_HANDLE( lpBitmap );
					break;
				}
			}
		}
		lpObjList = lpObjList->lpNext;
	}

	LeaveCriticalSection( &csGdiObjList );
	return hRetv;
}


// **************************************************
// 声明:HBITMAP _WinGdi_CreateBitmap( 
//								int nWidth, 
//								int nHeight, 
//								UINT cPlanes,
//								UINT cBitsPerPel,
//								int  iDir,
//								const VOID *lpvBits,									
//								_LPBITMAPDATA * lppBitmap,
//								UINT uiObjFlag,
//								CONST BITMAPINFO *lpbmi,
//								BOOL bIsShareResource
//								)
// 参数:
//	IN nWidth - 位图的宽度
//	IN nHeight - 位图的高度
//	IN cPlanes - 位面数
//	IN cBitsPerPel - 每个点的 bit数
//	IN iDir - 位图的方向(从顶向底或相反)
//	IN lpvBits - 位图数据
//	OUT lppBitmap - 用于接受描述位图格式的结构的指针
//	IN uiObjFlag - 附加的对象标志
//	IN lpbmi - 描述lpvBits位图格式的结构的指针,可以为NULL
//  IN bIsShareResource - 说明新对象是否需要共享(来自于资源文件, lpbmi必须= NULL)
// 返回值:
//	假如成功,返回位图对象句柄;否则,返回NULL
// 功能描述:
//	按要求创建位图对象
// 引用: 
//	
// ************************************************

HBITMAP _WinGdi_CreateBitmap( int nWidth, 
							  int nHeight, 
							  UINT cPlanes,
							  UINT cBitsPerPel,
							  int  iDir,
							  const VOID *lpvBits,
							  _LPBITMAPDATA * lppBitmap,
							  UINT uiObjFlag,
							  CONST BITMAPINFO *lpbmi,
							  BOOL bIsShareResource
							 )
{
    _LPBITMAPDATA lpBitmap;
	LPBYTE lpbBuf;
    int scanBytes, size;
	DWORD bmType = 0;

	ASSERT( nWidth >= 0 && nHeight >= 0 );
	//扫描行字节宽度
	scanBytes = (cBitsPerPel * nWidth+31) / 32 * 4;  // align to dword
	//总的位图需要的字节数
	size = scanBytes * nHeight * cPlanes;
	//
	if( lpbmi == NULL )
	{	//默认的位图格式,分配 _BITMAPDATA结构对象
		if( bIsShareResource )
		{
			lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, sizeof(_BITMAP_SHARE) );
			if( lpBitmap )
				memset( lpBitmap, 0, sizeof(_BITMAP_SHARE) );
			bmType |= BF_SHARE;
		}
		else
		{
			lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, sizeof(_BITMAPDATA) );
			if( lpBitmap )
				memset( lpBitmap, 0, sizeof(_BITMAPDATA) );
		}
		if( lpBitmap == NULL )
		{
			ASSERT( 0 );
			return NULL;
		}
	}
	else
	{	//lpbmi 包含设备无关信息
		DWORD dwAllocSize = 0;
		DWORD dwPalSize = 0;
		UINT  uiPalIndexNum = 0;

		if( lpbmi->bmiHeader.biBitCount <= 8 )
		{	// 可能有调色板
			uiPalIndexNum = (1 << lpbmi->bmiHeader.biBitCount);
			if( lpbmi->bmiHeader.biClrUsed )			
			    uiPalIndexNum = MIN( lpbmi->bmiHeader.biClrUsed, uiPalIndexNum );
			dwPalSize =  uiPalIndexNum * sizeof(RGBQUAD);
		}
		else if( ( lpbmi->bmiHeader.biBitCount == 16 ||
			       lpbmi->bmiHeader.biBitCount == 32 )   && 
			     lpbmi->bmiHeader.biCompression == BI_BITFIELDS )
		{	//无需调色板,应该有三个DWORD的 RGB 占位描述符
			uiPalIndexNum = 3;
			dwPalSize = sizeof( DWORD ) * uiPalIndexNum;
		}
		//计算 _BITMAPDATA 结构对象大小
		dwAllocSize = sizeof( _BITMAP_DIB ) + dwPalSize - sizeof( DWORD );
		//分配 _BITMAPDATA结构对象
		lpBitmap = (_LPBITMAPDATA)BlockHeap_AllocString( hgwmeBlockHeap, 0, dwAllocSize );
		if( lpBitmap )
		{
			UINT i;
			PALETTEENTRY * lpPal = ((_LPBITMAP_DIB)lpBitmap)->palEntry;
			RGBQUAD * lpQuad = (RGBQUAD *)lpbmi->bmiColors;

			memset( lpBitmap, 0, dwAllocSize );
			//初始化调色板信息
			if( lpbmi->bmiHeader.biCompression == BI_BITFIELDS )
			{	//三个 DWORD  mask
				for( i = 0; i < uiPalIndexNum; i++ )
				{
					*((LPDWORD)lpPal) = *( (LPDWORD)lpQuad );
					lpPal++;
					lpQuad++;
				}
			}
			else
			{
				for( i = 0; i < uiPalIndexNum; i++ )
				{
					lpPal->peRed = lpQuad->rgbRed;
					lpPal->peGreen = lpQuad->rgbGreen;
					lpPal->peBlue = lpQuad->rgbBlue;
					lpPal->peFlags = 0;
					lpPal++;
					lpQuad++;
				}
			}

			bmType |= BF_DIB;

			((_LPBITMAP_DIB)lpBitmap)->biClrImportant = lpbmi->bmiHeader.biClrImportant;
			((_LPBITMAP_DIB)lpBitmap)->biClrUsed = uiPalIndexNum;
			((_LPBITMAP_DIB)lpBitmap)->biCompression = lpbmi->bmiHeader.biCompression;
			((_LPBITMAP_DIB)lpBitmap)->biDir = lpbmi->bmiHeader.biHeight > 0 ? -1 : 1;
			((_LPBITMAP_DIB)lpBitmap)->biSizeImage = size;
		}
    }
    //分配位图数据缓存,为防止堆碎片。
	//如果缓存较小,则用BlockHeap_Alloc分配,
	//否则用Page_AllocMem分配
	if( bmType & BF_DIB )
	{   //frame buffer 会被 user 访问, so PM_SHARE
		lpbBuf = Page_AllocMem( size, NULL, PM_SHARE );
		bmType |= 1;
	}
	else
	{
		if( size <= MALLOC_SIZE_LIMIT )
		{
			lpbBuf  = (LPBYTE)BlockHeap_Alloc( hgwmeBlockHeap, 0, size );
			//lpbBuf  = (LPBYTE)BLK_Alloc( 0, size );
		}
		else
		{
			lpbBuf = Page_AllocMem( size, NULL, 0 );
			bmType |= 1;
		}
	}

	ASSERT( lpBitmap && lpbBuf );

    if( lpBitmap && lpbBuf )
    {	//分配成功
		int i;
        if( nWidth <= 0 )
            nWidth = 1;
        if( nHeight <= 0 )
            nHeight = 1;		

        lpBitmap->bmFlags = (WORD)bmType;
		lpBitmap->bmWidth = nWidth;
        lpBitmap->bmHeight = nHeight;
        lpBitmap->bmWidthBytes = scanBytes;
        lpBitmap->bmPlanes = cPlanes;
        lpBitmap->bmBitsPixel = cBitsPerPel;        
		lpBitmap->bmBits = lpbBuf;

		if( lpvBits )
		{	//如果有用户位图数据,则对齐到 WORD 
			int iDataByteWidth = (cBitsPerPel * nWidth+15) / 16 * 2;// align to word
			LPBYTE lpBuf = (LPBYTE)lpBitmap->bmBits;
			
			for( i = 0; i < nHeight; i++ )
			{
				memcpy( lpBuf, lpvBits, iDataByteWidth );
				lpBuf += scanBytes;
				(LPBYTE)lpvBits += iDataByteWidth;
			}
		}
		else
		{	//没有需要初始化的位图数据,为0
			memset( lpBitmap->bmBits, 0, size );
		}
        //加入对象链表
		AddToObjMgr( &lpBitmap->obj, OBJ_BITMAP | uiObjFlag, (ULONG)GetCallerProcess() );
    }
	else
	{	//错误,做清除工作
		if( lpBitmap )
		{
			BlockHeap_FreeString( hgwmeBlockHeap, 0, lpBitmap);
			//BLK_FreeString( 0, lpBitmap);
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -