231 lines
4.6 KiB
C++
231 lines
4.6 KiB
C++
// QRCode.cpp : Implementation of CQRCode
|
|
|
|
#include "stdafx.h"
|
|
#include "QRCode.h"
|
|
#include "..\QRCode\QR_Encode.h"
|
|
|
|
// CQRCode
|
|
|
|
STDMETHODIMP CQRCode::InterfaceSupportsErrorInfo(REFIID riid)
|
|
{
|
|
static const IID* arr[] =
|
|
{
|
|
&IID_IQRCode
|
|
};
|
|
|
|
for (int i=0; i < sizeof(arr) / sizeof(arr[0]); i++)
|
|
{
|
|
if (InlineIsEqualGUID(*arr[i],riid))
|
|
return S_OK;
|
|
}
|
|
return S_FALSE;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Text(BSTR* pVal)
|
|
{
|
|
*pVal = m_Text.AllocSysString();
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Text(BSTR newVal)
|
|
{
|
|
m_Text = CString(newVal);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
HRESULT CQRCode::StreamPNG(CxImage &img, VARIANT *ImageData, BOOL bPNG)
|
|
{
|
|
SAFEARRAY *psaData; BYTE *pData;
|
|
SAFEARRAYBOUND rgsabound[1];
|
|
|
|
long size=0;
|
|
BYTE* pBuffer=0;
|
|
{
|
|
{
|
|
CmyTimer timer("CQRCode::StreamPNG/de PNG encoden");
|
|
if (!img.Encode(pBuffer,size, bPNG?CXIMAGE_FORMAT_PNG:CXIMAGE_FORMAT_GIF))
|
|
return myAtlReportError (GetObjectCLSID(), "\nStreamPNG encode failed: %s", img.GetLastError());
|
|
}
|
|
|
|
// TODO: Echt netjes zou zijn om hier een IStream op te leveren?
|
|
// create safe array and copy image data
|
|
rgsabound[0].lLbound = 0; rgsabound[0].cElements = size;
|
|
psaData = SafeArrayCreate(VT_UI1, 1, rgsabound);
|
|
SafeArrayAccessData(psaData, (void **)&pData);
|
|
memcpy(pData,pBuffer,size);
|
|
SafeArrayUnaccessData(psaData);
|
|
img.FreeMemory (pBuffer);
|
|
// put data in variant
|
|
ImageData->vt = (VT_ARRAY | VT_UI1);
|
|
ImageData->parray = psaData;
|
|
}
|
|
myDoTRACE("\nCQRCode::StreamPNG done, sending %d bytes", size);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
bool CQRCode::CreateCxImage(CxImage *img)
|
|
{
|
|
CQR_Encode* pQR_Encode = new CQR_Encode;
|
|
|
|
BOOL res = pQR_Encode->EncodeData(m_nLevel, m_nVersion,
|
|
m_bAutoExtend, m_nMaskingNo,
|
|
m_Text );
|
|
if (!res)
|
|
return false;
|
|
|
|
img->Create((pQR_Encode->m_nSymbleSize+2*QR_MARGIN), (pQR_Encode->m_nSymbleSize+2*QR_MARGIN), 24 /* bpp */);
|
|
img->Clear(m_BgGrayColor);
|
|
img->SetTransIndex(-1);
|
|
for (int i = 0; i < pQR_Encode->m_nSymbleSize; ++i)
|
|
for (int j = 0; j < pQR_Encode->m_nSymbleSize; ++j)
|
|
{
|
|
if (pQR_Encode->m_byModuleData[i][j])
|
|
{
|
|
img->SetPixelColor(i + QR_MARGIN, pQR_Encode->m_nSymbleSize - j + QR_MARGIN - 1, m_Color);
|
|
}
|
|
}
|
|
img->Resample(m_nSize * img->GetWidth(), m_nSize * img->GetHeight());
|
|
delete pQR_Encode;
|
|
|
|
return true;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::GetAsPNG(VARIANT* ImageData)
|
|
{
|
|
try
|
|
{
|
|
myDoTRACE("\nCQRCode::GetAsPNG()");
|
|
|
|
CxImage img;
|
|
BOOL res = CreateCxImage(&img);
|
|
if (!res)
|
|
{
|
|
CString err; err.Format("Could not QRCode: %s", m_Text);
|
|
throw err;
|
|
}
|
|
|
|
return StreamPNG(img, ImageData, true /*bPNG*/);
|
|
}
|
|
catch (DWFException& ex)
|
|
{
|
|
CString err;
|
|
err.Format("%ls\n%ls\n%s\n%ls(%d)",ex.type(),ex.message(),ex.function(),ex.file(),ex.line());
|
|
return myAtlReportError (GetObjectCLSID(), "\nCQRCode::GetAsPNG('%s')\n%s", m_Text, err);
|
|
}
|
|
catch (CString& err)
|
|
{
|
|
return myAtlReportError (GetObjectCLSID(), "\nCQRCode::GetAsPNG('%s')\n%s", m_Text, err);
|
|
}
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Version(LONG* pVal)
|
|
{
|
|
*pVal = m_nVersion;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Version(LONG newVal)
|
|
{
|
|
if (newVal < -1 || newVal > 40)
|
|
return E_INVALIDARG;
|
|
m_nVersion = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Autoextend(VARIANT_BOOL* pVal)
|
|
{
|
|
*pVal = m_bAutoExtend;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Autoextend(VARIANT_BOOL newVal)
|
|
{
|
|
m_bAutoExtend = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Level(LONG* pVal)
|
|
{
|
|
*pVal = m_nLevel;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Level(LONG newVal)
|
|
{
|
|
if (newVal < 1 || newVal > 3)
|
|
return E_INVALIDARG;
|
|
m_nLevel = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Masking(LONG* pVal)
|
|
{
|
|
*pVal = m_nMaskingNo;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Masking(LONG newVal)
|
|
{
|
|
if (newVal < -1 || newVal > 7)
|
|
return E_INVALIDARG;
|
|
m_nMaskingNo = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Size(LONG* pVal)
|
|
{
|
|
*pVal = m_nSize;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Size(LONG newVal)
|
|
{
|
|
if (newVal < 1 || newVal > 64)
|
|
return E_INVALIDARG;
|
|
m_nSize = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_Color(LONG* pVal)
|
|
{
|
|
*pVal = m_Color;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_Color(LONG newVal)
|
|
{
|
|
m_Color = newVal;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::get_BgGrayColor(BYTE* pVal)
|
|
{
|
|
*pVal = m_BgGrayColor;
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
STDMETHODIMP CQRCode::put_BgGrayColor(BYTE newVal)
|
|
{
|
|
m_BgGrayColor = newVal;
|
|
|
|
return S_OK;
|
|
}
|