mirror of
https://github.com/ONLYOFFICE/core.git
synced 2026-07-11 06:22:44 +08:00
289 lines
6.7 KiB
C++
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;
|
|
}
|
|
|
|
|
|
}
|