📄 gvwdib.cpp
字号:
UINT
CDIB::ByteWidth(void)
{
ASSERT(m_valid);
if (!m_valid)
return 0;
return m_bytewidth;
}
// width of bitmap in bits
int
CDIB::Width(void)
{
ASSERT(m_valid);
if (!m_valid)
return 0;
return m_bmp.bmp2.biWidth;
}
// height of bitmap in lines
int
CDIB::Height(void)
{
ASSERT(m_valid);
if (!m_valid)
return 0;
return m_bmp.bmp2.biHeight;
}
// get size of bitmap
void
CDIB::GetRect(LPRECT prect)
{
ASSERT(m_valid);
if (prect == (LPRECT)NULL)
return;
prect->top = 0;
prect->left = 0;
if (m_valid) {
prect->bottom = Height();
prect->right = Width();
}
else {
prect->bottom = 0;
prect->right = 0;
}
}
BOOL
CDIB::Read(LPCSTR lpszFileName)
{
GFile *gf;
if ( (gf = gfile_open(lpszFileName, gfile_modeRead | gfile_shareDenyWrite))
== NULL )
return FALSE;
BOOL flag = Read(gf);
gfile_close(gf);
return flag;
}
// read bitmap to memory
BOOL
CDIB::Read(GFile *pFile)
{
BITMAPFILE bmf;
BYTE bh[SIZEOF_BITMAPFILE];
LPBYTE p;
DWORD length;
DWORD dwRead;
Lock();
CleanupBitmap();
m_valid = FALSE;
// MFC version of CFile would throw exceptions
// TRY {
if (gfile_read(pFile, &bh, SIZEOF_BITMAPFILE) != SIZEOF_BITMAPFILE) {
Unlock();
return FALSE;
}
p = bh;
bmf.bfType = GetWord(p);
p+=2;
if (bmf.bfType != (('M'<<8) | 'B')) {
Unlock();
return FALSE; // not a DIB bitmap
}
bmf.bfSize = GetDword(p);
p+=4;
bmf.bfReserved1 = GetWord(p);
p+=2;
bmf.bfReserved2 = GetWord(p);
p+=2;
bmf.bfOffBits = GetDword(p);
length = bmf.bfSize - SIZEOF_BITMAPFILE;
ASSERT(length < 64000000);
// We are now responsible for freeing this memory
m_bitmap = (LPBYTE)GlobalLock(GlobalAlloc(GHND, length));
ASSERT(m_bitmap != NULL);
p = m_bitmap;
while (length && (dwRead = gfile_read(pFile, p, length)) != 0) {
length -= dwRead;
p += dwRead;
}
// } CATCH(CFileException, pE) {
// if (pE->m_lOsError == ERROR_BROKEN_PIPE)
// return FALSE; // Someone probably closed the other end of the pipe
// pE->ReportError();
// }
// END_CATCH
BOOL flag = Init(m_bitmap);
Unlock();
return flag;
}
// read bitmap header and palette to memory, but not bits
BOOL
CDIB::ReadHeader(GFile *pFile)
{
BITMAPFILE bmf;
BYTE bh[SIZEOF_BITMAPFILE];
LPBYTE p;
DWORD length;
DWORD dwRead;
HGLOBAL hglobal;
Lock();
CleanupBitmap();
m_valid = FALSE;
// MFC version of CFile would throw exceptions
// TRY {
if (gfile_read(pFile, &bh, SIZEOF_BITMAPFILE) != SIZEOF_BITMAPFILE) {
Unlock();
return FALSE;
}
p = bh;
bmf.bfType = GetWord(p);
p+=2;
if (bmf.bfType != (('M'<<8) | 'B')) {
Unlock();
return FALSE; // not a DIB bitmap
}
bmf.bfSize = GetDword(p);
p+=4;
bmf.bfReserved1 = GetWord(p);
p+=2;
bmf.bfReserved2 = GetWord(p);
p+=2;
bmf.bfOffBits = GetDword(p);
// ASSERT(bmf.bfSize - SIZEOF_BITMAPFILE < 64000000);
// instead of loading the entire bitmap, only read the header
ASSERT(bmf.bfOffBits != 0);
length = bmf.bfOffBits - SIZEOF_BITMAPFILE;
ASSERT(length >= 40);
// make sure we have enough space to add a palette,
// in case we want to change the bits per pixel of
// the bitmap.
// We are now responsible for freeing this memory
hglobal = GlobalAlloc(GHND, SIZEOF_BITMAP2INFO + 64);
m_bitmap = (LPBYTE)GlobalLock(hglobal);
ASSERT(m_bitmap != NULL);
p = m_bitmap;
while (length && (dwRead = gfile_read(pFile, p, length)) != 0) {
length -= dwRead;
p += dwRead;
}
// } CATCH(CFileException, pE) {
// if (pE->m_lOsError == ERROR_BROKEN_PIPE)
// return FALSE; // Someone probably closed the other end of the pipe
// pE->ReportError();
// }
// END_CATCH
BOOL flag = Init(m_bitmap, NULL);
Unlock();
return flag;
}
// ============================
BOOL CDIB::Valid()
{
return m_valid;
}
// return string containing information about the bitmap
LPTSTR CDIB::DIBinfo()
{
// create a text message, suitable for printing
// or use in a dialog box MLE.
#define BUFSIZE 16384
Lock();
LPTSTR str = new TCHAR[BUFSIZE];
LPTSTR p = str;
int i;
ASSERT(str != NULL);
if (str == NULL)
return NULL;
wsprintf(p, TEXT("BMP info\r\n"));
p += lstrlen(p);
if (!m_valid) {
wsprintf(p, TEXT(" Bitmap not valid\r\n"));
Unlock();
return str;
}
wsprintf(p, TEXT(" biSize=%d\r\n biWidth=%d\r\n biHeight=%d\r\n biPlanes=%d\r\n biBitCount=%d\r\n"),
m_bmp.bmp2.biSize, m_bmp.bmp2.biWidth, m_bmp.bmp2.biHeight,
(int)m_bmp.bmp2.biPlanes, (int)m_bmp.bmp2.biBitCount);
p += lstrlen(p);
wsprintf(p, TEXT(" biSizeImage=%d\r\n biXPelsPerMeter=%d\r\n biYPelsPerMeter=%d\r\n"),
m_bmp.bmp2.biSizeImage, m_bmp.bmp2.biXPelsPerMeter, m_bmp.bmp2.biYPelsPerMeter);
p += lstrlen(p);
wsprintf(p, TEXT(" biClrUsed=%d\r\n biClrImportant=%d\r\n"),
m_bmp.bmp2.biClrUsed, m_bmp.bmp2.biClrImportant);
p += lstrlen(p);
int palcount = PalCount();
wsprintf(p, TEXT("palcount=%d\r\npallength=%d\r\nm_bytewidth=%d\r\n"),
palcount, PalLength(), m_bytewidth);
p += lstrlen(p);
if (palcount) {
LPBYTE pp = m_colors;
int r, g, b;
for (i = 0; i < palcount; i++) {
r = *pp++;
g = *pp++;
b = *pp++;
if (!m_old)
pp++;
wsprintf(p, TEXT("Color %d: %d %d %d\r\n"), i, r, g, b);
p += lstrlen(p);
}
}
if ( ((m_bmp.bmp2.biBitCount == 16) || (m_bmp.bmp2.biBitCount == 32))
&& (m_bmp.bmp2.biCompression == BI_BITFIELDS) ) {
LPDWORD pd = (LPDWORD)m_colors;
for (i = 0; i < 3; i++) {
wsprintf(p, TEXT("Bitfield %d: 0x%04x\r\n"), *pd++);
p += lstrlen(p);
}
}
wsprintf(p, TEXT("End of BMP info\r\n"));
ASSERT((p+lstrlen(p)-str) < BUFSIZE);
Unlock();
return str;
#undef BUFSIZE
}
BOOL CDIB::Lock(void)
{
// return m_critical_section.Lock();
return TRUE;
}
BOOL CDIB::Unlock(void)
{
// return m_critical_section.Unlock();
return TRUE;
}
// Copy bytes into a buffer, advancing buffer pointer
void CDIB::PutDWORD(LPBYTE &d, DWORD dw)
{
PutWORD(d, (WORD)dw);
PutWORD(d, (WORD)(dw >> 16));
}
void CDIB::PutWORD(LPBYTE &d, WORD w)
{
PutBYTE(d, (BYTE)(w));
PutBYTE(d, (BYTE)(w >> 8));
}
void CDIB::PutBYTE(LPBYTE &d, BYTE b)
{
*d++ = b;
}
BOOL CDIB::NewHeader(LPBYTE pHeader, UINT *pLen)
{
if (!Valid())
return FALSE;
UINT len = SIZEOF_BITMAPFILE + SIZEOF_BITMAP2 + PalLength();
if (pLen == NULL)
return FALSE;
if ( (pHeader == NULL) || (*pLen < len) ) {
*pLen = len;
return FALSE;
}
if (m_bmp.bmp2.biSizeImage == 0)
m_bmp.bmp2.biSizeImage = m_bytewidth * m_bmp.bmp2.biHeight;
LPBYTE p = pHeader;
// Create BITMAPFILEHEADER
PutBYTE(p, 'B'); // bfType
PutBYTE(p, 'M');
PutDWORD(p, len + m_bmp.bmp2.biSizeImage); // bfSize
PutWORD(p, 0); // bfReserved1
PutWORD(p, 0); // bfReserved2
PutDWORD(p, len); // bfOffsetBits
// Create BITMAPINFOHEADER
PutDWORD(p, m_bmp.bmp2.biSize);
PutDWORD(p, (DWORD)m_bmp.bmp2.biWidth);
PutDWORD(p, (DWORD)m_bmp.bmp2.biHeight);
PutWORD(p, m_bmp.bmp2.biPlanes);
PutWORD(p, m_bmp.bmp2.biBitCount);
PutDWORD(p, m_bmp.bmp2.biCompression);
PutDWORD(p, m_bmp.bmp2.biSizeImage);
PutDWORD(p, (DWORD)m_bmp.bmp2.biXPelsPerMeter);
PutDWORD(p, (DWORD)m_bmp.bmp2.biYPelsPerMeter);
PutDWORD(p, m_bmp.bmp2.biClrUsed);
PutDWORD(p, m_bmp.bmp2.biClrImportant);
// Create palette
switch (m_bmp.bmp2.biBitCount) {
case 1:
case 4:
case 8:
{
// Two methods we don't use are:
// pColours: may be RGB triples from an old BITMAP1
// m_bmp.bmiColors: may be palette indices, not colour values
ASSERT(m_bmp.bmp2.biCompression == BI_RGB);
int palcount = PalCount();
LPPALETTEENTRY lpe = new PALETTEENTRY[palcount];
GetPaletteEntries(m_palette, 0, palcount, lpe);
for (int i=0; i<palcount; i++) {
// Write RGB quads
PutBYTE(p, lpe[i].peBlue);
PutBYTE(p, lpe[i].peGreen);
PutBYTE(p, lpe[i].peRed);
PutBYTE(p, 0);
}
delete [] lpe;
break;
}
case 24:
// no palette
ASSERT(m_bmp.bmp2.biCompression == BI_RGB);
break;
case 16:
case 32:
if (m_bmp.bmp2.biCompression == BI_RGB) {
// no palette
}
else if (m_bmp.bmp2.biCompression == BI_BITFIELDS) {
LPDWORD pdw = (LPDWORD)(&m_bmp.rgb4[0]);
PutDWORD(p, pdw[0]);
PutDWORD(p, pdw[1]);
PutDWORD(p, pdw[2]);
}
else {
ASSERT(FALSE);
}
break;
}
// make sure we calculated things correctly
ASSERT( (UINT)(p-pHeader) == len);
*pLen = len;
return TRUE;
}
BOOL CDIB::Write(GFile *gf) {
UINT len = 0;
NewHeader(NULL, &len); // get header size
LPBYTE p = new BYTE[len];
ASSERT(p != NULL);
if (!NewHeader(p, &len)) {
delete p;
return FALSE;
}
// Write the headers and palette
gfile_write(gf, p, len);
delete p;
// Write the bits
ASSERT(m_bits != NULL);
gfile_write(gf, m_bits, m_bmp.bmp2.biSizeImage);
return TRUE;
}
BOOL CDIB::Write(LPCSTR lpszFileName)
{
// not implemented
GFile *gf;
if ( (gf = gfile_open(lpszFileName, gfile_modeCreate |
gfile_modeWrite | gfile_shareExclusive)) == NULL ) {
ASSERT(FALSE);
return FALSE;
}
BOOL flag = Write(gf);
gfile_close(gf);
return flag;
}
// Return a bitmap suitable for placing on the clipboard
HGLOBAL CDIB::MakeGlobalDIB()
{
// Allocate memory for header and bits
UINT len = 0;
if (!NewHeader(NULL, &len)) { // get header size
ASSERT(FALSE);
return NULL;
}
HGLOBAL hglobal = GlobalAlloc(GMEM_MOVEABLE | GMEM_SHARE,
len + m_bmp.bmp2.biSizeImage);
ASSERT(hglobal);
if (hglobal == NULL)
return NULL;
LPBYTE p = (LPBYTE)GlobalLock(hglobal);
ASSERT(p);
if (p == NULL) {
GlobalFree(hglobal);
return NULL;
}
// Copy the header and palette
if (!NewHeader(p, &len)) {
GlobalUnlock(hglobal);
GlobalFree(hglobal);
ASSERT(FALSE);
return NULL;
}
// Copy the bits
CopyMemory(p + len, m_bits, m_bmp.bmp2.biSizeImage);
GlobalUnlock(hglobal);
return hglobal;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -