Files
core/ASCImageStudio3/ASCGraphics/agg/ap_Image.cpp

289 lines
6.7 KiB
C++

//----------------------------------------------------------------------------
// Image class - Version 0.1.1 - 31-10-2004
// Marlon Mircevski
//----------------------------------------------------------------------------
//#include "stdafx.h"
#include <string.h>
#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<m_dwWidth*m_dwHeight;i++) { ((DWORD *)m_pImgData)[i] |= 0xFF000000; }
}
m_Status=Ok;
::ReleaseDC(NULL, hdc);
}
SVGImage::SVGImage():m_attributes(m_settings)
{
}
SVGImage::~SVGImage()
{
Clear();
}
void SVGImage::Clear()
{
m_storage.clear();
reset();
}
void SVGImage::indexation()
{
agg::svg::indexation_interpreter consumer(m_id2elem_map);
m_storage.traverse(consumer);
m_id2elem_map.sort_state(agg::svg::on);
}
void SVGImage::reset()
{
m_id2elem_map.clear();
m_attributes.clear();
}
bool SVGImage::Open(const WCHAR *filename)
{
if(!filename)
return false;
m_attributes.initial_zoom();
m_storage.clear();
reset();
agg::svg::parser p(m_storage, m_attr_map);
p.parse(filename);
indexation();
return true;
}
}