📄 dib.cpp
字号:
// Dib.cpp : implementation file
//
#include "stdafx.h"
#include "Dib.h"
//#include <windowsx.h> // especially for GlobalAllocPtr
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
IMPLEMENT_SERIAL(CDib, CObject, 0)
////////////////////////////////////////////////////////////////////////////
CDib::CDib()
{
m_dwLength = 0L;
m_nBits = 0;
m_lpBuf = NULL;
m_pPalette = NULL;
m_pBitmap = NULL;
m_hDib = NULL;
}
CDib:: CDib(HANDLE hDib, BOOL bDataHandleOnly)
{
if (hDib==NULL)
{
m_dwLength = 0L;
m_nBits = 0;
m_lpBuf = NULL;
m_pPalette = NULL;
m_pBitmap = NULL;
m_hDib = NULL;
return;
}
// Only use Bit-Data Handle
if (bDataHandleOnly)
{
m_pPalette = NULL;
m_pBitmap = NULL;
m_dwLength = ::GlobalSize(hDib)+sizeof(BITMAPFILEHEADER);
if (! AllocMemory())
return;
memcpy((LPSTR)m_lpBMI, (LPSTR)::GlobalLock((HGLOBAL)hDib), ::GlobalSize(hDib));
::GlobalUnlock(hDib);
// Fill in file type (first 2 bytes must be "BM" for a bitmap)
m_lpBMFH->bfType = 0x4d42; // "BM"
// Calculating the size of the DIB is a bit tricky (if we want to
// do it right). The easiest way to do this is to call GlobalSize()
// on our global handle, but since the size of our global memory may have
// been padded a few bytes, we may end up writing out a few too
// many bytes to the file (which may cause problems with some apps).
//
// So, instead let's calculate the size manually (if we can)
//
// First, find size of header plus size of color table. Since the
// first DWORD in both BITMAPINFOHEADER and BITMAPCOREHEADER conains
// the size of the structure, let's use this.
DWORD dwDIBSize;
dwDIBSize = *(LPDWORD)m_lpBMIH + GetPaletteSize(); // Partial Calculation
// Now calculate the size of the image
if ((m_lpBMIH->biCompression == BI_RLE8) ||
(m_lpBMIH->biCompression == BI_RLE4))
{
// It's an RLE bitmap, we can't calculate size, so trust the
// biSizeImage field
dwDIBSize += m_lpBMIH->biSizeImage;
}
else
{
DWORD dwBmBitsSize; // Size of Bitmap Bits only
// It's not RLE, so size is Width (DWORD aligned) * Height
dwBmBitsSize = WIDTHBYTES((m_lpBMIH->biWidth)*((DWORD)m_lpBMIH->biBitCount)) * m_lpBMIH->biHeight;
dwDIBSize += dwBmBitsSize;
// Now, since we have calculated the correct size, why don't we
// fill in the biSizeImage field (this will fix any .BMP files which
// have this field incorrect).
m_lpBMIH->biSizeImage = dwBmBitsSize;
}
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
m_lpBMFH->bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
m_lpBMFH->bfReserved1 = 0;
m_lpBMFH->bfReserved2 = 0;
/*
* Now, calculate the offset the actual bitmap bits will be in
* the file -- It's the Bitmap file header plus the DIB header,
* plus the size of the color table.
*/
m_lpBMFH->bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) +
m_lpBMIH->biSize + GetPaletteSize();
//if (IS_WIN30_DIB(m_lpBMIH))
// ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount== 4)||
// (m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24));
//else
// ASSERT((m_lpBMCH->bcBitCount==1)||(m_lpBMCH->bcBitCount== 4)||
// (m_lpBMCH->bcBitCount==8)||(m_lpBMCH->bcBitCount==24));
m_lpData = (LPSTR)m_lpBMFH + m_lpBMFH->bfOffBits;
if (IS_WIN30_DIB(m_lpBMIH))
m_nBits = m_lpBMIH->biBitCount;
else
m_nBits = m_lpBMCH->bcBitCount;
return;
}
// Use DIB Handle
m_hDib = hDib;
m_pPalette = NULL;
m_pBitmap = NULL;
m_dwLength = ::GlobalSize(m_hDib);
m_lpBuf = (LPSTR) ::GlobalLock((HGLOBAL) m_hDib);
m_lpBMFH = (LPBITMAPFILEHEADER)m_lpBuf;
m_lpBMIH = (LPBITMAPINFOHEADER)((LPSTR)m_lpBuf + sizeof(BITMAPFILEHEADER));
m_lpBMI = (LPBITMAPINFO)m_lpBMIH;
m_lpBMCH = (LPBITMAPCOREHEADER)m_lpBMIH;
m_lpBMC = (LPBITMAPCOREINFO)m_lpBMCH;
if (IS_WIN30_DIB(m_lpBMIH))
ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount== 4)||
(m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24));
else
ASSERT((m_lpBMCH->bcBitCount==1)||(m_lpBMCH->bcBitCount== 4)||
(m_lpBMCH->bcBitCount==8)||(m_lpBMCH->bcBitCount==24));
m_lpData = (LPSTR)m_lpBMFH + m_lpBMFH->bfOffBits;
if (IS_WIN30_DIB(m_lpBMIH))
m_nBits = m_lpBMIH->biBitCount;
else
m_nBits = m_lpBMCH->bcBitCount;
}
CDib::CDib(CDC* pDC, // Memory DC pointer, which has
// selected a DDB bitmap
int nBt, // color bits/pixel (default=0, use the value in DDB)
BOOL bCompr) // compression? (default = TRUE);
{
BITMAP bm;
int nPaletteSize;
m_pPalette = NULL;
m_pBitmap = NULL;
CBitmap *pEmptyBitmap = new CBitmap;
pEmptyBitmap->CreateCompatibleBitmap(pDC,0,0);
CBitmap *pBitmap = (CBitmap *)(pDC->SelectObject(pEmptyBitmap));
delete pDC->SelectObject(pBitmap);
pBitmap->GetObject(sizeof(bm), &bm);
switch (nBt)
{
case 1 :
case 4 :
case 8 :
case 24: m_nBits = nBt;
break;
default: m_nBits = bm.bmPlanes * bm.bmBitsPixel;
break;
}
switch (m_nBits)
{
case 1 : nPaletteSize = 2;
break;
case 4 : nPaletteSize = 16;
break;
case 8 : nPaletteSize = 256;
break;
default: nPaletteSize = 0;
break;
}
DWORD dwBytes = ((DWORD) bm.bmWidth * m_nBits) / 32;
if (((DWORD) bm.bmWidth * m_nBits) % 32)
dwBytes++;
dwBytes *= 4;
m_dwLength = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
if (! AllocMemory())
return;
m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
m_lpBMIH->biWidth = bm.bmWidth;
m_lpBMIH->biHeight = bm.bmHeight;
m_lpBMIH->biPlanes = 1;
m_lpBMIH->biBitCount = m_nBits;
if (bCompr && m_nBits==4)
m_lpBMIH->biCompression = BI_RLE4;
else if (bCompr && m_nBits==8)
m_lpBMIH->biCompression = BI_RLE8;
else
m_lpBMIH->biCompression = BI_RGB;
m_lpBMIH->biSizeImage = 0;
m_lpBMIH->biXPelsPerMeter = 0;
m_lpBMIH->biYPelsPerMeter = 0;
m_lpBMIH->biClrUsed = 0;
m_lpBMIH->biClrImportant = 0;
::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)pBitmap->GetSafeHandle(),
0, (WORD)bm.bmHeight, NULL, m_lpBMI, DIB_RGB_COLORS);
if (m_lpBMIH->biSizeImage == 0)
{
m_dwLength += dwBytes*bm.bmHeight;
m_lpBMIH->biCompression = BI_RGB;
TRACE("Can not do compression\n");
}
else
m_dwLength += m_lpBMIH->biSizeImage;
if (! AllocMemory(TRUE))
return;
m_lpData = (LPSTR)m_lpBMIH + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
m_lpBMFH->bfType = 0x4d42; //'BM'
m_lpBMFH->bfSize = m_dwLength;
m_lpBMFH->bfReserved1 = 0;
m_lpBMFH->bfReserved2 = 0;
m_lpBMFH->bfOffBits = m_lpData - m_lpBuf;
if (! ::GetDIBits(pDC->GetSafeHdc(), (HBITMAP)pBitmap->GetSafeHandle(),
0, (WORD)bm.bmHeight, m_lpData, m_lpBMI, DIB_RGB_COLORS))
m_dwLength = 0L;
}
CDib::CDib(CDC* pDC, // DC pointer
CBitmap* pBitmap, // DDB bitmap
int nBt, // color bits/pixel (default=0, use the value in DDB)
BOOL bCompr) // compression? (default = TRUE);
{
BITMAP bm;
int nPaletteSize;
m_pPalette = NULL;
m_pBitmap = NULL;
CDC *pMemDC = new CDC;
pMemDC->CreateCompatibleDC(pDC);
CBitmap* pOldBitmap = (CBitmap *)(pMemDC->SelectObject(pBitmap));
pBitmap->GetObject(sizeof(bm), &bm);
switch (nBt)
{
case 1 :
case 4 :
case 8 :
case 24: m_nBits = nBt;
break;
default: m_nBits = bm.bmPlanes * bm.bmBitsPixel;
break;
}
switch (m_nBits)
{
case 1 : nPaletteSize = 2;
break;
case 4 : nPaletteSize = 16;
break;
case 8 : nPaletteSize = 256;
break;
default: nPaletteSize = 0;
break;
}
DWORD dwBytes = ((DWORD) bm.bmWidth * m_nBits) / 32;
if (((DWORD) bm.bmWidth * m_nBits) % 32)
dwBytes++;
dwBytes *= 4;
m_dwLength = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
if (! AllocMemory())
return;
m_lpBMIH->biSize = sizeof(BITMAPINFOHEADER);
m_lpBMIH->biWidth = bm.bmWidth;
m_lpBMIH->biHeight = bm.bmHeight;
m_lpBMIH->biPlanes = 1;
m_lpBMIH->biBitCount = m_nBits;
if (bCompr && m_nBits==4)
m_lpBMIH->biCompression = BI_RLE4;
else if (bCompr && m_nBits==8)
m_lpBMIH->biCompression = BI_RLE8;
else
m_lpBMIH->biCompression = BI_RGB;
m_lpBMIH->biSizeImage = 0;
m_lpBMIH->biXPelsPerMeter = 0;
m_lpBMIH->biYPelsPerMeter = 0;
m_lpBMIH->biClrUsed = 0;
m_lpBMIH->biClrImportant = 0;
::GetDIBits(pMemDC->GetSafeHdc(), (HBITMAP)pBitmap->GetSafeHandle(),
0, (WORD)bm.bmHeight, NULL, m_lpBMI, DIB_RGB_COLORS);
if (m_lpBMIH->biSizeImage == 0)
{
m_dwLength += dwBytes*bm.bmHeight;
m_lpBMIH->biCompression = BI_RGB;
TRACE("Can not do compression\n");
}
else
m_dwLength += m_lpBMIH->biSizeImage;
if (! AllocMemory(TRUE))
return;
m_lpData = (LPSTR)m_lpBMIH + sizeof(BITMAPINFOHEADER) +
sizeof(RGBQUAD) * nPaletteSize;
m_lpBMFH->bfType = 0x4d42; //'BM'
m_lpBMFH->bfSize = m_dwLength;
m_lpBMFH->bfReserved1 = 0;
m_lpBMFH->bfReserved2 = 0;
m_lpBMFH->bfOffBits = m_lpData - m_lpBuf;
if (! ::GetDIBits(pMemDC->GetSafeHdc(), (HBITMAP)pBitmap->GetSafeHandle(),
0, (WORD)bm.bmHeight, m_lpData, m_lpBMI, DIB_RGB_COLORS))
m_dwLength = 0L;
pMemDC->SelectObject(pOldBitmap);
delete pMemDC;
}
CDib::~CDib()
{
if (m_hDib!=NULL)
{
::GlobalUnlock((HGLOBAL) m_hDib);
::GlobalFree((HGLOBAL) m_hDib);
m_lpBuf = NULL;
m_hDib = NULL;
}
if (m_pPalette!=NULL)
{
delete m_pPalette;
m_pPalette = NULL;
}
if (m_pBitmap!=NULL)
{
delete m_pBitmap;
m_pBitmap = NULL;
}
}
void CDib::Serialize(CArchive& ar)
{
CObject::Serialize(ar);
ar.Flush();
if (ar.IsStoring())
{
WriteDib(ar.GetFile());
}
else
{
ReadDib(ar.GetFile());
}
}
BOOL CDib::LoadDib(UINT uIDS, LPCSTR lpszDibType)
{
ASSERT(m_dwLength == 0L);
LPCSTR lpszDibRes = MAKEINTRESOURCE(uIDS);
HINSTANCE hInst = AfxGetInstanceHandle();
HRSRC hRes = ::FindResource(hInst, lpszDibRes, lpszDibType);
HGLOBAL hData = ::LoadResource(hInst, hRes);
if (hRes != NULL && hData != NULL)
{
char *lpBuf = (char *)::LockResource(hData);
m_dwLength = ((LPBITMAPFILEHEADER)lpBuf)->bfSize;
if (! AllocMemory())
return FALSE;
for (register DWORD i=0;i<m_dwLength;++i)
*(m_lpBuf+i) = *(lpBuf+i);
}
else
{
CString str = lpszDibRes;
str += " : Read Resource error!";
AfxMessageBox(str);
return FALSE;
}
if (m_lpBMFH->bfType != 0x4d42)
{
CString str = lpszDibRes;
str += " : Invalid bitmap file!";
AfxMessageBox(str);
return FALSE;
}
if (IS_WIN30_DIB(m_lpBMIH))
ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount== 4)||
(m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24));
else
ASSERT((m_lpBMCH->bcBitCount==1)||(m_lpBMCH->bcBitCount== 4)||
(m_lpBMCH->bcBitCount==8)||(m_lpBMCH->bcBitCount==24));
m_lpData = (LPSTR)m_lpBMFH + m_lpBMFH->bfOffBits;
m_nBits = m_lpBMIH->biBitCount;
return TRUE;
}
BOOL CDib::LoadDib(LPCSTR lpszDibRes, LPCSTR lpszDibType)
{
ASSERT(m_dwLength == 0L);
HINSTANCE hInst = AfxGetInstanceHandle();
HRSRC hRes = ::FindResource(hInst, lpszDibRes, lpszDibType);
HGLOBAL hData = ::LoadResource(hInst, hRes);
if (hRes != NULL && hData != NULL)
{
char *lpBuf = (char *)::LockResource(hData);
m_dwLength = ((LPBITMAPFILEHEADER)lpBuf)->bfSize;
if (! AllocMemory())
return FALSE;
for (register DWORD i=0;i<m_dwLength;++i)
*(m_lpBuf+i) = *(lpBuf+i);
}
else
{
CString str = lpszDibRes;
str += " : Read Resource error!";
AfxMessageBox(str);
return FALSE;
}
if (m_lpBMFH->bfType != 0x4d42)
{
CString str = lpszDibRes;
str += " : Invalid bitmap file!";
AfxMessageBox(str);
return FALSE;
}
if (IS_WIN30_DIB(m_lpBMIH))
ASSERT((m_lpBMIH->biBitCount==1)||(m_lpBMIH->biBitCount== 4)||
(m_lpBMIH->biBitCount==8)||(m_lpBMIH->biBitCount==24));
else
ASSERT((m_lpBMCH->bcBitCount==1)||(m_lpBMCH->bcBitCount== 4)||
(m_lpBMCH->bcBitCount==8)||(m_lpBMCH->bcBitCount==24));
m_lpData = (LPSTR)m_lpBMFH + m_lpBMFH->bfOffBits;
m_nBits = m_lpBMIH->biBitCount;
return TRUE;
}
BOOL CDib::LoadDib(LPCSTR lpszDibFile)
{
ASSERT(m_dwLength == 0L);
TRY
{
CFile file(lpszDibFile, CFile::modeRead|CFile::shareDenyNone);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -