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__ */