Files
Work/mdiwin/BITMAP.CPP
2024-08-07 09:16:27 -04:00

252 lines
8.3 KiB
C++
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#include <mdiwin/bitmap.hpp>
#define MaxBlock 64000L
Bitmap::Bitmap(void)
: mhFile(HFILE_ERROR), mMaxColors(0), mhPalette(0), mhGlobalImage(0),
mhGlobalBitmapInfo(0), mCurrentMode(Idle), mSizeImage(0),
mBlockSize(MaxBlock)
{
}
Bitmap::Bitmap(String pathFileName)
: mhFile(HFILE_ERROR), mMaxColors(0), mhPalette(0), mhGlobalImage(0),
mhGlobalBitmapInfo(0), mCurrentMode(Read), mSizeImage(0),
mBlockSize(MaxBlock)
{
processBitmap(pathFileName);
}
Bitmap::Bitmap(String pathFileName,HGLOBAL hGlobalImage,HGLOBAL hGlobalBitmapInfo)
: mhFile(HFILE_ERROR), mMaxColors(0), mhPalette(0), mhGlobalImage(0),
mhGlobalBitmapInfo(0), mCurrentMode(Write), mSizeImage(0),
mBlockSize(MaxBlock)
{
DWORD sizeBitmapInfo;
BITMAPINFO FAR *lpSourceBitmapInfo;
OFSTRUCT ofStruct;
UHUGE *lpSourceImage;
if(!hGlobalImage||!hGlobalBitmapInfo)return;
mFileName=pathFileName;
if(HFILE_ERROR==(mhFile=::OpenFile(pathFileName,&ofStruct,OF_WRITE|OF_CREATE)))return;
#if defined(__FLAT__)
sizeBitmapInfo=::GlobalSize(hGlobalBitmapInfo);
#else
sizeBitmapInfo=::GetSelectorLimit((UINT)hGlobalBitmapInfo)+1;
#endif
mhGlobalBitmapInfo=::GlobalAlloc(GMEM_FIXED,sizeBitmapInfo);
mpBitmapInfo=(BITMAPINFO FAR *)::GlobalLock(mhGlobalBitmapInfo);
lpSourceBitmapInfo=(BITMAPINFO FAR *)::GlobalLock(hGlobalBitmapInfo);
copyBits((UHUGE *)mpBitmapInfo,(UHUGE *)lpSourceBitmapInfo,sizeBitmapInfo);
::GlobalUnlock(hGlobalBitmapInfo);
mSizeImage=((((mpBitmapInfo->bmiHeader.biWidth*
mpBitmapInfo->bmiHeader.biBitCount)+31)&~31)>>3)*
mpBitmapInfo->bmiHeader.biHeight;
mhGlobalImage=::GlobalAlloc(GMEM_FIXED,mSizeImage);
mpImage=(UHUGE *)::GlobalLock(mhGlobalImage);
lpSourceImage=(UHUGE *)::GlobalLock(hGlobalImage);
copyBits(mpImage,lpSourceImage,mSizeImage);
::GlobalUnlock(hGlobalImage);
if(!(mMaxColors=(WORD)mpBitmapInfo->bmiHeader.biClrUsed))
mMaxColors=1 << mpBitmapInfo->bmiHeader.biBitCount;
}
Bitmap::~Bitmap()
{
cleanup();
}
WORD Bitmap::operator=(String pathFileName)
{
int returnCode;
cleanup();
mCurrentMode=Read;
returnCode=processBitmap(pathFileName);
::_lclose(mhFile);
mhFile=HFILE_ERROR;
return returnCode;
}
WORD Bitmap::processBitmap(String pathFileName)
{
OFSTRUCT ofStruct;
mFileName=pathFileName;
if(HFILE_ERROR==(mhFile=::OpenFile(pathFileName,&ofStruct,OF_READ)))return FALSE;
::_lread(mhFile,&mBitmapFileHeader,sizeof(BITMAPFILEHEADER));
if(Signature!=mBitmapFileHeader.bfType)
{
cleanup();
return FALSE;
}
createPalette();
decodeImage();
return TRUE;
}
WORD Bitmap::isValidBitmap(String pathFileName)const
{
HFILE hFile;
OFSTRUCT ofStruct;
BITMAPFILEHEADER bitmapFileHeader;
if(pathFileName.isNull())return FALSE;
if(HFILE_ERROR==(hFile=::OpenFile(pathFileName,&ofStruct,OF_READ)))return FALSE;
::_lread(hFile,&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
::_lclose(hFile);
if(Signature!=bitmapFileHeader.bfType)return FALSE;
return TRUE;
}
WORD Bitmap::setPalette(HPALETTE hPalette)
{
PALETTEENTRY FAR *lpPaletteEntry;
BITMAPINFOHEADER bitmapInfoHeader;
if(!isOkay()||!hPalette)return FALSE;
lpPaletteEntry=new PALETTEENTRY[MaxColors];
mMaxColors=::GetPaletteEntries(hPalette,0,MaxColors,(PALETTEENTRY FAR*)lpPaletteEntry);
::memcpy(&bitmapInfoHeader,mpBitmapInfo,sizeof(BITMAPINFOHEADER));
bitmapInfoHeader.biClrUsed=mMaxColors;
bitmapInfoHeader.biClrImportant=mMaxColors;
::GlobalUnlock(mhGlobalBitmapInfo);
::GlobalFree(mhGlobalBitmapInfo);
mhGlobalBitmapInfo=::GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*mMaxColors));
mpBitmapInfo=(BITMAPINFO FAR *)::GlobalLock(mhGlobalBitmapInfo);
::memcpy(mpBitmapInfo,&bitmapInfoHeader,sizeof(BITMAPINFOHEADER));
for(int i=0;i<mMaxColors;i++)
{
mpBitmapInfo->bmiColors[i].rgbRed=lpPaletteEntry[i].peRed;
mpBitmapInfo->bmiColors[i].rgbGreen=lpPaletteEntry[i].peGreen;
mpBitmapInfo->bmiColors[i].rgbBlue=lpPaletteEntry[i].peBlue;
}
delete lpPaletteEntry;
return TRUE;
}
void Bitmap::createPalette(void)
{
RGBQUAD FAR *pRGBQuad;
LOGPALETTE FAR *pLogicalPalette;
PALETTEENTRY FAR *pPaletteEntry;
BITMAPINFOHEADER bitmapInfoHeader;
HGLOBAL hGlobalPalette;
if(mhPalette)::DeleteObject(mhPalette);
::_lread(mhFile,&bitmapInfoHeader,sizeof(BITMAPINFOHEADER));
if(!(mMaxColors=(WORD)bitmapInfoHeader.biClrUsed))
mMaxColors=1 << bitmapInfoHeader.biBitCount;
mhGlobalBitmapInfo=::GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,
sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*mMaxColors));
mpBitmapInfo=(BITMAPINFO FAR *)::GlobalLock(mhGlobalBitmapInfo);
::memcpy(mpBitmapInfo,&bitmapInfoHeader,sizeof(BITMAPINFOHEADER));
hGlobalPalette=::GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,
sizeof(LOGPALETTE)+(mMaxColors*sizeof(PALETTEENTRY)));
pLogicalPalette=(LOGPALETTE FAR *)::GlobalLock(hGlobalPalette);
pLogicalPalette->palNumEntries=mMaxColors;
pLogicalPalette->palVersion=0x300;
for(int i=0;i<mMaxColors;i++)
{
pRGBQuad=(RGBQUAD FAR *)&mpBitmapInfo->bmiColors[i];
::_lread(mhFile,pRGBQuad,sizeof(RGBQUAD));
pPaletteEntry=(PALETTEENTRY FAR *)&pLogicalPalette->palPalEntry[i];
pPaletteEntry->peRed=pRGBQuad->rgbRed;
pPaletteEntry->peGreen=pRGBQuad->rgbGreen;
pPaletteEntry->peBlue=pRGBQuad->rgbBlue;
pPaletteEntry->peFlags=0;
}
mhPalette=::CreatePalette((LOGPALETTE FAR *)pLogicalPalette);
::GlobalUnlock(hGlobalPalette);
::GlobalFree(hGlobalPalette);
}
void Bitmap::decodeImage(void)
{
switch(mpBitmapInfo->bmiHeader.biCompression)
{
case BI_RGB :
mSizeImage=((((mpBitmapInfo->bmiHeader.biWidth*
mpBitmapInfo->bmiHeader.biBitCount)+31)&~31)>>3)*
mpBitmapInfo->bmiHeader.biHeight;
mhGlobalImage=::GlobalAlloc(GMEM_FIXED|GMEM_ZEROINIT,mSizeImage);
mpImage=(UHUGE*)::GlobalLock(mhGlobalImage);
::_llseek(mhFile,(mBitmapFileHeader.bfOffBits),0);
::_hread(mhFile,mpImage,mSizeImage);
break;
case BI_RLE4 :
cleanup();
::MessageBox(::GetFocus(),(LPSTR)"BI_RLE4 Is not implemented at this time.\nPlease try an uncompressed bitmap.",(LPSTR)"ERROR",MB_ICONEXCLAMATION);
break;
case BI_RLE8 :
cleanup();
::MessageBox(::GetFocus(),(LPSTR)"BI_RLE8 Is not implemented at this time.\nPlease try an uncompressed bitmap.",(LPSTR)"ERROR",MB_ICONEXCLAMATION);
break;
}
}
WORD Bitmap::displayBitmap(HWND hDisplayWindow,HDC hDC,int isActive,int conforming)const
{
RECT rect;
HPALETTE hOldPalette;
WORD width;
WORD height;
int suppliedDC;
if(!isOkay()||!hDisplayWindow)return FALSE;
if(Read!=mCurrentMode)return FALSE;
width=(WORD)mpBitmapInfo->bmiHeader.biWidth;
height=(WORD)mpBitmapInfo->bmiHeader.biHeight;
::GetClientRect(hDisplayWindow,(RECT FAR *)&rect);
if(!hDC){suppliedDC=FALSE;hDC=::GetDC(hDisplayWindow);}
if(isActive)hOldPalette=::SelectPalette(hDC,mhPalette,FALSE);
else hOldPalette=::SelectPalette(hDC,mhPalette,TRUE);
::RealizePalette(hDC);
if(conforming)
::StretchDIBits(hDC,0,0,rect.right,rect.bottom,0,0,width,height,mpImage,(BITMAPINFO *)mpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
else
::StretchDIBits(hDC,0,0,width,height,0,0,width,height,mpImage,(BITMAPINFO *)mpBitmapInfo,DIB_RGB_COLORS,SRCCOPY);
if(isActive)::SelectPalette(hDC,hOldPalette,FALSE);
else ::SelectPalette(hDC,hOldPalette,TRUE);
if(!suppliedDC)::ReleaseDC(hDisplayWindow,hDC);
return TRUE;
}
WORD Bitmap::saveBitmap(void)const
{
BITMAPFILEHEADER bitmapFileHeader;
if(!isOkay())return FALSE;
if(Write!=mCurrentMode)return FALSE;
::memset(&bitmapFileHeader,0,sizeof(BITMAPFILEHEADER));
bitmapFileHeader.bfType=Signature;
bitmapFileHeader.bfSize=sizeof(BITMAPFILEHEADER)+
sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*mMaxColors)+mSizeImage;
bitmapFileHeader.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*mMaxColors);
::_lwrite(mhFile,(char*)&bitmapFileHeader,sizeof(BITMAPFILEHEADER));
::_lwrite(mhFile,(char*)mpBitmapInfo,sizeof(BITMAPINFOHEADER)+(sizeof(RGBQUAD)*mMaxColors));
::_hwrite(mhFile,(char*)mpImage,mSizeImage);
return FALSE;
}
void Bitmap::cleanup(void)
{
if(HFILE_ERROR!=mhFile)
{::_lclose(mhFile);mhFile=HFILE_ERROR;}
if(mhPalette)
{::DeleteObject(mhPalette);mhPalette=0;}
if(mhGlobalImage)
{while(::GlobalUnlock(mhGlobalImage));::GlobalFree(mhGlobalImage);
mhGlobalImage=0;}
if(mhGlobalBitmapInfo)
{while(::GlobalUnlock(mhGlobalBitmapInfo));
::GlobalFree(mhGlobalBitmapInfo);mhGlobalBitmapInfo=0;}
}
void Bitmap::copyBits(UHUGE *destination,UHUGE *source,unsigned long length)const
{
for(unsigned long count=0;count<length;count++)
*destination++=*source++;
}