home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD-ROM User 1995 January
/
CDuser6Jan95.iso
/
WING
/
DIB.CP_
/
DIB.CP
Wrap
Text File
|
1994-06-24
|
25KB
|
986 lines
/*----------------------------------------------------------------------------*\
| Routines for dealing with Device independent bitmaps |
\*----------------------------------------------------------------------------*/
#include <windows.h>
#include <windowsx.h>
#include "dib.hpp"
#if defined(WIN32) || defined(_WIN32)
#include <memory.h> // for _fmemcpy()
#define _huge
#define hmemcpy memcpy
#endif
#define BFT_ICON 0x4349 /* 'IC' */
#define BFT_BITMAP 0x4d42 /* 'BM' */
#define BFT_CURSOR 0x5450 /* 'PT' */
/* flags for _lseek */
#define SEEK_CUR 1
#define SEEK_END 2
#define SEEK_SET 0
/*
* Open a DIB file and return a MEMORY DIB, a memory handle containing..
*
* BITMAP INFO bi
* palette data
* bits....
*
*/
PDIB DibOpenFile(LPSTR szFile)
{
HFILE fh;
DWORD dwLen;
DWORD dwBits;
PDIB pdib;
LPVOID p;
OFSTRUCT of;
#if defined(WIN32) || defined(_WIN32)
#define GetCurrentInstance() GetModuleHandle(NULL)
#else
#define GetCurrentInstance() (HINSTANCE)SELECTOROF((LPVOID)&of)
#endif
fh = OpenFile(szFile, &of, OF_READ);
if (fh == -1)
{
HRSRC h;
h = FindResource(GetCurrentInstance(), szFile, RT_BITMAP);
#if defined(WIN32) || defined(_WIN32)
//!!! can we call GlobalFree() on this? is it the right format.
//!!! can we write to this resource?
if (h)
return (PDIB)LockResource(LoadResource(GetCurrentInstance(), h));
#else
if (h)
fh = AccessResource(GetCurrentInstance(), h);
#endif
}
if (fh == -1)
return NULL;
pdib = DibReadBitmapInfo(fh);
if (!pdib)
return NULL;
/* How much memory do we need to hold the DIB */
dwBits = pdib->biSizeImage;
dwLen = pdib->biSize + DibPaletteSize(pdib) + dwBits;
/* Can we get more memory? */
p = GlobalReAllocPtr(pdib,dwLen,0);
if (!p)
{
GlobalFreePtr(pdib);
pdib = NULL;
}
else
{
pdib = (PDIB)p;
}
if (pdib)
{
/* read in the bits */
_hread(fh, (LPBYTE)pdib + (UINT)pdib->biSize + DibPaletteSize(pdib), dwBits);
}
_lclose(fh);
return pdib;
}
/*
* Write a global handle in CF_DIB format to a file.
*
*/
BOOL DibWriteFile(PDIB pdib, LPSTR szFile)
{
BITMAPFILEHEADER hdr;
HFILE fh;
OFSTRUCT of;
DWORD dwSize;
if (!pdib)
return FALSE;
fh = OpenFile(szFile,&of,OF_CREATE|OF_READWRITE);
if (fh == -1)
return FALSE;
dwSize = DibSize(pdib);
hdr.bfType = BFT_BITMAP;
hdr.bfSize = dwSize + sizeof(BITMAPFILEHEADER);
hdr.bfReserved1 = 0;
hdr.bfReserved2 = 0;
hdr.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + pdib->biSize +
DibPaletteSize(pdib);
_lwrite(fh,(LPCSTR)(LPVOID)&hdr,sizeof(BITMAPFILEHEADER));
_hwrite(fh,(LPCSTR)(LPVOID)pdib,dwSize);
_lclose(fh);
return TRUE;
}
/*
* CreateBIPalette()
*
* Given a Pointer to a BITMAPINFO struct will create a
* a GDI palette object from the color table.
*
*/
HPALETTE DibCreatePalette(PDIB pdib)
{
LOGPALETTE *pPal;
HPALETTE hpal = NULL;
int nNumColors;
int i;
RGBQUAD FAR * pRgb;
if (!pdib)
return NULL;
nNumColors = DibNumColors(pdib);
if (nNumColors == 3 && DibCompression(pdib) == BI_BITFIELDS)
nNumColors = 0;
if (nNumColors > 0)
{
pRgb = DibColors(pdib);
pPal = (LOGPALETTE*)LocalAlloc(LPTR,sizeof(LOGPALETTE) + nNumColors * sizeof(PALETTEENTRY));
if (!pPal)
goto exit;
pPal->palNumEntries = nNumColors;
pPal->palVersion = 0x300;
for (i = 0; i < nNumColors; i++)
{
pPal->palPalEntry[i].peRed = pRgb->rgbRed;
pPal->palPalEntry[i].peGreen = pRgb->rgbGreen;
pPal->palPalEntry[i].peBlue = pRgb->rgbBlue;
pPal->palPalEntry[i].peFlags = (BYTE)0;
pRgb++;
}
hpal = CreatePalette(pPal);
LocalFree((HLOCAL)pPal);
}
else
{
#if defined(WIN32) || defined(_WIN32)
HDC hdc = GetDC(NULL);
hpal = CreateHalftonePalette(hdc);
ReleaseDC(NULL, hdc);
#endif
}
exit:
return hpal;
}
/*
* ReadDibBitmapInfo()
*
* Will read a file in DIB format and return a global HANDLE to it's
* BITMAPINFO. This function will work with both "old" and "new"
* bitmap formats, but will allways return a "new" BITMAPINFO
*
*/
PDIB DibReadBitmapInfo(HFILE fh)
{
DWORD off;
HANDLE hbi = NULL;
int size;
int i;
int nNumColors;
RGBQUAD FAR *pRgb;
BITMAPINFOHEADER bi;
BITMAPCOREHEADER bc;
BITMAPFILEHEADER bf;
PDIB pdib;
if (fh == -1)
return NULL;
off = _llseek(fh,0L,SEEK_CUR);
if (sizeof(bf) != _lread(fh,(LPSTR)&bf,sizeof(bf)))
return FALSE;
/*
* do we have a RC HEADER?
*/
if (bf.bfType != BFT_BITMAP)
{
bf.bfOffBits = 0L;
_llseek(fh,off,SEEK_SET);
}
if (sizeof(bi) != _lread(fh,(LPSTR)&bi,sizeof(bi)))
return FALSE;
/*
* what type of bitmap info is this?
*/
switch (size = (int)bi.biSize)
{
default:
case sizeof(BITMAPINFOHEADER):
break;
case sizeof(BITMAPCOREHEADER):
bc = *(BITMAPCOREHEADER*)&bi;
bi.biSize = sizeof(BITMAPINFOHEADER);
bi.biWidth = (DWORD)bc.bcWidth;
bi.biHeight = (DWORD)bc.bcHeight;
bi.biPlanes = (UINT)bc.bcPlanes;
bi.biBitCount = (UINT)bc.bcBitCount;
bi.biCompression = BI_RGB;
bi.biSizeImage = 0;
bi.biXPelsPerMeter = 0;
bi.biYPelsPerMeter = 0;
bi.biClrUsed = 0;
bi.biClrImportant = 0;
_llseek(fh,(LONG)sizeof(BITMAPCOREHEADER)-sizeof(BITMAPINFOHEADER),SEEK_CUR);
break;
}
nNumColors = DibNumColors(&bi);
#if 0
if (bi.biSizeImage == 0)
bi.biSizeImage = DibSizeImage(&bi);
if (bi.biClrUsed == 0)
bi.biClrUsed = DibNumColors(&bi);
#else
FixBitmapInfo(&bi);
#endif
pdib = (PDIB)GlobalAllocPtr(GMEM_MOVEABLE,(LONG)bi.biSize + nNumColors * sizeof(RGBQUAD));
if (!pdib)
return NULL;
*pdib = bi;
pRgb = DibColors(pdib);
if (nNumColors)
{
if (size == sizeof(BITMAPCOREHEADER))
{
/*
* convert a old color table (3 byte entries) to a new
* color table (4 byte entries)
*/
_lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBTRIPLE));
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
{
_lread(fh,(LPVOID)pRgb,nNumColors * sizeof(RGBQUAD));
}
}
if (bf.bfOffBits != 0L)
_llseek(fh,off + bf.bfOffBits,SEEK_SET);
return pdib;
}
/*
* DibFromBitmap()
*
* Will create a global memory block in DIB format that represents the DDB
* passed in
*
*/
PDIB DibFromBitmap(HBITMAP hbm, DWORD biStyle, UINT biBits, HPA