|
|
/*****************************************************************************
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;
}
|