调整sane_user库的接口

This commit is contained in:
luoliangyi 2023-03-25 15:31:09 +08:00
parent 760cfb332b
commit ed7e7638ff
8 changed files with 489 additions and 241 deletions

View File

@ -8,6 +8,6 @@ HGSane_GetDeviceCount
HGSane_GetDeviceName
HGSane_OpenDevice
HGSane_CloseDevice
HGSane_GetDeviceHandle
HGSane_StartDevice
HGSane_StopDevice
HGSane_GetImage

View File

@ -283,7 +283,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -308,7 +308,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -335,7 +335,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -365,7 +365,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -395,7 +395,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -425,7 +425,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -455,7 +455,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -485,7 +485,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -515,7 +515,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -545,7 +545,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -575,7 +575,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -605,7 +605,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -635,7 +635,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>
@ -665,7 +665,7 @@
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_WINDOWS;NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile>
<Link>

View File

@ -55,8 +55,13 @@ CHGTestDlg::CHGTestDlg(CWnd* pParent /*=nullptr*/)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
#ifdef USE_SANE
m_saneMgr = NULL;
m_saneDev = NULL;
#else
m_dsm = NULL;
m_ds = NULL;
#endif
}
void CHGTestDlg::DoDataExchange(CDataExchange* pDX)
@ -120,8 +125,13 @@ BOOL CHGTestDlg::OnInitDialog()
HGBase_DestroyImage(image);
}
m_idx = 0;
#ifdef USE_SANE
HGSane_CreateManager("sane.dll", &m_saneMgr);
#else
HGTwain_LoadDSM(&m_dsm);
HGTwain_OpenDSM(m_dsm, m_hWnd, DSEventCallback, this);
#endif
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
@ -177,6 +187,21 @@ HCURSOR CHGTestDlg::OnQueryDragIcon()
void CHGTestDlg::OnBnClickedButton1()
{
#ifdef USE_SANE
if (NULL != m_saneDev)
{
return;
}
HGChar errInfo[256];
HGSane_OpenDevice(m_saneMgr, 0, &m_saneDev, errInfo, 256);
HGResult ret = HGSane_StartDevice(m_saneDev, SaneDeviceEventCallback, this, SaneDeviceImageCallback, this, errInfo, 256);
if (HGBASE_ERR_OK != ret)
{
HGSane_CloseDevice(m_saneDev);
m_saneDev = NULL;
}
#else
if (NULL != m_ds)
{
return;
@ -188,15 +213,36 @@ void CHGTestDlg::OnBnClickedButton1()
HGTwain_OpenDS(m_ds);
HGTwain_EnableDS(m_ds, HGTRUE, NULL);
}
#endif
}
void CHGTestDlg::OnBnClickedButton2()
{
#ifdef USE_SANE
HGSane_CloseDevice(m_saneDev);
m_saneDev = NULL;
#else
HGTwain_CloseDS(m_ds);
m_ds = NULL;
#endif
}
#ifdef USE_SANE
void HGAPI CHGTestDlg::SaneDeviceEventCallback(HGSaneDevice dev, HGUInt error, const HGChar* errInfo, HGPointer param)
{
CHGTestDlg* p = (CHGTestDlg*)param;
::PostMessage(p->m_hWnd, 2000, 0, 0);
}
void HGAPI CHGTestDlg::SaneDeviceImageCallback(HGSaneDevice dev, HGImage image, HGPointer param)
{
CHGTestDlg* p = (CHGTestDlg*)param;
CStringA strName;
strName.Format("D:\\HGTest_%u.jpg", p->m_idx++);
HGImgFmt_SaveImage(image, 0, NULL, strName);
}
#else
void CHGTestDlg::DSEventCallback(HGTwainDS ds, HGUInt event, HGPointer param)
{
CHGTestDlg* p = (CHGTestDlg*)param;
@ -240,3 +286,18 @@ void CHGTestDlg::DSEventCallback(HGTwainDS ds, HGUInt event, HGPointer param)
p->m_ds = NULL;
}
}
#endif
LRESULT CHGTestDlg::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
if (2000 == message)
{
#ifdef USE_SANE
HGSane_CloseDevice(m_saneDev);
m_saneDev = NULL;
#endif
}
return CDialogEx::WindowProc(message, wParam, lParam);
}

