DibUtil.cpp
资源名称:gloop.zip [点击查看]
上传用户:shxiangxiu
上传日期:2007-01-03
资源大小:1101k
文件大小:93k
源码类别:
OpenGL
开发平台:
Visual C++
- ////////////////////////////////////////////////////////////////////////////
- // DibUtil.cpp : Defines the global Device Independent Bitmap (dib) functions
- // for the application.
- //
- // glOOP (OpenGL Object Oriented Programming library)
- // Copyright (c) Craig Fahrnbach 1997, 1998
- //
- // OpenGL is a registered trademark of Silicon Graphics
- //
- //
- // This program is provided for educational and personal use only and
- // is provided without guarantee or warrantee expressed or implied.
- //
- // Commercial use is strickly prohibited without written permission
- // from ImageWare Development.
- //
- // This program is -not- in the public domain.
- //
- /////////////////////////////////////////////////////////////////////////////
- #include "stdafx.h"
- #include "glOOP.h"
- #include "DibUtil.h"
- /******************************************************************************
- * *
- * FUNCTION :CountBits(DWORD dw) *
- * *
- * PURPOSE :Count the number of set bits in a given DWORD *
- * *
- * *NOTE: :Used only in CreateBIPalette() for extracting RGB values *
- * from 16 and 32bpp DIBS *
- * *
- *****************************************************************************/
- BYTE CountBits(DWORD dw)
- {
- int i, Count = 0;
- for (i=0; i<sizeof(DWORD) * 8; i++)
- Count += (((1 << i) & dw) != 0);
- return Count;
- }
- /******************************************************************************
- * *
- * FUNCTION :CountBits(DWORD dw) *
- * *
- * PURPOSE :Count the number of set bits in a given DWORD *
- * *
- * *NOTE: :Used only in CreateBIPalette() for extracting RGB values *
- * from 16 and 32bpp DIBS *
- * *
- *****************************************************************************/
- BYTE RightmostBit(DWORD dw)
- {
- int i;
- for (i=0; i<sizeof(DWORD) * 8; i++)
- if (((1 << i) & dw) != 0)
- return i;
- return (BYTE)-1; // No bits are set
- }
- /******************************************************************************
- * *
- * FUNCTION :LeftmostBit(DWORD dw) *
- * *
- * PURPOSE :Returns the position of the leftmost set bit in a DWORD *
- * *
- * *NOTE: :Used only in CreateBIPalette() for extracting RGB values *
- * from 16 and 32bpp DIBS *
- * *
- *****************************************************************************/
- BYTE LeftmostBit(DWORD dw)
- {
- int i;
- for (i=(sizeof(DWORD) * 8)-1; i >= 0; i--)
- if (((1 << i) & dw) != 0)
- return i;
- return (BYTE)-1; // No bits are set
- }
- /******************************************************************************
- * *
- * FUNCTION :ValidMask(DWORD dw) *
- * *
- * PURPOSE :Determines if a given DWORD is valid as a color mask for *
- * 16 or 32bpp DIBS (are all the set bits contiguous) *
- * *
- * *NOTE: :Used only in CreateBIPalette() *
- * *
- *****************************************************************************/
- BOOL ValidMask(DWORD dw)
- {
- int iStart, iStop, i;
- iStart = LeftmostBit(dw);
- iStop = RightmostBit(dw);
- if (iStart == iStop)
- return TRUE;
- for (i=iStart; i>=iStop; i--)
- if (((1 << i) & dw) == 0)
- return FALSE;
- return TRUE;
- }
- /******************************************************************************
- * *
- * FUNCTION : GlobalFreeDIB(HGLOBAL hDIB) *
- * *
- * PURPOSE : Free the specified global memory object and invalidate *
- * its handle. *
- * *
- * RETURNS : If the function succeeds, the return value is NULL. *
- * If the function fails, the return value is equal to the *
- * handle of the global memory object. To get extended error *
- * information, call GetLastError. *
- * *
- *****************************************************************************/
- HGLOBAL GlobalFreeDIB(HGLOBAL hDIB)
- {
- LPBITMAPINFOHEADER lpbi = (LPBITMAPINFOHEADER)hDIB;
- if (!lpbi->biClrImportant)
- return GlobalFree(hDIB);
- if (GlobalFlags((HGLOBAL)lpbi->biClrImportant) == GMEM_INVALID_HANDLE) {
- SetLastError(0);
- return GlobalFree(hDIB);
- } else
- return GlobalFree((HANDLE)lpbi->biClrImportant);
- }
- /******************************************************************************
- * *
- * FUNCTION :OpenDIB(LPSTR szFilename) *
- * *
- * PURPOSE :Open a DIB file and create a memory DIB -- a memory handle *
- * containing BITMAPINFO, palette data and the bits. *
- * *
- * RETURNS :A handle to the DIB. *
- * *
- *****************************************************************************/
- HANDLE OpenDIB(LPSTR szFilename)
- {
- HFILE hFile;
- BITMAPINFOHEADER bih;
- LPBITMAPINFOHEADER lpbih;
- DWORD dwLen = 0;
- DWORD dwBits;
- HANDLE hDIB;
- HANDLE hMem;
- OFSTRUCT of;
- /* Open the file and read the DIB information */
- hFile = OpenFile(szFilename, &of, (UINT)OF_READ);
- if (hFile == HFILE_ERROR)
- {
- if(the3dEngine.m_bDisplayErrorMessages)
- {
- LPVOID lpMsgBuf;
- char buf[128];
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
- NULL,
- GetLastError(),
- MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
- (LPTSTR) &lpMsgBuf,
- 0,
- NULL);
- // Display the string.
- sprintf(buf, "Error reading file '%s'.nn Error: %sn", szFilename, lpMsgBuf);
- MessageBox( NULL, buf, "OpenDIB File Error!", MB_OK|MB_ICONINFORMATION );
- // Free the buffer.
- LocalFree( lpMsgBuf );
- }
- return NULL;
- }
- hDIB = ReadDIBBitmapInfo(hFile);
- if (!hDIB)
- return NULL;
- DIBInfo(hDIB, &bih);
- /* Calculate the memory needed to hold the DIB */
- dwBits = bih.biSizeImage;
- dwLen = bih.biSize + (DWORD)ColorTableSize (&bih) + dwBits;
- /* Try to increase the size of the bitmap info. buffer to hold the DIB */
- hMem = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE);
- if (!hMem){
- GlobalFreeDIB(hDIB);
- hDIB = NULL;
- }
- else
- hDIB = hMem;
- /* Read in the bits */
- if (hDIB){
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- _hread(hFile, (LPSTR)lpbih + (WORD)lpbih->biSize + ColorTableSize(lpbih), dwBits);
- }
- _lclose(hFile);
- return hDIB;
- }
- /******************************************************************************
- * *
- * FUNCTION : WriteDIB(LPSTR szFilename, HANDLE hDIB) *
- * *
- * PURPOSE : Write a global handle in CF_DIB format to a file. *
- * *
- * RETURNS : TRUE - if successful. *
- * FALSE - otherwise *
- * *
- *****************************************************************************/
- BOOL WriteDIB(LPSTR szFilename, HANDLE hDIB)
- {
- BITMAPFILEHEADER bmfhdr;
- LPBITMAPINFOHEADER lpbih;
- HFILE hFile;
- OFSTRUCT of;
- if (!hDIB)
- return FALSE;
- hFile = OpenFile(szFilename, &of, (UINT)OF_CREATE|OF_READWRITE);
- if (hFile == HFILE_ERROR)
- return FALSE;
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- /* Fill in the fields of the file header */
- bmfhdr.bfType = BFT_BITMAP;
- bmfhdr.bfSize = GlobalSize (hDIB) + SIZEOF_BITMAPFILEHEADER_PACKED;
- bmfhdr.bfReserved1 = 0;
- bmfhdr.bfReserved2 = 0;
- bmfhdr.bfOffBits = (DWORD)(SIZEOF_BITMAPFILEHEADER_PACKED +
- lpbih->biSize + ColorTableSize(lpbih));
- WritePackedFileHeader(hFile, &bmfhdr);
- /* Write the DIB header and the bits */
- _hwrite (hFile, (LPSTR)lpbih, GlobalSize (hDIB));
- _lclose(hFile);
- return TRUE;
- }
- /******************************************************************************
- * *
- * FUNCTION : WriteDIBEx(LPSTR szFilename, HANDLE hDIB, *
- * WORD wBPP, DWORD dwComp) *
- * *
- * PURPOSE : Write a global handle in CF_DIB format to a file with a *
- * specified pixel depth and compression format *
- * *
- * RETURNS : TRUE - if successful. *
- * FALSE - otherwise *
- * *
- *****************************************************************************/
- BOOL WriteDIBEx(LPSTR szFilename, HANDLE hDIB, WORD wBPP, DWORD dwComp)
- {
- BITMAPINFOHEADER bih;
- HANDLE hNewDIB;
- BOOL bReturn;
- DIBInfo(hDIB, &bih);
- if (((bih.biBitCount == wBPP) && (dwComp == bih.biCompression)) || ((wBPP == 0) && (dwComp == 0)))
- return WriteDIB(szFilename, hDIB);
- hNewDIB = CopyDIB(hDIB);
- // StartWait();
- hDIB = ChangeDIBFormat(hNewDIB, wBPP, dwComp);
- if (hDIB) {
- bReturn = WriteDIB(szFilename, hDIB);
- GlobalFreeDIB(hDIB);
- } else {
- bReturn = FALSE;
- GlobalFreeDIB(hNewDIB);
- }
- // EndWait();
- return bReturn;
- }
- /******************************************************************************
- * *
- * FUNCTION : DIBInfo(HANDLE hbi, LPBITMAPINFOHEADER lpbih) *
- * *
- * PURPOSE : Retrieves the DIB info associated with a CF_DIB *
- * format memory block. *
- * *
- * RETURNS : TRUE - if successful. *
- * FALSE - otherwise *
- * *
- *****************************************************************************/
- BOOL DIBInfo(HANDLE hbi, LPBITMAPINFOHEADER lpbih)
- {
- if (hbi){
- *lpbih = *(LPBITMAPINFOHEADER)hbi;
- /* fill in the default fields */
- if (NEW_DIB_FORMAT(lpbih)) {
- if (lpbih->biSizeImage == 0L)
- lpbih->biSizeImage = WIDTHBYTES(lpbih->biWidth*lpbih->biBitCount) * lpbih->biHeight;
- if (lpbih->biClrUsed == 0L)
- lpbih->biClrUsed = DIBNumColors (lpbih);
- }
- return TRUE;
- }
- return FALSE;
- }
- /******************************************************************************
- * *
- * FUNCTION : CreateBIPalette(LPBITMAPINFOHEADER lpbih) *
- * *
- * PURPOSE : Given a Pointer to a BITMAPINFO struct will create a *
- * a GDI palette object from the color table. *
- * *
- * RETURNS : A handle to the palette. *
- * *
- *****************************************************************************/
- HPALETTE CreateBIPalette(LPBITMAPINFOHEADER lpbih)
- {
- HPALETTE hPal = NULL;
- WORD nNumColors;
- LPRGBQUAD lprgbq;
- if (!lpbih)
- return NULL;
- if (!NEW_DIB_FORMAT(lpbih)) // Return if we dont have a BITMAPINFOHEADER
- return NULL;
- /* Get a pointer to the color table and the number of colors in it */
- lprgbq = (LPRGBQUAD)((LPSTR)lpbih + (WORD)lpbih->biSize);
- /* Adjust pointer for cases where BITFIELDS bitmaps might contain an optimal palette */
- if (lpbih->biCompression == BI_BITFIELDS)
- lprgbq = (LPRGBQUAD)((LPDWORD)lprgbq + 3);
- nNumColors = DIBNumColors(lpbih);
- lpbih->biClrUsed = nNumColors;
- if (nNumColors) /* Create a palette from the entries in the DIBs color table */
- hPal = CreatePaletteFromRGBQUAD(lprgbq, nNumColors);
- else
- {
- HDC hDC = GetDC(NULL);
- hPal = CreateHalftonePalette(hDC);
- ReleaseDC(NULL, hDC);
- } ;
- return hPal;
- }
- /******************************************************************************
- * *
- * FUNCTION : ReadDIBBitmapInfo(int hFile) *
- * *
- * PURPOSE : Will read a file in DIB format and return a global HANDLE *
- * to it's BITMAPINFO. This function will work with both *
- * "old" (BITMAPCOREHEADER) and "new" (BITMAPINFOHEADER) *
- * bitmap formats, but will always return a "new" BITMAPINFO *
- * *
- * RETURNS : A handle to the BITMAPINFO of the DIB in the file. *
- * *
- *****************************************************************************/
- HANDLE ReadDIBBitmapInfo(INT hFile)
- {
- DWORD dwOffset;
- HANDLE hbi = NULL;
- INT size;
- INT i;
- WORD nNumColors;
- LPRGBQUAD lprgbq;
- BITMAPINFOHEADER bih;
- BITMAPCOREHEADER bch;
- LPBITMAPINFOHEADER lpbih;
- BITMAPFILEHEADER bf;
- DWORD dwDWMasks= 0;
- DWORD dwWidth = 0;
- DWORD dwHeight = 0;
- WORD wPlanes, wBitCount;
- if (hFile == HFILE_ERROR)
- return NULL;
- /* Read the bitmap file header */
- ReadPackedFileHeader(hFile, &bf, &dwOffset);
- /* Do we have a RC HEADER? */
- if (!ISDIB (bf.bfType)) {
- bf.bfOffBits = 0L;
- _llseek(hFile, dwOffset, (UINT)SEEK_SET); /* seek back to beginning of file */
- }
- if (sizeof(bih) != _hread(hFile, (LPSTR)&bih, (UINT)sizeof(bih)))
- return FALSE;
- nNumColors = DIBNumColors (&bih);
- /* Check the nature (BITMAPINFO or BITMAPCORE) of the info. block
- * and extract the field information accordingly. If a BITMAPCOREHEADER,
- * transfer it's field information to a BITMAPINFOHEADER-style block
- */
- switch (size = (INT)bih.biSize){
- case sizeof (BITMAPINFOHEADER):
- break;
- case sizeof (BITMAPCOREHEADER):
- bch = *(LPBITMAPCOREHEADER)&bih;
- dwWidth = (DWORD)bch.bcWidth;
- dwHeight = (DWORD)bch.bcHeight;
- wPlanes = bch.bcPlanes;
- wBitCount = bch.bcBitCount;
- bih.biSize = sizeof(BITMAPINFOHEADER);
- bih.biWidth = dwWidth;
- bih.biHeight = dwHeight;
- bih.biPlanes = wPlanes;
- bih.biBitCount = wBitCount;
- bih.biCompression = BI_RGB;
- bih.biSizeImage = 0;
- bih.biXPelsPerMeter = 0;
- bih.biYPelsPerMeter = 0;
- bih.biClrUsed = nNumColors;
- bih.biClrImportant = nNumColors;
- _llseek(hFile, (LONG)sizeof (BITMAPCOREHEADER) - sizeof (BITMAPINFOHEADER), (UINT)SEEK_CUR);
- break;
- default:
- /* Not a DIB! */
- return NULL;
- }
- /* Fill in some default values if they are zero */
- if (bih.biSizeImage == 0){
- bih.biSizeImage = WIDTHBYTES((DWORD)bih.biWidth * bih.biBitCount) * bih.biHeight;
- }
- if (bih.biClrUsed == 0)
- bih.biClrUsed = DIBNumColors(&bih);
- /* Allocate for the BITMAPINFO structure and the color table. */
- if ((bih.biBitCount == 16) || (bih.biBitCount == 32))
- dwDWMasks = sizeof(DWORD) * 3;
- hbi = GlobalAlloc (GPTR, (LONG)bih.biSize + nNumColors * sizeof(RGBQUAD) + dwDWMasks);
- if (!hbi)
- return NULL;
- lpbih = (LPBITMAPINFOHEADER)hbi;
- *lpbih = bih;
- /* Get a pointer to the color table */
- lprgbq = (LPRGBQUAD)((LPSTR)lpbih + bih.biSize);
- if (nNumColors){
- if (size == sizeof(BITMAPCOREHEADER)){
- /* Convert a old color table (3 byte RGBTRIPLEs) to a new
- * color table (4 byte RGBQUADs)
- */
- _hread(hFile, (LPSTR)lprgbq, (UINT)nNumColors * sizeof(RGBTRIPLE));
- for (i = nNumColors - 1; i >= 0; i--){
- RGBQUAD rgbq;
- rgbq.rgbRed = ((RGBTRIPLE*)lprgbq)[i].rgbtRed;
- rgbq.rgbBlue = ((RGBTRIPLE*)lprgbq)[i].rgbtBlue;
- rgbq.rgbGreen = ((RGBTRIPLE*)lprgbq)[i].rgbtGreen;
- rgbq.rgbReserved = (BYTE)0;
- lprgbq[i] = rgbq;
- }
- }
- else
- _hread(hFile, (LPSTR)lprgbq, (UINT)nNumColors * sizeof(RGBQUAD));
- } else
- if (dwDWMasks)
- _hread(hFile, (LPSTR)lprgbq, dwDWMasks);
- if (bf.bfOffBits != 0L){
- _llseek(hFile, dwOffset + bf.bfOffBits, (UINT)SEEK_SET);
- }
- return hbi;
- }
- /******************************************************************************
- * *
- * FUNCTION : ColorTableSize(LPVOID lpv) *
- * *
- * 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 : Color table size in number of bytes. *
- * *
- *****************************************************************************/
- WORD ColorTableSize(LPVOID lpv)
- {
- LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
- if (NEW_DIB_FORMAT(lpbih))
- {
- if (((LPBITMAPINFOHEADER)(lpbih))->biCompression == BI_BITFIELDS)
- /* Remember that 16/32bpp dibs can still have a color table */
- return (sizeof(DWORD) * 3) + (DIBNumColors (lpbih) * sizeof (RGBQUAD));
- else
- return (DIBNumColors (lpbih) * sizeof (RGBQUAD));
- }
- else
- return (DIBNumColors (lpbih) * sizeof (RGBTRIPLE));
- }
- /******************************************************************************
- * *
- * FUNCTION : DIBNumColors(LPVOID lpv) *
- * *
- * PURPOSE : Determines the number of colors in the DIB by looking at *
- * the BitCount and ClrUsed fields in the info block. *
- * *
- * RETURNS : The number of colors in the DIB. With DIBS with more than *
- * 8-bits-per-pixel that have a color table table included, *
- * then the return value will be the number of colors in the *
- * color table rather than the number of colors in the DIB. *
- * *
- * *
- *****************************************************************************/
- WORD DIBNumColors(LPVOID lpv)
- {
- INT bits;
- LPBITMAPINFOHEADER lpbih = (LPBITMAPINFOHEADER)lpv;
- LPBITMAPCOREHEADER lpbch = (LPBITMAPCOREHEADER)lpv;
- /* 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 (NEW_DIB_FORMAT(lpbih)) {
- if (lpbih->biClrUsed != 0)
- return (WORD)lpbih->biClrUsed;
- bits = lpbih->biBitCount;
- }
- else
- bits = lpbch->bcBitCount;
- if (bits > 8)
- return 0; /* Since biClrUsed is 0, we dont have a an optimal palette */
- else
- return (1 << bits);
- }
- /******************************************************************************
- * *
- * 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 hBitmap, DWORD biStyle, WORD biBits, HPALETTE hPal)
- {
- BITMAP Bitmap;
- BITMAPINFOHEADER bih;
- LPBITMAPINFOHEADER lpbih;
- DWORD dwLen;
- HANDLE hDIB;
- HANDLE hMem;
- HDC hDC;
- if (!hBitmap)
- return NULL;
- if (hPal == NULL)
- hPal = (HPALETTE) GetStockObject(DEFAULT_PALETTE);
- GetObject(hBitmap, sizeof(Bitmap), (LPSTR)&Bitmap);
- if (biBits == 0)
- biBits = Bitmap.bmPlanes * Bitmap.bmBitsPixel;
- bih.biSize = sizeof(BITMAPINFOHEADER);
- bih.biWidth = Bitmap.bmWidth;
- bih.biHeight = Bitmap.bmHeight;
- bih.biPlanes = 1;
- bih.biBitCount = biBits;
- bih.biCompression = biStyle;
- bih.biSizeImage = 0;
- bih.biXPelsPerMeter = 0;
- bih.biYPelsPerMeter = 0;
- bih.biClrUsed = 0;
- bih.biClrImportant = 0;
- dwLen = bih.biSize + ColorTableSize(&bih);
- hDC = GetDC(NULL);
- hPal = SelectPalette(hDC, hPal, FALSE);
- RealizePalette(hDC);
- hDIB = GlobalAlloc(GPTR, dwLen);
- if (!hDIB) {
- SelectPalette(hDC, hPal, FALSE);
- ReleaseDC(NULL, hDC);
- return NULL;
- }
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- *lpbih = bih;
- /* call GetDIBits with a NULL lpBits param, so it will calculate the
- * biSizeImage field for us
- */
- GetDIBits(hDC,
- hBitmap,
- (UINT)0,
- (UINT)bih.biHeight,
- (LPVOID)NULL,
- (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS);
- bih = *lpbih;
- /* If the driver did not fill in the biSizeImage field, make one up */
- if (bih.biSizeImage == 0){
- bih.biSizeImage = WIDTHBYTES((DWORD)Bitmap.bmWidth * biBits) * Bitmap.bmHeight;
- if (biStyle != BI_RGB)
- bih.biSizeImage = (bih.biSizeImage * 3) / 2;
- }
- /* realloc the buffer big enough to hold all the bits */
- dwLen = bih.biSize + ColorTableSize(&bih) + bih.biSizeImage;
- if (hMem = GlobalReAlloc(hDIB, dwLen, GMEM_MOVEABLE))
- hDIB = hMem;
- else {
- GlobalFreeDIB(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
- */
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- if (!GetDIBits(hDC,
- hBitmap,
- (UINT)0,
- (UINT)bih.biHeight,
- (LPBYTE)lpbih + (WORD)lpbih->biSize + ColorTableSize(lpbih),
- (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS)) {
- hDIB = NULL;
- SelectPalette(hDC, hPal, FALSE);
- ReleaseDC(NULL, hDC);
- return NULL;
- }
- bih = *lpbih;
- 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 lpbih;
- HPALETTE hPalOld;
- HDC hDC;
- HBITMAP hBitmap;
- // StartWait();
- if (!hDIB)
- return NULL;
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- if (!lpbih)
- return NULL;
- hDC = GetDC(NULL);
- if (hPal){
- hPalOld = SelectPalette(hDC, hPal, FALSE);
- RealizePalette(hDC); // GDI Bug...????
- }
- hBitmap = CreateDIBitmap(hDC,
- lpbih,
- CBM_INIT,
- (LPSTR)lpbih + lpbih->biSize + ColorTableSize(lpbih),
- (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS );
- if (hPal)
- SelectPalette(hDC, hPalOld, FALSE);
- ReleaseDC(NULL, hDC);
- // EndWait();
- return hBitmap;
- }
- /******************************************************************************
- * *
- * FUNCTION : DrawBitmap(HDC hDC, int x, int y, *
- * HBITMAP hBitmap, DWORD dwROP) *
- * *
- * PURPOSE : Draws bitmap <hBitmap> at the specifed position in DC <hDC> *
- * *
- * RETURNS : Return value of BitBlt() *
- * *
- *****************************************************************************/
- BOOL DrawBitmap(HDC hDC, INT x, INT y, HBITMAP hBitmap, DWORD dwROP)
- {
- HDC hDCBits;
- BITMAP Bitmap;
- BOOL bResult;
- if (!hDC || !hBitmap)
- return FALSE;
- hDCBits = CreateCompatibleDC(hDC);
- GetObject(hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
- SelectObject(hDCBits, hBitmap);
- bResult = BitBlt(hDC, x, y, Bitmap.bmWidth, Bitmap.bmHeight, hDCBits, 0, 0, dwROP);
- DeleteDC(hDCBits);
- return bResult;
- }
- /******************************************************************************
- * *
- * FUNCTION : DIBBlt( HDC hDC, *
- * int x0, int y0, *
- * int dx, int dy, *
- * HANDLE hDIB, *
- * int x1, int y1, *
- * LONG dwROP) *
- * *
- * PURPOSE : Draws a bitmap in CF_DIB format, using SetDIBits to device. *
- * taking the same parameters as BitBlt(). *
- * *
- * RETURNS : TRUE - if function succeeds. *
- * FALSE - otherwise. *
- * *
- ******************************************************************************/
- BOOL DIBBlt (HDC hDC, INT x0, INT y0, INT dx, INT dy,
- HANDLE hDIB, INT x1, INT y1, LONG dwROP)
- {
- LPBITMAPINFOHEADER lpbih;
- LPSTR pBuf;
- if (!hDIB)
- return PatBlt(hDC, x0, y0, dx, dy, dwROP);
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- if (!lpbih)
- return FALSE;
- pBuf = (LPSTR)lpbih + (WORD)lpbih->biSize + ColorTableSize(lpbih);
- SetDIBitsToDevice (hDC, x0, y0, dx, dy,
- x1, y1,
- x1,
- dy,
- pBuf, (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS );
- return TRUE;
- }
- /******************************************************************************
- * *
- * FUNCTION : StretchDIBBlt( HDC hDC, *
- * int x, int y, *
- * int dx, int dy, *
- * HANDLE hDIB, *
- * int x0, int y0, *
- * int dx0, int dy0, *
- * LONG dwROP) *
- * *
- * PURPOSE : Draws a bitmap in CF_DIB format, using StretchDIBits() *
- * taking the same parameters as StretchBlt(). *
- * *
- * RETURNS : TRUE - if function succeeds. *
- * FALSE - otherwise. *
- * *
- ******************************************************************************/
- BOOL StretchDIBBlt (HDC hDC, INT x, INT y, INT dx, INT dy,
- HANDLE hDIB, INT x0, INT y0, INT dx0, INT dy0, LONG dwROP)
- {
- LPBITMAPINFOHEADER lpbih;
- LPSTR pBuf;
- BOOL bResult;
- if (!hDIB)
- return PatBlt(hDC, x, y, dx, dy, dwROP);
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- if (!lpbih)
- return FALSE;
- pBuf = (LPSTR)lpbih + (WORD)lpbih->biSize + ColorTableSize(lpbih);
- bResult = StretchDIBits (hDC, x, y, dx, dy,
- x0, y0, dx0, dy0,
- pBuf, (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS, dwROP);
- return bResult;
- }
- /******************************************************************************
- * *
- * FUNCTION : ReadPackedFileHeader(HFILE hFile, LPBITMAPFILEHEADER pbf) *
- * *
- * PURPOSE : read file header (which is packed) and convert into *
- * unpacked BITMAPFILEHEADER strucutre *
- * *
- * RETURNS : VOID *
- * *
- *****************************************************************************/
- VOID ReadPackedFileHeader(HFILE hFile, LPBITMAPFILEHEADER lpbmfhdr, LPDWORD lpdwOffset)
- {
- *lpdwOffset = _llseek(hFile, 0L, (UINT) SEEK_CUR);
- _hread(hFile, (LPSTR) &lpbmfhdr->bfType, sizeof(WORD)); /* read in bfType*/
- _hread(hFile, (LPSTR) &lpbmfhdr->bfSize, sizeof(DWORD) * 3); /* read in last 3 dwords*/
- }
- /******************************************************************************
- * *
- * FUNCTION : WritePackedFileHeader(HFILE hFile, LPBITMAPFILEHEADER pbf) *
- * *
- * PURPOSE : write header structure (which NOT packed) and write *
- * it out in PACKED format *
- * *
- * RETURNS : VOID *
- * *
- *****************************************************************************/
- VOID WritePackedFileHeader(HFILE hFile, LPBITMAPFILEHEADER lpbmfhdr)
- {
- _hwrite(hFile, (LPSTR)&lpbmfhdr->bfType, (UINT)sizeof (WORD));
- /* pass over extra word and write next 3 DWORDS! */
- _hwrite(hFile, (LPSTR)&lpbmfhdr->bfSize, sizeof(DWORD) * 3);
- }
- /******************************************************************************
- * *
- * HANDLE ConvertRGBDIB(HANDLE hSrcDIB, DWORD dwDstComp, WORD wDstBPP) *
- * *
- * Parameter: *
- * *
- * HDIB - handle to packed-DIB in memory *
- * WORD - desired bits per pixel *
- * DWORD - desired compression format *
- * *
- * Return Value: *
- * *
- * HDIB - handle to the new DIB if successful, else NULL *
- * *
- * Description: *
- * *
- * This function will create a new DIB with the specified BPP format using an *
- * existing DIB as the source of the bits. The conversion method will keep *
- * as much of the color information as possible. Both source and destination *
- * must be at least 16 bits-per-pixel. *
- * *
- * *Notes: *
- * The source DIB is never destroyed *
- * This function is not exposed and it is only called by ChangeDIBFormat() *
- * The function will return NULL if it fails *
- * *
- *****************************************************************************/
- HANDLE ConvertRGBDIB(HANDLE hSrcDIB, DWORD dwDstComp, WORD wDstBPP)
- {
- HDC hDC = GetDC(NULL);
- HDC hSrcMemDC = CreateCompatibleDC(NULL);
- HDC hDstMemDC = CreateCompatibleDC(NULL);
- HBITMAP hSrcBmp = NULL, hDstBmp = NULL;
- HANDLE hDstDIB = NULL;
- LPBITMAPINFOHEADER biSrcPtr, biDstPtr;
- LPRGBQUAD rgbqSrcPtr, rgbqDstPtr;
- RGBTRIPLE *bmSrcPtr, *bmDstPtr;
- LPVOID pSrcDisp, pDstDisp;
- __try {
- /* This method of conversion only works with > 8bpp format DIBs */
- if ((wDstBPP < 16) || (GetDIBBitCount(hSrcDIB) < 16))
- RAISE_AN_EXCEPTION();
- /* Initialize pointers for the source DIB */
- if (!GetDIBPointers(hSrcDIB, (LPVOID*)&biSrcPtr, (LPVOID*)&rgbqSrcPtr, (LPVOID*)&bmSrcPtr))
- RAISE_AN_EXCEPTION();
- /* Create destination DIB and initialize pointers for it */
- hDstDIB = CreateRGBDIB(biSrcPtr->biWidth, biSrcPtr->biHeight, wDstBPP, dwDstComp);
- if (!GetDIBPointers(hDstDIB, (LPVOID*)&biDstPtr, (LPVOID*)&rgbqDstPtr, (LPVOID*)&bmDstPtr))
- RAISE_AN_EXCEPTION();
- /* Create and load source DIB into source bitmap */
- hSrcBmp = CreateDIBSection(hDC, (LPBITMAPINFO)biSrcPtr, 0, &pSrcDisp, NULL, 0);
- if (!SelectObject(hSrcMemDC, hSrcBmp))
- RAISE_AN_EXCEPTION();
- CopyMemory(pSrcDisp, bmSrcPtr, biSrcPtr->biSizeImage);
- /* Create destination bitmap */
- hDstBmp = CreateDIBSection(hDC, (LPBITMAPINFO)biDstPtr, 0, &pDstDisp, NULL, 0);
- if (!SelectObject(hDstMemDC, hDstBmp))
- RAISE_AN_EXCEPTION();
- /* Make GDI do the conversion between the different BPP formats */
- BitBlt(hDstMemDC, 0, 0, biSrcPtr->biWidth, biSrcPtr->biHeight,
- hSrcMemDC, 0, 0, SRCCOPY);
- GdiFlush();
- /* Copy the converted data to our destination DIB */
- CopyMemory(bmDstPtr, pDstDisp, biDstPtr->biSizeImage);
- } __except (EXCEPTION_EXECUTE_HANDLER) {
- /* Something got hosed, make sure we deallocate our destination DIB */
- if (hDstDIB) {
- GlobalFreeDIB(hDstDIB);
- hDstDIB = NULL;
- }
- }
- /* Clean up the mess we made */
- if (hDC) ReleaseDC(NULL, hDC);
- if (hSrcMemDC) DeleteDC(hSrcMemDC);
- if (hDstMemDC) DeleteDC(hDstMemDC);
- if (hSrcBmp) DeleteObject(hSrcBmp);
- if (hDstBmp) DeleteObject(hDstBmp);
- return hDstDIB;
- }
- /******************************************************************************
- * *
- * HANDLE ChangeDIBFormat(HANDLE hDIB, WORD wBPP, DWORD dwComp) *
- * *
- * Parameter: *
- * *
- * HDIB - handle to packed-DIB in memory *
- * WORD - desired bits per pixel *
- * DWORD - desired compression format *
- * *
- * Return Value: *
- * *
- * HDIB - handle to the new DIB if successful, else NULL *
- * *
- * Description: *
- * *
- * This function will convert the bits per pixel and/or the compression *
- * format of the specified DIB. Note: If the conversion was unsuccessful, *
- * we return NULL. The original DIB is left alone. Don't use code like the *
- * following: *
- * *
- * hMyDIB = ChangeDIBFormat(hMyDIB, 8, BI_RLE4); *
- * *
- * The conversion will fail, but hMyDIB will now be NULL and the original *
- * DIB will now hang around in memory. We could have returned the old *
- * DIB, but we wanted to allow the programmer to check whether this *
- * conversion succeeded or failed. *
- * *
- *****************************************************************************/
- HANDLE ChangeDIBFormat(HANDLE hDIB, WORD wBPP, DWORD dwComp)
- {
- HBITMAP hBitmap; // Handle to bitmap
- LPBITMAPINFOHEADER lpbih; // Pointer to bitmap info
- HANDLE hNewDIB = NULL; // Handle to new DIB
- HPALETTE hPal; // Handle to palette, prev pal
- WORD wOldBPP, wNewBPP; // DIB bits per pixel, new bpp
- DWORD dwOldComp, dwNewComp; // DIB compression, new compression
- /* Check for a valid DIB handle */
- if (!hDIB)
- return NULL;
- /* Get the old DIB's bits per pixel and compression format */
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- wOldBPP = lpbih->biBitCount;
- dwOldComp = lpbih->biCompression;
- /* Validate wBPP and dwComp
- * They must match correctly (i.e., BI_RLE4 and 4 BPP or
- * BI_RLE8 and 8BPP, etc.) or we return failure */
- if (wBPP == 0) {
- wNewBPP = wOldBPP;
- if ((dwComp == BI_RLE4 && wNewBPP == 4) ||
- (dwComp == BI_RLE8 && wNewBPP == 8) ||
- (dwComp == BI_RGB))
- dwNewComp = dwComp;
- else
- return NULL;
- }
- else if (wBPP == 1 && dwComp == BI_RGB) {
- wNewBPP = wBPP;
- dwNewComp = BI_RGB;
- }
- else if (wBPP == 4) {
- wNewBPP = wBPP;
- if (dwComp == BI_RGB || dwComp == BI_RLE4)
- dwNewComp = dwComp;
- else
- return NULL;
- }
- else if (wBPP == 8) {
- wNewBPP = wBPP;
- if (dwComp == BI_RGB || dwComp == BI_RLE8)
- dwNewComp = dwComp;
- else
- return NULL;
- }
- else if (wBPP == 24 && dwComp == BI_RGB) {
- wNewBPP = wBPP;
- dwNewComp = BI_RGB;
- }
- else if (((wBPP == 16) || (wBPP == 32)) &&
- ((dwComp == BI_BITFIELDS) || (dwComp == BI_RGB))) {
- wNewBPP = wBPP;
- dwNewComp = dwComp;
- }
- else
- return NULL;
- if ((wOldBPP > 8) && (wNewBPP > 8))
- /* Keep as much color info as possible */
- hNewDIB = ConvertRGBDIB(hDIB, dwNewComp, wNewBPP);
- if (!hNewDIB) {
- /* Save the old DIB's palette */
- hPal = CreateDIBPalette(hDIB);
- if (!hPal)
- return NULL;
- /* Convert old DIB to a bitmap */
- hBitmap = BitmapFromDIB(hDIB, hPal);
- /* Convert Bitmap into a DIB with the new compression and BPP */
- hNewDIB = DIBFromBitmap(hBitmap, dwNewComp, wNewBPP, hPal);
- DeleteObject(hBitmap);
- DeleteObject(hPal);
- }
- if (hNewDIB)
- GlobalFreeDIB(hDIB);
- return hNewDIB;
- }
- /******************************************************************************
- * *
- * BOOL ChangeDIBPalette(HANDLE hDIB, HPALETTE hPal) *
- * *
- * Parameter: *
- * *
- * HDIB - handle to packed-DIB in memory *
- * HPALETTE - the new palette for the DIB *
- * *
- * Return Value: *
- * *
- * BOOL - returns success or failure status *
- * *
- * Description: *
- * *
- * This function will remap the colors in the given DIB so that they *
- * reference the colors in the new palette - note that this is not the same *
- * changing the DIBs color table since we are forcing the bits to be *
- * remapped to new values in addition to changing the color table. *
- * *
- *****************************************************************************/
- BOOL ChangeDIBPalette(HANDLE hDIB, HPALETTE hPal)
- {
- HDC hDC;
- HBITMAP hBitmap;
- LPBITMAPINFOHEADER lpbih; // Pointer to bitmap info
- HPALETTE hOldPal; // Handle to palette, prev pal
- /* Check for a valid DIB/Palette handle */
- if (!hDIB || !hPal)
- return FALSE;
- /* Convert old DIB to a bitmap */
- hBitmap = BitmapFromDIB(hDIB, hPal);
- /* Make sure it worked */
- if (!hBitmap)
- return FALSE;
- /* Get a pointer to the DIB header */
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- /* Get a DC and select/realize our palette in it */
- hDC = GetDC(NULL);
- hOldPal = SelectPalette(hDC, hPal, FALSE);
- RealizePalette(hDC);
- /* Call GetDIBits and get the new DIB bits */
- if (!GetDIBits(hDC,
- hBitmap,
- (UINT)0,
- (UINT)lpbih->biHeight,
- (LPBYTE)lpbih + (WORD)lpbih->biSize + ColorTableSize((LPSTR)lpbih),
- (LPBITMAPINFO)lpbih,
- DIB_RGB_COLORS))
- return FALSE;
- /* Clean up and return */
- SelectPalette(hDC, hOldPal, TRUE);
- RealizePalette(hDC);
- ReleaseDC(NULL, hDC);
- DeleteObject(hBitmap);
- return TRUE;
- }
- /******************************************************************************
- * *
- * HANDLE CopyDIB(HANDLE hDIBSrc) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want to make a copy of. *
- * *
- * Return Value: *
- * *
- * HANDLE - A copy of the DIB passed as a parameter *
- * *
- *****************************************************************************/
- HANDLE CopyDIB(HANDLE hDIBSrc)
- {
- HANDLE hDIBDst = NULL;
- DWORD dwSize = GlobalSize(hDIBSrc);
- if (!hDIBSrc)
- return NULL;
- hDIBDst = GlobalAlloc(GPTR, dwSize);
- if (!hDIBDst)
- return NULL;
- CopyMemory(hDIBDst, hDIBSrc, dwSize);
- return (hDIBDst);
- }
- /****************************************************************************
- * *
- * FUNCTION : CopyBitmap (HBITMAP hBitmap) *
- * *
- * PURPOSE : Copies the given bitmap to another. *
- * *
- * RETURNS : A handle to the new bitmap. *
- * *
- ****************************************************************************/
- HBITMAP CopyBitmap (HBITMAP hBitmap)
- {
- BITMAP Bitmap;
- RECT rect;
- if (!hBitmap)
- return NULL;
- GetObject (hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
- rect.left = 0;
- rect.top = 0;
- rect.right = Bitmap.bmWidth;
- rect.bottom = Bitmap.bmHeight;
- return CropBitmap (hBitmap, &rect);
- }
- /****************************************************************************
- * *
- * FUNCTION : CropBitmap (HBITMAP hBitmap, LPRECT lpRect) *
- * *
- * PURPOSE : Crops a bitmap to a new size specified by the lpRect *
- * parameter. *
- * *
- * RETURNS : A handle to the new bitmap. *
- * *
- ****************************************************************************/
- HBITMAP CropBitmap (HBITMAP hBitmap, LPRECT lpRect)
- {
- HDC hMemDCsrc;
- HDC hMemDCdst;
- HDC hDC;
- HBITMAP hNewBm;
- BITMAP Bitmap;
- INT dx, dy;
- if (!hBitmap)
- return NULL;
- hDC = GetDC (NULL);
- hMemDCsrc = CreateCompatibleDC (hDC);
- hMemDCdst = CreateCompatibleDC (hDC);
- GetObject (hBitmap, sizeof(BITMAP), (LPSTR)&Bitmap);
- dx = lpRect->right - lpRect->left;
- dy = lpRect->bottom - lpRect->top;
- /*hNewBm = +++CreateBitmap - Not Recommended(use CreateDIBitmap)+++ (dx, dy, Bitmap.BitmapPlanes, Bitmap.BitmapBitsPixel, NULL);*/
- hNewBm = CreateBitmap(dx, dy, Bitmap.bmPlanes, Bitmap.bmBitsPixel, NULL);
- if (hNewBm) {
- SelectObject (hMemDCsrc, hBitmap);
- SelectObject (hMemDCdst, hNewBm);
- BitBlt (hMemDCdst,
- 0,
- 0,
- dx,
- dy,
- hMemDCsrc,
- lpRect->left,
- lpRect->top,
- SRCCOPY);
- }
- ReleaseDC (NULL, hDC);
- DeleteDC (hMemDCsrc);
- DeleteDC (hMemDCdst);
- return hNewBm;
- }
- /******************************************************************************
- * *
- * BOOL CopyDIBData(HANDLE hDIBDst, HANDLE hDIBSrc) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want to copy to. *
- * HANDLE - The handle to the DIB you want to copy from. *
- * *
- * Return Value: *
- * *
- * HANDLE - Success or failure of the function *
- * *
- * Replaces the contents of the destination DIB with the contents of the *
- * source DIB. This will fail if the initial sizes of the DIBS are *
- * not equal. *
- * *
- *****************************************************************************/
- BOOL CopyDIBData(HANDLE hDIBDst, HANDLE hDIBSrc)
- {
- DWORD dwDstSize = GlobalSize(hDIBDst);
- DWORD dwSrcSize = GlobalSize(hDIBSrc);
- if (dwDstSize != dwDstSize)
- return FALSE;
- CopyMemory(hDIBDst, hDIBSrc, dwDstSize);
- return (TRUE);
- }
- /******************************************************************************
- * *
- * HANDLE GetDIBFromClipboard(HWND hWnd) *
- * *
- * Parameter: *
- * *
- * HWND - The handle of the window that will own the clipboard *
- * *
- * Return Value: *
- * *
- * HANDLE - Handle to the DIB that was on the Clipboard *
- * *
- *****************************************************************************/
- HANDLE GetDIBFromClipboard(HWND hWnd)
- {
- HANDLE hData;
- HANDLE hDIB;
- if (OpenClipboard(hWnd)) {
- hData = GetClipboardData(CF_DIB);
- if (hData == NULL) {
- hData = GetClipboardData(CF_BITMAP);
- if (hData != NULL) {
- HPALETTE hPal, hClipPal = (HPALETTE)GetClipboardData(CF_PALETTE);
- hPal = CopyPalette(hClipPal);
- hDIB = DIBFromBitmap((HBITMAP)hData, BI_RGB, 8, hPal);
- DeleteObject(hPal);
- } else
- return NULL;
- } else
- hDIB = CopyDIB(hData);
- CloseClipboard();
- } else
- return NULL;
- return hDIB;
- }
- /******************************************************************************
- * *
- * BOOL GetDIBResolution(HANDLE hDIB, LONG *iXRes, LONG *iYRes) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want get the resolution of *
- * LONG* - Pointer to x resolution *
- * LONG* - Pointer to y resolution *
- * *
- * Return Value: *
- * *
- * HANDLE - Success or failure of the function *
- * *
- * Reads the width and the height of a DIB from the BITMAPINFOHEADER and *
- * returns the values. *
- * *
- *****************************************************************************/
- BOOL GetDIBResolution(HANDLE hDIB, LONG *iXRes, LONG *iYRes)
- {
- if (!hDIB) return FALSE;
- *iXRes = ((LPBITMAPINFOHEADER)hDIB)->biWidth;
- *iYRes = ((LPBITMAPINFOHEADER)hDIB)->biHeight;
- return TRUE;
- }
- /******************************************************************************
- * *
- * DWORD GetDIBColorUsed(HANDLE hDIB) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want to check *
- * *
- * Return Value: *
- * *
- * DWORD - Number of colors used by the DIB *
- * *
- * Reads and returns the number of colors used from the BITMAPINFOHEADER *
- * *
- *****************************************************************************/
- DWORD GetDIBColorUsed(HANDLE hDIB)
- {
- DWORD dwClrUsed;
- if (!hDIB)
- return 0;
- dwClrUsed = ((LPBITMAPINFOHEADER)hDIB)->biClrUsed;
- return dwClrUsed;
- }
- /******************************************************************************
- * *
- * DWORD GetDIBCopmression(HANDLE hDIB) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want to check *
- * *
- * Return Value: *
- * *
- * DWORD - The compression type for the given DIB *
- * *
- *****************************************************************************/
- DWORD GetDIBCompression(HANDLE hDIB)
- {
- DWORD dwComp;
- if (!hDIB)
- return 0;
- dwComp = ((LPBITMAPINFOHEADER)hDIB)->biCompression;
- return dwComp;
- }
- /******************************************************************************
- * *
- * DWORD GetDIBBitcount(HANDLE hDIB) *
- * *
- * Parameter: *
- * *
- * HANDLE - The handle to the DIB you want to check *
- * *
- * Return Value: *
- * *
- * DWORD - The number of bits per pixel for given DIB *
- * *
- *****************************************************************************/
- WORD GetDIBBitCount(HANDLE hDIB)
- {
- WORD wBitCount;
- if (!hDIB)
- return 0;
- wBitCount = ((LPBITMAPINFOHEADER)hDIB)->biBitCount;
- return wBitCount;
- }
- /******************************************************************************
- * *
- * FUNCTION : CreateDIBPalette(HANDLE hbi) *
- * *
- * PURPOSE : Given a Global HANDLE to a BITMAPINFO Struct will create a *
- * GDI palette object from the color table. (BITMAPINFOHEADER *
- * format DIBs only) *
- * *
- * RETURNS : A handle to the palette. *
- * *
- *****************************************************************************/
- HPALETTE CreateDIBPalette (HANDLE hbi)
- {
- HPALETTE hPal;
- if (!hbi)
- return NULL;
- hPal = CreateBIPalette((LPBITMAPINFOHEADER)hbi);
- return hPal;
- }
- /******************************************************************************
- * *
- * FUNCTION : CreateDIBPaletteEx(HANDLE hbi, BYTE bFlags) *
- * *
- * PURPOSE : Given a Global HANDLE to a BITMAPINFO Struct will create a *
- * GDI palette object from the color table. (BITMAPINFOHEADER *
- * format DIBs only) In addition, you can specify the palette *
- * palette flags for the palette entries. *
- * *
- * RETURNS : A handle to the palette. *
- * *
- *****************************************************************************/
- HPALETTE CreateDIBPaletteEx(HANDLE hDIB, BYTE bFlags)
- {
- HPALETTE hPal, hNewPal;
- if (!hDIB)
- return NULL;
- hPal = CreateDIBPalette(hDIB);
- hNewPal = CopyPaletteEx(hPal, bFlags);
- DeleteObject(hPal);
- return hNewPal;
- }
- /******************************************************************************
- * *
- * FUNCTION : GetDIBPointers(HANDLE hDIB, LPVOID *biPtr, *
- * LPVOID *rgbqPtr, LPVOID *bmPtr) *
- * *
- * PURPOSE : Given a handle to a DIB in CF_DIB format, this function will *
- * retrieve pointers for the bitmap info, color table, and bits *
- * *
- *****************************************************************************/
- BOOL GetDIBPointers(HANDLE hDIB, LPVOID *biPtr, LPVOID *rgbqPtr, LPVOID *bmPtr)
- {
- LPBITMAPINFO pbi;
- pbi = (LPBITMAPINFO)hDIB;
- if (!pbi)
- return FALSE;
- *biPtr = (LPVOID)pbi;
- *rgbqPtr = (LPVOID)((LPSTR)pbi + (WORD)((LPBITMAPINFOHEADER)pbi)->biSize);
- if (((LPBITMAPINFOHEADER)pbi)->biCompression == BI_BITFIELDS)
- rgbqPtr = (LPVOID*)((LPDWORD)rgbqPtr + 3);
- *bmPtr = (LPBYTE)pbi + (WORD)pbi->bmiHeader.biSize + ColorTableSize(pbi);
- return TRUE;
- }
- /******************************************************************************
- * *
- * FUNCTION : HANDLE CreateRGBDIB(DWORD dwWidth, DWORD dwHeight, *
- * WORD wBPP, DWORD dwComp); *
- * *
- * PURPOSE : Returns a handle to a RGB DIB (no color table) with the *
- * specified width, height, bits per pixel, and compression. *
- * *
- *****************************************************************************/
- HANDLE CreateRGBDIB(DWORD dwWidth, DWORD dwHeight, WORD wBPP, DWORD dwComp)
- {
- HANDLE hDIB;
- LPBITMAPINFOHEADER lpbih;
- DWORD dwSize;
- LPDWORD lpMasks;
- /* We cant support compression so check to see if that's what is being asked for */
- if ((dwComp == BI_RLE8) || (dwComp == BI_RLE4)) return NULL;
- /* Allocate enough memory to hold the DIB */
- switch (wBPP) {
- case 8: dwSize = ((DWORD)BYTESPERLINE(dwWidth, 8) * dwHeight) + sizeof(RGBQUAD) * 256; break;
- case 16: dwSize = ((dwWidth + (dwWidth & 1)) << 1) * dwHeight; break;
- case 24: dwSize = (DWORD)BYTESPERLINE(dwWidth, 24) * dwHeight; break;
- case 32: dwSize = ((dwWidth * dwHeight) << 2); break;
- default: return NULL;
- }
- if (dwComp == BI_BITFIELDS) /* Add in space for DWORD masks */
- hDIB = GlobalAlloc(GPTR, (DWORD)sizeof(BITMAPINFOHEADER) + (sizeof(DWORD) * 3) + dwSize);
- else
- hDIB = GlobalAlloc(GPTR, (DWORD)sizeof(BITMAPINFOHEADER) + dwSize);
- if (!hDIB)
- return NULL;
- lpbih = (LPBITMAPINFOHEADER)hDIB;
- lpbih->biSize = sizeof(BITMAPINFOHEADER);
- lpbih->biWidth = dwWidth;
- lpbih->biHeight = dwHeight;
- lpbih->biPlanes = 1;
- lpbih->biBitCount = wBPP;
- lpbih->biCompression = dwComp;
- lpbih->biSizeImage = ((DWORD)BYTESPERLINE(dwWidth, wBPP) * dwHeight);
- lpMasks = (LPDWORD)((LPSTR)lpbih + (WORD)lpbih->biSize);
- if (dwComp == BI_BITFIELDS)
- if (wBPP == 16) {
- lpMasks[0] = MAKE565WORD(0xff, 0, 0);
- lpMasks[1] = MAKE565WORD(0, 0xff, 0);
- lpMasks[2] = MAKE565WORD(0, 0, 0xff);
- } else if (wBPP == 32) {
- lpMasks[0] = 0xff0000;
- lpMasks[1] = 0x00ff00;
- lpMasks[2] = 0x0000ff;
- }
- 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 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);
- return nColors;
- }
- /******************************************************************************
- * *
- * HPALETTE CreatePaletteFromRGBQUAD(LPRGBQUAD rgbqPalette, WORD wEntries) *
- * *
- * Parameter: *
- * *
- * LPRGBQUAD - pointer to RGBQUADs *
- * WORD - the number of RGBQUADs we are pointing to *
- * *
- * Return Value: *
- * *
- * HPALETTE - returns a handle to a palette or NULL if it failes *
- * *
- * Description: *
- * *
- * This function will build a valid HPALETTE when given an array of RGBQUADs *
- * *
- *****************************************************************************/
- HPALETTE CreatePaletteFromRGBQUAD(LPRGBQUAD rgbqPalette, WORD wEntries)
- {
- HPALETTE hPal;
- LPLOGPALETTE lplgPal;
- PALETTEENTRY pe[256];
- int i;
- lplgPal = (LPLOGPALETTE)GlobalAlloc(GPTR, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * wEntries);
- if (!lplgPal)
- return NULL;
- lplgPal->palVersion = PALVERSION;
- lplgPal->palNumEntries = wEntries;
- for (i=0; i<wEntries; i++) {
- lplgPal->palPalEntry[i].peRed = rgbqPalette[i].rgbRed;
- lplgPal->palPalEntry[i].peGreen = rgbqPalette[i].rgbGreen;
- lplgPal->palPalEntry[i].peBlue = rgbqPalette[i].rgbBlue;
- lplgPal->palPalEntry[i].peFlags = 0;
- }
- CopyMemory(pe, lplgPal->palPalEntry, wEntries * sizeof(PALETTEENTRY));
- hPal = CreatePalette(lplgPal);
- GlobalFree(lplgPal);
- return hPal;
- }
- /******************************************************************************
- * *
- * WORD CreateRGBQUADFromPalette(LPRGBQUAD rgbqPalette, HPALETTE hPal); *
- * *
- * Parameter: *
- * *
- * LPRGBQUAD - pointer to RGBQUADs *
- * HPALETTE - HANDLE of Palette *
- * *
- * Return Value: *
- * *
- * WORD - returns the number of palette entries copied into the *
- * LPRGBQUAD array *
- * *
- * Description: *
- * *
- * This function will fill an array of RGBQUAD from given a palette handle *
- * *
- *****************************************************************************/
- WORD CreateRGBQUADFromPalette(LPRGBQUAD rgbqPalette, HPALETTE hPal)
- {
- int i;
- WORD wEntries;
- GetObject(hPal, sizeof(wEntries), &wEntries);
- GetPaletteEntries(hPal, 0, wEntries, (LPPALETTEENTRY)rgbqPalette);
- for (i=0; i<wEntries; i++) {
- rgbqPalette[i].rgbReserved = rgbqPalette[i].rgbRed;
- rgbqPalette[i].rgbRed = rgbqPalette[i].rgbBlue;
- rgbqPalette[i].rgbBlue = rgbqPalette[i].rgbReserved;
- rgbqPalette[i].rgbReserved = 0;
- }
- return wEntries;
- }
- /******************************************************************************
- * *
- * 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 GetSystemPalette()
- {
- 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;
- if (!(GetDeviceCaps(hDC, RASTERCAPS) & RC_PALETTE)) {
- ReleaseDC(NULL, hDC);
- return NULL;
- }
- nColors = PalEntriesOnDevice(hDC); // Number of palette entries
- /* Allocate room for the palette */
- hLogPal = GlobalAlloc(GPTR, 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)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.
- */
- hPal = CreatePalette(lpLogPal);
- /* clean up */
- GlobalFree(hLogPal);
- ReleaseDC(NULL, hDC);
- return hPal;
- }
- /******************************************************************************
- * *
- * HPALETTE CreateNewPalette() *
- * *
- * Parameter: *
- * *
- * HDC - Handle to a Device Context *
- * *
- * Return Value: *
- * *
- * HPALETTE - Returns a handle to a palette or NULL if it *
- * fails. *
- * *
- * Description: *
- * *
- * This function will build a palette with a spectrum of colors. It is *
- * useful when you want to display a number of DIBs each with a different *
- * palette yet still have an a good selection of colors for the DIBs to map *
- * to. *
- * *
- *****************************************************************************/
- HPALETTE CreateNewPalette(HDC hDC)
- {
- PIXELFORMATDESCRIPTOR pfd; // Pixel Format Descriptor
- LOGPALETTE *pPal; // Pointer to memory for logical palette
- HPALETTE hPal; // Handle to our palette
- int nPixelFormat; // Pixel format index
- int nColors; // Number of entries in palette
- int i; // Counting variable
- BYTE RedRange,GreenRange,BlueRange;
- // Range for each color entry (7,7,and 3)
- // Get the pixel format index and retrieve the pixel format description
- nPixelFormat = GetPixelFormat(hDC);
- DescribePixelFormat(hDC, nPixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pfd);
- // Does this pixel format require a palette? If not, do not create a
- // palette and just return NULL
- if(!(pfd.dwFlags & PFD_NEED_PALETTE))
- return NULL;
- // Number of entries in palette. 8 bits yeilds 256 entries
- nColors = 1 << pfd.cColorBits;
- // Allocate space for a logical palette structure plus all the palette entries
- pPal = (LOGPALETTE*)malloc(sizeof(LOGPALETTE) +nColors*sizeof(PALETTEENTRY));
- // Fill in palette header
- pPal->palVersion = 0x300; // Windows 3.0
- pPal->palNumEntries = nColors; // table size
- // Build mask of all 1's. This creates a number represented by having
- // the low order x bits set, where x = pfd.cRedBits, pfd.cGreenBits, and
- // pfd.cBlueBits.
- RedRange = (1 << pfd.cRedBits) -1;
- GreenRange = (1 << pfd.cGreenBits) - 1;
- BlueRange = (1 << pfd.cBlueBits) -1;
- // Loop through all the palette entries
- for(i = 0; i < nColors; i++)
- {
- // Fill in the 8-bit equivalents for each component
- pPal->palPalEntry[i].peRed = (i >> pfd.cRedShift) & RedRange;
- pPal->palPalEntry[i].peRed = (unsigned char)(
- (double) pPal->palPalEntry[i].peRed * 255.0 / RedRange);
- pPal->palPalEntry[i].peGreen = (i >> pfd.cGreenShift) & GreenRange;
- pPal->palPalEntry[i].peGreen = (unsigned char)(
- (double)pPal->palPalEntry[i].peGreen * 255.0 / GreenRange);
- pPal->palPalEntry[i].peBlue = (i >> pfd.cBlueShift) & BlueRange;
- pPal->palPalEntry[i].peBlue = (unsigned char)(
- (double)pPal->palPalEntry[i].peBlue * 255.0 / BlueRange);
- pPal->palPalEntry[i].peFlags = (unsigned char) NULL;
- }
- // Create the palette
- hPal = CreatePalette(pPal);
- // Go ahead and select and realize the palette for this device context
- // SelectPalette(hDC,(HPALETTE)hPalette,FALSE);
- // RealizePalette(hDC);
- // Free the memory used for the logical palette structure
- free(pPal);
- return hPal; // Return the handle to this palette
- }
- /******************************************************************************
- * *
- * HPALETTE CreateSpectrumPalette2() *
- * *
- * Parameter: *
- * *
- * (none) *
- * *
- * Return Value: *
- * *
- * HPALETTE - Returns a handle to a spectrum palette or NULL if it *
- * fails. *
- * *
- * Description: *
- * *
- * This function will build a palette with a spectrum of colors. It is *
- * useful when you want to display a number of DIBs each with a different *
- * palette yet still have an a good selection of colors for the DIBs to map *
- * to. *
- * *
- *****************************************************************************/
- HPALETTE CreateSpectrumPalette2()
- {
- HPALETTE hPal;
- LPLOGPALETTE lplgPal;
- BYTE red, green, blue;
- int i;
- lplgPal = (LPLOGPALETTE)GlobalAlloc(GPTR, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * MAXPALETTE);
- if (!lplgPal)
- return NULL;
- lplgPal->palVersion = PALVERSION;
- lplgPal->palNumEntries = MAXPALETTE;
- red = green = blue = 0;
- for (i = 0; i < MAXPALETTE; i++) {
- lplgPal->palPalEntry[i].peRed = red;
- lplgPal->palPalEntry[i].peGreen = green;
- lplgPal->palPalEntry[i].peBlue = blue;
- lplgPal->palPalEntry[i].peFlags = (BYTE)0;
- if (!(red += 32))
- if (!(green += 32))
- blue += 64;
- }
- hPal = CreatePalette(lplgPal);
- GlobalFree(lplgPal);
- return hPal;
- }
- /******************************************************************************
- * *
- * HANDLE CopyPalette(HPALETTE hPal) *
- * *
- * Parameter: *
- * *
- * HPALETTE - The handle to the palette you want to make a copy of. *
- * *
- * Return Value: *
- * *
- * HPALETTE - A copy of the palette passed as a parameter *
- * *
- *****************************************************************************/
- HPALETTE CopyPalette(HPALETTE hPal)
- {
- HPALETTE hPalNew;
- LPLOGPALETTE lplgPal;
- WORD iNumEntries;
- GetObject(hPal, sizeof(iNumEntries), &iNumEntries);
- lplgPal = (LPLOGPALETTE)GlobalAlloc(GPTR, sizeof(LOGPALETTE) + sizeof(PALETTEENTRY) * iNumEntries);
- if (!lplgPal)
- return NULL;
- lplgPal->palVersion = PALVERSION;
- lplgPal->palNumEntries = GetPaletteEntries(hPal, 0, iNumEntries, lplgPal->palPalEntry);
- hPalNew = CreatePalette(lplgPal);
- GlobalFree(lplgPal);
- return (hPalNew);
- }
- /******************************************************************************
- * *
- * FUNCTION : CopyPaletteEx(HPALETTE hPal, BYTE bFlags) *
- * *
- * PURPOSE : Given a handle to a palette, this function return a copy of *
- * the palette with all of the flags set to a the specified *
- * value. *
- * *
- * RETURNS : A handle to the palette. *
- * *
- *****************************************************************************/
- HPALETTE CopyPaletteEx(HPALETTE hPal, BYTE bFlag)
- {
- int i;
- WORD wNumColors;
- PALETTEENTRY pe[MAXPALETTE];
- HPALETTE hNewPal;
- if (!hPal || !GetObject(hPal, sizeof(wNumColors), &wNumColors))
- return NULL;
- hNewPal = CopyPalette(hPal);
- GetPaletteEntries(hNewPal, 0, wNumColors, (LPPALETTEENTRY)&pe);
- for (i=0; i<(int)wNumColors; i++)
- pe[i].peFlags = bFlag;
- SetPaletteEntries(hNewPal, 0, wNumColors, (LPPALETTEENTRY)&pe);
- return hNewPal;
- }
- /******************************************************************************
- * *
- * HPALETTE CreateIdentityPalette(LPRGBQUAD lprgbq, int nColors) *
- * *
- * LPRGBQUAD - pointer to RGBQUADs *
- * int - the number of RGBQUADs we are pointing to *
- * *
- * Return Value: *
- * *
- * HPALETTE - returns a handle to an identity palette or NULL if it *
- * fails *
- * *
- * *Note: This code was originally taken from the WinG online docs *
- *****************************************************************************/
- HPALETTE CreateIdentityPalette(LPRGBQUAD lprgbq, int nColors)
- {
- int i;
- struct {
- WORD Version;
- WORD NumberOfEntries;
- PALETTEENTRY aEntries[MAXPALETTE];
- } Palette =
- {
- 0x300,
- MAXPALETTE
- };
- //*** Just use the screen DC where we need it
- HDC hDC = GetDC(NULL);
- //*** For SYSPAL_NOSTATIC, just copy the color table into
- //*** a PALETTEENTRY array and replace the first and last entries
- //*** with black and white
- if (GetSystemPaletteUse(hDC) == SYSPAL_NOSTATIC)
- {
- //*** Fill in the palette with the given values, marking each
- //*** as PC_NOCOLLAPSE
- for(i = 0; i < nColors; i++)
- {
- Palette.aEntries[i].peRed = lprgbq[i].rgbRed;
- Palette.aEntries[i].peGreen = lprgbq[i].rgbGreen;
- Palette.aEntries[i].peBlue = lprgbq[i].rgbBlue;
- Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
- }
- //*** Mark any unused entries PC_NOCOLLAPSE
- for (; i < MAXPALETTE; ++i)
- Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
- //*** Make sure the last entry is white
- //*** This may replace an entry in the array!
- Palette.aEntries[255].peRed = 255;
- Palette.aEntries[255].peGreen = 255;
- Palette.aEntries[255].peBlue = 255;
- Palette.aEntries[255].peFlags = 0;
- //*** And the first is black
- //*** This may replace an entry in the array!
- Palette.aEntries[0].peRed = 0;
- Palette.aEntries[0].peGreen = 0;
- Palette.aEntries[0].peBlue = 0;
- Palette.aEntries[0].peFlags = 0;
- }
- else
- //*** For SYSPAL_STATIC, get the twenty static colors into
- //*** the array, then fill in the empty spaces with the
- //*** given color table
- {
- int nStaticColors;
- int nUsableColors;
- //*** Get the static colors from the system palette
- nStaticColors = GetDeviceCaps(hDC, NUMCOLORS);
- GetSystemPaletteEntries(hDC, 0, MAXPALETTE, Palette.aEntries);
- //*** Set the peFlags of the lower static colors to zero
- nStaticColors = nStaticColors / 2;
- for (i=0; i<nStaticColors; i++)
- Palette.aEntries[i].peFlags = 0;
- //*** Fill in the entries from the given color table
- nUsableColors = nColors - nStaticColors;
- for (; i<nUsableColors; i++)
- {
- Palette.aEntries[i].peRed = lprgbq[i].rgbRed;
- Palette.aEntries[i].peGreen = lprgbq[i].rgbGreen;
- Palette.aEntries[i].peBlue = lprgbq[i].rgbBlue;
- Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
- }
- //*** Mark any empty entries as PC_NOCOLLAPSE
- for (; i<MAXPALETTE - nStaticColors; i++)
- Palette.aEntries[i].peFlags = PC_NOCOLLAPSE;
- //*** Set the peFlags of the upper static colors to zero
- for (i = MAXPALETTE - nStaticColors; i<MAXPALETTE; i++)
- Palette.aEntries[i].peFlags = 0;
- }
- //*** Remember to release the DC!
- ReleaseDC(NULL, hDC);
- //*** Return the palette
- return CreatePalette((LPLOGPALETTE)&Palette);
- }
- /******************************************************************************
- * *
- * void ClearSystemPalette(void) *
- * *
- * Purpose: Clears the system palette by realizing an all black palette. *
- * This will ensure that palette-managed applications executed *
- * before your application will not affect the identity mapping of *
- * your palette. *
- * *
- * *
- * *Note: This code was originally taken from the WinG online docs *
- *****************************************************************************/
- void ClearSystemPalette(void)
- {
- //*** A dummy palette setup
- struct
- {
- WORD Version;
- WORD NumberOfEntries;
- PALETTEENTRY aEntries[MAXPALETTE];
- } Palette =
- {
- 0x300,
- MAXPALETTE
- };
- HPALETTE ScreenPalette = 0;
- HDC ScreenDC;
- int Counter;
- //*** Reset everything in the system palette to black
- for (Counter = 0; Counter < MAXPALETTE; Counter++)
- {
- Palette.aEntries[Counter].peRed = 0;
- Palette.aEntries[Counter].peGreen = 0;
- Palette.aEntries[Counter].peBlue = 0;
- Palette.aEntries[Counter].peFlags = PC_NOCOLLAPSE;
- }
- //*** Create, select, realize, deselect, and delete the palette
- ScreenDC = GetDC(NULL);
- ScreenPalette = CreatePalette((LPLOGPALETTE)&Palette);
- if (ScreenPalette)
- {
- ScreenPalette = SelectPalette(ScreenDC, ScreenPalette, FALSE);
- RealizePalette(ScreenDC);
- ScreenPalette = SelectPalette(ScreenDC, ScreenPalette, FALSE);
- DeleteObject(ScreenPalette);
- }
- ReleaseDC(NULL, ScreenDC);
- }