Fonctions diverses
#include <windows.h>
#include <malloc.h>
#include "bitmaps.h"
/* int number of color entries in header
** DIBitmapColors(BITMAPINFO FAR *bmi); pointer to bitmap header
**
** This function returns the number of colors in the color table of
** the specified Device-Independant Bitmap. */
int DIBitmapColors(BITMAPINFO FAR *bmi)
{
if (bmi->bmiHeader.biClrUsed == 0)
{ /* Maximum number of entries */
switch (bmi->bmiHeader.biBitCount)
{
case 1: return 2; /* Monochrome bitmap -> 2 colors */
case 4: return 16; /* 4-bit image -> 16 colors */
case 8: return 256; /* 8-bit image -> 256 colors */
case 24: return 0; /* 24-bt image -> 0 colors in color table */
}
}
return 0;
}
/* LPSTR pointer to bitmap bits
** DIBitmapBits(BITMAPINFO FAR *bmi); pointer to bitmap header
**
** This function returns a pointer to the bits in a packed Device-
** Independant Bitmap. */
LPSTR DIBitmapBits(BITMAPINFO FAR *bmi)
{
LPSTR bits;
int colors = DIBitmapColors(bmi);
bits = ((LPSTR)bmi) + (unsigned int)bmi->bmiHeader.biSize;
if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
bits += colors * sizeof(RGBTRIPLE);
else
bits += colors * sizeof(RGBQUAD);
return bits;
}
/* HBITMAP Handle of duplicate if it could be created
** CopyBitmap(HBITMAP hbm); Handle of bitmap to copy
**
** This function will create a duplicate of the passed bitmap, returning
** the handle of the new bitmap if successful, and NULL if it could not
** perform the copy. */
HBITMAP CopyBitmap(HBITMAP hbm)
{
HBITMAP hbmNew = (HBITMAP)NULL;
HBITMAP oldBm;
HDC hdcMem;
BITMAP bm;
GetObject(hbm, sizeof(bm), (LPSTR)&bm);
hdcMem = CreateCompatibleDC(NULL);
if (hdcMem != (HDC)NULL)
{
oldBm = SelectObject(hdcMem, hbm);
hbmNew = CreateCompatibleBitmap(hdcMem, bm.bmWidth, bm.bmHeight);
if (hbmNew != (HBITMAP)NULL)
{
SelectObject(hdcMem, hbmNew);
DrawBitmap(hdcMem, 0, 0, hbm);
}
SelectObject(hdcMem, oldBm);
DeleteDC(hdcMem);
}
return hbmNew;
}
/* HDIB handle of new packed DIB (NULL if an error occurred)
** BitmapToDIB(
** HBITMAP hbm, handle of logical bitmap to convert
** int mode); mode to use when converting
**
** This function will convert a logical bitmap into a unencoded packed Device
** Independant Bitmap */
HDIB BitmapToDIB(HBITMAP hbm)
{
int i;
HDC hdc;
HDIB result = (HDIB)NULL;
BITMAPINFO *bmi;
LPSTR ptr, sptr, dptr;
int hdrSize;
int bitsPerPixel;
BITMAP bm;
/* Get bitmap information */
GetObject(hbm, sizeof(bm), (LPSTR)&bm);
if (bm.bmPlanes == 1)
bitsPerPixel = bm.bmBitsPixel;
else
bitsPerPixel = bm.bmPlanes;
/* Building a Windows compatible Bitmap */
hdrSize = sizeof(BITMAPINFOHEADER);
switch (bitsPerPixel)
{
case 1:
hdrSize += 2 * sizeof(RGBQUAD);
break;
case 3:
++ bitsPerPixel;
case 4:
hdrSize += 16 * sizeof(RGBQUAD);
break;
case 8:
hdrSize += 256 * sizeof(RGBQUAD);
break;
}
bmi = (BITMAPINFO *)malloc(hdrSize);
bmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
bmi->bmiHeader.biWidth = bm.bmWidth;
bmi->bmiHeader.biHeight = bm.bmHeight;
bmi->bmiHeader.biPlanes = 1;
bmi->bmiHeader.biBitCount = bitsPerPixel;
bmi->bmiHeader.biCompression = BI_RGB;
bmi->bmiHeader.biSizeImage = 0;
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
/* Get a DC to use */
hdc = GetDC(MainWindow);
if (hdc != (HDC)NULL)
{
if (GetDIBits(hdc, hbm, 0, bm.bmHeight, NULL, (LPBITMAPINFO)bmi, DIB_RGB_COLORS))
{
result = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
(long)hdrSize + bmi->bmiHeader.biSizeImage);
if (result != (HANDLE)NULL)
{
ptr = (LPSTR)GlobalLock(result);
if (ptr == NULL)
{
GlobalFree(result);
result = (HANDLE)NULL;
ErrorBox("BitmapToDIB(): Unable to lock DIB memory" );
}
else
sptr = (LPSTR)bmi;
}
}
if (result)
{ /* Copy header */
dptr = ptr;
for (i = 0 ; i < hdrSize ; ++ i) *dptr ++ = *sptr ++;
/* Get the bits */
if (! GetDIBits(hdc, hbm, 0, bm.bmHeight, dptr, (LPBITMAPINFO)ptr, DIB_RGB_COLORS))
{
GlobalUnlock(result);
GlobalFree(result);
result = (HANDLE)NULL;
}
else
GlobalUnlock(result);
}
ReleaseDC(MainWindow, hdc);
}
else
ErrorBox("BitmapToDIB(): Unable to get DC from main window" );
if (bmi != NULL) free(bmi);
return result;
}