📄 imageobj.c
字号:
if( lpbBuf )
{ //释放分配的位图缓存
if( bmType & 1 )
{ //该lpbBuf是用 Page_AllocMem分配的
Page_FreeMem( lpbBuf, size );
}
else{ //该lpbBuf是用 BlockHeap_Alloc 分配的
BlockHeap_Free( hgwmeBlockHeap, 0, lpbBuf, size );
//BLK_Free( 0, lpbBuf, size );
}
}
lpBitmap = NULL;
lpbBuf = NULL;
}
if( lppBitmap )
*lppBitmap = lpBitmap;
if( lpBitmap )
return (HBITMAP)PTR_TO_HANDLE( lpBitmap );
ASSERT( 0 );
return NULL;
}
// **************************************************
// 声明:HBITMAP WINAPI WinGdi_CreateBitmap(
// int nWidth,
// int nHeight,
// UINT cPlanes,
// UINT cBitsPerPel,
// const VOID *lpvBits )
// 参数:
// IN nWidth-位图宽度
// IN nHeight-位图高度
// IN cPlanes-位图位面数 (仅支持1位面)
// IN cBitsPerPel-每点bit数
// IN lpvBits-位图数据
// 返回值:
// 假如成功,返回有效的位图句柄;否则,返回 NULL
// 功能描述:
// 创建位图对象
// 引用:
// 系统API
// ************************************************
HBITMAP WINAPI WinGdi_CreateBitmap( int nWidth, int nHeight, UINT cPlanes, UINT cBitsPerPel, const VOID *lpvBits )
{
return _WinGdi_CreateBitmap( nWidth, nHeight, cPlanes, cBitsPerPel, 0, lpvBits, NULL, 0, NULL, FALSE );
}
// **************************************************
// 声明:int WINAPI WinGdi_GetDIBits(
// HDC hdc,
// HBITMAP hbmp,
// UINT uStartScan,
// UINT cScanLines,
// LPVOID lpvBits,
// LPBITMAPINFO lpbi,
// UINT uiUsage )
// 参数:
// IN hdc -目标DC
// IN hbmp - 位图句柄
// IN uStartScan - 从位图的第几扫描行开始得到数据
// IN cScanLines - 共需要得到的扫描行数
// IN lpvBits - 用于得到位图数据的缓存,假如是NULL,该功能在lpbi里返回位图的大小和格式
// IN lpbi - BITMAPINFO结构指针,说明需要返回的数据类型
// IN uiUsage - 说明BITMAPINFO成员bmiColors的格式,可以为:
// DIB_PAL_COLORS - 颜色表包含16bits的索引值数组,用于指向当前的调色板
// DIB_RGB_COLORS - 颜色表包含红、绿、蓝值
// 返回值:
// 假如成功并且lpvBits为NULL,该功能填充lpbi结构并返回
// 位图总的扫描函数;假如成功并且lpvBits不为NULL,该功
// 能返回实际拷贝的扫描行数,lpvBits为得到的位图数据
// 功能描述:
// 用规定的格式返回位图的数据
// 引用:
// 系统API
// ************************************************
int WINAPI WinGdi_GetDIBits(
HDC hdc,
HBITMAP hbmp,
UINT uStartScan,
UINT cScanLines,
LPVOID lpvBits,
LPBITMAPINFO lpbi,
UINT uiUsage )
{ // device depent format -> device indepent format
_LPBITMAPDATA lpImage = _GetHBITMAPPtr( hbmp );
if( lpImage )
{ //有效的位图对象
if( lpvBits == NULL )
{ // 填充位图信息 fill the lpbi data
if( lpbi->bmiHeader.biSize == sizeof( BITMAPINFO ) )
{
lpbi->bmiHeader.biHeight = lpImage->bmHeight;
lpbi->bmiHeader.biPlanes = lpImage->bmPlanes;
lpbi->bmiHeader.biWidth = lpImage->bmWidth;
if( lpImage->bmBitsPixel == 16 || lpImage->bmBitsPixel == 32 )
lpbi->bmiHeader.biCompression = BI_BITFIELDS;
else
lpbi->bmiHeader.biCompression = BI_RGB;
lpbi->bmiHeader.biClrImportant = 0;
lpbi->bmiHeader.biClrUsed = 0;
lpbi->bmiHeader.biSizeImage = lpImage->bmWidthBytes * lpImage->bmHeight;
lpbi->bmiHeader.biBitCount = lpImage->bmBitsPixel;
return lpbi->bmiHeader.biHeight;
}
}
else
{ //需要位图数据
_BITMAPDATA bmp;
BITMAPINFO bi;
RECT rcDestClip;
_LPCDISPLAYDRV lpDrv;
int iDir, iMinHeight, iMinWidth;
//定义需要的位图格式数据
// define dest bitmap
bmp.bmBits = lpvBits;
bmp.bmBitsPixel = (BYTE)lpbi->bmiHeader.biBitCount;
bmp.bmHeight = cScanLines;
bmp.bmPlanes = (BYTE)lpbi->bmiHeader.biPlanes;
bmp.bmWidth = (WORD)lpbi->bmiHeader.biWidth;
bmp.bmFlags = 0;
bmp.bmWidthBytes = (lpbi->bmiHeader.biBitCount * lpbi->bmiHeader.biWidth + 31) / 32 * 4; // align to dword
lpDrv = GetDisplayDeviceDriver( &bmp );
if( lpDrv == NULL )
return 0; //系统不支持该位图格式
//定义源位图格式数据
// define the source bitmap
bi.bmiHeader.biBitCount = lpImage->bmBitsPixel;
bi.bmiHeader.biClrImportant = 0;
bi.bmiHeader.biClrUsed = 0;
bi.bmiHeader.biCompression = BI_RGB;
if( (lpImage->bmFlags & BF_DIB) &&
( (_LPBITMAP_DIB)lpImage )->biDir < 0 )
{
bi.bmiHeader.biHeight = lpImage->bmHeight;
}
else
bi.bmiHeader.biHeight = -lpImage->bmHeight;
bi.bmiHeader.biPlanes = lpImage->bmPlanes;
bi.bmiHeader.biSize = sizeof( bi.bmiHeader );
bi.bmiHeader.biSizeImage = 0;
bi.bmiHeader.biWidth = lpImage->bmWidth;
bi.bmiHeader.biXPelsPerMeter = 0;
bi.bmiHeader.biYPelsPerMeter = 0;
if( bi.bmiHeader.biHeight > 0 )
{
iDir = -1;
iMinHeight = MIN( bmp.bmHeight, bi.bmiHeader.biHeight );
}
else
{
iDir = 1;
iMinHeight = MIN( bmp.bmHeight, (-bi.bmiHeader.biHeight) );
}
iMinWidth = MIN( bmp.bmWidth, bi.bmiHeader.biWidth ); // LN, 2003-07-14, ADD
rcDestClip.left = 0;
rcDestClip.top = 0;
rcDestClip.right = iMinWidth;
rcDestClip.bottom = iMinHeight;
//将源位图转化到目标格式
return _WinGdi_ConvertImageColorValue(
lpDrv,
(_LPBITMAP_DIB)&bmp,
&rcDestClip,
&bi,
NULL,
uStartScan,
cScanLines,
lpImage->bmWidthBytes,
lpImage->bmBits + lpImage->bmWidthBytes * uStartScan,
uiUsage );
}
}
return 0;
}
// **************************************************
// 声明:int WINAPI WinGdi_SetDIBits(
// HDC hdc, // handle to device context
// HBITMAP hbmp, // handle to bitmap
// UINT uStartScan, // starting scan line
// UINT cScanLines, // number of scan lines
// CONST VOID *lpvBits, // array of bitmap bits
// CONST BITMAPINFO *lpbmi, // address of structure with bitmap data
// UINT fuColorUse // type of color indexes to use
// )
// 参数:
// IN hdc - DC句柄
// IN hbmp - 需要设置数据的位图
// IN uStartScan - 说明lpvBits的数据的开始扫描行
// IN cScanLines -说明lpvBits的数据所具有的扫描行行数
// IN lpvBits - 保存有位图数据的指针,该数据将拷贝到hbmp
// IN lpbmi - BITMAPINFO数据结构,用于描述lpvBits指向的数据信息
// IN fuColorUse - 说明BITMAPINFO结构成员bmiColors的类型:
// DIB_PAL_COLORS - bmiColors为16索引数组,每一个索引值指向当前hdc的调色板的对应项
// DIB_RGB_COLORS - bmiColors为红、绿、蓝颜色数组
// 返回值:
// 假如成功,返回拷贝到hbmp的行数;否则,返回0
// 功能描述:
// 根据DIB数据格式设置位图数据到 hbmp
// 引用:
// 系统API
// ************************************************
#define ABS( v ) ( (v) > 0 ? (v) : -(v) )
int WINAPI WinGdi_SetDIBits(
HDC hdc, // handle to device context
HBITMAP hbmp, // handle to bitmap
UINT uStartScan, // starting scan line
UINT cScanLines, // number of scan lines
CONST VOID *lpvBits, // array of bitmap bits
CONST BITMAPINFO *lpbmi, // address of structure with bitmap data
UINT fuColorUse // type of color indexes to use
)
{
_LPBITMAPDATA lpImage = _GetHBITMAPPtr( hbmp );
int nHeight;
RECT rcDestClip;
_LPCDISPLAYDRV lpDrv;
//得到该位图的驱动程序接口
lpDrv = GetDisplayDeviceDriver( lpImage );
if( lpDrv == NULL )
return 0;
if( lpbmi )
nHeight = ABS(lpbmi->bmiHeader.biHeight);
if( lpbmi &&
lpImage )
{
int iDir;
int iScanLineBytes = (lpbmi->bmiHeader.biBitCount * lpbmi->bmiHeader.biWidth + 31) / 32 * 4; // align to dword
int iMinWidth, iMinHeight;
if( lpbmi->bmiHeader.biHeight > 0 )
{ //方向为底到顶
iDir = -1;
iMinHeight = MIN( lpImage->bmHeight, nHeight );
}
else
{ //方向为顶到底
iDir = 1;
iMinHeight = MIN( lpImage->bmHeight, nHeight );
}
iMinWidth = MIN( lpImage->bmWidth, lpbmi->bmiHeader.biWidth );
rcDestClip.left = 0;
rcDestClip.top = 0;
rcDestClip.right = iMinWidth;
rcDestClip.bottom = iMinHeight;
//从源到目标转化位图数据
return _WinGdi_ConvertImageColorValue(
lpDrv,
(_LPBITMAP_DIB)lpImage,
&rcDestClip,
lpbmi,
NULL,
uStartScan,
cScanLines,
iScanLineBytes,
lpvBits,
fuColorUse
);
}
return 0;
}
// **************************************************
// 声明:HBITMAP WINAPI WinGdi_CreateDIBSection(
// HDC hdc,
// CONST BITMAPINFO *lpbmi,
// UINT iUsage, //must = PAL
// VOID ** lppvBits,
// HANDLE hSection, // must = NULL
// DWORD dwOffset // = 0
// )
// 参数:
// IN hdc - DC句柄
// IN lpbmi - BITMAPINFO结构指针,用于说明需要创建的位图信息
// IN iUsage - 说明BITMAPINFO结构成员bmiColors的类型:
// DIB_PAL_COLORS - bmiColors为16索引数组,每一个索引值指向当前hdc的调色板的对应项
// DIB_RGB_COLORS - bmiColors为红、绿、蓝颜色数组
// IN lppvBits - 用于接收指向位图数据的内存地址
// IN hSection - 必须为NULL
// IN dwOffset - 必须为0
// 返回值:
// 假如成功,返回有效的位图句柄;否则,返回NULL
// 功能描述:
// 创建一个用户能直接写位图数据的不依赖设备的位图
// 引用:
// 系统API
// ************************************************
HBITMAP WINAPI WinGdi_CreateDIBSection(
HDC hdc,
CONST BITMAPINFO *lpbmi,
UINT iUsage, //must = PAL
VOID ** lppvBits,
HANDLE hSection, // must = NULL
DWORD dwOffset // = 0
)
{
//Handle to a device context. If the value of iUsage is DIB_PAL_COLORS,
//the function uses this device context's logical palette to initialize the DIB's colors
//我将来会支持该功能
if( lppvBits )
*lppvBits = NULL;
{
_LPBITMAPDATA lpBitmap;
HBITMAP hBitmap;
int iHeight = lpbmi->bmiHeader.biHeight;
int iDir;
if( iHeight < 0 )
{ //方向为底到顶
iDir = 0;
iHeight = -iHeight;
}
else
iDir = 1;
//创建位图对象
hBitmap = _WinGdi_CreateBitmap(
lpbmi->bmiHeader.biWidth,
iHeight,
lpbmi->bmiHeader.biPlanes,
lpbmi->bmiHeader.biBitCount,
iDir,
NULL,
&lpBitmap,
0,
lpbmi,
FALSE );
if( lpBitmap )
{ //因为该内存为 GWME 进程创建,其它进程没有对其访问的权,所以需要映射
//以后将改变该方法,直接从调用者进程分配
if( lppvBits )
*lppvBits = MapPtrToProcess( (LPVOID)lpBitmap->bmBits, hgwmeProcess );//GetCurrentProcess() );
return hBitmap;
}
}
return NULL;
}
// **************************************************
// 声明:HBITMAP WINAPI WinGdi_CreateDIBitmap(
// HDC hdc, // handle to DC
// CONST BITMAPINFOHEADER *lpbmih, // bitmap data
// DWORD fdwInit, // initialization option
// CONST VOID *lpbInit, // initialization data
// CONST BITMAPINFO *lpbmi, // color-format data
// UINT fuUsage // color-data usage
// )
// 参数:
// IN hdc - DC句柄
// IN lpbmih – BITMAPINFOHEADER结构指针,用于描述需要创建的位图的高度和宽度
// IN fdwInit – 初始化标志。假如是CBM_INIT,系统用lpbInit 和lpbmi去初始化位图数据
// IN lpbInit – 包含需要初始化的位图数据,数据格式由lpbmi说明
// IN lpbmi – BITMAPINFO结构指针,用于描述lpbInit指向的数据格式
// IN fuUsage - 说明BITMAPINFO结构成员bmiColors的类型:
// DIB_PAL_COLORS – bmiColors为16索引数组,每一个索引值指向当前hdc的调色板的对应项
// DIB_RGB_COLORS – bmiColors为红、绿、蓝颜色数组
// 返回值:
// 假如成功,返回TRUE;否则,返回FALSE
// 功能描述:
// 创建一个设备依赖的位图并从设备不依赖的位图拷贝数据
// 引用:
// 系统API
// ************************************************
HBITMAP WINAPI WinGdi_CreateDIBitmap(
HDC hdc, // handle to DC
CONST BITMAPINFOHEADER *lpbmih, // bitmap data
DWORD fdwInit, // initialization option
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -