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