📄 loadimg.c
字号:
yDestDir = 1;
}
}
else
{ //目标是反向 // b->u
if( iSrcDir < 0 )
{ //源是反向 // b->u
yDestStart = lpDestImage->bitmap.bmHeight - rcDestClip.bottom;
lpbDestStart = lpDestImage->bitmap.bmBits + yDestStart * lpDestImage->bitmap.bmWidthBytes;
iDestWidthBytes = lpDestImage->bitmap.bmWidthBytes;
yDestDir = 1;
}
else
{ //源是正向
yDestStart = lpDestImage->bitmap.bmHeight - rcDestClip.top - 1;
lpbDestStart = lpDestImage->bitmap.bmBits + yDestStart * lpDestImage->bitmap.bmWidthBytes;
iDestWidthBytes = -lpDestImage->bitmap.bmWidthBytes;
yDestDir = -1;
}
}
dwReadScanLine = dwScanLineNum;
//准备点操作结构
pixelData.lpDestImage = &lpDestImage->bitmap;
pixelData.pattern = 0;
pixelData.rop = R2_COPYPEN;
if( lpbi->bmiHeader.biBitCount == 1 )
{ //源是单色位图格式
COLORREF * lprgb = (COLORREF *)lpbi->bmiColors;
if( lpDestImage->bitmap.bmBitsPixel == 1 &&
lprcDestClip == NULL &&
lprcSrcClip == NULL )
{ //目标是单色位图格式
for( ; dwReadScanLine; dwReadScanLine--, lpbData += dwScanLineWidth )
{ //直接拷贝
memcpy( lpbDestStart, lpbData, dwScanLineWidth );
lpbDestStart += iDestWidthBytes;
}
}
else
{ //目标是非单色位图格式
//用逐个写点的方法
for( ; dwReadScanLine; dwReadScanLine--, yDestStart += yDestDir, lpbData += dwScanLineWidth )
{ //每行
int xe = xDestStart + xDestWidth;
LPCBYTE lpbColor = lpbData + (xSrcStart >> 3); // xs / 8
int iBits = 0x80 >> ( xSrcStart & 0x7 );
pixelData.y = yDestStart;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor++ )
{ //每列
for( ; iBits && pixelData.x < xe; iBits >>= 1, pixelData.x++ )
{
if( *lpbColor & iBits )
{
pixelData.color = *(lprgb+1);
}
else
{
pixelData.color = *lprgb;
}
lpDrv->lpPutPixel( &pixelData );
}
iBits = 0x80;
}
}
}
}
else if( lpbi->bmiHeader.biBitCount == 2 )
{ //源是2bit/pixel位图格式
INT16 * lpPal = (INT16 *)lpbi->bmiColors;
RGBQUAD * lpquad = (RGBQUAD *)lpbi->bmiColors;
UINT cIndex = 0xffffffffl;
//用逐个写点的方法
for( ; dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPCBYTE lpbColor = lpbData + (xSrcStart >> 2); // xSrc / 4
int xe = xDestStart + xDestWidth;
int iBits = 0xc0 >> ( ( xSrcStart & 0x3 ) << 1 );
pixelData.y = yDestStart;//dwStartScanLine; // dest
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor++ )
{ //每列
int iShift = 6;
for( ; iBits && pixelData.x < xe; iBits >>= 2, pixelData.x++, iShift-= 2 )
{
UINT v = (*lpbColor & iBits) >> iShift;
//如果前一次的颜色值与当前的相同,则不需要
//再去得到设备相关的颜色值;否则,需要重新计算
//设备相关的颜色值
if( cIndex != v )
{ //得到设备相关的颜色值
cIndex = v;
if( fuColorUse == DIB_PAL_COLORS )
pixelData.color = lpPal[v];
else
pixelData.color = lpDrv->lpRealizeColor( RGB( lpquad[v].rgbRed, lpquad[v].rgbGreen, lpquad[v].rgbBlue ), NULL, 0, 0 );
}
lpDrv->lpPutPixel( &pixelData );
}
iBits = 0xc0;
}
}
}
else if( lpbi->bmiHeader.biBitCount == 4 )
{ //源是4bit/pixel位图格式
INT16 * lpPal = (INT16 *)lpbi->bmiColors;
RGBQUAD * lpquad = (RGBQUAD *)lpbi->bmiColors;
UINT cIndex = 0xffffffffl;
//用逐个写点的方法
for( ; dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPCBYTE lpbColor = lpbData + (xSrcStart >> 1);
int xe = xDestStart + xDestWidth;
int iBits = 0xf0 >> ( ( xSrcStart & 0x1 ) << 2 );
pixelData.y = yDestStart;//dwStartScanLine;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor++ )
{ //每列
int iShift = 4;
for( ; iBits && pixelData.x < xe; iBits >>= 4, pixelData.x++, iShift -= 4 )
{
UINT v = (*lpbColor & iBits) >> iShift;
//如果前一次的颜色值与当前的相同,则不需要
//再去得到设备相关的颜色值;否则,需要重新计算
//设备相关的颜色值
if( cIndex != v )
{ //得到设备相关的颜色值
cIndex = v;
if( fuColorUse == DIB_PAL_COLORS )
pixelData.color = lpPal[v];//lprgb[v];
else
pixelData.color = lpDrv->lpRealizeColor( RGB( lpquad[v].rgbRed, lpquad[v].rgbGreen, lpquad[v].rgbBlue ), NULL, 0, 0 );
}
lpDrv->lpPutPixel( &pixelData );
}
iBits = 0xf0;
}
}
}
else if( lpbi->bmiHeader.biBitCount == 8 )
{ //源是8bit/pixel位图格式
INT16 * lpPal = (INT16 *)lpbi->bmiColors;
RGBQUAD * lpquad = (RGBQUAD *)lpbi->bmiColors;
UINT v = 0xffffffffl;
for( ; dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPCBYTE lpbColor = lpbData;
int xe = xDestStart + xDestWidth;
pixelData.y = yDestStart;//dwStartScanLine;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor++, pixelData.x++ )
{ //每列
//如果前一次的颜色值与当前的相同,则不需要
//再去得到设备相关的颜色值;否则,需要重新计算
//设备相关的颜色值
// 假如 v == *lpbColor, pixelData.color 的值可以重用
if( v != *lpbColor )
{
v = *lpbColor;
if( fuColorUse == DIB_PAL_COLORS )
pixelData.color = lpPal[v];
else
{
pixelData.color = lpDrv->lpRealizeColor( RGB( lpquad[v].rgbRed, lpquad[v].rgbGreen, lpquad[v].rgbBlue ), NULL, 0, 0 );
}
}
lpDrv->lpPutPixel( &pixelData );
}
}
}
else if( lpbi->bmiHeader.biBitCount == 16 )
{ //源是16bit/pixel位图格式
DWORD dwRedMask, dwGreenMask, dwBlueMask;
DWORD dwrgb, dwSrc = 0xffffffffl;
int iRedShift, iGreenShift, iBlueShift;
//包含颜色位模吗 ?
if( lpbi->bmiHeader.biCompression == BI_RGB )
{ //默认的位格式 = 5r-5g-5b format
/*
dwRedMask = 0x001F;//0x7C00;
iRedShift = GetShiftValue( dwRedMask );//0;//10;
dwGreenMask = 0x07e0;//0x03E0;
iGreenShift = GetShiftValue( dwGreenMask );//5;
dwBlueMask = 0xf800;//0x001F;
iBlueShift = GetShiftValue( dwBlueMask );//11;//0;
*/
/*
The bitmap has a maximum of 2^16 colors.
If the biCompression member of the BITMAPINFOHEADER is BI_RGB,
the bmiColors member of BITMAPINFO is NULL. Each WORD in the
bitmap array represents a single pixel. The relative
intensities of red, green, and blue are represented
with five bits for each color component. The value for blue is
in the least significant five bits, followed by five bits each
for green and red. The most significant bit is not used.
*/
dwRedMask = 0x7C00;
iRedShift = GetShiftValue( dwRedMask );//0;//10;
dwGreenMask = 0x03E0;
iGreenShift = GetShiftValue( dwGreenMask );//5;
dwBlueMask = 0x001F;
iBlueShift = GetShiftValue( dwBlueMask );//11;//0;
}
else
{ //非默认的 得到格式
//得到移位操作值
dwRedMask = *(LPDWORD)lpbi->bmiColors;
iRedShift = GetShiftValue(dwRedMask);
dwGreenMask = *( (LPDWORD)lpbi->bmiColors + 1 );
iGreenShift = GetShiftValue(dwGreenMask);
dwBlueMask = *( (LPDWORD)lpbi->bmiColors + 2 );
iBlueShift = GetShiftValue(dwBlueMask);
}
for( ;dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPWORD lpwData = (LPWORD)lpbData;
int xe = xDestStart + xDestWidth;
pixelData.y = yDestStart;//dwStartScanLine;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; pixelData.x++ )
{ //每列
//如果前一次的颜色值与当前的相同,则不需要
//再去得到设备相关的颜色值;否则,需要重新计算
//设备相关的颜色值
// 假如 dwSrc == *lpwData, pixelData.color 的值可以重用
if( dwSrc != *lpwData )
{
dwSrc = *lpwData;
dwrgb =
( ( ( dwSrc & dwRedMask ) << iRedShift ) >> 24 ) |
( ( ( dwSrc & dwGreenMask ) << iGreenShift ) >> 16 ) |
( ( ( dwSrc & dwBlueMask ) << iBlueShift ) >> 8 );
pixelData.color = lpDrv->lpRealizeColor( dwrgb, NULL, 0, 0 );
}
lpDrv->lpPutPixel( &pixelData );
lpwData++;
}
}
}
else if( lpbi->bmiHeader.biBitCount == 24 )
{ //源是24bit/pixel位图格式
for( ; dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPCBYTE lpbColor = lpbData;
int xe = xDestStart + xDestWidth;
pixelData.y = yDestStart;//dwStartScanLine;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor+=3, pixelData.x++ )
{ //每列
pixelData.color = lpDrv->lpRealizeColor( RGB( *(lpbColor+2), *(lpbColor+1), *lpbColor ), NULL, 0, 0 );
lpDrv->lpPutPixel( &pixelData );
}
}
}
else if( lpbi->bmiHeader.biBitCount == 32 )
{ //源是32bit/pixel位图格式
DWORD dwColor = ~( *( (LPDWORD)lpbData ) );
for( ; dwReadScanLine; dwReadScanLine--, yDestStart+=yDestDir, lpbData += dwScanLineWidth )
{ //每行
LPBYTE lpbColor = (LPBYTE)lpbData;
int xe = xDestStart + xDestWidth;
pixelData.y = yDestStart;//dwStartScanLine;
pixelData.x = xDestStart;
for( ; pixelData.x < xe; lpbColor+=4, pixelData.x++ )
{ //每列
if( dwColor != *( (LPDWORD)lpbColor ) )
{ // the color bytes format is b + g + r , LN 2003-09-06
dwColor = *( (LPDWORD)lpbColor );
// pixelData.color = lpDrv->lpRealizeColor( dwColor );
pixelData.color = lpDrv->lpRealizeColor( RGB( *(lpbColor+2), *(lpbColor+1), *lpbColor ), NULL, 0, 0 );
}
lpDrv->lpPutPixel( &pixelData );
}
}
}
return (int)(dwScanLineNum - dwReadScanLine);
}
typedef struct _MYBITMAPFILEHEADER
{
WORD bfDumy; // to align
WORD bfType;
DWORD bfSize;
WORD bfReserved1;
WORD bfReserved2;
DWORD bfOffBits;
}MYBITMAPFILEHEADER, * PMYBITMAPFILEHEADER, FAR * LPMYBITMAPFILEHEADER;
// **************************************************
// 声明:static HBITMAP _HandleImageData( HANDLE hFile, BITMAPINFO *lpbi )
// 参数:
// IN hFile - 位图文件句柄
// IN lpbi - 包含位图基本信息的结构
// IN bShare - 是否共享
// 返回值:
// 假如成功,返回新的位图对象句柄;否则,返回NULL
// 功能描述:
// 处理位图文件,创建新的位图对象
// 引用:
//
// ************************************************
#define DEBUG_HANDLE_IMAGE_DATA 0
static HBITMAP _HandleImageData( HANDLE hFile, BITMAPINFO *lpbi, BOOL bShare )
{
HBITMAP hbmp;
int iHeight = lpbi->bmiHeader.biHeight;
_LPBITMAPDATA lpImage;
_LPCDISPLAYDRV lpDrv;
//是否反向 ?
if( iHeight < 0 )
iHeight = -iHeight;
//创建一个内存位图对象
if( lpbi->bmiHeader.biPlanes == 1 && lpbi->bmiHeader.biBitCount == 1 )
hbmp = _WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, iHeight, 1, 1, 0, NULL, NULL, 0, NULL, bShare );
//WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, iHeight, 1, 1, 0 );
else
hbmp = _WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, iHeight, lpDisplayBitmap->bmPlanes, lpDisplayBitmap->bmBitsPixel, 0, NULL, NULL, 0, NULL, bShare );
//hbmp = WinGdi_CreateBitmap( lpbi->bmiHeader.biWidth, iHeight, lpDisplayBitmap->bmPlanes, lpDisplayBitmap->bmBitsPixel, 0 );
if( hbmp )
{ //扫描行宽度
int iScanLineBytes = (lpbi->bmiHeader.biBitCount * lpbi->bmiHeader.biWidth + 31) / 32 * 4; // align to dword
DWORD dwTotalSize = iScanLineBytes * iHeight;
LPBYTE lpbData;
DWORD dwReadSize;
DWORD dwReadScanLine;
int iDir;
lpImage = _GetHBITMAPPtr( hbmp );
ASSERT( lpImage );
//得到该位图格式支持的设备驱动程序
lpDrv = GetDisplayDeviceDriver( lpImage );
ASSERT( lpDrv );
//是否需要太多的临时内存,如果需要太多,则逐行处理
//否则一次读出所有的数据
if( dwTotalSize <= 1024 )
{ //读出所有的数据
lpbData = (LPBYTE)malloc( dwTotalSize );
dwReadSize = dwTotalSize;
dwReadScanLine = lpbi->bmiHeader.biHeight;
}
else
{ //逐行处理
lpbData = (LPBYTE)malloc( iScanLineBytes );
dwReadSize = iScanLineBytes;
dwReadScanLine = 1;
}
if( lpbData )
{
DWORD dwCount;
DWORD dwStartScanLine;
DWORD dwRealReadSize;
//转化调色板
_ConvertRGBQUADColorToPalColor( lpbi );
if( (int)lpbi->bmiHeader.biHeight > 0 )
{ //反向
dwStartScanLine = 0;
iDir = -1;
}
else
{ //正向
dwStartScanLine = 0;
iDir = 1;
}
for( dwCount = 0;dwCount < dwTotalSize; dwCount += dwReadSize )
{ //读位图数据
ReadFile(hFile, lpbData, dwReadSize,&dwRealReadSize,NULL);
if( dwRealReadSize != dwReadSize )
{ // error
WARNMSG( DEBUG_HANDLE_IMAGE_DATA, ( "_HandleImageData: error in _HandleImageData.\r\n" ) );
break;
}
//转化
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -