📄 dibutil.c
字号:
/* allocate memory block for logical palette */
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) *
wNumColors);
/* if not enough memory, clean up and return NULL */
if (!hLogPal)
{
GlobalUnlock(hDIB);
return NULL;
}
/* lock memory block and get pointer to it */
lpPal = (LPLOGPALETTE)GlobalLock(hLogPal);
/* set version and number of palette entries */
lpPal->palVersion = PALVERSION;
lpPal->palNumEntries = wNumColors;
/* store RGB triples (if Win 3.0 DIB) or RGB quads (if OS/2 DIB)
* into palette
*/
for (i = 0; i < wNumColors; i++)
{
if (bWinStyleDIB)
{
lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
else
{
lpPal->palPalEntry[i].peRed = lpbmc->bmciColors[i].rgbtRed;
lpPal->palPalEntry[i].peGreen = lpbmc->bmciColors[i].rgbtGreen;
lpPal->palPalEntry[i].peBlue = lpbmc->bmciColors[i].rgbtBlue;
lpPal->palPalEntry[i].peFlags = 0;
}
}
/* create the palette and get handle to it */
hPal = CreatePalette(lpPal);
/* if error getting handle to palette, clean up and return NULL */
if (!hPal)
{
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
return NULL;
}
}
/* clean up */
GlobalUnlock(hLogPal);
GlobalFree(hLogPal);
GlobalUnlock(hDIB);
/* return handle to DIB's palette */
return hPal;
}
/*************************************************************************
*
* DIBToBitmap()
*
* Parameters:
*
* HDIB hDIB - specifies the DIB to convert
*
* HPALETTE hPal - specifies the palette to use with the bitmap
*
* Return Value:
*
* HBITMAP - identifies the device-dependent bitmap
*
* Description:
*
* This function creates a bitmap from a DIB using the specified palette.
* If no palette is specified, default is used.
*
* NOTE:
*
* The bitmap returned from this funciton is always a bitmap compatible
* with the screen (e.g. same bits/pixel and color planes) rather than
* a bitmap with the same attributes as the DIB. This behavior is by
* design, and occurs because this function calls CreateDIBitmap to
* do its work, and CreateDIBitmap always creates a bitmap compatible
* with the hDC parameter passed in (because it in turn calls
* CreateCompatibleBitmap).
*
* So for instance, if your DIB is a monochrome DIB and you call this
* function, you will not get back a monochrome HBITMAP -- you will
* get an HBITMAP compatible with the screen DC, but with only 2
* colors used in the bitmap.
*
* If your application requires a monochrome HBITMAP returned for a
* monochrome DIB, use the function SetDIBits().
*
* Also, the DIBpassed in to the function is not destroyed on exit. This
* must be done later, once it is no longer needed.
*
* History: Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 9/15/91 Patrick Schreiber Added header and comments
* 3/27/92 Mark Bader Added comments about resulting
* bitmap format
*
************************************************************************/
HBITMAP FAR DIBToBitmap(HDIB hDIB, HPALETTE hPal)
{
LPSTR lpDIBHdr, lpDIBBits; // pointer to DIB header, pointer to DIB bits
HBITMAP hBitmap; // handle to device-dependent bitmap
HDC hDC; // handle to DC
HPALETTE hOldPal = NULL; // handle to a palette
/* if invalid handle, return NULL */
if (!hDIB)
return NULL;
/* lock memory block and get a pointer to it */
lpDIBHdr = GlobalLock(hDIB);
/* get a pointer to the DIB bits */
lpDIBBits = FindDIBBits(lpDIBHdr);
/* get a DC */
hDC = GetDC(NULL);
if (!hDC)
{
/* clean up and return NULL */
GlobalUnlock(hDIB);
return NULL;
}
/* select and realize palette */
if (hPal)
hOldPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
/* create bitmap from DIB info. and bits */
hBitmap = CreateDIBitmap(hDC, (LPBITMAPINFOHEADER)lpDIBHdr, CBM_INIT,
lpDIBBits, (LPBITMAPINFO)lpDIBHdr, DIB_RGB_COLORS);
/* restore previous palette */
if (hOldPal)
SelectPalette(hDC, hOldPal, FALSE);
/* clean up */
ReleaseDC(NULL, hDC);
GlobalUnlock(hDIB);
/* return handle to the bitmap */
return hBitmap;
}
/*************************************************************************
*
* BitmapToDIB()
*
* Parameters:
*
* HBITMAP hBitmap - specifies the bitmap to convert
*
* HPALETTE hPal - specifies the palette to use with the bitmap
*
* Return Value:
*
* HDIB - identifies the device-dependent bitmap
*
* Description:
*
* This function creates a DIB from a bitmap using the specified palette.
*
* History: Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 9/15/91 Patrick Schreiber Added header and comments
* 12/10/91 Patrick Schreiber Added bits per pixel validation
* and check GetObject return value
*
************************************************************************/
HDIB FAR BitmapToDIB(HBITMAP hBitmap, HPALETTE hPal)
{
BITMAP bm; // bitmap structure
BITMAPINFOHEADER bi; // bitmap header
BITMAPINFOHEADER FAR *lpbi; // pointer to BITMAPINFOHEADER
DWORD dwLen; // size of memory block
HANDLE hDIB, h; // handle to DIB, temp handle
HDC hDC; // handle to DC
WORD biBits; // bits per pixel
/* check if bitmap handle is valid */
if (!hBitmap)
return NULL;
/* fill in BITMAP structure, return NULL if it didn't work */
if (!GetObject(hBitmap, sizeof(bm), (LPSTR)&bm))
return NULL;
/* if no palette is specified, use default palette */
if (hPal == NULL)
hPal = GetStockObject(DEFAULT_PALETTE);
/* calculate bits per pixel */
biBits = bm.bmPlanes * bm.bmBitsPixel;
/* make sure bits per pixel is valid */
if (biBits <= 1)
biBits = 1;
else if (biBits <= 4)
biBits = 4;
else if (biBits <= 8)
biBits = 8;
else /* if greater than 8-bit, force to 24-bit */
biBits = 24;
/* initialize BITMAPINFOHEADER */
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = bm.bmWidth;
bi.biHeight = bm.bmHeight;
bi.biPlanes = 1;
bi.biBitCount = biBits;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
/* calculate size of memory block required to store BITMAPINFO */
dwLen = bi.biSize + PaletteSize((LPSTR)&bi);
/* get a DC */
hDC = GetDC(NULL);
/* select and realize our palette */
hPal = SelectPalette(hDC, hPal, FALSE);
RealizePalette(hDC);
/* alloc memory block to store our bitmap */
hDIB = GlobalAlloc(GHND, dwLen);
/* if we couldn't get memory block */
if (!hDIB)
{
/* clean up and return NULL */
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
/* lock memory and get pointer to it */
lpbi = (VOID FAR *)GlobalLock(hDIB);
/* use our bitmap info. to fill BITMAPINFOHEADER */
*lpbi = bi;
/* call GetDIBits with a NULL lpBits param, so it will calculate the
* biSizeImage field for us
*/
GetDIBits(hDC, hBitmap, 0, (WORD)bi.biHeight, NULL, (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS);
/* get the info. returned by GetDIBits and unlock memory block */
bi = *lpbi;
GlobalUnlock(hDIB);
/* if the driver did not fill in the biSizeImage field, make one up */
if (bi.biSizeImage == 0)
bi.biSizeImage = WIDTHBYTES((DWORD)bm.bmWidth * biBits) * bm.bmHeight;
/* realloc the buffer big enough to hold all the bits */
dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + bi.biSizeImage;
if (h = GlobalReAlloc(hDIB, dwLen, 0))
hDIB = h;
else
{
/* clean up and return NULL */
GlobalFree(hDIB);
hDIB = NULL;
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
/* lock memory block and get pointer to it */
lpbi = (VOID FAR *)GlobalLock(hDIB);
/* call GetDIBits with a NON-NULL lpBits param, and actualy get the
* bits this time
*/
if (GetDIBits(hDC, hBitmap, 0, (WORD)bi.biHeight, (LPSTR)lpbi + (WORD)lpbi
->biSize + PaletteSize((LPSTR)lpbi), (LPBITMAPINFO)lpbi,
DIB_RGB_COLORS) == 0)
{
/* clean up and return NULL */
GlobalUnlock(hDIB);
hDIB = NULL;
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
return NULL;
}
bi = *lpbi;
/* clean up */
GlobalUnlock(hDIB);
SelectPalette(hDC, hPal, TRUE);
RealizePalette(hDC);
ReleaseDC(NULL, hDC);
/* return handle to the DIB */
return hDIB;
}
/*************************************************************************
*
* PalEntriesOnDevice()
*
* Parameter:
*
* HDC hDC - device context
*
* Return Value:
*
* int - number of palette entries on device
*
* Description:
*
* This function gets the number of palette entries on the specified device
*
* History: Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 9/15/91 Patrick Schreiber Added header and comments
*
************************************************************************/
int FAR PalEntriesOnDevice(HDC hDC)
{
int nColors; // number of colors
/* Find out the number of palette entries on this
* device.
*/
nColors = GetDeviceCaps(hDC, SIZEPALETTE);
/* For non-palette devices, we'll use the # of system
* colors for our palette size.
*/
if (!nColors)
nColors = GetDeviceCaps(hDC, NUMCOLORS);
assert(nColors);
return nColors;
}
/*************************************************************************
*
* GetSystemPalette()
*
* Parameters:
*
* None
*
* Return Value:
*
* HPALETTE - handle to a copy of the current system palette
*
* Description:
*
* This function returns a handle to a palette which represents the system
* palette. The system RGB values are copied into our logical palette using
* the GetSystemPaletteEntries function.
*
* History:
*
* Date Author Reason
* 6/01/91 Garrett McAuliffe Created
* 9/15/91 Patrick Schreiber Added header and comments
* 12/20/91 Mark Bader Added GetSystemPaletteEntries call
*
************************************************************************/
HPALETTE FAR GetSystemPalette(void)
{
HDC hDC; // handle to a DC
static HPALETTE hPal = NULL; // handle to a palette
HANDLE hLogPal; // handle to a logical palette
LPLOGPALETTE lpLogPal; // pointer to a logical palette
int nColors; // number of colors
/* Find out how many palette entries we want. */
hDC = GetDC(NULL);
if (!hDC)
return NULL;
nColors = PalEntriesOnDevice(hDC); // Number of palette entries
/* Allocate room for the palette and lock it. */
hLogPal = GlobalAlloc(GHND, sizeof(LOGPALETTE) + nColors * sizeof(
PALETTEENTRY));
/* if we didn't get a logical palette, return NULL */
if (!hLogPal)
return NULL;
/* get a pointer to the logical palette */
lpLogPal = (LPLOGPALETTE)GlobalLock(hLogPal);
/* set some important fields */
lpLogPal->palVersion = PALVERSION;
lpLogPal->palNumEntries = nColors;
/* Copy the current system palette into our logical palette */
GetSystemPaletteEntries(hDC, 0, nColors,
(LPPALETTEENTRY)(lpLogPal->palPalEntry));
/* Go ahead and create the palette. Once it's created,
* we no longer need the LOGPALETTE, so free it.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -