home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
World of Shareware - Software Farm 2
/
wosw_2.zip
/
wosw_2
/
CPROG
/
WBITMAP.ZIP
/
BMMANIP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-11-12
|
14KB
|
650 lines
/*
** $id: ssvcid bmmanip.c 1.1 11/12/91 8:38 am$
** This file contains various functions for manipulating bitmaps.
**
** (C) 1991 Larry Widing
*/
#include <windows.h>
#include <dos.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.
**
** Modification History:
** 09/12/91 LCW Created
*/
int
DIBitmapColors(BITMAPINFO FAR *bmi)
{
if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
/*
** OS/2 PM Bitmap, use bcBitCount field to determine colors
*/
switch (((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcBitCount)
{
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 */
}
}
else
{
/*
** Windows bitmap
*/
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 */
}
}
else
{
return (int)bmi->bmiHeader.biClrUsed;
}
}
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.
**
** Modification History:
** 09/12/91 LCW Created
*/
LPSTR
DIBitmapBits(BITMAPINFO FAR *bmi)
{
LPSTR bits;
int colors = DIBitmapColors(bmi);
bits = ((LPSTR)bmi) + bmi->bmiHeader.biSize;
if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
bits += colors * sizeof(RGBTRIPLE);
}
else
{
bits += colors * sizeof(RGBQUAD);
}
return bits;
}
/*
** BOOL TRUE if successful, FALSE otherwise
** DrawBitmap(
** HDC hdc, Handle of target device context
** int x, X coordinate to draw bitmap at
** int y, Y coordinate to draw bitmap at
** HBITMAP hbm); Handle of bitmap to draw
**
** This function draws the specified bitmap onto the target device
** context at the given coordinates. If an error occurs, the FALSE will
** be returned to the caller, otherwise TRUE will be returned if the
** bitmap was drawn without a problem.
**
** Modification History:
** 09/09/91 LCW Created
*/
BOOL
DrawBitmap(HDC hdc, int x, int y, HBITMAP hbm)
{
HDC hdcMem; /* Handle of memory context to use in drawing bitmap */
HBITMAP oldBm;
POINT ptSize, ptOrg;
BITMAP bm;
hdcMem = CreateCompatibleDC(hdc);
if (hdcMem != (HDC)NULL)
{
/*
** Select bitmap to be draw into memory context
*/
oldBm = SelectObject(hdcMem, hbm);
/*
** Set the mapping mode for the memory context to match the
** target device context.
*/
SetMapMode(hdcMem, GetMapMode(hdc));
/*
** Get the details of the bitmap being drawn
*/
GetObject(hbm, sizeof(BITMAP), (LPSTR)&bm);
/*
** Adjust height and width for mapping mode
*/
ptSize.x = bm.bmWidth;
ptSize.y = bm.bmHeight;
DPtoLP(hdc, (LPPOINT)&ptSize, 1);
/*
** Adjust origin for mapping mode
*/
ptOrg.x = 0;
ptOrg.y = 0;
DPtoLP(hdcMem, (LPPOINT)&ptOrg, 1);
/*
** Draw the bitmap
*/
BitBlt(hdc, x, y, ptSize.x, ptSize.y, hdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
/*
** Clean up
*/
SelectObject(hdcMem, oldBm);
DeleteDC(hdcMem);
return TRUE;
}
return FALSE;
}
/*
** BOOL TRUE if successful, FALSE if an error occurred
** DrawDIBitmap(
** HDC hdc, Handle of target device context
** int x, X coordinate to draw bitmap at
** int y, Y coordinate to draw bitmap at
** HANDLE hbm); Handle of memory block holding packed DIB
**
** This function draws the specified DI bitmap onto the target device
** context at the given coordinates. If an error occurs, the FALSE will
** be returned to the caller, otherwise TRUE will be returned if the DI
** bitmap was drawn without a problem.
**
** Modification History:
** 09/09/91 LCW Created
*/
BOOL
DrawDIBitmap(HDC hdc, int x, int y, HANDLE hbm)
{
int width, height;
BITMAPINFO FAR *bmi;
LPSTR bits;
bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
if (bmi != NULL)
{
bits = DIBitmapBits(bmi);
if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
{
width = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcWidth;
height = ((BITMAPCOREINFO FAR *)bmi)->bmciHeader.bcHeight;
}
else
{
width = (WORD)bmi->bmiHeader.biWidth;
height = (WORD)bmi->bmiHeader.biHeight;
}
SetDIBitsToDevice(hdc, x, y, width, height, 0, 0, 0, height, bits,
bmi, DIB_RGB_COLORS);
GlobalUnlock(hbm);
return TRUE;
}
return FALSE;
}
/*
** 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.
**
** Modification History:
** 09/09/91 LCW Created
*/
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;
}
/*
** HANDLE Handle of newly created DI Bitmap
** CopyDIBitmap(HANDLE hbm); Handle of DI Bitmap to copy
**
** This function will create a dupilicate of the passed packed DI Bitmap,
** returning a handle to the newly created memory block. If the copy could
** not be performed, then NULL is returned.
**
** Modification History:
** 09/09/91 LCW Created
*/
HANDLE
CopyDIBitmap(HANDLE hbm)
{
DWORD size;
HANDLE hbmNew;
size = GlobalSize(hbm);
if (size != 0)
{
hbmNew = GlobalAlloc(GMEM_MOVEABLE, size);
if (hbmNew != (HANDLE)NULL)
{
BYTE HUGE *src;
BYTE HUGE *dest;
src = (BYTE HUGE *)GlobalLock(hbm);
if (src != NULL)
{
dest = (BYTE HUGE *)GlobalLock(hbmNew);
if (dest != NULL)
{
while (size != 0)
{
*dest = *src;
#if defined(__TSC__)
if (FP_OFF(dest) == 0xffff)
{
dest = MK_FP(FP_SEG(dest) + 8, 0);
}
else
++dest;
if (FP_OFF(src) == 0xffff)
{
src = MK_FP(FP_SEG(src) + 8, 0);
}
else
++src;
#else
++dest;
++src;
#endif
--size;
}
GlobalUnlock(hbmNew);
}
else
{
GlobalFree(hbmNew);
hbmNew = (HANDLE)NULL;
}
GlobalUnlock(hbm);
}
}
}
return hbmNew;
}
/*
** HBITMAP handle of logical bitmap created, or NULL
** DibToBitmap(HANDLE hbm); handle of packed DIB to convert
**
** This function converts a packed DIB into a logical bitmap, returning
** a handle to the resulting bitmap.
**
** Modification History:
** 10/16/91 LCW Created
*/
HBITMAP
DibToBitmap(HANDLE hbm)
{
HBITMAP bm = (HBITMAP)NULL;
HDC hdc;
BITMAPINFO FAR *bmi;
LPSTR bits;
bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
if (bmi != NULL)
{
hdc = GetDC(MainWindow);
if (hdc != (HDC)NULL)
{
bits = DIBitmapBits(bmi);
bm = CreateDIBitmap(hdc, (LPBITMAPINFOHEADER)bmi, CBM_INIT,
bits, bmi, DIB_RGB_COLORS);
ReleaseDC(MainWindow, hdc);
}
GlobalUnlock(hbm);
}
return bm;
}
/*
** HANDLE 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 packed Device
** Independant Bitmap, using the mode parameter to determine if the resulting
** DIB should be run length encoded (mode == 1), a OS/2 compatible DIB
** (mode == 2) or a unencoded DIB (mode == 0).
**
** Modification History:
** 09/07/91 LCW Created
*/
HANDLE
BitmapToDIB(HBITMAP hbm, int mode)
{
int i;
HDC hdc;
HANDLE result = (HANDLE)NULL;
BITMAPINFO *bmi;
BITMAPCOREINFO *bmci;
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;
if (mode == 2)
{
/*
** Building a OS/2 bitmap - allocate a LPBITMAPCOREINFO record
*/
hdrSize = sizeof(BITMAPCOREHEADER);
switch (bitsPerPixel)
{
case 1:
hdrSize += 2 * sizeof(RGBTRIPLE);
break;
case 3:
++bitsPerPixel;
case 4:
hdrSize += 16 * sizeof(RGBTRIPLE);
break;
case 8:
hdrSize += 256 * sizeof(RGBTRIPLE);
break;
}
bmci = (BITMAPCOREINFO *)malloc(hdrSize);
bmci->bmciHeader.bcSize = sizeof(BITMAPCOREHEADER);
bmci->bmciHeader.bcWidth = bm.bmWidth;
bmci->bmciHeader.bcHeight = bm.bmHeight;
bmci->bmciHeader.bcPlanes = 1;
bmci->bmciHeader.bcBitCount = bitsPerPixel;
bmi = NULL;
}
else
{
/*
** 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;
if (mode == 0 || (bitsPerPixel != 8 && bitsPerPixel != 4))
bmi->bmiHeader.biCompression = BI_RGB;
else if (bitsPerPixel == 8)
bmi->bmiHeader.biCompression = BI_RLE8;
else
bmi->bmiHeader.biCompression = BI_RLE4;
bmi->bmiHeader.biSizeImage = 0;
bmi->bmiHeader.biXPelsPerMeter = 0;
bmi->bmiHeader.biYPelsPerMeter = 0;
bmi->bmiHeader.biClrUsed = 0;
bmi->bmiHeader.biClrImportant = 0;
bmci = NULL;
}
/*
** Get a DC to use
*/
hdc = GetDC(MainWindow);
if (hdc != (HDC)NULL)
{
/*
** Allocate storage needed
*/
if (bmi == NULL)
{
DWORD bitSize = (DWORD)bm.bmWidth * (DWORD)bitsPerPixel / 8;
if ((bitSize & 3) != 0)
bitSize += 4 - (bitSize & 3);
result = GlobalAlloc(GMEM_MOVEABLE | GMEM_ZEROINIT,
(long)hdrSize + (DWORD)bm.bmHeight * bitSize);
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)bmci;
}
}
}
else
{
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);
if (bmci != NULL)
free(bmci);
return result;
}
/*
** int TRUE if hbm points to a OS/2 DIB
** DibIsOs2(HANDLE hbm); handle of packed DIB to check
**
** This function checks the passd packed DIB to determine if it is a
** OS/2 compatible DIB.
**
** Modification History:
** 10/16/91 LCW Created
*/
int
DibIsOs2(HANDLE hbm)
{
int rc = FALSE;
BITMAPINFO FAR *bmi;
bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
if (bmi != NULL)
{
if (bmi->bmiHeader.biSize == sizeof(BITMAPCOREHEADER))
rc = TRUE;
GlobalUnlock(hbm);
}
return rc;
}
/*
** int TRUE if hbm points to a compressed DIB
** DibIsCompressed(HANDLE hbm); handle of packed DIB to check
**
** This function checks the passed packed DIB to determine if it is
** a compressed windows DIB or not.
**
** Modification History:
** 10/16/91 LCW Created
*/
int
DibIsCompressed(HANDLE hbm)
{
int rc = FALSE;
BITMAPINFO FAR *bmi;
bmi = (BITMAPINFO FAR *)GlobalLock(hbm);
if (bmi != NULL)
{
if (bmi->bmiHeader.biSize != sizeof(BITMAPCOREHEADER)
&& bmi->bmiHeader.biCompression != BI_RGB)
rc = TRUE;
GlobalUnlock(hbm);
}
return rc;
}
/*
** Modification History
** --------------------
** $lgb$
** 10/15/91 Larry Widing Initial version for Win Tech Journal Article.
** 11/12/91 Larry Widing Added DibIsOs2() and DibIsCompressed()
** fucntions.
** $lge$
*/