View File

@ -4,6 +4,7 @@
#pragma once
//#define USE_SANE
// CHGTestDlg 对话框
class CHGTestDlg : public CDialogEx
@ -20,10 +21,17 @@ public:
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
int m_idx;
#ifdef USE_SANE
HGSaneManager m_saneMgr;
HGSaneDevice m_saneDev;
static void HGAPI SaneDeviceEventCallback(HGSaneDevice dev, HGUInt error, const HGChar* errInfo, HGPointer param);
static void HGAPI SaneDeviceImageCallback(HGSaneDevice dev, HGImage image, HGPointer param);
#else
HGTwainDSM m_dsm;
HGTwainDS m_ds;
static void HGAPI DSEventCallback(HGTwainDS ds, HGUInt event, HGPointer param);
#endif
// 实现
protected:
@ -38,4 +46,5 @@ protected:
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
virtual LRESULT WindowProc(UINT message, WPARAM wParam, LPARAM lParam);
};

View File

@ -60,7 +60,7 @@ HGResult HGAPI HGSane_GetDeviceName(HGSaneManager mgr, HGUInt index, HGChar* nam
return saneManagerImpl->GetDeviceName(index, name, maxLen);
}
HGResult HGAPI HGSane_OpenDevice(HGSaneManager mgr, HGUInt index, HGSaneDevice* dev)
HGResult HGAPI HGSane_OpenDevice(HGSaneManager mgr, HGUInt index, HGSaneDevice* dev, HGChar* errInfo, HGUInt errInfoLen)
{
if (NULL == mgr)
{
@ -68,7 +68,15 @@ HGResult HGAPI HGSane_OpenDevice(HGSaneManager mgr, HGUInt index, HGSaneDevice*
}
HGSaneManagerImpl* saneManagerImpl = (HGSaneManagerImpl*)mgr;
return saneManagerImpl->OpenDevice(index, (HGSaneDeviceImpl**)dev);
class HGSaneDeviceImpl* saneDeviceImpl = NULL;
HGResult ret = saneManagerImpl->OpenDevice(index, &saneDeviceImpl, errInfo, errInfoLen);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
*dev = (HGSaneDevice)saneDeviceImpl;
return HGBASE_ERR_OK;
}
HGResult HGAPI HGSane_CloseDevice(HGSaneDevice dev)
@ -79,10 +87,10 @@ HGResult HGAPI HGSane_CloseDevice(HGSaneDevice dev)
}
HGSaneDeviceImpl* saneDeviceImpl = (HGSaneDeviceImpl*)dev;
return saneDeviceImpl->mgrImpl->CloseDevice(saneDeviceImpl);
return saneDeviceImpl->Close();
}
HGResult HGAPI HGSane_StartDevice(HGSaneDevice dev, HGSane_DeviceEventCallback func, HGPointer param)
HGResult HGAPI HGSane_GetDeviceHandle(HGSaneDevice dev, SANE_Handle* handle)
{
if (NULL == dev)
{
@ -90,7 +98,19 @@ HGResult HGAPI HGSane_StartDevice(HGSaneDevice dev, HGSane_DeviceEventCallback f
}
HGSaneDeviceImpl* saneDeviceImpl = (HGSaneDeviceImpl*)dev;
return saneDeviceImpl->mgrImpl->StartDevice(saneDeviceImpl, func, param);
return saneDeviceImpl->GetHandle(handle);
}
HGResult HGAPI HGSane_StartDevice(HGSaneDevice dev, HGSane_DeviceEventCallback eventFunc, HGPointer eventParam,
HGSane_DeviceImageCallback imageFunc, HGPointer imageParam, HGChar* errInfo, HGUInt errInfoLen)
{
if (NULL == dev)
{
return HGBASE_ERR_INVALIDARG;
}
HGSaneDeviceImpl* saneDeviceImpl = (HGSaneDeviceImpl*)dev;
return saneDeviceImpl->Start(eventFunc, eventParam, imageFunc, imageParam, errInfo, errInfoLen);
}
HGResult HGAPI HGSane_StopDevice(HGSaneDevice dev)
@ -101,16 +121,5 @@ HGResult HGAPI HGSane_StopDevice(HGSaneDevice dev)
}
HGSaneDeviceImpl* saneDeviceImpl = (HGSaneDeviceImpl*)dev;
return saneDeviceImpl->mgrImpl->StopDevice(saneDeviceImpl);
}
HGResult HGAPI HGSane_GetImage(HGSaneDevice dev, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == dev)
{
return HGBASE_ERR_INVALIDARG;
}
HGSaneDeviceImpl* saneDeviceImpl = (HGSaneDeviceImpl*)dev;
return saneDeviceImpl->mgrImpl->GetImage(saneDeviceImpl, type, origin, image);
return saneDeviceImpl->Stop();
}

