home *** CD-ROM | disk | FTP | other *** search
- /*===========================================================================*\
- |
- | File: cgdib.cpp
- |
- | Description:
- |
- |-----------------------------------------------------------------------------
- |
- | Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
- |
- | Written by Moss Bay Engineering, Inc. under contract to Microsoft Corporation
- |
- \*===========================================================================*/
-
- /**************************************************************************
-
- (C) Copyright 1995-1996 Microsoft Corp. All rights reserved.
-
- You have a royalty-free right to use, modify, reproduce and
- distribute the Sample Files (and/or any modified version) in
- any way you find useful, provided that you agree that
- Microsoft has no warranty obligations or liability for any
- Sample Application Files which are modified.
-
- we do not recomend you base your game on IKlowns, start with one of
- the other simpler sample apps in the GDK
-
- **************************************************************************/
-
-
- #ifdef __WATCOMC__
- #include <windows.h>
- #endif
- #include <windowsx.h>
- #include "cgglobl.h"
- #include "cgrsrce.h"
- #include "cgscreen.h"
- #include "cgexcpt.h"
- #include "cgdebug.h"
- #include "cgdib.h"
-
- /* Macro to determine to round off the given value to the closest byte */
- #define WIDTHBYTES(i) ((i+31)/32*4)
-
- #define BFT_BITMAP 0x4d42 /* 'BM' */
-
- /* macro to determine if resource is a DIB */
- #define ISDIB(bft) ((bft) == BFT_BITMAP)
-
- /* Macros to display/remove hourglass cursor for lengthy operations */
- #define StartWait() hcurSave = SetCursor(hCursor=LoadCursor(NULL,IDC_WAIT));
- #define EndWait() SetCursor(hCursor=hcurSave)
-
- #define PALVERSION 0x300
- #define MAXPALETTE 256 /* max. # supported palette entries */
-
- WORD PaletteSize (VOID FAR * pv);
- WORD DibNumColors (VOID FAR * pv);
- HPALETTE CreateDibPalette (HANDLE hdib);
- HPALETTE CreateBIPalette (LPBITMAPINFOHEADER lpbi);
- HANDLE DibFromBitmap (HBITMAP hbm, DWORD biStyle, WORD biBits, HPALETTE hpal);
- HBITMAP BitmapFromDib (HANDLE hdib, HPALETTE hpal);
- BOOL DibInfo (HANDLE hdib,LPBITMAPINFOHEADER lpbi);
- HANDLE ReadDibBitmapInfo (int fh);
- VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff);
-
- static HCURSOR hCursor;
- static HCURSOR hcurSave;
-
- /*---------------------------------------------------------------------------*\
- |
- | Class CGameDIB
- |
- | DESCRIPTION:
- |
- |
- |
- \*---------------------------------------------------------------------------*/
- CGameDIB::CGameDIB(
- ) : mImageValid( FALSE ),
- mpBitmapInfo( NULL ),
- mpBits( NULL ),
- mpFileName( NULL ),
- mhBitmap( NULL )
- {
- }
-
- CGameDIB::CGameDIB(
- LPSTR pFileName
- ) : mImageValid( FALSE ),
- mpBitmapInfo( NULL ),
- mpBits( NULL ),
- mpFileName( NULL ),
- mhBitmap( NULL )
- {
- if (pFileName)
- {
- mpFileName = new char[lstrlen(pFileName)+1];
- lstrcpy( mpFileName, pFileName );
-
- // Load the DIB into memory.
- OpenDIB(pFileName);
-
- // Set the flag to indicate that we now have a valid image in memory.
- // NOTE: OpenDIB will throw exception if there's a problem, so we can
- // assume here that image is valid.
- mImageValid = TRUE;
- }
- }
-
- // construct a new DIB section in memory of given size, palette
- CGameDIB::CGameDIB(
- int width,
- int height,
- HPALETTE hPal
- ) : mImageValid( FALSE ),
- mpBitmapInfo( NULL ),
- mpBits( NULL ),
- mpFileName( NULL ),
- mhBitmap( NULL )
- {
- PALETTEENTRY entries[256];
- LPBITMAPINFO pBI = (LPBITMAPINFO) GlobalAllocPtr( GHND, sizeof( BITMAPINFO ) );
-
- if (!pBI)
- throw CGameResourceError();
-
- // !!!NOTE: we're assuming 8 BPP
- pBI->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- pBI->bmiHeader.biWidth = width;
- pBI->bmiHeader.biHeight = height; // make it top-down
- pBI->bmiHeader.biPlanes = 1;
- pBI->bmiHeader.biBitCount = 8;
-
- pBI->bmiHeader.biCompression = BI_RGB;
- pBI->bmiHeader.biXPelsPerMeter = 0;
- pBI->bmiHeader.biYPelsPerMeter = 0;
- pBI->bmiHeader.biClrUsed = 256;
- pBI->bmiHeader.biClrImportant = 256;
-
- pBI->bmiHeader.biSizeImage = WIDTHBYTES(width*8) * height;
-
- /* Calculate the memory needed to hold the DIB */
- DWORD dwBits = pBI->bmiHeader.biSizeImage;
- DWORD dwLen = pBI->bmiHeader.biSize + (DWORD)PaletteSize (pBI);
-
- /* Try to increase the size of the bitmap info. buffer to hold the DIB */
- pBI = (LPBITMAPINFO) GlobalReAllocPtr(pBI, dwLen, GHND);
- if (!pBI)
- {
- throw CGameResourceError();
- }
-
- mpBitmapInfo = pBI;
-
- HDC hdc = GetDC( HWND_DESKTOP );
-
- if (hdc)
- {
- // now create the color table from given palette
- HPALETTE hOldPal = NULL;
-
- if (hPal == NULL)
- hPal = (HPALETTE)GetCurrentObject( hdc, OBJ_PAL );
- else
- {
- hOldPal = SelectPalette( hdc, hPal, FALSE );
- RealizePalette( hdc );
- }
-
- UINT numColors = GetSystemPaletteEntries(
- hdc,
- 0, // start index
- MAXPALETTE, // num to get
- entries
- );
-
-
-
- for (UINT i=0; i<numColors; i++)
- {
- pBI->bmiColors[i].rgbRed = entries[i].peRed;
- pBI->bmiColors[i].rgbGreen = entries[i].peGreen;
- pBI->bmiColors[i].rgbBlue = entries[i].peBlue;
- }
-
- mhBitmap = CreateDIBSection(
- hdc,
- mpBitmapInfo,
- DIB_RGB_COLORS,
- (void**) &mpBits,
- NULL,
- 0
- );
-
- mImageValid = (mhBitmap != NULL);
-
- if (hOldPal)
- {
- SelectPalette( hdc, hOldPal, FALSE );
- RealizePalette( hdc );
- }
-
- ReleaseDC( HWND_DESKTOP, hdc );
- }
- }
-
- /*---------------------------------------------------------------------------*\
- | ~CGameDIB
- \*---------------------------------------------------------------------------*/
- CGameDIB::~CGameDIB()
- {
- delete[] mpFileName;
-
- if (mhBitmap)
- {
- DeleteObject( mhBitmap );
- }
-
- if (mpBitmapInfo)
- {
- GlobalFreePtr( mpBitmapInfo );
- }
- }
-
- /*---------------------------------------------------------------------------*\
- | GetWidth()
- \*---------------------------------------------------------------------------*/
- int
- CGameDIB::GetWidth()
- {
- if (mpBitmapInfo)
- return mpBitmapInfo->bmiHeader.biWidth;
-
- return 0;
- }
-
- /*---------------------------------------------------------------------------*\
- | GetHeight()
- \*---------------------------------------------------------------------------*/
- int
- CGameDIB::GetHeight()
- {
- if (mpBitmapInfo)
- return mpBitmapInfo->bmiHeader.biHeight;
-
- return 0;
- }
-
- /*---------------------------------------------------------------------------*\
- | CreatePalette
- \*---------------------------------------------------------------------------*/
- HPALETTE
- CGameDIB::CreatePalette()
- {
- return CreateBIPalette( (PBITMAPINFOHEADER) mpBitmapInfo );
- }
-
- /*---------------------------------------------------------------------------*\
- | OpenDIB
- \*---------------------------------------------------------------------------*/
- void
- CGameDIB::OpenDIB (char* pFileName)
- {
- HFILE fh;
- BITMAPINFOHEADER bi;
- LPBITMAPINFOHEADER lpbi;
- DWORD dwLen = 0;
- DWORD dwBits;
- HANDLE hdib;
- HANDLE h;
- OFSTRUCT of;
-
- if (!pFileName)
- return;
-
- /* Open the file and read the DIB information */
- fh = OpenFile(pFileName, &of, (UINT)OF_READ);
- if (fh == -1)
- {
- DB_LOG(DB_PROBLEM, "DEBUG: OpenFile failed in OpenDIB");
- throw CGameException(
- IDS_INVALID_FILE
- );
- }
-
- hdib = ReadDibBitmapInfo(fh);
-
- DWORD offset = SetFilePointer( (HANDLE) fh, 0, NULL, FILE_CURRENT );
-
- if (!hdib)
- {
- DB_LOG(DB_PROBLEM, "DEBUG: Invalid DIB file in OpenDIB");
- throw CGameException(
- IDS_INVALID_FILE
- );
- }
-
- DibInfo(hdib,&bi);
-
- #ifdef ConvertToPaletteRelative
- /* Convert the DIB color table to palette relative indexes, so
- * SetDIBits() and SetDIBitsToDevice() can avoid color matching.
- * We can do this because the palette we realize is identical
- * to the color table of the bitmap, ie the indexes match 1 to 1
- *
- * Now that the DIB color table is palette indexes not RGB values
- * we must use DIB_PAL_COLORS as the wUsage parameter to SetDIBits()
- */
- lpbi = (VOID FAR *) GlobalLock(hbiCurrent);
- if (lpbi->biBitCount != 24) {
- fPalColors = TRUE;
-
- pw = (WORD FAR *) ((LPSTR) lpbi + lpbi->biSize);
-
- for (i = 0; i < (int) lpbi->biClrUsed; i++)
- *pw++ = (WORD) i;
- }
- GlobalUnlock(hbiCurrent);
- #endif
-
- /* Calculate the memory needed to hold the DIB */
- dwBits = bi.biSizeImage;
- dwLen = bi.biSize + (DWORD)PaletteSize (&bi);
-
- /* Try to increase the size of the bitmap info. buffer to hold the DIB */
- h = GlobalReAlloc(hdib, dwLen, GHND);
- if (!h)
- {
- GlobalFree(hdib);
- hdib = NULL;
- throw CGameResourceError();
- }
- else
- hdib = h;
-
- /* Read in the bits */
- if (hdib)
- {
- lpbi = (LPBITMAPINFOHEADER)GlobalLock(hdib);
- mpBitmapInfo = (LPBITMAPINFO) lpbi;
-
- HDC hdc = GetDC( HWND_DESKTOP );
-
- if (hdc)
- {
- mhBitmap = CreateDIBSection(
- hdc,
- mpBitmapInfo,
- DIB_RGB_COLORS,
- (void**) &mpBits,
- NULL,
- 0
- );
-
- ReadFile(
- (HANDLE)fh,
- mpBits,
- dwBits,
- &dwLen,
- NULL
- );
-
- ReleaseDC( HWND_DESKTOP, hdc );
- }
- }
-
- CloseHandle((HANDLE)fh);
- }
-
- /*---------------------------------------------------------------------------*\
- | GetPixelAddress()
- \*---------------------------------------------------------------------------*/
- LPBYTE // return address of the pixel -- NULL if out of range
- CGameDIB::GetPixelAddress(
- int x,
- int y
- )
- {
- long width;
-
- // check params
- if (( x < 0 ) || ( y < 0 ) || ( x >= GetWidth() ) || ( y >= GetHeight() ))
- {
- return NULL;
- }
-
- // round up to DWORD boundary
- width = (GetWidth() + 3) & ~3;
- return mpBits + (long)(GetHeight()-y-1) * width + (long)x;
- }
-
- /*---------------------------------------------------------------------------*\
- | GetPixelAddress()
- \*---------------------------------------------------------------------------*/
- COLORREF
- CGameDIB::GetPixelColor(
- int x,
- int y
- )
- {
- LPBYTE pPixel = GetPixelAddress( x, y );
-
- if (pPixel)
- {
- RGBQUAD quad = mpBitmapInfo->bmiColors[*pPixel];
-
- return PALETTERGB( quad.rgbRed, quad.rgbGreen, quad.rgbBlue );
- }
-
- // else
- return 0; // invalid params
- }
-
- /*---------------------------------------------------------------------------*\
- | GetColorTable()
- \*---------------------------------------------------------------------------*/
- UINT // return the number of entries copied
- CGameDIB::GetColorTable(UINT start, UINT count, RGBQUAD* pArray)
- {
- UINT result = 0;
-
- if (mpBitmapInfo)
- {
- for (int i=start; ( i < DibNumColors(mpBitmapInfo)) && (result < count); i++)
- {
- pArray[result] = mpBitmapInfo->bmiColors[i];
- ++result;
- }
- }
-
- return result;
- }
-
- /****************************************************************************
- * *
- * FUNCTION : DibInfo(HANDLE hbi,LPBITMAPINFOHEADER lpbi) *
- * *
- * PURPOSE : Retrieves the DIB info associated with a CF_DIB *
- * format memory block. *
- * *
- * RETURNS : TRUE - if successful. *
- * FALSE - otherwise *
- * *
- ****************************************************************************/
- BOOL DibInfo (
- HANDLE hbi,
- LPBITMAPINFOHEADER lpbi)
- {
- if (hbi)
- {
- *lpbi = *(LPBITMAPINFOHEADER)GlobalLock (hbi);
-
- /* fill in the default fields */
- if (lpbi->biSize != sizeof (BITMAPCOREHEADER))
- {
- if (lpbi->biSizeImage == 0L)
- lpbi->biSizeImage = WIDTHBYTES(lpbi->biWidth*lpbi->biBitCount) * lpbi->biHeight;
-
- if (lpbi->biClrUsed == 0L)
- lpbi->biClrUsed = DibNumColors (lpbi);
- }
- GlobalUnlock (hbi);
- return TRUE;
- }
- return FALSE;
- }
-
- /****************************************************************************
- * *
- * FUNCTION : CreateBIPalette(LPBITMAPINFOHEADER lpbi) *
- * *
- * 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 lpbi)
- {
- LOGPALETTE *pPal;
- HPALETTE hpal = NULL;
- WORD nNumColors;
- BYTE red;
- BYTE green;
- BYTE blue;
- WORD i;
- RGBQUAD FAR *pRgb;
-
- if (!lpbi)
- return NULL;
-
- if (lpbi->biSize != sizeof(BITMAPINFOHEADER))
- return NULL;
-
- /* Get a pointer to the color table and the number of colors in it */
- pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + (WORD)lpbi->biSize);
- nNumColors = DibNumColors(lpbi);
-
- if (nNumColors)
- {
- /* Allocate for the logical palette structure */
- pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
- if (!pPal)
- return NULL;
-
- pPal->palNumEntries = nNumColors;
- pPal->palVersion = PALVERSION;
-
- /* Fill in the palette entries from the DIB color table and
- * create a logical color palette.
- */
-
- // keep index 0 black, index 255 white to keep Windows happy
- pPal->palPalEntry[0].peRed = 0;
- pPal->palPalEntry[0].peGreen = 0;
- pPal->palPalEntry[0].peBlue = 0;
- pPal->palPalEntry[0].peFlags = PC_EXPLICIT;
-
- for (i = 1; i < (nNumColors-1); i++)
- {
- pPal->palPalEntry[i].peRed = pRgb[i].rgbRed;
- pPal->palPalEntry[i].peGreen = pRgb[i].rgbGreen;
- pPal->palPalEntry[i].peBlue = pRgb[i].rgbBlue;
- pPal->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
- }
-
- if (nNumColors == 256)
- {
- pPal->palPalEntry[255].peRed = 255; // PC_EXPLICIT treats number as a long
- pPal->palPalEntry[255].peGreen = 0;
- pPal->palPalEntry[255].peBlue = 0;
- pPal->palPalEntry[255].peFlags = PC_EXPLICIT;
- }
-
- hpal = CreatePalette(pPal);
- LocalFree((HANDLE)pPal);
- }
- else if (lpbi->biBitCount == 24)
- {
- /* A 24 bitcount DIB has no color table entries so, set the number of
- * to the maximum value (256).
- */
- nNumColors = MAXPALETTE;
- pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
- if (!pPal)
- return NULL;
-
- pPal->palNumEntries = nNumColors;
- pPal->palVersion = PALVERSION;
-
- red = green = blue = 0;
-
- /* Generate 256 (= 8*8*4) RGB combinations to fill the palette
- * entries.
- */
- for (i = 0; i < pPal->palNumEntries; i++)
- {
- pPal->palPalEntry[i].peRed = red;
- pPal->palPalEntry[i].peGreen = green;
- pPal->palPalEntry[i].peBlue = blue;
- pPal->palPalEntry[i].peFlags = (BYTE)0;
-
- if (!(red += 32))
- if (!(green += 32))
- blue += 64;
- }
- hpal = CreatePalette(pPal);
- LocalFree((HANDLE)pPal);
- }
- return hpal;
- }
-
- /****************************************************************************
- * *
- * 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)GlobalLock(hbi));
- GlobalUnlock(hbi);
- return hpal;
- }
-
- /****************************************************************************
- * *
- * FUNCTION : ReadDibBitmapInfo(int fh) *
- * *
- * 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 fh)
- {
- DWORD off;
- HANDLE hbi = NULL;
- INT size;
- INT i;
- WORD nNumColors;
-
- RGBQUAD FAR *pRgb;
- BITMAPINFOHEADER bi;
- BITMAPCOREHEADER bc;
- LPBITMAPINFOHEADER lpbi;
- BITMAPFILEHEADER bf;
- DWORD dwWidth = 0;
- DWORD dwHeight = 0;
- WORD wPlanes, wBitCount;
-
- if (fh == -1)
- return NULL;
- #ifdef FIXDWORDALIGNMENT
- /* Reset file pointer and read file header */
- off = _llseek(fh, 0L, (UINT)SEEK_CUR);
- if ((SIZEOF_BITMAPFILEHEADER_PACKED) != _lread(fh, (LPSTR)&bf, (UINT)sizeof (SIZEOF_BITMAPFILEHEADER_PACKED)))
- return FALSE;
- #else
- ReadBitMapFileHeaderandConvertToDwordAlign(fh, &bf, &off);
- /* at this point we have read the file into bf*/
- #endif
-
- /* Do we have a RC HEADER? */
- if (!ISDIB (bf.bfType))
- {
- bf.bfOffBits = 0L;
- SetFilePointer((HANDLE)fh, off, NULL, FILE_BEGIN); /*seek back to beginning of file*/
- }
- if (!ReadFile((HANDLE)fh, (LPSTR)&bi, (UINT)sizeof(bi), &dwWidth, NULL) ||
- sizeof (bi) != dwWidth)
- return FALSE;
-
- nNumColors = DibNumColors (&bi);
-
- /* 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)bi.biSize)
- {
- case sizeof (BITMAPINFOHEADER):
- break;
-
- case sizeof (BITMAPCOREHEADER):
- bc = *(BITMAPCOREHEADER*)&bi;
-
- dwWidth = (DWORD)bc.bcWidth;
- dwHeight = (DWORD)bc.bcHeight;
- wPlanes = bc.bcPlanes;
- wBitCount = bc.bcBitCount;
-
- bi.biSize = sizeof(BITMAPINFOHEADER);
- bi.biWidth = dwWidth;
- bi.biHeight = dwHeight;
- bi.biPlanes = wPlanes;
- bi.biBitCount = wBitCount;
-
- bi.biCompression = BI_RGB;
- bi.biSizeImage = 0;
- bi.biXPelsPerMeter = 0;
- bi.biYPelsPerMeter = 0;
- bi.biClrUsed = nNumColors;
- bi.biClrImportant = nNumColors;
-
- _llseek(fh, (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 (bi.biSizeImage == 0)
- {
- bi.biSizeImage = WIDTHBYTES ((DWORD)bi.biWidth * bi.biBitCount)
- * bi.biHeight;
- }
- if (bi.biClrUsed == 0)
- bi.biClrUsed = DibNumColors(&bi);
-
- /* Allocate for the BITMAPINFO structure and the color table. */
- hbi = GlobalAlloc (GHND, (LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
- if (!hbi)
- return NULL;
- lpbi = (LPBITMAPINFOHEADER)GlobalLock (hbi);
- *lpbi = bi;
-
- /* Get a pointer to the color table */
- pRgb = (RGBQUAD FAR *)((LPSTR)lpbi + bi.biSize);
- if (nNumColors)
- {
- DWORD bytesRead;
-
- if (size == sizeof(BITMAPCOREHEADER))
- {
- /* Convert a old color table (3 byte RGBTRIPLEs) to a new
- * color table (4 byte RGBQUADs)
- */
- ReadFile((HANDLE)fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBTRIPLE), &bytesRead, NULL);
-
- for (i = nNumColors - 1; i >= 0; i--)
- {
- RGBQUAD rgb;
-
- rgb.rgbRed = ((RGBTRIPLE FAR *)pRgb)[i].rgbtRed;
- rgb.rgbBlue = ((RGBTRIPLE FAR *)pRgb)[i].rgbtBlue;
- rgb.rgbGreen = ((RGBTRIPLE FAR *)pRgb)[i].rgbtGreen;
- rgb.rgbReserved = (BYTE)0;
-
- pRgb[i] = rgb;
- }
- }
- else
- ReadFile((HANDLE)fh, (LPSTR)pRgb, (UINT)nNumColors * sizeof(RGBQUAD), &bytesRead, NULL);
- }
-
- if (bf.bfOffBits != 0L)
- {
- SetFilePointer((HANDLE)fh, off + bf.bfOffBits, NULL, FILE_BEGIN);
- }
- GlobalUnlock(hbi);
- return hbi;
- }
-
- /****************************************************************************
- * *
- * 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 (WORD)(NumColors * sizeof(RGBTRIPLE));
- else
- return (WORD)(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 : 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 = (LPBITMAPINFOHEADER)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,
- (LPBYTE)lpbi + lpbi->biSize + PaletteSize(lpbi), //cast changed for C++
- (LPBITMAPINFO)lpbi,
- DIB_RGB_COLORS );
-
- if (hpal)
- SelectPalette(hdc,hpalT,FALSE);
-
- ReleaseDC(NULL,hdc);
- GlobalUnlock(hdib);
-
- EndWait();
-
- return hbm;
- }
-
- /****************************************************************************
- * *
- * FUNCTION : ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf)
- * *
- * PURPOSE : read file header (which is packed) and convert into unpacked BITMAPFILEHEADER strucutre
- * *
- * RETURNS : VOID
- * *
- ****************************************************************************/
-
- VOID ReadBitMapFileHeaderandConvertToDwordAlign(HFILE fh, LPBITMAPFILEHEADER pbf, LPDWORD lpdwoff)
- {
- DWORD off;
-
- off = SetFilePointer((HANDLE)fh, 0L, NULL, FILE_CURRENT);
- *lpdwoff = off;
-
- /* BITMAPFILEHEADER STRUCUTURE is as follows
- * BITMAPFILEHEADER
- * WORD bfType
- > .... < add WORD if packed here!
- * DWORD bfSize
- * WORD bfReserved1
- * WORD bfReserved2
- * DWORD bfOffBits
- * This is the packed format, unpacked adds a WORD after bfType
- */
-
- /* read in bfType*/
- ReadFile((HANDLE)fh, (LPSTR) &pbf->bfType, sizeof(WORD), &off, NULL);
- /* read in last 3 dwords*/
- ReadFile((HANDLE)fh, (LPSTR) &pbf->bfSize, sizeof(DWORD) * 3, &off, NULL);
- }
-