#include #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;ibmiColors[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;ibmiColors[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