You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
377 lines
7.5 KiB
377 lines
7.5 KiB
|
|
/*****************************************************************************
|
|
Description:
|
|
Handles Device Independent Bitmap.
|
|
|
|
PaletteSize() - Calculates the palette size in bytes
|
|
of given DIB
|
|
|
|
DibNumColors() - Determines the number of colors in DIB
|
|
|
|
BitmapFromDib() - Creates a DDB given a global handle to
|
|
a block in CF_DIB format.
|
|
|
|
DibFromBitmap() - Creates a DIB repr. the DDB passed in.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include <windows.h>
|
|
#include "dib.h"
|
|
|
|
|
|
static HCURSOR hcurSave;
|
|
|
|
|
|
/*
|
|
*
|
|
* FUNCTION : PaletteSize(VOID FAR * pv)
|
|
*
|
|
* PURPOSE : Calculates the palette size in bytes. If the info. block
|
|
* is of the BITMAPCOREHEADER type, the number of colors is
|
|
* multiplied by 3 to give the palette size, otherwise the
|
|
* number of colors is multiplied by 4. *
|
|
*
|
|
* RETURNS : Palette size in number of bytes.
|
|
*
|
|
*/
|
|
|
|
WORD PaletteSize (
|
|
VOID FAR * pv)
|
|
{
|
|
LPBITMAPINFOHEADER lpbi;
|
|
WORD NumColors;
|
|
|
|
lpbi = (LPBITMAPINFOHEADER)pv;
|
|
NumColors = DibNumColors(lpbi);
|
|
|
|
if (lpbi->biSize == sizeof(BITMAPCOREHEADER))
|
|
return NumColors * sizeof(RGBTRIPLE);
|
|
else
|
|
return NumColors * sizeof(RGBQUAD);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* FUNCTION : DibNumColors(VOID FAR * pv)
|
|
*
|
|
* PURPOSE : Determines the number of colors in the DIB by looking at
|
|
* the BitCount filed in the info block.
|
|
*
|
|
* RETURNS : The number of colors in the DIB.
|
|
*
|
|
*/
|
|
|
|
WORD DibNumColors (
|
|
VOID FAR * pv)
|
|
{
|
|
int bits;
|
|
LPBITMAPINFOHEADER lpbi;
|
|
LPBITMAPCOREHEADER lpbc;
|
|
|
|
|
|
lpbi = ((LPBITMAPINFOHEADER)pv);
|
|
lpbc = ((LPBITMAPCOREHEADER)pv);
|
|
|
|
|
|
|
|
/* With the BITMAPINFO format headers, the size of the palette
|
|
* is in biClrUsed, whereas in the BITMAPCORE - style headers, it
|
|
* is dependent on the bits per pixel ( = 2 raised to the power of
|
|
* bits/pixel).
|
|
*/
|
|
|
|
if (lpbi->biSize != sizeof(BITMAPCOREHEADER))
|
|
{
|
|
if (lpbi->biClrUsed != 0)
|
|
return (WORD)lpbi->biClrUsed;
|
|
bits = lpbi->biBitCount;
|
|
}
|
|
else
|
|
bits = lpbc->bcBitCount;
|
|
|
|
|
|
|
|
switch (bits)
|
|
{
|
|
case 1:
|
|
return 2;
|
|
case 4:
|
|
return 16;
|
|
case 8:
|
|
return 256;
|
|
default:
|
|
/* A 24 bitcount DIB has no color table */
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* FUNCTION : DibFromBitmap()
|
|
*
|
|
* PURPOSE : Will create a global memory block in DIB format that
|
|
* represents the Device-dependent bitmap (DDB) passed in.
|
|
*
|
|
* RETURNS : A handle to the DIB
|
|
*
|
|
*/
|
|
|
|
HANDLE DibFromBitmap (
|
|
HBITMAP hbm,
|
|
DWORD biStyle,
|
|
WORD biBits,
|
|
HPALETTE hpal)
|
|
{
|
|
BITMAP bm;
|
|
BITMAPINFOHEADER bi;
|
|
BITMAPINFOHEADER FAR *lpbi;
|
|
DWORD dwLen;
|
|
HANDLE hdib;
|
|
HANDLE h;
|
|
HDC hdc;
|
|
|
|
|
|
|
|
if (!hbm)
|
|
return NULL;
|
|
|
|
|
|
if (hpal == NULL)
|
|
{
|
|
hpal = GetStockObject(DEFAULT_PALETTE);
|
|
}
|
|
|
|
|
|
if (!GetObject(hbm,sizeof(bm),(LPSTR)&bm))
|
|
return NULL;
|
|
|
|
|
|
if (biBits == 0)
|
|
biBits = bm.bmPlanes * bm.bmBitsPixel;
|
|
|
|
|
|
|
|
// make sure we have the right # of bits
|
|
|
|
if (biBits <= 1)
|
|
biBits = 1;
|
|
else if (biBits <= 4)
|
|
biBits = 4;
|
|
else if (biBits <= 8)
|
|
biBits = 8;
|
|
else
|
|
biBits = 24;
|
|
|
|
|
|
|
|
bi.biSize = sizeof(BITMAPINFOHEADER);
|
|
bi.biWidth = bm.bmWidth;
|
|
bi.biHeight = bm.bmHeight;
|
|
bi.biPlanes = 1;
|
|
bi.biBitCount = biBits;
|
|
bi.biCompression = biStyle;
|
|
bi.biSizeImage = 0;
|
|
bi.biXPelsPerMeter = 0;
|
|
bi.biYPelsPerMeter = 0;
|
|
bi.biClrUsed = 0;
|
|
bi.biClrImportant = 0;
|
|
|
|
dwLen = bi.biSize + PaletteSize (&bi);
|
|
|
|
|
|
|
|
|
|
hdc = GetDC(NULL);
|
|
|
|
hpal = SelectPalette (hdc, hpal, FALSE);
|
|
RealizePalette (hdc);
|
|
|
|
|
|
|
|
hdib = GlobalAlloc (GHND, dwLen);
|
|
|
|
if (!hdib)
|
|
{
|
|
SelectPalette (hdc,hpal,FALSE);
|
|
ReleaseDC (NULL,hdc);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
|
|
|
|
lpbi = (VOID FAR *)GlobalLock(hdib);
|
|
*lpbi = bi;
|
|
|
|
|
|
|
|
|
|
/* call GetDIBits with a NULL lpBits param, so it will calculate the
|
|
* biSizeImage field for us
|
|
*/
|
|
|
|
GetDIBits (hdc,
|
|
hbm,
|
|
0,
|
|
(WORD)bi.biHeight,
|
|
NULL,
|
|
(LPBITMAPINFO)lpbi,
|
|
DIB_RGB_COLORS);
|
|
|
|
|
|
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;
|
|
|
|
if (biStyle != BI_RGB)
|
|
bi.biSizeImage = (bi.biSizeImage * 3) / 2;
|
|
}
|
|
|
|
|
|
|
|
|
|
// realloc the buffer big enough to hold all the bits
|
|
|
|
dwLen = bi.biSize + PaletteSize(&bi) + bi.biSizeImage;
|
|
|
|
if (h = GlobalReAlloc (hdib,dwLen,0))
|
|
hdib = h;
|
|
else
|
|
{
|
|
GlobalFree(hdib);
|
|
hdib = NULL;
|
|
|
|
SelectPalette(hdc,hpal,FALSE);
|
|
ReleaseDC(NULL,hdc);
|
|
return hdib;
|
|
}
|
|
|
|
|
|
|
|
|
|
/* call GetDIBits with a NON-NULL lpBits param, and actualy get the
|
|
* bits this time
|
|
*/
|
|
|
|
lpbi = (VOID FAR *)GlobalLock(hdib);
|
|
|
|
if (0 == GetDIBits (hdc,
|
|
hbm,
|
|
0,
|
|
(WORD)bi.biHeight,
|
|
(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
|
|
(LPBITMAPINFO)lpbi,
|
|
DIB_RGB_COLORS))
|
|
{
|
|
GlobalUnlock (hdib);
|
|
hdib = NULL;
|
|
SelectPalette (hdc, hpal, FALSE);
|
|
ReleaseDC (NULL, hdc);
|
|
return NULL;
|
|
}
|
|
|
|
|
|
bi = *lpbi;
|
|
GlobalUnlock (hdib);
|
|
|
|
|
|
SelectPalette (hdc, hpal, FALSE);
|
|
|
|
ReleaseDC (NULL, hdc);
|
|
|
|
return hdib;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
*
|
|
* FUNCTION : BitmapFromDib(HANDLE hdib, HPALETTE hpal)
|
|
*
|
|
* PURPOSE : Will create a DDB (Device Dependent Bitmap) given a global
|
|
* handle to a memory block in CF_DIB format
|
|
*
|
|
* RETURNS : A handle to the DDB.
|
|
*
|
|
*/
|
|
|
|
HBITMAP BitmapFromDib (
|
|
HANDLE hdib,
|
|
HPALETTE hpal)
|
|
{
|
|
LPBITMAPINFOHEADER lpbi;
|
|
HPALETTE hpalT;
|
|
HDC hdc;
|
|
HBITMAP hbm = NULL;
|
|
|
|
|
|
|
|
StartWait();
|
|
|
|
|
|
if (!hdib)
|
|
goto done;
|
|
|
|
|
|
lpbi = (VOID FAR *)GlobalLock (hdib);
|
|
if (!lpbi)
|
|
goto done;
|
|
|
|
|
|
|
|
hdc = GetDC (NULL);
|
|
|
|
if (hpal)
|
|
{
|
|
hpalT = SelectPalette (hdc, hpal, FALSE);
|
|
RealizePalette (hdc);
|
|
}
|
|
|
|
hbm = CreateDIBitmap (hdc,
|
|
(LPBITMAPINFOHEADER)lpbi,
|
|
(LONG)CBM_INIT,
|
|
(LPSTR)lpbi + lpbi->biSize + PaletteSize(lpbi),
|
|
(LPBITMAPINFO)lpbi,
|
|
DIB_RGB_COLORS);
|
|
|
|
|
|
if (hpal)
|
|
SelectPalette (hdc, hpalT, FALSE);
|
|
|
|
|
|
ReleaseDC (NULL, hdc);
|
|
GlobalUnlock (hdib);
|
|
|
|
|
|
done:
|
|
|
|
EndWait();
|
|
|
|
return hbm;
|
|
|
|
}
|