View File

@ -5,17 +5,15 @@
#include "../base/HGBaseErr.h"
#include "HGSaneErr.h"
#include "../base/HGImage.h"
#include "sane.h"
HG_DECLARE_HANDLE(HGSaneManager);
HG_DECLARE_HANDLE(HGSaneDevice);
#define HGSANE_DEVEVENT_UNKNOWN 0L
#define HGSANE_DEVEVENT_IMGREADY 1L
#define HGSANE_DEVEVENT_ERROR 2L
/* Sane设备事件回调
/* Sane设备回调
*/
typedef void (HGAPI* HGSane_DeviceEventCallback)(HGSaneDevice dev, HGUInt event, HGPointer param);
typedef void (HGAPI* HGSane_DeviceEventCallback)(HGSaneDevice dev, HGUInt error, const HGChar *errInfo, HGPointer param);
typedef void (HGAPI* HGSane_DeviceImageCallback)(HGSaneDevice dev, HGImage image, HGPointer param);
HGEXPORT HGResult HGAPI HGSane_CreateManager(const HGChar *sanePath, HGSaneManager* mgr);
@ -25,14 +23,15 @@ HGEXPORT HGResult HGAPI HGSane_GetDeviceCount(HGSaneManager mgr, HGUInt *count);
HGEXPORT HGResult HGAPI HGSane_GetDeviceName(HGSaneManager mgr, HGUInt index, HGChar *name, HGUInt maxLen);
HGEXPORT HGResult HGAPI HGSane_OpenDevice(HGSaneManager mgr, HGUInt index, HGSaneDevice *dev);
HGEXPORT HGResult HGAPI HGSane_OpenDevice(HGSaneManager mgr, HGUInt index, HGSaneDevice *dev, HGChar *errInfo, HGUInt errInfoLen);
HGEXPORT HGResult HGAPI HGSane_CloseDevice(HGSaneDevice dev);
HGEXPORT HGResult HGAPI HGSane_StartDevice(HGSaneDevice dev, HGSane_DeviceEventCallback func, HGPointer param);
HGEXPORT HGResult HGAPI HGSane_GetDeviceHandle(HGSaneDevice dev, SANE_Handle *handle);
HGEXPORT HGResult HGAPI HGSane_StartDevice(HGSaneDevice dev, HGSane_DeviceEventCallback eventFunc, HGPointer eventParam,
HGSane_DeviceImageCallback imageFunc, HGPointer imageParam, HGChar* errInfo, HGUInt errInfoLen);
HGEXPORT HGResult HGAPI HGSane_StopDevice(HGSaneDevice dev);
HGEXPORT HGResult HGAPI HGSane_GetImage(HGSaneDevice dev, HGUInt type, HGUInt origin, HGImage* image);
#endif /* __HGSANE_H__ */

View File

