#include "HGSaneImpl.hpp" #include "../base/HGInc.h" HGSaneManagerImpl::HGSaneManagerImpl() { m_dll = NULL; m_f_sane_init = NULL; m_f_sane_exit = NULL; m_f_sane_get_devices = NULL; m_f_sane_open = NULL; m_f_sane_close = NULL; m_f_sane_start = NULL; m_f_sane_read = NULL; m_f_sane_cancel = NULL; m_f_sane_set_io_mode = NULL; m_f_sane_strstatus = NULL; } HGSaneManagerImpl::~HGSaneManagerImpl() { } HGResult HGSaneManagerImpl::Create(const HGChar* sanePath) { if (NULL != m_dll) { return HGBASE_ERR_FAIL; } HGResult ret = HGBase_CreateDll(sanePath, &m_dll); if (HGBASE_ERR_OK != ret) { return ret; } ret = FindFunctions(); if (HGBASE_ERR_OK != ret) { HGBase_DestroyDll(m_dll); m_dll = NULL; return ret; } if (SANE_STATUS_GOOD != m_f_sane_init(NULL, NULL)) { HGBase_DestroyDll(m_dll); m_dll = NULL; return HGBASE_ERR_FAIL; } return HGBASE_ERR_OK; } HGResult HGSaneManagerImpl::Destroy() { if (!m_devList.empty()) { return HGBASE_ERR_FAIL; } if (NULL != m_dll) { m_f_sane_exit(); HGBase_DestroyDll(m_dll); m_dll = NULL; } return HGBASE_ERR_OK; } HGResult HGSaneManagerImpl::GetDeviceCount(HGUInt* count) { if (NULL == count) { return HGBASE_ERR_INVALIDARG; } const SANE_Device **device_list; if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE)) { return HGBASE_ERR_FAIL; } *count = 0; const SANE_Device** p; for (p = device_list; *p != NULL; ++p) ++(*count); return HGBASE_ERR_OK; } HGResult HGSaneManagerImpl::GetDeviceName(HGUInt index, HGChar* name, HGUInt maxLen) { if (NULL == name || 0 == maxLen) { return HGBASE_ERR_INVALIDARG; } const SANE_Device** device_list; if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE)) { return HGBASE_ERR_FAIL; } HGUInt count = 0; const SANE_Device** p; for (p = device_list; *p != NULL; ++p) ++count; if (index >= count) return HGBASE_ERR_INVALIDARG; if (NULL == device_list[index]->name) return HGBASE_ERR_FAIL; if (maxLen < strlen(device_list[index]->name) + 1) return HGBASE_ERR_FAIL; strcpy(name, device_list[index]->name); return HGBASE_ERR_OK; } HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device) { if (NULL == device) { return HGBASE_ERR_INVALIDARG; } const SANE_Device** device_list; if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE)) { return HGBASE_ERR_FAIL; } HGUInt count = 0; const SANE_Device** p; for (p = device_list; *p != NULL; ++p) ++count; if (index >= count) return HGBASE_ERR_INVALIDARG; SANE_Handle handle = NULL; if (SANE_STATUS_GOOD != m_f_sane_open(device_list[index]->name, &handle)) { return HGBASE_ERR_FAIL; } m_f_sane_set_io_mode(handle, SANE_FALSE); HGSaneDeviceImpl* saneDeviceImpl = new HGSaneDeviceImpl(this); saneDeviceImpl->devHandle = handle; m_devList.push_back(saneDeviceImpl); *device = saneDeviceImpl; 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 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); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_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); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_open", (HGPointer*)&m_f_sane_open); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_close", (HGPointer*)&m_f_sane_close); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_start", (HGPointer*)&m_f_sane_start); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_read", (HGPointer*)&m_f_sane_read); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_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); if (HGBASE_ERR_OK != ret) break; ret = HGBase_GetDllProcAddress(m_dll, "sane_strstatus", (HGPointer*)&m_f_sane_strstatus); if (HGBASE_ERR_OK != ret) break; } while (0); return ret; }