//---------------------------------------------------------------------------- // Image class - Version 0.1.1 - 31-10-2004 // Marlon Mircevski //---------------------------------------------------------------------------- //#include "stdafx.h" #include #include "ap_Image.h" #include "X__CacheFile.h" #include "ap_Mem.h" inline LPVOID ZC_GetCreateItemBuff(LPCWSTR szwFilename, DWORD *pdwRetWidth, DWORD *pdwRetHeight) { return Z__CacheFile.GetCreateItemBuff(szwFilename, pdwRetWidth, pdwRetHeight); } inline LPVOID ZC_GetCreateCopy(LPVOID pSourceBuff, DWORD dwWidth, DWORD dwHeight) { return Z__CacheFile.GetCreateCopy(pSourceBuff, dwWidth, dwHeight); } inline void ZC_Release(LPVOID pBuff) { Z__CacheFile.Release(pBuff); } namespace Aggplus { ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// Image::Image() : m_dwWidth(0), m_dwHeight(0), m_nStride(0), m_pImgData(NULL), m_bExternalBuffer(false), m_Status(WrongState) { } Image::Image(const WCHAR *filename, BOOL useEmbeddedColorManagement) : m_dwWidth(0), m_dwHeight(0), m_nStride(0), m_pImgData(NULL), m_bExternalBuffer(false) { Create(filename); } Image::~Image() { Destroy(); } void Image::Create(const WCHAR *filename) { Destroy(); m_pImgData=ZC_GetCreateItemBuff(filename, &m_dwWidth, &m_dwHeight); m_nStride=4*m_dwWidth; if(!m_pImgData) { Destroy(); } else m_Status=Ok; } void Image::CopyFrom(const Image *pSource) { Destroy(); if(pSource && pSource->m_Status == Ok) { m_Status=Ok; m_dwWidth=pSource->m_dwWidth; m_dwHeight=pSource->m_dwHeight; m_nStride=pSource->m_nStride; m_bExternalBuffer=false; if(pSource->m_bExternalBuffer) { assert((unsigned)abs(m_nStride)==4*m_dwWidth); m_pImgData=ap_malloc16(4*m_dwWidth*m_dwHeight); memcpy(m_pImgData, pSource->m_pImgData, 4*m_dwWidth*m_dwHeight); } else { m_pImgData=ZC_GetCreateCopy(pSource->m_pImgData, m_dwWidth, m_dwHeight); if(!m_pImgData) { Destroy(); } } } } Image *Image::Clone() const { Image *pRet=new Image; pRet->CopyFrom(this); return(pRet); } void Image::Destroy() { if(m_pImgData) { if(!m_bExternalBuffer) { ZC_Release(m_pImgData); } } m_Status=WrongState; m_pImgData=NULL; m_dwWidth=m_dwHeight=m_nStride=0; m_bExternalBuffer=false; } Bitmap::Bitmap(INT width, INT height, PixelFormat format) : Image() { assert(format==PixelFormat32bppARGB); if(width<=0 || height<=0) { m_Status=InvalidParameter; return; } m_pImgData=ap_malloc16(4*width*height); assert(m_pImgData); if(m_pImgData) { memset(m_pImgData, 0, 4*width*height); m_dwWidth=width; m_dwHeight=height; m_nStride=4*m_dwWidth; m_Status=Ok; } } Bitmap::Bitmap(INT width, INT height, INT stride, PixelFormat format, BYTE* scan0) : Image() { assert(format==PixelFormat32bppARGB); assert(scan0); //Warning! This is not Gdiplus behavior; it returns Ok! if(width<=0 || height<=0 || stride==0) { m_Status=InvalidParameter; return; } m_bExternalBuffer=true; if(stride>0) m_pImgData=scan0; else m_pImgData=scan0+(height-1)*stride; m_dwWidth=width; m_dwHeight=height; m_nStride=stride; m_Status=Ok; } Bitmap::Bitmap(const WCHAR *filename, BOOL useIcm) : Image(filename, useIcm) { } Bitmap::Bitmap(HBITMAP hbm, HPALETTE hpal) : Image() { Create(hbm, hpal); } Bitmap::Bitmap(HINSTANCE hInstance, const WCHAR* bitmapName) : Image() { HBITMAP hBMRes=::LoadBitmapW(hInstance, bitmapName); if(hBMRes) { Create(hBMRes, NULL); ::DeleteObject(hBMRes); } } Bitmap::~Bitmap() { } void Bitmap::Create(HBITMAP hbm, HPALETTE hpal) { Destroy(); BITMAPINFO bi; bool b32bitImg=false; //Step 1 memset(&bi, 0, sizeof(BITMAPINFO)); bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); HDC hdc=::GetDC(NULL); int nChk=GetDIBits(hdc, // handle to device context hbm, // handle to bitmap 0, // first scan line to set in destination bitmap 1, // number of scan lines to copy NULL, // address of array for bitmap bits &bi, // address of structure with bitmap data DIB_RGB_COLORS // RGB or palette index ); if(!nChk || bi.bmiHeader.biWidth<=0 || bi.bmiHeader.biHeight<=0) return; if(bi.bmiHeader.biBitCount==32 && bi.bmiHeader.biCompression == BI_RGB) b32bitImg=true; //Step 2 m_dwWidth=bi.bmiHeader.biWidth; m_dwHeight=bi.bmiHeader.biHeight; m_bExternalBuffer=false; m_pImgData=ap_malloc16(4*m_dwWidth*m_dwHeight); memset(&bi, 0, sizeof(BITMAPINFO)); bi.bmiHeader.biSize=sizeof(BITMAPINFOHEADER); bi.bmiHeader.biWidth = m_dwWidth; // fill in width from parameter bi.bmiHeader.biHeight = -int(m_dwHeight); // fill in height from parameter bi.bmiHeader.biPlanes = 1; // must be 1 bi.bmiHeader.biBitCount = 32; // from parameter bi.bmiHeader.biCompression = BI_RGB; bi.bmiHeader.biSizeImage = m_dwWidth * m_dwHeight * 4; //bi.bmiHeader.biXPelsPerMeter = 0; //bi.bmiHeader.biYPelsPerMeter = 0; //bi.bmiHeader.biClrUsed = 0; //bi.bmiHeader.biClrImportant = 0; nChk=GetDIBits(hdc, // handle to device context hbm, // handle to bitmap 0, // first scan line to set in destination bitmap m_dwHeight, // number of scan lines to copy m_pImgData, // address of array for bitmap bits &bi, // address of structure with bitmap data DIB_RGB_COLORS // RGB or palette index ); //Opaque Alpha! if(!b32bitImg) { for(DWORD i=0;i