📄 dibsection.cpp
字号:
if(hdc == NULL)
goto exit;
m_uColorTableSize = NumColorEntries(bm.bmBitsPixel, BI_RGB);
// Initialize the BITMAPINFOHEADER in m_DIBinfo
bih.biSize = sizeof(BITMAPINFOHEADER);
bih.biWidth = bm.bmWidth;
bih.biHeight = bm.bmHeight;
bih.biPlanes = 1; // Must always be 1 according to docs
bih.biBitCount = bm.bmBitsPixel;
#ifdef _WIN32_WCE
// DCR 4/02/01 I've found PocketPCs need BI_BITFIELDS for 16 bit dibs.
if(bm.bmBitsPixel == 16 || bm.bmBitsPixel == 32)
bih.biCompression = BI_BITFIELDS;
else
bih.biCompression = BI_RGB;
#else // _WIN32_WCE
bih.biCompression = BI_RGB;
#endif // _WIN32_WCE
bih.biSizeImage = BytesPerLine(bm.bmWidth, bm.bmBitsPixel) * bm.bmHeight;
bih.biXPelsPerMeter = 0;
bih.biYPelsPerMeter = 0;
bih.biClrUsed = 0;
bih.biClrImportant = 0;
DWORD dwColors = GetColorTableEntries(hdc, hBitmap);
if(bm.bmBitsPixel == 16)
bih.biClrUsed = dwColors;
// If the driver did not fill in the biSizeImage field, then compute it
// Each scan line of the image is aligned on a DWORD (32bit) boundary
if(bih.biSizeImage == 0)
bih.biSizeImage = BytesPerLine(bih.biWidth, bih.biBitCount) * bih.biHeight;
#ifndef DIBSECTION_NO_PALETTE
if(hPalette != NULL)
SetPalette(hPalette);
if(m_hPalette != NULL)
{
hpalOld = SelectPalette(hdc, m_hPalette, FALSE);
RealizePalette(hdc);
}
#endif // DIBSECTION_NO_PALETTE
// Create it
m_hBitmap = CreateDIBSection(hdc, (const PBITMAPINFO)m_DIBinfo, m_uColorDataType, (void**)&m_ppvBits, NULL, 0);
#ifndef DIBSECTION_NO_PALETTE
if(hpalOld != NULL)
{
SelectPalette(hdc, hpalOld, FALSE);
hpalOld = NULL;
}
#endif // DIBSECTION_NO_PALETTE
if(m_hBitmap == NULL)
goto cleanup;
#ifndef DIBSECTION_NO_PALETTE
// If palette was supplied then create a palette using the entries in the DIB
// color table.
if(hPalette == NULL)
CreateSparePalette();
#endif // DIBSECTION_NO_PALETTE
// Need to copy the supplied bitmap onto the newly created DIBsection
hdcMem = CreateCompatibleDC(hdc);
hdcCopy = CreateCompatibleDC(hdc);
if(hdcMem == NULL || hdcCopy == NULL)
goto cleanup;
#ifndef DIBSECTION_NO_PALETTE
if(m_hPalette != NULL)
{
SelectPalette(hdcMem, m_hPalette, FALSE);
RealizePalette(hdcMem);
SelectPalette(hdcCopy, m_hPalette, FALSE);
RealizePalette(hdcCopy);
}
#endif // DIBSECTION_NO_PALETTE
#ifndef _WIN32_WCE
GdiFlush();
#endif // !_WIN32_WCE
{
HGDIOBJ hbmpOldMem = SelectObject(hdcMem, hBitmap);
HGDIOBJ hbmpOldCopy = SelectObject(hdcCopy, m_hBitmap);
BitBlt(hdcCopy, 0, 0, bm.bmWidth, bm.bmHeight, hdcMem, 0,0, SRCCOPY);
SelectObject(hdcMem, hbmpOldMem);
SelectObject(hdcCopy, hbmpOldCopy);
}
#ifndef DIBSECTION_NO_PALETTE
if(m_hPalette != NULL)
{
SelectObject(hdcMem, GetStockObject(DEFAULT_PALETTE));
SelectObject(hdcCopy, GetStockObject(DEFAULT_PALETTE));
}
#endif // DIBSECTION_NO_PALETTE
bResult = TRUE;
cleanup:
if(!bResult)
{
_ShowLastError();
CleanUp();
}
if(hdcMem != NULL)
DeleteDC(hdcMem);
if(hdcCopy != NULL)
DeleteDC(hdcCopy);
if(hdc != NULL)
ReleaseDC(NULL, hdc);
exit:
return bResult;
}
#ifdef PERSISTANCE_SUPPORT
//////////////////////////////////////////////////////////////////////////////
// Persistance...
// Loads the bitmap from a bitmap file with the name lpszFileName. If failure,
// then object is initialised back to an empty bitmap.
BOOL CDIBSection::Load(LPCTSTR pszFileName)
{
CFile file;
if(!file.Open(pszFileName, CFile::modeRead))
return FALSE;
// Get the current file position.
DWORD dwFileStart = file.GetPosition();
// The first part of the file contains the file header.
// This will tell us if it is a bitmap, how big the header is, and how big
// the file is. The header size in the file header includes the color table.
BITMAPFILEHEADER BmpFileHdr;
int iBytes = file.Read(&BmpFileHdr, sizeof(BmpFileHdr));
if(iBytes != sizeof(BmpFileHdr))
{
TRACE("Failed to read file header\n");
return FALSE;
}
// Check that we have the magic 'BM' at the start.
if(BmpFileHdr.bfType != DS_BITMAP_FILEMARKER)
{
TRACE("Not a bitmap file\n");
return FALSE;
}
// Read the header (assuming it's a DIB).
DIBINFO BmpInfo;
iBytes = file.Read(&BmpInfo, sizeof(BITMAPINFOHEADER));
if(iBytes != sizeof(BITMAPINFOHEADER))
{
TRACE("Failed to read BITMAPINFOHEADER\n");
return FALSE;
}
// Check that we have a real Windows DIB file.
if(BmpInfo.bmiHeader.biSize != sizeof(BITMAPINFOHEADER))
{
TRACE("File is not a Windows DIB\n");
return FALSE;
}
// See how big the color table is in the file (if there is one).
int iColors = NumColorEntries(BmpInfo.bmiHeader.biBitCount, BmpInfo.bmiHeader.biCompression, BmpInfo.bmiHeader.biClrUsed);
if(iColors > 0)
{
// Read the color table from the file.
int iColorTableSize = sizeof(RGBQUAD) * iColors;
iBytes = file.Read(BmpInfo.GetColorTable(), iColorTableSize);
if(iBytes != iColorTableSize)
{
TRACE("Failed to read color table\n");
return FALSE;
}
}
// So how big the bitmap surface is.
int iBitsSize = BmpFileHdr.bfSize - BmpFileHdr.bfOffBits;
// Double check that the bitmap surface if ok (sometimes the file size is a
// little larger than the bitmap itself, which may cause overflows)
int iSurfaceSize = BytesPerLine(BmpInfo.bmiHeader.biWidth,
BmpInfo.bmiHeader.biBitCount) * BmpInfo.bmiHeader.biHeight;
if(iSurfaceSize < iBitsSize)
{
// In this case we don't need the entire file
iBitsSize = iSurfaceSize;
}
// Allocate the memory for the bits and read the bits from the file.
PBYTE pBits = (PBYTE)malloc(iBitsSize);
if(pBits == NULL)
{
TRACE("Out of memory for DIB bits\n");
return FALSE;
}
// Seek to the bits in the file.
file.Seek(dwFileStart + BmpFileHdr.bfOffBits, CFile::begin);
// read the bits
iBytes = file.Read(pBits, iBitsSize);
if(iBytes != iBitsSize)
{
TRACE("Failed to read bits\n");
free(pBits);
return FALSE;
}
// Everything went OK.
BmpInfo.bmiHeader.biSizeImage = iBitsSize;
if(!SetBitmap((PBITMAPINFO)BmpInfo, pBits))
{
TRACE("Failed to set bitmap info\n");
free(pBits);
return FALSE;
}
free(pBits);
return TRUE;
}
// Saves the image to file.
BOOL CDIBSection::Save(LPCTSTR pszFileName)
{
BITMAPFILEHEADER hdr;
PBITMAPINFOHEADER pbi = GetBitmapInfoHeader();
if(pbi == NULL || pszFileName == NULL)
return FALSE;
CFile file;
if(!file.Open(pszFileName, CFile::modeWrite | CFile::modeCreate))
return FALSE;
DWORD dwBitmapInfoSize = sizeof(BITMAPINFO) + sizeof(RGBQUAD) * (m_uColorTableSize - 1);
DWORD dwFileHeaderSize = dwBitmapInfoSize + sizeof(hdr);
// Fill in the fields of the file header
hdr.bfType = DS_BITMAP_FILEMARKER;
hdr.bfSize = dwFileHeaderSize + pbi->biSizeImage;
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = dwFileHeaderSize;
// Write the file header
file.Write(&hdr, sizeof(hdr));
// Write the DIB header
file.Write(pbi, dwBitmapInfoSize);
// Write DIB bits
file.Write(GetDIBits(), pbi->biSizeImage);
return TRUE;
}
#endif // PERSISTANCE_SUPPORT
// Creates a copy of another CDIBSection object
BOOL CDIBSection::Copy(CDIBSection& ds)
{
BOOL bResult = SetBitmap(ds.GetBitmapInfo(), ds.GetDIBits());
if(bResult)
{
SetColorTable(ds.GetColorTableSize(), ds.GetColorTable());
#ifndef DIBSECTION_NO_PALETTE
CreateSparePalette();
#endif // DIBSECTION_NO_PALETTE
}
return bResult;
}
/////////////////////////////////////////////////////////////////////////////
// CDIBSection palette stuff
BOOL CDIBSection::SetColorTable(UINT uNumColors, LPRGBQUAD pColors)
{
if(m_hBitmap == NULL || m_uColorTableSize == 0
|| pColors == NULL || uNumColors == 0 || uNumColors > 256)
return FALSE;
BOOL bResult = FALSE;
#ifdef _WIN32_WCE
LPRGBQUAD pColorTable = GetColorTable();
ASSERT(pColorTable);
if(pColorTable)
{
UINT uCount = min(m_uColorTableSize, uNumColors);
ZeroMemory(pColorTable, sizeof(RGBQUAD) * m_uColorTableSize);
CopyMemory(pColorTable, pColors, sizeof(RGBQUAD) * uCount);
bResult = TRUE;
}
#else // _WIN32_WCE
// Create a memory DC compatible with the screen
HDC hdcMem = CreateCompatibleDC(NULL);
if(hdcMem != NULL)
{
HGDIOBJ hbmpOld = SelectObject(hdcMem, m_hBitmap);
if(hbmpOld)
{
SetDIBColorTable(hdcMem, 0, uNumColors, pColors);
bResult = TRUE;
// Clean up
SelectObject(hdcMem, hbmpOld);
}
DeleteDC(hdcMem);
}
#endif // _WIN32_WCE
return bResult;
}
#ifndef DIBSECTION_NO_PALETTE
// Creates the palette from the DIB section's color table. Assumes m_uColorTableSize
// has been set and the DIBsection m_hBitmap created
BOOL CDIBSection::CreateSparePalette()
{
PALETTEINFO pi;
if(m_hPalette != NULL)
{
DeleteObject(m_hPalette);
m_hPalette = NULL;
}
if(m_hBitmap == NULL)
return FALSE;
BOOL bPalInfoReady = FALSE;
HDC hdc = NULL;
LPRGBQUAD pRGB = NULL;
HDC hdcMem = NULL;
// Create a 256 color halftone palette if there is no color table in the DIB section
if(m_uColorTableSize == 0)
goto exit;
hdc = GetDC(NULL);
if(hdc == NULL)
return FALSE;
// Get space for the color entries
pRGB = new RGBQUAD[m_uColorTableSize];
if(pRGB == NULL)
goto cleanup;
// Create a memory DC compatible with the current DC
hdcMem = CreateCompatibleDC(hdc);
if(hdcMem == NULL)
goto cleanup;
HGDIOBJ hbmpOld;
hbmpOld = SelectObject(hdcMem, m_hBitmap);
if(hbmpOld == NULL)
goto cleanup;
// Get the colors used.
UINT uColors;
uColors = GetDIBColorTable(hdcMem, 0, m_uColorTableSize, pRGB);
// Clean up
SelectObject(hdc, hbmpOld);
if(uColors == 0) // No colors retrieved => the bitmap in the DC is not a DIB section
goto cleanup;
// Create and fill a LOGPALETTE structure with the colors used.
pi.palNumEntries = (WORD)m_uColorTableSize;
int i;
for(i=0; i<(int)uColors; i++)
{
pi.palPalEntry[i].peRed = pRGB[i].rgbRed;
pi.palPalEntry[i].peGreen = pRGB[i].rgbGreen;
pi.palPalEntry[i].peBlue = pRGB[i].rgbBlue;
pi.palPalEntry[i].peFlags = 0;
}
bPalInfoReady = TRUE;
cleanup:
if(hdcMem != NULL)
DeleteDC(hdcMem);
if(pRGB != NULL)
delete[] pRGB;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -