123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203 |
- #ifndef __PCL_OBJECT_IMAGE__2001_04_27__H__
- #define __PCL_OBJECT_IMAGE__2001_04_27__H__
- #include "ObjBase.h"
- #include "FColor.h"
- #include "ObjProgress.h"
- #include "oxo_helper.h"
- #include "imagefile/Interface_ImageHandle.h"
- #include "imagefile/Interface_ImageHandleFactory.h"
- #include "pixelprocessor/Interface_PixelProcessor.h"
- class FCObjImage : public FCObjGraph
- {
- public:
-
-
-
- FCObjImage () ;
-
- FCObjImage (const FCObjImage& img) ;
-
- FCObjImage (int nWidth, int nHeight, int nColorBit) ;
-
- FCObjImage (const char* szFileName) ;
- FCObjImage& operator= (const FCObjImage& img) ;
- virtual ~FCObjImage() {Destroy();}
-
-
- virtual int Serialize (bool bSave, BYTE* pSave) ;
-
-
-
- bool Create (const BITMAPINFOHEADER* pBmif) ;
-
- bool Create (int nWidth, int nHeight, int nColorBit) ;
-
- void Destroy() ;
-
-
-
-
- bool IsValidImage() const {return (m_pByte != 0);}
-
- BYTE* GetBits (int iLine) const ;
-
- BYTE* GetBits (int x, int y) const ;
-
- BYTE* GetMemStart() const {return m_pByte;}
-
- int Width() const {return m_DibInfo.biWidth;}
-
- int Height() const {return m_DibInfo.biHeight;}
-
- WORD ColorBits() const {return m_DibInfo.biBitCount;}
-
- int GetPitch() const {return 4 * ((Width() * ColorBits() + 31) / 32);}
-
- BITMAPINFOHEADER* NewImgInfoWithPalette() const ;
-
-
- void BoundRect (RECT& rc) const ;
-
-
-
-
- bool IsInside (int x, int y) const {return (x>=0) && (x<Width()) && (y>=0) && (y<Height());}
-
- DWORD GetPixelData (int x, int y) const ;
-
- void SetPixelData (int x, int y, DWORD dwPixel) ;
-
-
-
-
-
- bool GetColorTable (int iFirstIndex, int iNumber, RGBQUAD* pColors) const ;
-
-
- bool SetColorTable (int iFirstIndex, int iNumber, const RGBQUAD* pColors) ;
-
- void CopyPalette (const FCObjImage& imgSrc) ;
-
-
-
-
- void ConvertTo24Bit() {__ConvertToTrueColor(24);}
-
- void ConvertTo32Bit() {__ConvertToTrueColor(32);}
-
-
-
-
- void GetAlphaChannel (FCObjImage* imgAlpha) const ;
-
- void AppendAlphaChannel (const FCObjImage& alpha8) ;
-
- void SetAlphaChannelValue (int nValue) ;
-
-
-
-
-
- bool GetSubBlock (FCObjImage* SubImg, RECT rcBlock) const ;
-
- bool CoverBlock (const FCObjImage& Img, int x, int y) ;
- void TileBlock (const FCObjImage& Img, int x, int y) ;
-
- void AlphaBlend (const FCObjImage& img32, const RECT& rcDest, const RECT& rcSrc, int nAlphaPercent) ;
-
- void CombineImage (const FCObjImage& img32, int x=0, int y=0, int nAlphaPercent=100) ;
- void LogicalBlend (const FCObjImage & MaskImg, LOGICAL_OP LogOP, int x=0, int y=0) ;
-
- void ExpandFrame (bool bCopyEdge, int iLeft, int iTop, int iRight, int iBottom) ;
-
- void Stretch (int nNewWidth, int nNewHeight) ;
-
- void Stretch_Smooth (int nNewWidth, int nNewHeight, FCObjProgress * progress = NULL) ;
-
- void SinglePixelProcessProc (FCInterface_PixelProcess& rProcessor, FCObjProgress* pProgress=NULL) ;
-
-
-
-
- static void SetImageHandleFactory (FCImageHandleFactory* pFactory) {__ManageImageHandleFactory(false,pFactory);}
-
- static FCImageHandleFactory* GetImageHandleFactory() {return __ManageImageHandleFactory(true,0);}
-
- bool Load (const char* szFileName, FCImageProperty* pProperty = 0) ;
-
- bool Load (BYTE* pStart, int nMemSize, IMAGE_TYPE imgType, FCImageProperty* pProperty = 0) ;
-
- bool LoadDIBStream (const void* pDIB, int nBufferSize) ;
-
- bool Save (const char* szFileName, int nFlag = -1) const
- {
-
- FCImageProperty imgProp ;
- imgProp.SetPropertyValue (PROPERTY_TAG_SAVE_FLAG, FCOXOHelper::X2A(nFlag).c_str()) ;
- return Save (szFileName, imgProp) ;
- }
-
- bool Save (const char* szFileName, const FCImageProperty& rProp) const ;
-
- private:
- BITMAPINFOHEADER m_DibInfo ;
- BYTE * m_pByte ;
- BYTE ** m_ppLine ;
- DWORD m_dwBitFields[3] ;
- RGBQUAD * m_pPalette ;
- private:
- void __SetGrayPalette() ;
- void __InitClassMember() ;
- void __ConvertToTrueColor (int iColor) ;
- static RGBQUAD __Split16Bit_565 (WORD wPixel) ;
- static RGBQUAD __Split16Bit_555 (WORD wPixel) ;
- static void __FillImageRect (const FCObjImage& img, const RECT& rcBlock, const void* pSrc) ;
- static FCImageHandleFactory* __ManageImageHandleFactory (bool bGet, FCImageHandleFactory* pFactory) ;
- } ;
- inline void FCObjImage::__InitClassMember()
- {
- memset (&m_DibInfo, 0, sizeof(m_DibInfo)) ;
- m_dwBitFields[0]=m_dwBitFields[1]=m_dwBitFields[2]=0 ;
- m_pByte=0 ; m_ppLine=0 ; m_pPalette=0 ;
- }
- inline FCObjImage::FCObjImage()
- {
- __InitClassMember() ;
- }
- inline FCObjImage::FCObjImage (const FCObjImage& img)
- {
- __InitClassMember() ;
- *this = img ;
- }
- inline FCObjImage::FCObjImage (int nWidth, int nHeight, int nColorBit)
- {
- __InitClassMember() ;
- Create (nWidth, nHeight, nColorBit) ;
- }
- inline FCObjImage::FCObjImage (const char* szFileName)
- {
- __InitClassMember() ;
- Load (szFileName) ;
- }
- inline bool FCObjImage::Create (const BITMAPINFOHEADER* pBmif)
- {
-
- if (!pBmif || (pBmif->biHeight <= 0) || (pBmif->biWidth <= 0))
- {assert(false); return false;}
- if (!((pBmif->biCompression == BI_RGB) || (pBmif->biCompression == BI_BITFIELDS)))
- {assert(false); return false;}
- switch (pBmif->biBitCount)
- {
- case 1 :
- case 4 :
- case 8 :
- case 16 :
- case 24 :
- case 32 : break ;
- default : assert(false); return false;
- }
- if (IsValidImage())
- Destroy() ;
-
- memset (&m_DibInfo, 0, sizeof(m_DibInfo)) ;
- m_DibInfo.biSize = sizeof(BITMAPINFOHEADER) ;
- m_DibInfo.biWidth = pBmif->biWidth ;
- m_DibInfo.biHeight = pBmif->biHeight ;
- m_DibInfo.biPlanes = 1 ;
- m_DibInfo.biBitCount = pBmif->biBitCount ;
- m_DibInfo.biCompression = pBmif->biCompression ;
- m_DibInfo.biXPelsPerMeter = pBmif->biXPelsPerMeter ;
- m_DibInfo.biYPelsPerMeter = pBmif->biYPelsPerMeter ;
-
- if (pBmif->biBitCount == 16)
- {
- m_dwBitFields[0] = MASK16_RED_555 ;
- m_dwBitFields[1] = MASK16_GREEN_555 ;
- m_dwBitFields[2] = MASK16_BLUE_555 ;
- if (pBmif->biCompression == BI_BITFIELDS)
- memcpy (m_dwBitFields, pBmif + 1, 12) ;
- }
- else
- m_DibInfo.biCompression = BI_RGB ;
-
- m_pByte = FCOXOHelper::ZeroMalloc (GetPitch()*Height()) ;
- assert (((int)m_pByte % 4) == 0) ;
-
- m_ppLine = (BYTE **) new BYTE [sizeof(BYTE*) * Height()] ;
- const int nPitch = GetPitch() ;
- m_ppLine[0] = m_pByte + (Height() - 1) * nPitch ;
- for (int y = 1 ; y < Height() ; y++)
- m_ppLine[y] = m_ppLine[y - 1] - nPitch ;
-
- if (ColorBits() <= 8)
- {
- m_pPalette = new RGBQUAD[1 << ColorBits()] ;
- __SetGrayPalette() ;
- }
- return true ;
- }
- inline bool FCObjImage::Create (int nWidth, int nHeight, int nColorBit)
- {
- BITMAPINFOHEADER bmih ;
- memset (&bmih, 0, sizeof(bmih)) ;
- bmih.biWidth = nWidth ;
- bmih.biHeight = nHeight ;
- bmih.biBitCount = nColorBit ;
- bmih.biCompression = BI_RGB ;
- return this->Create (&bmih) ;
- }
- inline void FCObjImage::Destroy()
- {
- if (m_ppLine)
- delete[] m_ppLine ;
- FCOXOHelper::ZeroFree (m_pByte) ;
- if (m_pPalette)
- delete[] m_pPalette ;
- __InitClassMember() ;
- }
- inline BYTE* FCObjImage::GetBits (int iLine) const
- {
- assert (IsInside(0,iLine)) ;
- return m_ppLine[iLine] ;
- }
- inline BYTE* FCObjImage::GetBits (int x, int y) const
- {
- assert (IsInside(x,y)) ;
- if (ColorBits() == 32)
- return (m_ppLine[y] + x * 4) ;
- if (ColorBits() == 8)
- return (m_ppLine[y] + x) ;
- return (m_ppLine[y] + x * ColorBits() / 8) ;
- }
- inline BITMAPINFOHEADER* FCObjImage::NewImgInfoWithPalette() const
- {
-
- const int nColorNum = 1 << ColorBits(),
- nPalBytes = ((ColorBits() <= 8) ? (4*nColorNum) : 0) ;
- BITMAPINFOHEADER * pBmfh = (BITMAPINFOHEADER*) new BYTE[16 + sizeof(BITMAPINFOHEADER) + nPalBytes] ;
- *pBmfh = m_DibInfo ;
-
- if (ColorBits() <= 8)
- GetColorTable (0, nColorNum, (RGBQUAD*)(pBmfh + 1)) ;
- else
- memcpy (pBmfh + 1, m_dwBitFields, 12) ;
- return pBmfh ;
- }
- inline void FCObjImage::BoundRect (RECT& rc) const
- {
- RECT rcImg = {0, 0, Width(), Height()} ;
- ::IntersectRect (&rc, &rcImg, &rc) ;
- }
- inline DWORD FCObjImage::GetPixelData (int x, int y) const
- {
- if (!IsInside(x, y))
- {assert(false); return 0;}
- const BYTE * pPixel = GetBits (x,y) ;
- switch (ColorBits())
- {
- case 1 : return 0x01 & (*pPixel >> (7 - (x & 7))) ;
- case 4 : return 0x0F & (*pPixel >> (x & 1 ? 0 : 4)) ;
- case 8 : return *(BYTE*)pPixel ;
- case 16 : return *(WORD*)pPixel ;
- case 24 :
- {
- DWORD dwrgb = 0 ;
- FCColor::CopyPixel (&dwrgb, pPixel, 3) ;
- return dwrgb ;
- }
- case 32 : return *(DWORD*)pPixel ;
- default : assert(false) ;
- }
- return 0 ;
- }
- inline void FCObjImage::SetPixelData (int x, int y, DWORD dwPixel)
- {
- if (!IsInside(x, y))
- {assert(false); return;}
- BYTE * pPixel = GetBits (x,y) ;
- switch (ColorBits())
- {
- case 1 : *pPixel &= ~(1 << (7 - (x & 7))) ;
- *pPixel |= dwPixel << (7 - (x & 7)) ;
- break ;
- case 4 : *pPixel &= 0x0F << (x & 1 ? 4 : 0) ;
- *pPixel |= dwPixel << (x & 1 ? 0 : 4) ;
- break ;
- case 8 :
- case 16 :
- case 24 :
- case 32 : FCColor::CopyPixel (pPixel, &dwPixel, ColorBits() / 8) ;
- break ;
- default : assert(false) ;
- }
- }
- inline bool FCObjImage::GetColorTable (int iFirstIndex, int iNumber, RGBQUAD* pColors) const
- {
- if (!IsValidImage() || (ColorBits() > 8) || (iFirstIndex < 0) || !pColors || !m_pPalette)
- {assert(false); return false;}
- const int nColorNum = 1 << ColorBits() ;
- for (int i=0 ; i < iNumber ; i++)
- {
- int nIndex = iFirstIndex + i ;
- if (nIndex < nColorNum)
- pColors[i] = m_pPalette[nIndex] ;
- }
- return true ;
- }
- inline bool FCObjImage::SetColorTable (int iFirstIndex, int iNumber, const RGBQUAD* pColors)
- {
- if (!IsValidImage() || (ColorBits() > 8) || (iFirstIndex < 0) || !pColors || !m_pPalette)
- {assert(false); return false;}
- const int nColorNum = 1 << ColorBits() ;
- for (int i=0 ; i < iNumber ; i++)
- {
- int nIndex = iFirstIndex + i ;
- if (nIndex < nColorNum)
- m_pPalette[nIndex] = pColors[i] ;
- }
- return true ;
- }
- inline void FCObjImage::CopyPalette (const FCObjImage& imgSrc)
- {
- if (!IsValidImage() || (ColorBits() > 8) || (ColorBits() != imgSrc.ColorBits()))
- {assert(false); return;}
- RGBQUAD pPal[256] ;
- int nNum = 1 << imgSrc.ColorBits() ;
- imgSrc.GetColorTable (0, nNum, pPal) ;
- SetColorTable (0, nNum, pPal) ;
- }
- inline void FCObjImage::__SetGrayPalette()
- {
- if (!IsValidImage() || (ColorBits() > 8))
- {assert(false); return;}
-
- RGBQUAD pPal[256] ;
- const int nNum = 1 << ColorBits(),
- nSpan = 255 / (nNum - 1) ;
- for (int i=0 ; i < nNum ; i++)
- {
- PCL_R(&pPal[i]) = PCL_G(&pPal[i]) = PCL_B(&pPal[i]) = i * nSpan ;
- }
- SetColorTable (0, nNum, pPal) ;
- }
- inline RGBQUAD FCObjImage::__Split16Bit_565 (WORD wPixel)
- {
- RGBQUAD rgb ;
- PCL_R(&rgb) = (MASK16_RED_565 & wPixel) >> 8 ;
- PCL_G(&rgb) = (MASK16_GREEN_565 & wPixel) >> 3 ;
- PCL_B(&rgb) = (MASK16_BLUE_565 & wPixel) << 3 ;
- return rgb ;
- }
- inline RGBQUAD FCObjImage::__Split16Bit_555 (WORD wPixel)
- {
- RGBQUAD rgb ;
- PCL_R(&rgb) = (MASK16_RED_555 & wPixel) >> 7 ;
- PCL_G(&rgb) = (MASK16_GREEN_555 & wPixel) >> 2 ;
- PCL_B(&rgb) = (MASK16_BLUE_555 & wPixel) << 3 ;
- return rgb ;
- }
- inline void FCObjImage::__ConvertToTrueColor (int iColor)
- {
- if (!IsValidImage() || (ColorBits() == iColor))
- return ;
- if ((iColor != 24) && (iColor != 32))
- {assert(false); return;}
-
- const FCObjImage OldPic (*this) ;
- if (!Create (OldPic.Width(), OldPic.Height(), iColor))
- return ;
-
- RGBQUAD pPal[256] ;
- if (OldPic.ColorBits() <= 8)
- OldPic.GetColorTable (0, 1 << OldPic.ColorBits(), pPal) ;
-
- const int nNewSpan = this->ColorBits() / 8,
- nOldSpan = OldPic.ColorBits() / 8 ;
- for (int y=0 ; y < Height() ; y++)
- {
- const BYTE * pOld = OldPic.GetBits (y) ;
- BYTE * pNew = this->GetBits (y) ;
- for (int x=0 ; x < Width() ; x++, pNew+=nNewSpan, pOld+=nOldSpan)
- {
- switch (OldPic.ColorBits())
- {
- case 1 :
- case 4 :
- case 8 :
- FCColor::CopyPixel (pNew, &pPal[OldPic.GetPixelData(x,y)], 3) ;
- break ;
- case 16 :
- {
- RGBQUAD crTrans ;
- if (OldPic.m_dwBitFields[1] == MASK16_GREEN_555)
- crTrans = __Split16Bit_555 (*(WORD*)pOld) ;
- else if (OldPic.m_dwBitFields[1] == MASK16_GREEN_565)
- crTrans = __Split16Bit_565 (*(WORD*)pOld) ;
- FCColor::CopyPixel (pNew, &crTrans, 3) ;
- }
- break ;
- case 24 :
- case 32 :
- FCColor::CopyPixel (pNew, pOld, 3) ;
- break ;
- }
- }
- }
- if (iColor == 32)
- SetAlphaChannelValue (0xFF) ;
- }
- inline void FCObjImage::GetAlphaChannel (FCObjImage* imgAlpha) const
- {
-
- if (!imgAlpha || !IsValidImage() || (ColorBits() != 32) || (imgAlpha == this)
- || !imgAlpha->Create (Width(), Height(), 8))
- {
- assert(false) ; return ;
- }
-
- for (int y=0 ; y < Height() ; y++)
- for (int x=0 ; x < Width() ; x++)
- *imgAlpha->GetBits(x,y) = PCL_A(GetBits(x,y)) ;
- }
- inline void FCObjImage::AppendAlphaChannel (const FCObjImage& alpha)
- {
- if (!IsValidImage() || !alpha.IsValidImage() || (ColorBits() != 32) || (alpha.ColorBits() != 8) ||
- (Width() != alpha.Width()) || (Height() != alpha.Height()))
- {
- assert(false) ; return ;
- }
-
- for (int y=0 ; y < Height() ; y++)
- for (int x=0 ; x < Width() ; x++)
- PCL_A(GetBits(x,y)) = *alpha.GetBits(x,y) ;
- }
- inline void FCObjImage::SetAlphaChannelValue (int nValue)
- {
- if (!IsValidImage() || (ColorBits() != 32))
- {
- assert(false) ; return ;
- }
- for (int y=0 ; y < Height() ; y++)
- for (int x=0 ; x < Width() ; x++)
- PCL_A(GetBits(x,y)) = nValue ;
- }
- inline FCObjImage& FCObjImage::operator= (const FCObjImage& img)
- {
- if (!img.IsValidImage() || (&img == this))
- return (*this) ;
- PCL_array<BITMAPINFOHEADER> bmfh (img.NewImgInfoWithPalette()) ;
- if (Create (bmfh.get()))
- {
-
- memcpy (GetMemStart(), img.GetMemStart(), img.GetPitch()*img.Height()) ;
-
- if (img.ColorBits() <= 8)
- CopyPalette (img) ;
-
- FCObjGraph::operator=(img) ;
- }
- return *this ;
- }
- inline bool FCObjImage::GetSubBlock (FCObjImage* SubImg, RECT rcBlock) const
- {
- if (!IsValidImage() || !SubImg || (SubImg == this) || (ColorBits() < 8))
- {
- assert(false); return false;
- }
- const RECT rcImage = {0, 0, Width(), Height()} ;
- RECT rcD ;
- assert (IsRectInRect (rcImage, rcBlock)) ;
- if (::IntersectRect (&rcD, &rcImage, &rcBlock) == 0)
- {
- assert(false); return false;
- }
- if (!SubImg->Create (RECTWIDTH(rcD), RECTHEIGHT(rcD), ColorBits()))
- return false ;
-
- const int nSubPitch = SubImg->Width() * ColorBits() / 8 ;
- for (int i=0 ; i < SubImg->Height() ; i++)
- memcpy (SubImg->GetBits(i), GetBits(rcD.left, rcD.top + i), nSubPitch) ;
-
- if (ColorBits() <= 8)
- SubImg->CopyPalette (*this) ;
-
- SubImg->SetGraphObjPos (rcD.left, rcD.top) ;
- return true ;
- }
- inline bool FCObjImage::CoverBlock (const FCObjImage& Img, int x, int y)
- {
- if (!IsValidImage() || !Img.IsValidImage() || (ColorBits() != Img.ColorBits()) || (ColorBits() < 8))
- {
- assert(false); return false;
- }
-
- const RECT rcImage = {0, 0, Width(), Height()},
- rcCover = {x, y, x+Img.Width(), y+Img.Height()} ;
- RECT rcD ;
- if (::IntersectRect (&rcD, &rcImage, &rcCover) == 0)
- return false ;
-
- const int nSubPitch = RECTWIDTH(rcD) * Img.ColorBits() / 8 ;
- for (int cy=rcD.top ; cy < rcD.bottom ; cy++)
- {
- const BYTE * pS = Img.GetBits (rcD.left-x, cy-y) ;
- BYTE * pD = this->GetBits (rcD.left, cy) ;
- memcpy (pD, pS, nSubPitch) ;
- }
- return true ;
- }
- inline void FCObjImage::TileBlock (const FCObjImage & Img, int x, int y)
- {
- int nYStart = y ;
- while (nYStart < Height())
- {
- int nXStart = x ;
- while (nXStart < Width())
- {
- CoverBlock (Img, nXStart, nYStart) ;
- nXStart += Img.Width() ;
- }
- nYStart += Img.Height() ;
- }
- }
- inline void FCObjImage::CombineImage (const FCObjImage& Img32, int x, int y, int nAlphaPercent)
- {
- RECT rcD ;
- {
- RECT rcImg = {0, 0, Width(), Height()},
- rcMask = {x, y, x+Img32.Width(), y+Img32.Height()} ;
- ::IntersectRect (&rcD, &rcImg, &rcMask) ;
- }
- if ((Img32.ColorBits() != 32) || (ColorBits() != 32) || IsRectEmpty(&rcD))
- {
- assert(false); return;
- }
- nAlphaPercent = FClamp (nAlphaPercent, 0, 100) ;
- for (int cy=rcD.top ; cy < rcD.bottom ; cy++)
- {
- RGBQUAD * pDest = (RGBQUAD*)this->GetBits (rcD.left, cy),
- * pSrc = (RGBQUAD*)Img32.GetBits (rcD.left-x, cy-y) ;
- for (int cx=rcD.left ; cx < rcD.right ; cx++, pDest++, pSrc++)
- FCColor::CombineAlphaPixel(pDest, *pDest, pSrc,
- (nAlphaPercent == 100) ? PCL_A(pSrc)
- : (PCL_A(pSrc)*nAlphaPercent/100)) ;
- }
- }
- inline void FCObjImage::AlphaBlend (const FCObjImage& Img32, const RECT& rcDest, const RECT& rcSrc, int nAlphaPercent)
- {
- if (nAlphaPercent == 0)
- return ;
-
- const RECT rcMask = {0, 0, Img32.Width(), Img32.Height()},
- rcImg = {0, 0, Width(), Height()} ;
- RECT rcT ;
- IntersectRect(&rcT, &rcDest, &rcImg) ;
- if (!IsValidImage() || (ColorBits() < 24) || !Img32.IsValidImage() || (Img32.ColorBits() != 32) ||
- !IsRectInRect (rcMask, rcSrc) || IsRectEmpty(&rcT))
- {
- assert(false); return;
- }
- nAlphaPercent = FClamp (nAlphaPercent, 0, 100) ;
- const int nSpan = ColorBits() / 8 ;
- if ((RECTWIDTH(rcDest) == RECTWIDTH(rcSrc)) && (RECTHEIGHT(rcDest) == RECTHEIGHT(rcSrc)))
- {
- const int nSrcX = rcT.left - rcDest.left + rcSrc.left ;
- for (int y=rcT.top ; y < rcT.bottom ; y++)
- {
- const BYTE * pSrc = Img32.GetBits (nSrcX, y-rcDest.top+rcSrc.top) ;
- BYTE * pDest = this->GetBits (rcT.left, y) ;
- for (int x=rcT.left ; x < rcT.right ; x++, pDest+=nSpan, pSrc+=4)
- FCColor::AlphaBlendPixel (pDest, pSrc, (nAlphaPercent==100) ? PCL_A(pSrc)
- : PCL_A(pSrc)*nAlphaPercent/100) ;
- }
- }
- else
- {
- PCL_array<int> pX (RECTWIDTH(rcT)),
- pY (RECTHEIGHT(rcT)) ;
- int x, y ;
- for (y=rcT.top ; y < rcT.bottom ; y++)
- pY[y-rcT.top] = rcSrc.top+(y-rcDest.top)*RECTHEIGHT(rcSrc)/RECTHEIGHT(rcDest) ;
- for (x=rcT.left ; x < rcT.right ; x++)
- pX[x-rcT.left] = rcSrc.left+(x-rcDest.left)*RECTWIDTH(rcSrc)/RECTWIDTH(rcDest) ;
- for (y=rcT.top ; y < rcT.bottom ; y++)
- {
- BYTE * pDest = this->GetBits (rcT.left, y) ;
- for (x=rcT.left ; x < rcT.right ; x++, pDest+=nSpan)
- {
- const BYTE * pSrc = Img32.GetBits (pX[x-rcT.left], pY[y-rcT.top]) ;
- FCColor::AlphaBlendPixel (pDest, pSrc, (nAlphaPercent==100) ? PCL_A(pSrc)
- : PCL_A(pSrc)*nAlphaPercent/100) ;
- }
- }
- }
- }
- inline void FCObjImage::LogicalBlend (const FCObjImage & MaskImg, LOGICAL_OP LogOP, int x, int y)
- {
- if (!IsValidImage() || !MaskImg.IsValidImage() || (ColorBits() != MaskImg.ColorBits()) || (this == &MaskImg))
- {
- assert(false) ; return ;
- }
- assert (ColorBits() == 8) ;
- const RECT rcSrc1 = {0, 0, Width(), Height()},
- rcSrc2 = {x, y, x+MaskImg.Width(), y+MaskImg.Height()} ;
- RECT rcDest ;
- if (::IntersectRect (&rcDest, &rcSrc1, &rcSrc2) == 0)
- return ;
- const int nSpan = ColorBits() / 8;
- for (int cy=rcDest.top ; cy < rcDest.bottom ; cy++)
- {
- const BYTE * pSrc = MaskImg.GetBits (rcDest.left-x, cy-y) ;
- BYTE * pDest = this->GetBits (rcDest.left, cy) ;
- for (int cx=rcDest.left ; cx < rcDest.right ; cx++, pDest+=nSpan, pSrc+=nSpan)
- switch (LogOP)
- {
- case LOGI_OR : *pDest |= *pSrc ; break ;
- case LOGI_AND : *pDest &= *pSrc ; break ;
- case LOGI_XOR : *pDest ^= *pSrc ; break ;
- case LOGI_SEL_ADD :
- if (*pSrc == 0xFF)
- *pDest = 0xFF ;
- break ;
- case LOGI_SEL_SUB :
- if (*pSrc == 0xFF)
- *pDest = 0 ;
- break ;
- default : assert(false);
- }
- }
- }
- inline int FCObjImage::Serialize (bool bSave, BYTE* pSave)
- {
- const BYTE * pBak = pSave ;
- if (bSave)
- {
- assert (ColorBits() > 8) ;
- memcpy (pSave, &m_DibInfo, sizeof(m_DibInfo)) ; pSave += sizeof(m_DibInfo) ;
- memcpy (pSave, m_dwBitFields, 12) ; pSave += 12 ;
- int nWrite = GetPitch() * Height() ;
- memcpy (pSave, GetMemStart(), nWrite) ; pSave += nWrite ;
- }
- else
- {
- Create ((BITMAPINFOHEADER*)pSave) ;
- pSave += sizeof(m_DibInfo) + 12 ;
- int nWrite = GetPitch() * Height() ;
- memcpy (GetMemStart(), pSave, nWrite) ;
- pSave += nWrite ;
- }
- pSave += FCObjGraph::Serialize (bSave, pSave) ;
- return (int)(pSave - pBak) ;
- }
- inline bool FCObjImage::Load (const char* szFileName, FCImageProperty* pProperty)
- {
- IMAGE_TYPE imgType = GetImageHandleFactory()->QueryImageFileType(szFileName) ;
- std::auto_ptr<FCImageHandleBase> pHandler (GetImageHandleFactory()->CreateImageHandle(imgType)) ;
- if (!pHandler.get())
- return false ;
- PCL_Interface_Composite<FCObjImage> listImage ;
- std::auto_ptr<FCImageProperty> pImgProp ;
- bool bRet = pHandler->LoadImageFile (szFileName, listImage, pImgProp) ;
- if (bRet)
- {
- if (listImage.PCL_GetObjectCount())
- *this = *listImage.PCL_GetObject(0) ;
- if (pImgProp.get() && pProperty)
- *pProperty = *pImgProp ;
- }
- assert (bRet) ;
- return bRet ;
- }
- inline bool FCObjImage::Load (BYTE* pStart, int nMemSize, IMAGE_TYPE imgType, FCImageProperty* pProperty)
- {
- std::auto_ptr<FCImageHandleBase> pHandler (GetImageHandleFactory()->CreateImageHandle(imgType)) ;
- if (!pHandler.get())
- return false ;
- PCL_Interface_Composite<FCObjImage> listImage ;
- std::auto_ptr<FCImageProperty> pImgProp ;
- bool bRet = pHandler->LoadImageMemory (pStart, nMemSize, listImage, pImgProp) ;
- if (bRet)
- {
- if (listImage.PCL_GetObjectCount())
- *this = *listImage.PCL_GetObject(0) ;
-
- if (pImgProp.get() && pProperty)
- *pProperty = *pImgProp ;
- }
- assert (bRet) ;
- return bRet ;
- }
- inline bool FCObjImage::LoadDIBStream (const void* pDIB, int nBufferSize)
- {
- const BITMAPINFOHEADER * pBmif = (const BITMAPINFOHEADER*)pDIB ;
- if (!Create(pBmif))
- {assert(false); return false;}
- const BYTE * p = (const BYTE*)pDIB + pBmif->biSize ;
- if (ColorBits() <= 8)
- {
- int n = 1 << ColorBits() ;
- SetColorTable (0, n, (const RGBQUAD*)p) ;
- p += (4 * n) ;
- }
- else if (pBmif->biCompression == BI_BITFIELDS)
- {
- p += 12 ;
- }
-
- int nLeave = nBufferSize - (p - (BYTE*)pDIB) ;
- assert (nLeave >= GetPitch()*Height()) ;
- memcpy (GetMemStart(), p, FMin (nLeave, GetPitch()*Height())) ;
- return true ;
- }
- inline bool FCObjImage::Save (const char* szFileName, const FCImageProperty& rProp) const
- {
- if (!IsValidImage() || !szFileName)
- return false ;
- IMAGE_TYPE imgType = GetImageHandleFactory()->QueryImageFileType(szFileName) ;
- std::auto_ptr<FCImageHandleBase> pHandler (GetImageHandleFactory()->CreateImageHandle(imgType)) ;
- if (!pHandler.get())
- return false ;
-
- std::deque<const FCObjImage*> saveList ;
- saveList.push_back (this) ;
- return pHandler->SaveImageFile (szFileName, saveList, rProp) ;
- }
- inline void FCObjImage::__FillImageRect (const FCObjImage& img, const RECT& rcBlock, const void* pSrc)
- {
- RECT rc = {0, 0, img.Width(), img.Height()} ;
- IntersectRect (&rc, &rc, &rcBlock) ;
- if (IsRectEmpty(&rc))
- return ;
- const int nSpan = img.ColorBits() / 8 ;
- for (int y=rc.top ; y < rc.bottom ; y++)
- {
- BYTE * pPixel = img.GetBits (rc.left, y) ;
- for (int x=rc.left ; x < rc.right ; x++, pPixel += nSpan)
- FCColor::CopyPixel (pPixel, pSrc, nSpan) ;
- }
- }
- inline void FCObjImage::ExpandFrame (bool bCopyEdge, int iLeft, int iTop, int iRight, int iBottom)
- {
- if ((ColorBits() < 8) || (iLeft < 0) || (iTop < 0) || (iRight < 0) || (iBottom < 0))
- {
- assert(false) ; return ;
- }
- if ((iLeft == 0) && (iTop == 0) && (iRight == 0) && (iBottom == 0))
- return ;
-
- const FCObjImage imgOld(*this) ;
- if (!Create (imgOld.Width()+iLeft+iRight, imgOld.Height()+iTop+iBottom, imgOld.ColorBits()))
- {
- assert(false) ; return ;
- }
-
- SetGraphObjPos (imgOld.GetGraphObjPos().x - iLeft, imgOld.GetGraphObjPos().y - iTop) ;
-
- CoverBlock (imgOld, iLeft, iTop) ;
-
- if (!bCopyEdge)
- return ;
-
- const RECT rcUL = {0, 0, iTop, iLeft},
- rcUR = {Width()-iRight, 0, Width(), iTop},
- rcDL = {0, Height()-iBottom, iLeft, Height()},
- rcDR = {Width()-iRight, Height()-iBottom, Width(), Height()} ;
- __FillImageRect (*this, rcUL, imgOld.GetBits (0, 0)) ;
- __FillImageRect (*this, rcUR, imgOld.GetBits (imgOld.Width()-1, 0)) ;
- __FillImageRect (*this, rcDL, imgOld.GetBits (0, imgOld.Height()-1)) ;
- __FillImageRect (*this, rcDR, imgOld.GetBits (imgOld.Width()-1, imgOld.Height()-1)) ;
-
- const int dwPitch = GetPitch(),
- nSpan = ColorBits() / 8,
- nOldLineBytes = imgOld.Width() * nSpan ;
- int m ;
- BYTE * pSrc, * pDest ;
-
- pSrc = GetBits (iLeft, iTop) ;
- pDest = pSrc + dwPitch ;
- for (m=0 ; m < iTop ; m++, pDest += dwPitch)
- memcpy (pDest, pSrc, nOldLineBytes) ;
-
- pSrc = GetBits (iLeft, imgOld.Height() + iTop - 1) ;
- pDest = pSrc - dwPitch ;
- for (m=0 ; m < iBottom ; m++, pDest -= dwPitch)
- memcpy (pDest, pSrc, nOldLineBytes) ;
-
- pSrc = GetBits (iLeft, iTop) ;
- pDest = GetBits (0, iTop) ;
- for (m=0 ; m < imgOld.Height() ; m++, pDest -= dwPitch, pSrc -= dwPitch)
- {
- BYTE * pTemp = pDest ;
- for (int i=0 ; i < iLeft ; i++, pTemp += nSpan)
- FCColor::CopyPixel (pTemp, pSrc, nSpan) ;
- }
-
- pSrc = GetBits (iLeft + imgOld.Width() - 1, iTop) ;
- pDest = pSrc + nSpan ;
- for (m=0 ; m < imgOld.Height() ; m++, pDest -= dwPitch, pSrc -= dwPitch)
- {
- BYTE * pTemp = pDest ;
- for (int i=0 ; i < iRight ; i++, pTemp += nSpan)
- FCColor::CopyPixel (pTemp, pSrc, nSpan) ;
- }
- }
- inline void FCObjImage::Stretch (int nNewWidth, int nNewHeight)
- {
-
- if (!IsValidImage() || (nNewWidth <= 0) || (nNewHeight <= 0) || (ColorBits() < 8))
- {
- return ;
- }
- if ((nNewWidth == Width()) && (nNewHeight == Height()))
- return ;
-
- const FCObjImage imgOld(*this) ;
- if (!Create (nNewWidth, nNewHeight, imgOld.ColorBits()))
- {
- assert(false) ; return ;
- }
-
- if (ColorBits() <= 8)
- CopyPalette (imgOld) ;
-
- const int nSpan = ColorBits() / 8 ;
- PCL_array<int> pTabX (Width()) ;
- for (int xx=0 ; xx < Width() ; xx++)
- {
- pTabX[xx] = xx * imgOld.Width() / Width() ;
- assert (pTabX[xx] < imgOld.Width()) ;
- }
- for (int mm=0 ; mm < (Width() - 1) ; mm++)
- pTabX[mm] = (pTabX[mm+1] - pTabX[mm]) * nSpan ;
-
- for (int y=0 ; y < Height() ; y++)
- {
- const BYTE * pOld = imgOld.GetBits (y * imgOld.Height() / Height()) ;
- BYTE * pPixel = GetBits (y) ;
- for (int x=0 ; x < Width() ; x++)
- {
- FCColor::CopyPixel (pPixel, pOld, nSpan) ;
- pOld += pTabX[x] ;
- pPixel += nSpan ;
- }
- }
- }
- inline void FCObjImage::Stretch_Smooth (int nNewWidth, int nNewHeight, FCObjProgress * progress)
- {
-
- if (!IsValidImage() || (nNewWidth <= 0) || (nNewHeight <= 0) || (ColorBits() < 24))
- {
- assert(false) ; return ;
- }
- if ((nNewWidth == Width()) && (nNewHeight == Height()))
- return ;
-
- if ((Width() == 1) || (Height() == 1))
- {
- ExpandFrame (true, 0, 0, (Width()==1) ? 1 : 0, (Height()==1) ? 1 : 0) ;
- }
-
- const FCObjImage imgOld(*this) ;
- if (!Create (nNewWidth, nNewHeight, imgOld.ColorBits()))
- {
- assert(false) ; return ;
- }
-
- PCL_array<int> pTabX (Width()),
- pXMod (Width()) ;
- for (int i=0 ; i < Width() ; i++)
- {
- pTabX[i] = i * imgOld.Width() / Width() ;
- pXMod[i] = (i * imgOld.Width()) % Width() ;
-
- if (pTabX[i] >= imgOld.Width()-1)
- {
- pTabX[i] = imgOld.Width() - 2 ;
- pXMod[i] = Width() - 1 ;
- }
- }
-
- const int nSpan = ColorBits() / 8,
- nPitch = imgOld.GetPitch() ;
- if (progress)
- progress->ResetProgress() ;
- for (int y=0 ; y < Height() ; y++)
- {
- int nSrcY = y * imgOld.Height() / Height(),
- nYMod = (y * imgOld.Height()) % Height() ;
- if (nSrcY >= imgOld.Height()-1)
- {
- nSrcY = imgOld.Height() - 2 ;
- nYMod = Height() - 1 ;
- }
- const double un_y = nYMod / (double)Height() ;
- BYTE * pWrite = GetBits(y) ;
- for (int x=0 ; x < Width() ; x++, pWrite += nSpan)
- {
-
- const int nSrcX = pTabX[x],
- nXMod = pXMod[x] ;
- const BYTE * pOldPix = imgOld.GetBits (nSrcX, nSrcY) ;
- if ((nXMod == 0) && (nYMod == 0))
- {
- FCColor::CopyPixel (pWrite, pOldPix, nSpan) ;
- }
- else
- {
- const BYTE * pcrPixel[4] =
- {
- pOldPix, pOldPix + nSpan,
- pOldPix - nPitch, pOldPix - nPitch + nSpan
- } ;
- RGBQUAD crRet = FCColor::Get_Bilinear_Pixel (nXMod/(double)Width(), un_y, ColorBits() == 32, pcrPixel) ;
- FCColor::CopyPixel (pWrite, &crRet, nSpan) ;
- }
- }
- if (progress)
- progress->SetProgress (y * 100 / Height()) ;
- }
- }
- inline void FCObjImage::SinglePixelProcessProc (FCInterface_PixelProcess& rProcessor, FCObjProgress* pProgress)
- {
- if (!rProcessor.ValidateColorBits (this))
- {assert(false); return;}
-
- rProcessor.OnEnterProcess (this) ;
- if (pProgress)
- pProgress->ResetProgress() ;
- switch (rProcessor.QueryProcessType())
- {
- case FCInterface_PixelProcess::PROCESS_TYPE_PIXEL :
- {
- for (int y=0 ; y < Height() ; y++)
- {
- for (int x=0 ; x < Width() ; x++)
- {
- rProcessor.ProcessPixel (this, x, y, GetBits(x,y)) ;
- }
- if (pProgress)
- pProgress->SetProgress ((y+1) * 100 / Height()) ;
- }
- }
- break ;
- case FCInterface_PixelProcess::PROCESS_TYPE_WHOLE :
- rProcessor.ProcessWholeImage (this, pProgress) ;
- break ;
- }
-
- rProcessor.OnLeaveProcess (this) ;
- }
- #endif
|