关于CDib类中BITMAPFILEHEADER使用方法的不解
在《精通visual c++图像处理编程》这本书第三章的范例中,其CDib类有这样一个方法:
BOOL CDib::Read(CFile *pFile)
{
WaitCursorBegin();//显示沙漏光标
LPBITMAPINFOHEADER lpbi;
DWORD dwSize;
TRY
{
// 读取DIB文件头
BITMAPFILEHEADER bmfHdr;
pFile->Read(&bmfHdr, sizeof(BITMAPFILEHEADER));
// 判断是否为DIB文件
if (bmfHdr.bfType != DIB_HEADER_MARKER/*"BM"*/)
{
WaitCursorEnd();
return FALSE;
}
DWORD dwLength = pFile->GetLength();
if (bmfHdr.bfSize != dwLength)
bmfHdr.bfSize = dwLength;
// 读取DIB缓存
dwSize = bmfHdr.bfSize - sizeof(BITMAPFILEHEADER);
lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, dwSize);
DWORD dwCount = pFile->Read(lpbi, dwSize);
// 是否读取成功
if (dwCount != dwSize)
{
GlobalFreePtr(lpbi);
WaitCursorEnd();
return FALSE;
}
// 测试是否为Windows DIB——OS/2 DIB在使用其它DIB API时会导致奇怪的问题,因为头中的域是不同的,而且,颜色表项也比较小
// 如果不是Windows DIB(如果大小不对),返回NULL
if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
{
GlobalFreePtr(lpbi);
WaitCursorEnd();
return FALSE;
}
// 为颜色数项赋值
int nNumColors = (UINT)lpbi->biClrUsed;
if (nNumColors == 0)
{
// 对于24位像素没有颜色表,除此以外都是默认大小
if (lpbi->biBitCount != 24)
nNumColors = 1 << lpbi->biBitCount; // 标准大小的颜色表
}
// 如果值为0,则赋默认值
if (lpbi->biClrUsed == 0)
lpbi->biClrUsed = nNumColors;
if (lpbi->biSizeImage == 0)
lpbi->biSizeImage = ((((lpbi->biWidth * (DWORD)lpbi->biBitCount) + 31) & ~31) >> 3) * lpbi->biHeight;
}
CATCH (CException, e)
{
GlobalFreePtr(lpbi);
WaitCursorEnd();
return FALSE;
}
END_CATCH
// 通过DIB缓存建立CDib
BOOL bSuccess = Create((LPBYTE)lpbi);
GlobalFreePtr(lpbi);
WaitCursorEnd();
return bSuccess;
}
我在这里有点没看明白:
1、
dwSize = bmfHdr.bfSize - sizeof(BITMAPFILEHEADER);
lpbi = (LPBITMAPINFOHEADER)GlobalAllocPtr(GHND, dwSize);
lpbi指向的是“LPBITMAPINFOHEADER+RGBQUAD”还是只有“LPBITMAPINFOHEADER”?
2、
函数最后的Create调用的是CDib类的Create函数,用来创建CDib对象:
BOOL bSuccess = Create((LPBYTE)lpbi);
这里传入的参数lpbi是不是就是指向BITMAPFILEHEADER的指针呢?
创建CDib对象只需要BITMAPFILEHEADER就可以了吗?不需要RGBQUAD和位图数据吗?
Create函数如下:
BOOL CDib::Create(LPBYTE lpDIB)
{
if (lpDIB == NULL)
return FALSE;
DWORD dwSize = DIBlockSize(lpDIB);
HDIB hDib = GlobalAlloc(GHND, dwSize);
// 测试DIB句柄是否正确
if (! hDib)
return FALSE;
LPBYTE lpbi = (LPBYTE)GlobalLock(hDib);
if (! lpbi)
return FALSE;
CopyMemory(lpbi, lpDIB, dwSize);
GlobalUnlock(hDib);
Destroy();
m_hDib = hDib;
return UpdateInternal();
}
我是小白,求解惑