@ -14,6 +14,9 @@ HGSaneManagerImpl::HGSaneManagerImpl()
m_f_sane_cancel = NULL;
m_f_sane_set_io_mode = NULL;
m_f_sane_strstatus = NULL;
m_f_sane_get_parameters = NULL;
m_f_sane_get_option_descriptor = NULL;
m_f_sane_control_option = NULL;
}
HGSaneManagerImpl::~HGSaneManagerImpl()
@ -46,7 +49,7 @@ HGResult HGSaneManagerImpl::Create(const HGChar* sanePath)
{
HGBase_DestroyDll(m_dll);
m_dll = NULL;
return HGBASE_ERR_FAIL;
return HGSANE_ERR_FAIL;
}
return HGBASE_ERR_OK;
@ -54,7 +57,7 @@ HGResult HGSaneManagerImpl::Create(const HGChar* sanePath)
HGResult HGSaneManagerImpl::Destroy()
{
if (!m_devList.empty())
if (!m_listDeviceImpl.empty())
{
return HGBASE_ERR_FAIL;
}
@ -76,10 +79,10 @@ HGResult HGSaneManagerImpl::GetDeviceCount(HGUInt* count)
return HGBASE_ERR_INVALIDARG;
}
const SANE_Device **device_list;
const SANE_Device** device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
return HGSANE_ERR_FAIL;
}
*count = 0;
@ -100,7 +103,7 @@ HGResult HGSaneManagerImpl::GetDeviceName(HGUInt index, HGChar* name, HGUInt max
const SANE_Device** device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
return HGSANE_ERR_FAIL;
}
HGUInt count = 0;
@ -119,9 +122,9 @@ HGResult HGSaneManagerImpl::GetDeviceName(HGUInt index, HGChar* name, HGUInt max
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device)
HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** deviceImpl, HGChar* errInfo, HGUInt errInfoLen)
{
if (NULL == device)
if (NULL == deviceImpl)
{
return HGBASE_ERR_INVALIDARG;
}
@ -129,7 +132,7 @@ HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device)
const SANE_Device** device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
return HGSANE_ERR_FAIL;
}
HGUInt count = 0;
@ -140,194 +143,74 @@ HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device)
if (index >= count)
return HGBASE_ERR_INVALIDARG;
SANE_Handle handle = NULL;
if (SANE_STATUS_GOOD != m_f_sane_open(device_list[index]->name, &handle))
HGSaneDeviceImpl* newDeviceImpl = new HGSaneDeviceImpl(this);
HGResult ret = newDeviceImpl->Open(device_list[index]->name, errInfo, errInfoLen);
if (HGBASE_ERR_OK != ret)
{
return HGBASE_ERR_FAIL;
delete newDeviceImpl;
return ret;
}
m_f_sane_set_io_mode(handle, SANE_FALSE);
HGSaneDeviceImpl* saneDeviceImpl = new HGSaneDeviceImpl(this);
saneDeviceImpl->devHandle = handle;
m_devList.push_back(saneDeviceImpl);
*device = saneDeviceImpl;
m_listDeviceImpl.push_back(newDeviceImpl);
*deviceImpl = newDeviceImpl;
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::CloseDevice(HGSaneDeviceImpl* device)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
HGResult ret = HGBASE_ERR_FAIL;
std::list<HGSaneDeviceImpl*>::iterator iter;
for (iter = m_devList.begin(); iter != m_devList.end(); ++iter)
{
if (device == *iter)
{
StopDevice(device);
m_f_sane_close(device->devHandle);
delete device;
m_devList.erase(iter);
ret = HGBASE_ERR_OK;
break;
}
}
return ret;
}
HGResult HGSaneManagerImpl::StartDevice(HGSaneDeviceImpl* device, HGSane_DeviceEventCallback func, HGPointer param)
{
if (NULL == device || NULL == func)
{
return HGBASE_ERR_INVALIDARG;
}
if (NULL != device->thread)
{
return HGBASE_ERR_FAIL;
}
if (SANE_STATUS_GOOD != m_f_sane_start(device->devHandle))
{
return HGBASE_ERR_FAIL;
}
device->func = func;
device->param = param;
device->stopThread = HGFALSE;
HGBase_OpenThread(ThreadFunc, device, &device->thread);
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::StopDevice(HGSaneDeviceImpl* device)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
device->stopThread = HGTRUE;
// 该函数应该打断m_f_sane_read
m_f_sane_cancel(device->devHandle);
HGBase_CloseThread(device->thread);
device->thread = NULL;
device->func = NULL;
device->param = NULL;
device->recvData.clear();
device->imgReady = HGFALSE;
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::GetImage(HGSaneDeviceImpl* device, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
HGBase_EnterLock(device->lock);
HGBool imgReady = device->imgReady;
HGBase_LeaveLock(device->lock);
if (!imgReady)
{
return HGBASE_ERR_FAIL;
}
// 从m_recvData中加载
return HGBASE_ERR_FAIL;
}
void HGAPI HGSaneManagerImpl::ThreadFunc(HGThread thread, HGPointer param)
{
HGSaneDeviceImpl* p = (HGSaneDeviceImpl*)param;
while (!p->stopThread)
{
SANE_Byte data[2048];
SANE_Int len = 0;
SANE_Status stat = p->mgrImpl->m_f_sane_read(p->devHandle, data, 5000, &len);
if (SANE_STATUS_GOOD == stat)
{
HGBase_EnterLock(p->lock);
for (SANE_Int i = 0; i < len; ++i)
{
p->recvData.push_back(data[i]);
}
HGBase_LeaveLock(p->lock);
}
else
{
assert(NULL != p->func);
if (SANE_STATUS_EOF == stat)
{
HGBase_EnterLock(p->lock);
p->imgReady = HGTRUE;
HGBase_LeaveLock(p->lock);
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_IMGREADY, p->param);
}
else
{
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_ERROR, p->param);
}
break;
}
}
}
HGResult HGSaneManagerImpl::FindFunctions()
{
HGResult ret = HGBASE_ERR_OK;
do
{
ret = HGBase_GetDllProcAddress(m_dll, "sane_init", (HGPointer*)&m_f_sane_init);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_init", (HGPointer*)&m_f_sane_init);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_exit", (HGPointer*)&m_f_sane_exit);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_exit", (HGPointer*)&m_f_sane_exit);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_get_devices", (HGPointer*)&m_f_sane_get_devices);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_get_devices", (HGPointer*)&m_f_sane_get_devices);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_open", (HGPointer*)&m_f_sane_open);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_open", (HGPointer*)&m_f_sane_open);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_close", (HGPointer*)&m_f_sane_close);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_close", (HGPointer*)&m_f_sane_close);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_start", (HGPointer*)&m_f_sane_start);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_start", (HGPointer*)&m_f_sane_start);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_read", (HGPointer*)&m_f_sane_read);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_read", (HGPointer*)&m_f_sane_read);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_cancel", (HGPointer*)&m_f_sane_cancel);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_cancel", (HGPointer*)&m_f_sane_cancel);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_set_io_mode", (HGPointer*)&m_f_sane_set_io_mode);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_set_io_mode", (HGPointer*)&m_f_sane_set_io_mode);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_strstatus", (HGPointer*)&m_f_sane_strstatus);
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_strstatus", (HGPointer*)&m_f_sane_strstatus);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_get_parameters", (HGPointer*)&m_f_sane_get_parameters);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_get_option_descriptor", (HGPointer*)&m_f_sane_get_option_descriptor);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_hgsane_control_option", (HGPointer*)&m_f_sane_control_option);
if (HGBASE_ERR_OK != ret)
break;
@ -335,3 +218,290 @@ HGResult HGSaneManagerImpl::FindFunctions()
return ret;
}
void HGSaneManagerImpl::RemoveDevice(class HGSaneDeviceImpl* deviceImpl)
{
std::list<class HGSaneDeviceImpl*>::iterator iter;
for (iter = m_listDeviceImpl.begin(); iter != m_listDeviceImpl.end(); ++iter)
{
if (*iter == deviceImpl)
{
m_listDeviceImpl.erase(iter);
delete deviceImpl;
break;
}
}
}
HGSaneDeviceImpl::HGSaneDeviceImpl(HGSaneManagerImpl* mgr)
{
m_mgrImpl = mgr;
m_devHandle = NULL;
m_buffer = NULL;
m_bufferSize = 0;
m_dpi = 0;
m_eventFunc = NULL;
m_eventParam = NULL;
m_imageFunc = NULL;
m_imageParam = NULL;
m_stopThread = HGFALSE;
m_thread = NULL;
}
HGSaneDeviceImpl::~HGSaneDeviceImpl()
{
}
HGResult HGSaneDeviceImpl::Open(const HGChar* devName, HGChar* errInfo, HGUInt errInfoLen)
{
if (NULL != m_devHandle)
{
return HGBASE_ERR_FAIL;
}
if (NULL == devName)
{
return HGBASE_ERR_INVALIDARG;
}
SANE_Handle handle = NULL;
SANE_Status stat = m_mgrImpl->m_f_sane_open(devName, &handle);
if (SANE_STATUS_GOOD != stat)
{
if (NULL != errInfo)
{
const char* err = m_mgrImpl->m_f_sane_strstatus(stat);
if (NULL != err && errInfoLen >= strlen(err) + 1)
{
strcpy(errInfo, err);
}
}
return HGSANE_ERR_FAIL;
}
m_mgrImpl->m_f_sane_set_io_mode(handle, SANE_FALSE);
m_devHandle = handle;
return HGBASE_ERR_OK;
}
HGResult HGSaneDeviceImpl::Close()
{
if (NULL == m_devHandle)
{
return HGBASE_ERR_FAIL;
}
Stop();
m_mgrImpl->m_f_sane_close(m_devHandle);
m_devHandle = NULL;
m_mgrImpl->RemoveDevice(this);
return HGBASE_ERR_OK;
}
HGResult HGSaneDeviceImpl::GetHandle(SANE_Handle* handle)
{
if (NULL == handle)
{
return HGBASE_ERR_INVALIDARG;
}
*handle = m_devHandle;
return HGBASE_ERR_OK;
}
HGResult HGSaneDeviceImpl::Start(HGSane_DeviceEventCallback eventFunc, HGPointer eventParam,
HGSane_DeviceImageCallback imageFunc, HGPointer imageParam, HGChar* errInfo, HGUInt errInfoLen)
{
if (NULL != m_thread)
{
return HGBASE_ERR_FAIL;
}
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat = m_mgrImpl->m_f_sane_get_parameters(m_devHandle, &params);
if (SANE_STATUS_GOOD != stat)
{
if (NULL != errInfo)
{
const char* err = m_mgrImpl->m_f_sane_strstatus(stat);
if (NULL != err && errInfoLen >= strlen(err) + 1)
{
strcpy(errInfo, err);
}
}
return HGSANE_ERR_FAIL;
}
m_bufferSize = 5000 * 4000;
m_buffer = (HGByte *)malloc(m_bufferSize);
if (NULL == m_buffer)
{
return HGBASE_ERR_OUTOFMEMORY;
}
m_dpi = GetDpi();
stat = m_mgrImpl->m_f_sane_start(m_devHandle);
if (SANE_STATUS_GOOD != stat)
{
if (NULL != errInfo)
{
const char* err = m_mgrImpl->m_f_sane_strstatus(stat);
if (NULL != err && errInfoLen >= strlen(err) + 1)
{
strcpy(errInfo, err);
}
}
m_dpi = 0;
free(m_buffer);
m_buffer = NULL;
m_bufferSize = 0;
return HGSANE_ERR_FAIL;
}
m_eventFunc = eventFunc;
m_eventParam = eventParam;
m_imageFunc = imageFunc;
m_imageParam = imageParam;
m_stopThread = HGFALSE;
HGBase_OpenThread(ThreadFunc, this, &m_thread);
return HGBASE_ERR_OK;
}
HGResult HGSaneDeviceImpl::Stop()
{
if (NULL == m_thread)
{
return HGBASE_ERR_FAIL;
}
m_stopThread = HGTRUE;
m_mgrImpl->m_f_sane_cancel(m_devHandle);
HGBase_CloseThread(m_thread);
m_thread = NULL;
m_eventFunc = NULL;
m_eventParam = NULL;
m_imageFunc = NULL;
m_imageParam = NULL;
m_dpi = 0;
free(m_buffer);
m_buffer = NULL;
m_bufferSize = 0;
return HGBASE_ERR_OK;
}
HGUInt HGSaneDeviceImpl::GetDpi()
{
HGUInt dpi = 0;
SANE_Int num_dev_options = 0;
m_mgrImpl->m_f_sane_control_option(m_devHandle, 0, SANE_ACTION_GET_VALUE, &num_dev_options, NULL);
for (int i = 1; i < num_dev_options; ++i)
{
const SANE_Option_Descriptor* desp = m_mgrImpl->m_f_sane_get_option_descriptor(m_devHandle, i);
if (nullptr == desp)
continue;
if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = 0;
m_mgrImpl->m_f_sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
if (0 == strcmp(desp->name, SANE_NAME_SCAN_RESOLUTION))
{
dpi = (HGUInt)value;
break;
}
}
}
return dpi;
}
void HGAPI HGSaneDeviceImpl::ThreadFunc(HGThread thread, HGPointer param)
{
HGSaneDeviceImpl* p = (HGSaneDeviceImpl*)param;
while (!p->m_stopThread)
{
SANE_Parameters params;
memset(&params, 0, sizeof(SANE_Parameters));
SANE_Status stat1 = p->m_mgrImpl->m_f_sane_get_parameters(p->m_devHandle, &params);
SANE_Int readSize = 0;
SANE_Status stat2 = SANE_STATUS_GOOD;
while (readSize < p->m_bufferSize)
{
SANE_Int len = 0;
stat2 = p->m_mgrImpl->m_f_sane_read(p->m_devHandle, p->m_buffer + readSize, p->m_bufferSize - readSize, &len);
readSize += len;
if (SANE_STATUS_GOOD != stat2)
{
break;
}
}
if (SANE_STATUS_GOOD == stat2)
{
// m_bufferSize空间不够
if (NULL != p->m_eventFunc)
p->m_eventFunc((HGSaneDevice)p, HGSANE_ERR_FAIL, p->m_mgrImpl->m_f_sane_strstatus(SANE_STATUS_INVAL), p->m_eventParam);
break;
}
else if (SANE_STATUS_EOF == stat2)
{
if (0 == readSize)
{
if (NULL != p->m_eventFunc)
p->m_eventFunc((HGSaneDevice)p, HGBASE_ERR_OK, NULL, p->m_eventParam);
break;
}
else if (SANE_STATUS_GOOD != stat1 || readSize != params.bytes_per_line * params.lines)
{
if (NULL != p->m_eventFunc)
p->m_eventFunc((HGSaneDevice)p, HGSANE_ERR_FAIL, p->m_mgrImpl->m_f_sane_strstatus(SANE_STATUS_INVAL), p->m_eventParam);
break;
}
}
else if (SANE_STATUS_CANCELLED == stat2)
{
break;
}
else
{
if (NULL != p->m_eventFunc)
p->m_eventFunc((HGSaneDevice)p, HGSANE_ERR_FAIL, p->m_mgrImpl->m_f_sane_strstatus(stat2), p->m_eventParam);
break;
}
if (NULL != p->m_imageFunc)
{
HGUInt imgType = 0;
if (params.format == SANE_FRAME_GRAY)
{
if (1 == params.depth)
imgType = HGBASE_IMGTYPE_BINARY;
else if (8 == params.depth)
imgType = HGBASE_IMGTYPE_GRAY;
}
else if (params.format == SANE_FRAME_RGB)
{
imgType = HGBASE_IMGTYPE_RGB;
}
HGImageInfo imgInfo = { (HGUInt)params.pixels_per_line, (HGUInt)params.lines,
imgType, (HGUInt)params.bytes_per_line, HGBASE_IMGORIGIN_TOP };
HGImage img = NULL;
HGBase_CreateImageWithData(p->m_buffer, &imgInfo, &img);
if (NULL != img)
{
HGBase_SetImageDpi(img, p->m_dpi, p->m_dpi);
p->m_imageFunc((HGSaneDevice)p, img, p->m_imageParam);
HGBase_DestroyImage(img);
}
}
}
}

