267 lines
9.5 KiB
C
267 lines
9.5 KiB
C
|
/*******************************************************************************
|
||
|
* *
|
||
|
* MODULE : DIB.C *
|
||
|
* *
|
||
|
* DESCRIPTION : Routines for dealing with Device Independent Bitmaps. *
|
||
|
* *
|
||
|
* 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 (pv)
|
||
|
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 (pv)
|
||
|
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 (hbm, biStyle, biBits, hpal)
|
||
|
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);
|
||
|
|
||
|
GetObject(hbm,sizeof(bm),(LPSTR)&bm);
|
||
|
|
||
|
if (biBits == 0)
|
||
|
biBits = bm.bmPlanes * bm.bmBitsPixel;
|
||
|
|
||
|
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 (GetDIBits( hdc,
|
||
|
hbm,
|
||
|
0,
|
||
|
(WORD)bi.biHeight,
|
||
|
(LPSTR)lpbi + (WORD)lpbi->biSize + PaletteSize(lpbi),
|
||
|
(LPBITMAPINFO)lpbi, DIB_RGB_COLORS) == 0){
|
||
|
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;
|
||
|
|
||
|
StartWait();
|
||
|
|
||
|
if (!hdib)
|
||
|
return NULL;
|
||
|
|
||
|
lpbi = (VOID FAR *)GlobalLock(hdib);
|
||
|
|
||
|
if (!lpbi)
|
||
|
return NULL;
|
||
|
|
||
|
hdc = GetDC(NULL);
|
||
|
|
||
|
if (hpal){
|
||
|
hpalT = SelectPalette(hdc,hpal,FALSE);
|
||
|
RealizePalette(hdc); // GDI Bug...????
|
||
|
}
|
||
|
|
||
|
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);
|
||
|
|
||
|
EndWait();
|
||
|
|
||
|
return hbm;
|
||
|
}
|