📄 dibapi.cpp
字号:
if ((lpBI->biCompression == BI_RLE8) || (lpBI->biCompression == BI_RLE4))
{
// It's an RLE bitmap, we can't calculate size, so trust the
// biSizeImage field
dwDIBSize += lpBI->biSizeImage;
}
else
{
DWORD dwBmBitsSize; // Size of Bitmap Bits only
// It's not RLE, so size is Width (DWORD aligned) * Height
dwBmBitsSize = WIDTHBYTES((lpBI->biWidth)*((DWORD)lpBI->biBitCount)) * lpBI->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).
lpBI->biSizeImage = dwBmBitsSize;
}
// Calculate the file size by adding the DIB size to sizeof(BITMAPFILEHEADER)
bmfHdr.bfSize = dwDIBSize + sizeof(BITMAPFILEHEADER);
bmfHdr.bfReserved1 = 0;
bmfHdr.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.
*/
bmfHdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + lpBI->biSize
+ PaletteSize((LPSTR)lpBI);
TRY
{
// Write the file header
file.Write((LPSTR)&bmfHdr, sizeof(BITMAPFILEHEADER));
//
// Write the DIB header and the bits
//
file.WriteHuge(lpBI, dwDIBSize);
}
CATCH (CFileException, e)
{
::GlobalUnlock((HGLOBAL) hDib);
THROW_LAST();
}
END_CATCH
::GlobalUnlock((HGLOBAL) hDib);
return TRUE;
}
/*************************************************************************
Function: ReadDIBFile (CFile&)
Purpose: Reads in the specified DIB file into a global chunk of
memory.
Returns: A handle to a dib (hDIB) if successful.
NULL if an error occurs.
Comments: BITMAPFILEHEADER is stripped off of the DIB. Everything
from the end of the BITMAPFILEHEADER structure on is
returned in the global memory handle.
*************************************************************************/
HDIB WINAPI ReadDIBFile(CFile& file)
{
BITMAPFILEHEADER bmfHeader;
DWORD dwBitsSize;
HDIB hDIB;
LPSTR pDIB;
/*
* get length of DIB in bytes for use when reading
*/
dwBitsSize = file.GetLength();
/*
* Go read the DIB file header and check if it's valid.
*/
if (file.Read((LPSTR)&bmfHeader, sizeof(bmfHeader)) != sizeof(bmfHeader))
return NULL;
if (bmfHeader.bfType != DIB_HEADER_MARKER)
return NULL;
/*
* Allocate memory for DIB
*/
hDIB = (HDIB) ::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT, dwBitsSize);
if (hDIB == 0)
{
return NULL;
}
pDIB = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
/*
* Go read the bits.
*/
if (file.ReadHuge(pDIB, dwBitsSize - sizeof(BITMAPFILEHEADER)) !=
dwBitsSize - sizeof(BITMAPFILEHEADER) )
{
::GlobalUnlock((HGLOBAL) hDIB);
::GlobalFree((HGLOBAL) hDIB);
return NULL;
}
::GlobalUnlock((HGLOBAL) hDIB);
return hDIB;
}
HGLOBAL WINAPI CopyHandle (HGLOBAL h)
{
if (h == NULL)
return NULL;
DWORD dwLen = ::GlobalSize((HGLOBAL) h);
HGLOBAL hCopy = ::GlobalAlloc(GHND, dwLen);
if (hCopy != NULL)
{
void* lpCopy = ::GlobalLock((HGLOBAL) hCopy);
void* lp = ::GlobalLock((HGLOBAL) h);
memcpy(lpCopy, lp, dwLen);
::GlobalUnlock(hCopy);
::GlobalUnlock(h);
}
return hCopy;
}
DWORD WINAPI BytesPerLine(LPBYTE lpDIB)
{
return WIDTHBYTES(((LPBITMAPINFOHEADER)lpDIB)->biWidth*
((LPBITMAPINFOHEADER)lpDIB)->biPlanes*
((LPBITMAPINFOHEADER)lpDIB)->biBitCount);
}
//创建空的DIB
HDIB WINAPI CreateDIB(DWORD dwWidth,DWORD dwHeight,WORD wBitCount)
{
BITMAPINFOHEADER bi;
LPBITMAPINFOHEADER lpbi;
DWORD dwLen;
HDIB hDIB;
DWORD dwBytesPerLine;
LPSTR pDib;
int clrused;
if(wBitCount<=1)
wBitCount=1;
else if(wBitCount<=4)
wBitCount=4;
else if(wBitCount<=8)
wBitCount=8;
else if(wBitCount<=24)
wBitCount=24;
else
wBitCount=4;
clrused=1<<wBitCount;
bi.biSize=sizeof(BITMAPINFOHEADER);
bi.biWidth=dwWidth;
bi.biHeight=dwHeight;
bi.biPlanes=1;
bi.biBitCount=wBitCount;
bi.biCompression=BI_RGB;
bi.biSizeImage=0;
bi.biXPelsPerMeter=0;
bi.biYPelsPerMeter=0;
bi.biClrUsed=clrused;
bi.biClrImportant=0;
dwBytesPerLine=WIDTHBYTES(wBitCount*dwWidth);
dwLen=bi.biSize+PaletteSize((LPSTR)&bi)+(dwBytesPerLine*dwHeight);
hDIB=(HDIB)::GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,dwLen);
if(!hDIB)
return NULL;
pDib = (LPSTR) ::GlobalLock((HGLOBAL) hDIB);
lpbi= (LPBITMAPINFOHEADER)pDib;
*lpbi=bi;
GlobalUnlock(hDIB);
return hDIB;
}
//创建256色的DIB
HDIB WINAPI Create256GrayImage(DWORD Width,DWORD Height)
{
int i;
HDIB hDesDib;
LPBYTE pDesDib;
int DesMemWidth;
RGBQUAD * pColorTable;
LPBITMAPINFOHEADER bmHdr;
DesMemWidth = Width + (sizeof(DWORD) - Width %sizeof(DWORD) )%sizeof(DWORD);
hDesDib = (HDIB)::GlobalAlloc(GHND,sizeof(BITMAPINFOHEADER)+256*sizeof(RGBQUAD)+DesMemWidth*Height);
if(hDesDib == NULL) return NULL;
pDesDib = (LPBYTE)::GlobalLock((HGLOBAL)hDesDib);
bmHdr = (LPBITMAPINFOHEADER)pDesDib;
pColorTable = (RGBQUAD *)( pDesDib + sizeof(BITMAPINFOHEADER) );
bmHdr -> biSize = (DWORD)(sizeof(BITMAPINFOHEADER)) ;
bmHdr -> biWidth = Width ;
bmHdr -> biHeight= Height;
bmHdr -> biPlanes= 1 ;
bmHdr -> biBitCount = 8 ;
bmHdr -> biCompression = 0L;
bmHdr -> biSizeImage = 0L;
bmHdr -> biXPelsPerMeter = 0L;
bmHdr -> biYPelsPerMeter = 0L;
bmHdr -> biClrUsed = 0L;
bmHdr -> biClrImportant = 0L;
for(i=0;i<256;i++)
{
pColorTable[i].rgbBlue = (BYTE)i;
pColorTable[i].rgbGreen = (BYTE)i;
pColorTable[i].rgbRed = (BYTE)i;
pColorTable[i].rgbReserved = 0;
}
::GlobalUnlock((HGLOBAL)hDesDib);
return hDesDib;
}
//创建当前系统DIB
HDIB WINAPI CreateDefaultDIB(DWORD dwWidth,DWORD dwHeight)
{
HDC hDC=GetDC(NULL);
if(!hDC)
return NULL;
int nDeviceBitsPixel=GetDeviceCaps(hDC, BITSPIXEL);
HDIB hDIB=CreateDIB(dwWidth,dwHeight,nDeviceBitsPixel);
LPBITMAPINFO lpbmi=(LPBITMAPINFO)GlobalLock(hDIB);
LPSTR lpDIBBits=FindDIBBits((LPSTR)lpbmi);
DWORD dwBitsSize=lpbmi->bmiHeader.biHeight*BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
for(DWORD l=0;l<dwBitsSize;l++)
lpDIBBits[l]=char(0xff);
if(nDeviceBitsPixel>8)
{
GlobalUnlock(hDIB);
ReleaseDC(NULL,hDC);
return hDIB;
}
int nColors=PalEntriesOnDevice(hDC);
PALETTEENTRY pe[256];
GetSystemPaletteEntries(hDC,0,nColors,pe);
for(int i=0;i<nColors;++i)
{
lpbmi->bmiColors[i].rgbRed=pe[i].peRed;
lpbmi->bmiColors[i].rgbGreen=pe[i].peGreen;
lpbmi->bmiColors[i].rgbBlue=pe[i].peBlue;
lpbmi->bmiColors[i].rgbReserved=0;
}
GlobalUnlock(hDIB);
ReleaseDC(NULL,hDC);
return hDIB;
}
int WINAPI PalEntriesOnDevice(HDC hDC)
{
int nColors;
nColors=(1<<(GetDeviceCaps(hDC,BITSPIXEL)*GetDeviceCaps(hDC,PLANES)));
// assert(nColors);
return nColors;
}
HDIB WINAPI ConvertDIBFormat(HDIB hSrcDIB,UINT nbpp,HPALETTE hPalSrc)
{
LPBITMAPINFO lpSrcDIB=(LPBITMAPINFO)::GlobalLock(hSrcDIB);
LPBITMAPINFO lpbmi=NULL;
LPBYTE lpSourceBits,lpTargetBits,lpResult;
HDC hDC=NULL,hSourceDC,hTargetDC;
HBITMAP hSourceBitmap,hTargetBitmap,
hOldTargetBitmap,hOldSourceBitmap;
DWORD dwSourceBitsSize,dwTargetBitsSize,dwTargetHeadersSize,dwColorNum;
HDIB hDIB;
int nWidth,nHeight;
if(nbpp<=8)
dwColorNum=1<<nbpp;
else
dwColorNum=0;
dwTargetHeadersSize=sizeof(BITMAPINFO)+(dwColorNum*sizeof(RGBQUAD));
nWidth=DIBWidth((LPSTR)lpSrcDIB);
nHeight=DIBHeight((LPSTR)lpSrcDIB);
lpbmi=(LPBITMAPINFO)malloc(dwTargetHeadersSize);
lpbmi->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
lpbmi->bmiHeader.biWidth=nWidth;
lpbmi->bmiHeader.biHeight=nHeight;
lpbmi->bmiHeader.biPlanes=1;
lpbmi->bmiHeader.biBitCount=nbpp;
lpbmi->bmiHeader.biCompression=BI_RGB;
lpbmi->bmiHeader.biSizeImage=0;
lpbmi->bmiHeader.biXPelsPerMeter=0;
lpbmi->bmiHeader.biYPelsPerMeter=0;
lpbmi->bmiHeader.biClrUsed=0;
lpbmi->bmiHeader.biClrImportant=0;
if(!CopyColorTable(lpbmi,lpSrcDIB,hPalSrc))
{
free(lpbmi);
return NULL;
}
hDC=GetDC(NULL);
hTargetBitmap=CreateDIBSection(hDC,lpbmi,DIB_RGB_COLORS,
(VOID**)&lpTargetBits,NULL,0);
hSourceBitmap=CreateDIBSection(hDC,lpSrcDIB,DIB_RGB_COLORS,
(VOID**)&lpSourceBits,NULL,0);
hTargetDC=CreateCompatibleDC(hDC);
hSourceDC=CreateCompatibleDC(hDC);
dwSourceBitsSize=lpSrcDIB->bmiHeader.biHeight*BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
dwTargetBitsSize=lpbmi->bmiHeader.biHeight*BytesPerLine((LPBYTE)&(lpbmi->bmiHeader));
memcpy(lpSourceBits,FindDIBBits((LPSTR)lpSrcDIB),dwSourceBitsSize);
lpbmi->bmiHeader.biSizeImage=dwTargetBitsSize;
hOldSourceBitmap=(HBITMAP)SelectObject(hSourceDC,hSourceBitmap);
hOldTargetBitmap=(HBITMAP)SelectObject(hTargetDC,hTargetBitmap);
//////////////////////////////////////////////////////////////////////////////
if(lpSrcDIB->bmiHeader.biBitCount<=8)
SetDIBColorTable(hSourceDC,0,1<<lpSrcDIB->bmiHeader.biBitCount,lpSrcDIB->bmiColors);
if(lpSrcDIB->bmiHeader.biBitCount<=8)
SetDIBColorTable(hTargetDC,0,1<<lpbmi->bmiHeader.biBitCount,lpbmi->bmiColors);
BitBlt(hTargetDC,0,0,lpbmi->bmiHeader.biWidth,
lpbmi->bmiHeader.biHeight,hSourceDC,0,0,SRCCOPY);
SelectObject(hSourceDC,hOldSourceBitmap);
SelectObject(hTargetDC,hOldTargetBitmap);
DeleteDC(hSourceDC);
DeleteDC(hTargetDC);
ReleaseDC(NULL,hDC);
GdiFlush();
hDIB=(HDIB)::GlobalAlloc(GHND,dwTargetBitsSize+dwTargetHeadersSize);
lpResult=(LPBYTE)GlobalLock(hDIB);
memcpy(lpResult,lpbmi,dwTargetHeadersSize);
memcpy((BYTE*)FindDIBBits((LPSTR)lpResult),lpTargetBits,dwTargetBitsSize);
hSrcDIB=hDIB;
DeleteObject(hTargetBitmap);
DeleteObject(hSourceBitmap);
free(lpbmi);
GlobalUnlock(hSrcDIB);
GlobalUnlock(hDIB);
return hDIB;
}
BOOL WINAPI CopyColorTable(LPBITMAPINFO lpTarget,LPBITMAPINFO lpSource,HPALETTE hPalSrc)
{
switch(lpTarget->bmiHeader.biBitCount)
{
case 8:
if(hPalSrc)
{
PALETTEENTRY pe[256];
UINT i;
GetPaletteEntries(hPalSrc,0,256,pe);
for(i=0;i<256;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbReserved=0;
}
}
else
{
if(lpSource->bmiHeader.biBitCount==8)
{
memcpy(lpTarget->bmiColors,lpSource->bmiColors,256*sizeof(RGBQUAD));
}
else
{
HPALETTE hPal;
HDC hDC=GetDC(NULL);
PALETTEENTRY pe[256];
UINT i;
hPal=CreateOctreePalette((LPBYTE)lpSource,256,8);
if(!hPal)
hPal=CreateHalftonePalette(hDC);
ReleaseDC(NULL,hDC);
GetPaletteEntries(hPal,0,256,pe);
DeleteObject(hPal);
for(i=0;i<256;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbReserved=0;
}
}
}
break;
case 4:
if(hPalSrc)
{
PALETTEENTRY pe[16];
UINT i;
GetPaletteEntries(hPalSrc,0,16,pe);
for(i=0;i<16;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbReserved=0;
}
}
else
{
if(lpSource->bmiHeader.biBitCount==4)
{
memcpy(lpTarget->bmiColors,lpSource->bmiColors,16*sizeof(RGBQUAD));
}
else
{
HPALETTE hPal;
PALETTEENTRY pe[256];
UINT i;
hPal=(HPALETTE)GetStockObject(DEFAULT_PALETTE);
GetPaletteEntries(hPal,0,16,pe);
for(i=0;i<16;i++)
{
lpTarget->bmiColors[i].rgbRed=pe[i].peRed;
lpTarget->bmiColors[i].rgbBlue=pe[i].peBlue;
lpTarget->bmiColors[i].rgbGreen=pe[i].peGreen;
lpTarget->bmiColors[i].rgbReserved=pe[i].peFlags;
}
}
}
break;
case 1:
lpTarget->bmiColors[0].rgbRed=0;
lpTarget->bmiColors[0].rgbBlue=0;
lpTarget->bmiColors[0].rgbGreen=0;
lpTarget->bmiColors[0].rgbReserved=0;
lpTarget->bmiColors[1].rgbRed=255;
lpTarget->bmiColors[1].rgbBlue=255;
lpTarget->bmiColors[1].rgbGreen=255;
lpTarget->bmiColors[1].rgbReserved=0;
break;
case 32:
case 24:
case 16:
default:
break;
}
return TRUE;
}
HPALETTE WINAPI CreateOctreePalette(LPBYTE lpDIB,UINT nMaxColors,UINT nColorBits)
{
HANDLE hImage;
hImage=DIBTODIBSection(lpDIB);
if(!hImage)
return NULL;
return BuildOctreePalette(hImage,nMaxColors,nColorBits);
}
HBITMAP WINAPI DIBTODIBSection(LPBYTE lpDIB)
{
LPBITMAPINFO lpSrcDIB=(LPBITMAPINFO)lpDIB;
LPBYTE lpSourceBits;
HDC hDC=NULL,hSourceDC;
HBITMAP hSourceBitmap,hOldSourceBitmap;
DWORD dwSourceBitsSize;
hDC=GetDC(NULL);
hSourceBitmap=CreateDIBSection(hDC,lpSrcDIB,DIB_RGB_COLORS,
(VOID**)&lpSourceBits,NULL,0);
hSourceDC=CreateCompatibleDC(hDC);
dwSourceBitsSize=lpSrcDIB->bmiHeader.biHeight*BytesPerLine((LPBYTE)&(lpSrcDIB->bmiHeader));
memcpy(lpSourceBits,FindDIBBits((LPSTR)lpSrcDIB),dwSourceBitsSize);
hOldSourceBitmap=(HBITMAP)SelectObject(hSourceDC,hSourceBitmap);
//////////////////////////////////////////////////////////////////////////////
if(lpSrcDIB->bmiHeader.biBitCount<=8)
SetDIBColorTable(hSourceDC,0,1<<lpSrcDIB->bmiHeader.biBitCount,lpSrcDIB->bmiColors);
SelectObject(hSourceDC,hOldSourceBitmap);
DeleteDC(hSourceDC);
ReleaseDC(NULL,hDC);
GdiFlush();
return hSourceBitmap;
}
HPALETTE WINAPI BuildOctreePalette(HANDLE hImage,UINT nMaxColors,UINT nColorBits)
{
DIBSECTION ds;
int i,j,npad;
BYTE* pbBits;
WORD* pwBits;
DWORD* pdwBits;
DWORD rmask,gmask,bmask;
int rright,gright,bright;
int rleft,gleft,bleft;
BYTE r,g,b;
WORD wColor;
DWORD dwColor,dwSize;
LOGPALETTE* plp;
HPALETTE hPalette;
NODE* pTree;
UINT nLeafCount,nIndex;
NODE* pReducibleNodes[9];
HDC hdc;
BYTE* pBuffer;
BITMAPINFO bmi;
pTree=NULL;
nLeafCount=0;
if(nColorBits>8)
return NULL;
for(i=0;i<=(int)nColorBits;i++)
pReducibleNodes[i]=NULL;
GetObject(hImage,sizeof(ds),&ds);
npad=ds.dsBm.bmWidthBytes-(((ds.dsBmih.biWidth*ds.dsBmih.biBitCount)+7)/8);
switch(ds.dsBmih.biBitCount)
{
case 1:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -