diff --git a/build/windows/HGSaneUser/HGSaneUser.def b/build/windows/HGSaneUser/HGSaneUser.def
index 018c7a4c..de03796f 100644
--- a/build/windows/HGSaneUser/HGSaneUser.def
+++ b/build/windows/HGSaneUser/HGSaneUser.def
@@ -8,6 +8,6 @@ HGSane_GetDeviceCount
HGSane_GetDeviceName
HGSane_OpenDevice
HGSane_CloseDevice
+HGSane_GetDeviceHandle
HGSane_StartDevice
HGSane_StopDevice
-HGSane_GetImage
diff --git a/build/windows/HGTest/HGTest.vcxproj b/build/windows/HGTest/HGTest.vcxproj
index 95062309..7afd88f4 100644
--- a/build/windows/HGTest/HGTest.vcxproj
+++ b/build/windows/HGTest/HGTest.vcxproj
@@ -283,7 +283,7 @@
true
WIN32;_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -308,7 +308,7 @@
true
_WINDOWS;_DEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -335,7 +335,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -365,7 +365,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -395,7 +395,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -425,7 +425,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -455,7 +455,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -485,7 +485,7 @@
true
WIN32;_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -515,7 +515,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -545,7 +545,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -575,7 +575,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -605,7 +605,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -635,7 +635,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
@@ -665,7 +665,7 @@
true
_WINDOWS;NDEBUG;%(PreprocessorDefinitions)
pch.h
- ../../../modules/base/;../../../modules;../../../sdk;%(AdditionalIncludeDirectories)
+ ../../../modules/base/;../../../modules;../../../sdk;../../../third_party/sane/;%(AdditionalIncludeDirectories)
true
diff --git a/build/windows/HGTest/HGTestDlg.cpp b/build/windows/HGTest/HGTestDlg.cpp
index 13bb87d8..7fa5a21a 100644
--- a/build/windows/HGTest/HGTestDlg.cpp
+++ b/build/windows/HGTest/HGTestDlg.cpp
@@ -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);
+}
diff --git a/build/windows/HGTest/HGTestDlg.h b/build/windows/HGTest/HGTestDlg.h
index 740f4d05..27d82c67 100644
--- a/build/windows/HGTest/HGTestDlg.h
+++ b/build/windows/HGTest/HGTestDlg.h
@@ -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);
};
diff --git a/modules/sane_user/HGSane.cpp b/modules/sane_user/HGSane.cpp
index 8cb6e9d1..1a00a7da 100644
--- a/modules/sane_user/HGSane.cpp
+++ b/modules/sane_user/HGSane.cpp
@@ -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();
}
\ No newline at end of file
diff --git a/modules/sane_user/HGSane.h b/modules/sane_user/HGSane.h
index ae6ff9ab..502332bc 100644
--- a/modules/sane_user/HGSane.h
+++ b/modules/sane_user/HGSane.h
@@ -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__ */
\ No newline at end of file
diff --git a/modules/sane_user/HGSaneImpl.cpp b/modules/sane_user/HGSaneImpl.cpp
index 198c9040..c2f6c5a6 100644
--- a/modules/sane_user/HGSaneImpl.cpp
+++ b/modules/sane_user/HGSaneImpl.cpp
@@ -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,198 +143,365 @@ 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::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;
} while (0);
return ret;
+}
+
+void HGSaneManagerImpl::RemoveDevice(class HGSaneDeviceImpl* deviceImpl)
+{
+ std::list::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(¶ms, 0, sizeof(SANE_Parameters));
+ SANE_Status stat = m_mgrImpl->m_f_sane_get_parameters(m_devHandle, ¶ms);
+ 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(¶ms, 0, sizeof(SANE_Parameters));
+ SANE_Status stat1 = p->m_mgrImpl->m_f_sane_get_parameters(p->m_devHandle, ¶ms);
+
+ 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);
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/modules/sane_user/HGSaneImpl.hpp b/modules/sane_user/HGSaneImpl.hpp
index 2b2ed4d8..d94e3640 100644
--- a/modules/sane_user/HGSaneImpl.hpp
+++ b/modules/sane_user/HGSaneImpl.hpp
@@ -7,6 +7,7 @@
#include "../base/HGThread.h"
#include "../base/HGLock.h"
#include "sane.h"
+#include "saneopts.h"
#include
#include
@@ -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 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 m_listDeviceImpl;
+};
- std::list 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__ */