View File

@ -7,6 +7,7 @@
#include "../base/HGThread.h"
#include "../base/HGLock.h"
#include "sane.h"
#include "saneopts.h"
#include <list>
#include <vector>
@ -20,42 +21,13 @@ typedef SANE_Status (*f_sane_read)(SANE_Handle handle, SANE_Byte* data, SANE_Int
typedef void (*f_sane_cancel)(SANE_Handle handle);
typedef SANE_Status (*f_sane_set_io_mode)(SANE_Handle handle, SANE_Bool non_blocking);
typedef SANE_String_Const (*f_sane_strstatus)(SANE_Status status);
struct HGSaneDeviceImpl
{
HGSaneDeviceImpl(class HGSaneManagerImpl* mgr)
{
mgrImpl = mgr;
HGBase_CreateLock(&lock);
devHandle = NULL;
func = NULL;
param = NULL;
stopThread = HGFALSE;
thread = NULL;
imgReady = HGFALSE;
}
~HGSaneDeviceImpl()
{
HGBase_DestroyLock(lock);
lock = NULL;
}
class HGSaneManagerImpl* mgrImpl;
HGLock lock;
SANE_Handle devHandle;
HGSane_DeviceEventCallback func;
HGPointer param;
HGBool stopThread;
HGThread thread;
HGBool imgReady;
std::vector<SANE_Byte> recvData;
};
typedef SANE_Status (*f_sane_get_parameters)(SANE_Handle handle, SANE_Parameters* params);
typedef SANE_Option_Descriptor* (*f_sane_get_option_descriptor)(SANE_Handle handle, SANE_Int option);
typedef SANE_Status (*f_sane_control_option)(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info);
class HGSaneManagerImpl
{
friend class HGSaneDeviceImpl;
public:
HGSaneManagerImpl();
~HGSaneManagerImpl();
@ -64,16 +36,11 @@ public:
HGResult Destroy();
HGResult GetDeviceCount(HGUInt *count);
HGResult GetDeviceName(HGUInt index, HGChar* name, HGUInt maxLen);
HGResult OpenDevice(HGUInt index, HGSaneDeviceImpl **device);
HGResult CloseDevice(HGSaneDeviceImpl *device);
HGResult StartDevice(HGSaneDeviceImpl* device, HGSane_DeviceEventCallback func, HGPointer param);
HGResult StopDevice(HGSaneDeviceImpl* device);
HGResult GetImage(HGSaneDeviceImpl* device, HGUInt type, HGUInt origin, HGImage* image);
HGResult OpenDevice(HGUInt index, class HGSaneDeviceImpl **deviceImpl, HGChar* errInfo, HGUInt errInfoLen);
private:
static void HGAPI ThreadFunc(HGThread thread, HGPointer param);
HGResult FindFunctions();
void RemoveDevice(class HGSaneDeviceImpl* deviceImpl);
private:
HGDll m_dll;
@ -87,8 +54,41 @@ private:
f_sane_cancel m_f_sane_cancel;
f_sane_set_io_mode m_f_sane_set_io_mode;
f_sane_strstatus m_f_sane_strstatus;
f_sane_get_parameters m_f_sane_get_parameters;
f_sane_get_option_descriptor m_f_sane_get_option_descriptor;
f_sane_control_option m_f_sane_control_option;
std::list<class HGSaneDeviceImpl*> m_listDeviceImpl;
};
std::list<HGSaneDeviceImpl*> m_devList;
class HGSaneDeviceImpl
{
public:
HGSaneDeviceImpl(HGSaneManagerImpl* mgr);
~HGSaneDeviceImpl();
HGResult Open(const HGChar *devName, HGChar* errInfo, HGUInt errInfoLen);
HGResult Close();
HGResult GetHandle(SANE_Handle* handle);
HGResult Start(HGSane_DeviceEventCallback eventFunc, HGPointer eventParam,
HGSane_DeviceImageCallback imageFunc, HGPointer imageParam, HGChar* errInfo, HGUInt errInfoLen);
HGResult Stop();
private:
HGUInt GetDpi();
static void HGAPI ThreadFunc(HGThread thread, HGPointer param);
private:
class HGSaneManagerImpl* m_mgrImpl;
SANE_Handle m_devHandle;
HGByte* m_buffer;
HGInt m_bufferSize;
HGUInt m_dpi;
HGSane_DeviceEventCallback m_eventFunc;
HGPointer m_eventParam;
HGSane_DeviceImageCallback m_imageFunc;
HGPointer m_imageParam;
volatile HGBool m_stopThread;
HGThread m_thread;
};
#endif /* __HGSANEIMPL_HPP__ */