home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $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$
- */
-