code_app/sdk/scannerlib/HGLibDeviceImpl.cpp

1094 lines
28 KiB
C++
Raw Normal View History

2022-07-19 03:51:00 +00:00
#include "HGLibDeviceImpl.hpp"
#include "base/HGInc.h"
#include "base/HGInfo.h"
2022-07-19 09:09:52 +00:00
#include "base/HGImage.h"
2022-07-19 03:51:00 +00:00
#include "HGString.h"
const char* GROUP_NAME[] = {
NULL,
"\345\237\272\346\234\254\350\256\276\347\275\256",
"\344\272\256\345\272\246",
"\345\233\276\345\203\217\345\244\204\347\220\206",
"\351\200\201\347\272\270\346\226\271\345\274\217\350\256\276\347\275\256"
};
const char* OPTION_NAME[] = {
NULL,
OPTION_TITLE_DLSC,
OPTION_TITLE_DLSCLX,
OPTION_TITLE_YSMS,
OPTION_TITLE_HBTXYZ,
OPTION_TITLE_HDHHBTX_CS,
OPTION_TITLE_24WCSTX_DLSCCH,
OPTION_TITLE_24WCSTX_DTKCH,
OPTION_TITLE_BJYC,
OPTION_TITLE_BJSCFDFW,
OPTION_TITLE_RHYMH,
OPTION_TITLE_QCMW,
OPTION_TITLE_CWW,
OPTION_TITLE_CWKS,
OPTION_TITLE_HBTXZDYH,
OPTION_TITLE_ZDYHCC,
OPTION_TITLE_ZZCC,
OPTION_TITLE_ZDYSMQY,
OPTION_TITLE_SMQYZCmm,
OPTION_TITLE_SMQYYCmm,
OPTION_TITLE_SMQYSCmm,
OPTION_TITLE_SMQYXCmm,
OPTION_TITLE_CCJC,
OPTION_TITLE_SMYM,
OPTION_TITLE_TGKBYLMD,
OPTION_TITLE_FZQD,
OPTION_TITLE_XMSJ,
OPTION_TITLE_FBL,
OPTION_TITLE_HZ,
OPTION_TITLE_JHZFM,
OPTION_TITLE_TXCF,
OPTION_TITLE_ZDJP,
OPTION_TITLE_QYSDQX,
OPTION_TITLE_LDZ,
OPTION_TITLE_DBD,
OPTION_TITLE_GMZ,
OPTION_TITLE_ZPMS,
OPTION_TITLE_XCHK,
OPTION_TITLE_SSYZ,
OPTION_TITLE_YZ,
OPTION_TITLE_BJKZDJ,
OPTION_TITLE_BYSJ,
OPTION_TITLE_BJTCFS,
OPTION_TITLE_FZST,
OPTION_TITLE_FZSTDJ,
OPTION_TITLE_CKYC,
OPTION_TITLE_CKSSFWZFMBL,
OPTION_TITLE_SCTC,
OPTION_TITLE_CSBJC,
OPTION_TITLE_SZTPCL,
OPTION_TITLE_ZDJC,
OPTION_TITLE_SMZS,
OPTION_TITLE_SMSL,
OPTION_TITLE_WGFX,
OPTION_TITLE_BMXZ180,
OPTION_TITLE_ZJJC,
OPTION_TITLE_ZJDX,
OPTION_TITLE_WXJC,
OPTION_TITLE_WXRRD,
OPTION_TITLE_ZDCZQD,
OPTION_TITLE_CZYZ,
OPTION_TITLE_DZSM
};
const char* OPTION_ENUMVALUE[] = {
NULL,
OPTION_VALUE_DLSCLX_W,
OPTION_VALUE_DLSCLX_CS_HD_HB,
OPTION_VALUE_DLSCLX_CS_HD,
OPTION_VALUE_DLSCLX_CS_HB,
OPTION_VALUE_DLSCLX_HD_HB,
OPTION_VALUE_YSMS_24WCS,
OPTION_VALUE_YSMS_256JHD,
OPTION_VALUE_YSMS_HB,
OPTION_VALUE_YSMS_YSZDSB,
OPTION_VALUE_HDHHBTX_CS_BCS,
OPTION_VALUE_HDHHBTX_CS_CHS,
OPTION_VALUE_HDHHBTX_CS_CLS,
OPTION_VALUE_HDHHBTX_CS_CHULANSE,
OPTION_VALUE_HDHHBTX_CS_HSZQ,
OPTION_VALUE_HDHHBTX_CS_LSZQ,
OPTION_VALUE_HDHHBTX_CS_LANSEZENGQIANG,
OPTION_VALUE_RHYMH_W,
OPTION_VALUE_RHYMH_RH,
OPTION_VALUE_RHYMH_JYBRH,
OPTION_VALUE_RHYMH_MH,
OPTION_VALUE_RHYMH_JYBMH,
OPTION_VALUE_ZZCC_A3,
OPTION_VALUE_ZZCC_8K,
OPTION_VALUE_ZZCC_A4,
OPTION_VALUE_ZZCC_A4HX,
OPTION_VALUE_ZZCC_16K,
OPTION_VALUE_ZZCC_16KHX,
OPTION_VALUE_ZZCC_A5,
OPTION_VALUE_ZZCC_A5HX,
OPTION_VALUE_ZZCC_A6,
OPTION_VALUE_ZZCC_A6HX,
OPTION_VALUE_ZZCC_B4,
OPTION_VALUE_ZZCC_B5,
OPTION_VALUE_ZZCC_B5HX,
OPTION_VALUE_ZZCC_B6,
OPTION_VALUE_ZZCC_B6HX,
OPTION_VALUE_ZZCC_Letter,
OPTION_VALUE_ZZCC_LetterHX,
OPTION_VALUE_ZZCC_DoubleLetter,
OPTION_VALUE_ZZCC_LEGAL,
OPTION_VALUE_ZZCC_PPYSCC,
OPTION_VALUE_ZZCC_ZDSMCCZDCQ,
OPTION_VALUE_ZZCC_ZDSMCC,
OPTION_VALUE_ZZCC_SLSJ,
OPTION_VALUE_SMYM_DM,
OPTION_VALUE_SMYM_SM,
OPTION_VALUE_SMYM_TGKBYTY,
OPTION_VALUE_SMYM_TGKBYFPZ,
OPTION_VALUE_SMYM_DZ,
OPTION_VALUE_HZ_W,
OPTION_VALUE_HZ_SDYX,
OPTION_VALUE_HZ_HZYX,
OPTION_VALUE_BJTCFS_TDBX,
OPTION_VALUE_BJTCFS_ADBX,
OPTION_VALUE_FZSTDJ_R,
OPTION_VALUE_FZSTDJ_JR,
OPTION_VALUE_FZSTDJ_YB,
OPTION_VALUE_FZSTDJ_JQ,
OPTION_VALUE_FZSTDJ_Q,
OPTION_VALUE_SZTPCL_DQTXBTZSM,
OPTION_VALUE_SZTPCL_DQTXBJXSM,
OPTION_VALUE_SZTPCL_SCTXBTZSM,
OPTION_VALUE_SZTPCL_SCTXBJXSM,
OPTION_VALUE_SMZS_LXSM,
OPTION_VALUE_SMZS_SMZDZS,
OPTION_VALUE_WGFX_0,
OPTION_VALUE_WGFX_90,
OPTION_VALUE_WGFX_180,
OPTION_VALUE_WGFX__90,
OPTION_VALUE_WGFX_ZDWBFXSB
};
struct DeviceParam
{
DeviceParam()
{
valueType = 0;
intValue = 0;
doubleValue = 0;
boolValue = false;
rangeType = 0;
intValueMin = 0;
intValueMax = 0;
doubleValueMin = 0;
doubleValueMax = 0;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
2022-08-18 10:42:57 +00:00
std::string option;
int valueType;
std::string stringValue;
int intValue;
double doubleValue;
bool boolValue;
int rangeType;
std::vector<std::string> stringValueList;
std::vector<int> intValueList;
std::vector<double> doubleValueList;
int intValueMin;
int intValueMax;
double doubleValueMin;
double doubleValueMax;
};
struct DeviceParamsGroup
{
std::string groupName;
std::vector<DeviceParam> devParams;
};
2022-07-19 03:51:00 +00:00
HGLibDeviceHotPlugEventFunc HGLibDeviceImpl::m_hotPlugEventFunc = NULL;
HGPointer HGLibDeviceImpl::m_hotPlugEventParam = NULL;
HGBool HGLibDeviceImpl::m_init = HGFALSE;
2022-07-19 09:09:52 +00:00
std::map<SANE_Handle, HGLibDeviceImpl*> HGLibDeviceImpl::m_deviceList;
2022-07-19 03:51:00 +00:00
HGLibDeviceImpl::HGLibDeviceImpl()
{
2022-07-19 09:09:52 +00:00
m_devHandle = NULL;
m_devName.clear();
m_scanning = HGFALSE;
m_scanEvent = NULL;
m_eventFunc = NULL;
m_eventParam = NULL;
m_imageFunc = NULL;
m_imageParam = NULL;
2022-07-19 03:51:00 +00:00
}
HGLibDeviceImpl::~HGLibDeviceImpl()
{
}
HGBool HGLibDeviceImpl::Init(HGLibDeviceHotPlugEventFunc func, HGPointer param)
{
if (m_init)
{
return HGFALSE;
}
assert(NULL == m_hotPlugEventFunc);
m_hotPlugEventFunc = func;
m_hotPlugEventParam = param;
SANE_Int version_code = 0;
if (SANE_STATUS_GOOD != sane_init_ex(&version_code, sane_ex_callback, NULL))
{
m_hotPlugEventFunc = NULL;
m_hotPlugEventParam = NULL;
return HGFALSE;
}
m_init = HGTRUE;
return HGTRUE;
}
HGBool HGLibDeviceImpl::Deinit()
{
if (!m_init)
{
return HGFALSE;
}
2022-07-19 09:09:52 +00:00
if (!m_deviceList.empty())
{
return HGFALSE;
}
2022-07-19 03:51:00 +00:00
sane_exit();
m_hotPlugEventFunc = NULL;
m_hotPlugEventParam = NULL;
m_init = HGFALSE;
return HGTRUE;
}
HGChar** HGLibDeviceImpl::GetNameList()
{
2022-07-20 06:30:01 +00:00
const SANE_Device **device = NULL;
sane_get_devices(&device, SANE_TRUE);
if (NULL == device)
{
return NULL;
}
std::vector<std::string> devNameList;
const SANE_Device** p = device;
while (NULL != *p)
{
devNameList.push_back((*p)->name);
++p;
}
2022-07-19 09:09:52 +00:00
2022-07-20 06:30:01 +00:00
if (devNameList.empty())
{
return NULL;
}
HGChar** nameList = (HGChar **)malloc((devNameList.size() + 1) * sizeof(HGChar *));
2022-07-19 09:09:52 +00:00
if (NULL != nameList)
{
2022-07-20 06:30:01 +00:00
nameList[devNameList.size()] = NULL;
for (int i = 0; i < (int)devNameList.size(); ++i)
2022-07-19 09:09:52 +00:00
{
2022-07-20 06:30:01 +00:00
nameList[i] = (HGChar *)malloc(devNameList[i].size() + 1);
2022-07-19 09:09:52 +00:00
if (NULL != nameList[i])
2022-07-20 06:30:01 +00:00
strcpy(nameList[i], devNameList[i].c_str());
2022-07-19 09:09:52 +00:00
}
}
return nameList;
2022-07-19 03:51:00 +00:00
}
HGBool HGLibDeviceImpl::ReleaseNameList(HGChar** deviceName)
{
if (NULL == deviceName)
{
return HGFALSE;
}
2022-07-19 09:09:52 +00:00
HGChar** p = deviceName;
while (0 != *p)
2022-07-19 03:51:00 +00:00
{
2022-07-19 09:09:52 +00:00
free(*p);
++p;
2022-07-19 03:51:00 +00:00
}
free(deviceName);
return HGTRUE;
}
2022-07-19 09:09:52 +00:00
HGLibDeviceImpl* HGLibDeviceImpl::Open(const HGChar* deviceName)
{
SANE_Handle devHandle = NULL;
sane_open(deviceName, &devHandle);
if (NULL == devHandle)
{
return NULL;
}
HGLibDeviceImpl* deviceImpl = new HGLibDeviceImpl;
deviceImpl->m_devHandle = devHandle;
deviceImpl->m_devName = deviceName;
m_deviceList[devHandle] = deviceImpl;
return deviceImpl;
}
HGBool HGLibDeviceImpl::Close()
{
assert(NULL != m_devHandle);
assert(!m_devName.empty());
StopScan();
sane_close(m_devHandle);
m_devHandle = NULL;
m_devName.clear();
std::map<SANE_Handle, HGLibDeviceImpl*>::iterator iter;
for (iter = m_deviceList.begin(); iter != m_deviceList.end(); ++iter)
{
if (iter->second == this)
{
m_deviceList.erase(iter);
break;
}
}
delete this;
return HGTRUE;
}
HGBool HGLibDeviceImpl::SetParam(HGUInt option, const HGVoid* data)
{
assert(NULL != m_devHandle);
if (NULL == data)
return HGFALSE;
const char *optionName = GetOptionName(option);
if (NULL == optionName)
return HGFALSE;
HGBool ret = HGFALSE;
SANE_Int num_dev_options = 0;
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 = sane_get_option_descriptor(m_devHandle, i);
if (NULL == desp)
continue;
const char* name = desp->title;
2022-08-18 10:42:57 +00:00
while (' ' == *name)
++name;
if (0 == strcmp(optionName, name))
{
if (SANE_TYPE_STRING == desp->type)
{
SANE_Char* value = (SANE_Char*)GetOptionEnumValue(*(HGUInt*)data);
if (NULL != value)
{
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, value, NULL))
ret = HGTRUE;
}
}
else if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = (SANE_Int)(*(HGInt*)data);
if (SANE_STATUS_GOOD != sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = HGTRUE;
}
else if (SANE_TYPE_FIXED == desp->type)
{
SANE_Fixed value = SANE_FIX(*(HGDouble*)data);
if (SANE_STATUS_GOOD != sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = HGTRUE;
}
else if (SANE_TYPE_BOOL == desp->type)
{
SANE_Bool value = (SANE_Bool)(*(HGBool*)data);
if (SANE_STATUS_GOOD != sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, &value, NULL))
ret = HGTRUE;
}
break;
}
}
return ret;
}
HGLibDeviceParamGroup* HGLibDeviceImpl::GetParamGroupList(HGUInt* count)
2022-07-19 09:09:52 +00:00
{
assert(NULL != m_devHandle);
if (NULL == count)
return NULL;
std::vector<DeviceParamsGroup> devParams;
SANE_Int num_dev_options = 0;
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 = sane_get_option_descriptor(m_devHandle, i);
if (NULL == desp)
continue;
const char* name = desp->title;
2022-08-18 10:42:57 +00:00
while (' ' == *name)
++name;
if (SANE_TYPE_GROUP == desp->type)
{
DeviceParamsGroup group;
2022-08-18 10:42:57 +00:00
group.groupName = name;
devParams.push_back(group);
}
else if (SANE_TYPE_STRING == desp->type)
{
char value[256] = { 0 };
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL);
DeviceParam devParam;
2022-08-18 10:42:57 +00:00
devParam.option = name;
devParam.valueType = HGLIB_OPTION_VALUETYPE_ENUM;
devParam.stringValue = value;
assert(SANE_CONSTRAINT_STRING_LIST == desp->constraint_type);
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_ENUMLIST;
const SANE_String_Const* p = desp->constraint.string_list;
while (NULL != *p)
{
devParam.stringValueList.push_back(*p);
++p;
}
assert(!devParams.empty());
devParams[devParams.size() - 1].devParams.push_back(devParam);
}
else if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
DeviceParam devParam;
2022-08-18 10:42:57 +00:00
devParam.option = name;
devParam.valueType = HGLIB_OPTION_VALUETYPE_INT;
devParam.intValue = (int)value;
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTLIST;
const SANE_Word* p = desp->constraint.word_list;
for (SANE_Int i = 0; i < p[0]; ++i)
{
devParam.intValueList.push_back(p[i + 1]);
}
}
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTRANGE;
devParam.intValueMin = desp->constraint.range->min;
devParam.intValueMax = desp->constraint.range->max;
}
assert(!devParams.empty());
devParams[devParams.size() - 1].devParams.push_back(devParam);
}
else if (SANE_TYPE_FIXED == desp->type)
{
SANE_Word value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
DeviceParam devParam;
2022-08-18 10:42:57 +00:00
devParam.option = name;
devParam.valueType = HGLIB_OPTION_VALUETYPE_DOUBLE;
devParam.doubleValue = SANE_UNFIX(value);
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST;
const SANE_Word* p = desp->constraint.word_list;
for (SANE_Int i = 0; i < p[0]; ++i)
{
devParam.doubleValueList.push_back(SANE_UNFIX(p[i + 1]));
}
}
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE;
devParam.doubleValueMin = SANE_UNFIX(desp->constraint.range->min);
devParam.doubleValueMax = SANE_UNFIX(desp->constraint.range->max);
}
assert(!devParams.empty());
devParams[devParams.size() - 1].devParams.push_back(devParam);
}
else if (SANE_TYPE_BOOL == desp->type)
{
SANE_Bool value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
DeviceParam devParam;
2022-08-18 10:42:57 +00:00
devParam.option = name;
devParam.valueType = HGLIB_OPTION_VALUETYPE_BOOL;
devParam.boolValue = (bool)value;
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_NULL;
assert(!devParams.empty());
devParams[devParams.size() - 1].devParams.push_back(devParam);
}
}
*count = (HGUInt)devParams.size();
HGLibDeviceParamGroup* paramGroup = (HGLibDeviceParamGroup*)malloc((*count) * sizeof(HGLibDeviceParamGroup));
if (NULL != paramGroup)
{
for (int i = 0; i < (int)devParams.size(); ++i)
{
paramGroup[i].group = GetGroupName(devParams[i].groupName.c_str());
paramGroup[i].paramCount = (HGUInt)devParams[i].devParams.size();
paramGroup[i].param = (HGLibDeviceParam*)malloc(paramGroup[i].paramCount * sizeof(HGLibDeviceParam));
if (NULL != paramGroup[i].param)
{
for (int j = 0; j < (int)devParams[i].devParams.size(); ++j)
{
HGLibDeviceParam& dest = paramGroup[i].param[j];
DeviceParam& src = devParams[i].devParams[j];
dest.option = GetOptionName(src.option.c_str());
2022-08-18 10:42:57 +00:00
dest.type = src.valueType;
if (HGLIB_OPTION_VALUETYPE_INT == dest.type)
2022-08-18 10:42:57 +00:00
dest.intValue = src.intValue;
else if (HGLIB_OPTION_VALUETYPE_DOUBLE == dest.type)
2022-08-18 10:42:57 +00:00
dest.doubleValue = src.doubleValue;
else if (HGLIB_OPTION_VALUETYPE_BOOL == dest.type)
2022-08-18 10:42:57 +00:00
dest.boolValue = (HGBool)src.boolValue;
else if (HGLIB_OPTION_VALUETYPE_ENUM == dest.type)
dest.enumValue = GetOptionEnumValue(src.stringValue.c_str());
dest.rangeType = src.rangeType;
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == dest.rangeType)
{
2022-07-20 06:30:01 +00:00
dest.intValueList.count = (HGUInt)src.intValueList.size();
dest.intValueList.value = (HGInt *)malloc(dest.intValueList.count * sizeof(HGInt));
if (NULL != dest.intValueList.value)
{
for (int k = 0; k < (int)src.intValueList.size(); ++k)
{
dest.intValueList.value[k] = src.intValueList[k];
}
}
}
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == dest.rangeType)
{
2022-07-20 06:30:01 +00:00
dest.doubleValueList.count = (HGUInt)src.doubleValueList.size();
dest.doubleValueList.value = (HGDouble*)malloc(dest.doubleValueList.count * sizeof(HGDouble));
if (NULL != dest.doubleValueList.value)
{
for (int k = 0; k < (int)src.doubleValueList.size(); ++k)
{
dest.doubleValueList.value[k] = src.doubleValueList[k];
}
}
}
else if (HGLIB_OPTION_VALUERANGETYPE_INTRANGE == dest.rangeType)
{
dest.intValueRange.minValue = src.intValueMin;
dest.intValueRange.maxValue = src.intValueMax;
}
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE == dest.rangeType)
{
dest.doubleValueRange.minValue = src.doubleValueMin;
dest.doubleValueRange.maxValue = src.doubleValueMax;
}
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == dest.rangeType)
{
dest.enumValueList.count = (HGUInt)src.stringValueList.size();
dest.enumValueList.value = (HGUInt*)malloc(dest.enumValueList.count * sizeof(HGUInt));
if (NULL != dest.enumValueList.value)
{
for (int k = 0; k < (int)src.stringValueList.size(); ++k)
{
dest.enumValueList.value[k] = GetOptionEnumValue(src.stringValueList[k].c_str());
}
}
}
}
}
}
}
return paramGroup;
2022-07-19 09:09:52 +00:00
}
HGLibDeviceParam* HGLibDeviceImpl::GetParam(HGUInt option)
{
assert(NULL != m_devHandle);
const char* optionName = GetOptionName(option);
if (NULL == optionName)
return NULL;
HGLibDeviceParam* param = NULL;
SANE_Int num_dev_options = 0;
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 = sane_get_option_descriptor(m_devHandle, i);
if (NULL == desp)
continue;
const char* name = desp->title;
2022-08-18 10:42:57 +00:00
while (' ' == *name)
++name;
if (0 == strcmp(optionName, name))
{
DeviceParam devParam;
2022-08-18 10:42:57 +00:00
devParam.option = name;
if (SANE_TYPE_STRING == desp->type)
{
char value[256] = { 0 };
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, value, NULL);
devParam.valueType = HGLIB_OPTION_VALUETYPE_ENUM;
devParam.stringValue = value;
assert(SANE_CONSTRAINT_STRING_LIST == desp->constraint_type);
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_ENUMLIST;
const SANE_String_Const* p = desp->constraint.string_list;
while (NULL != *p)
{
devParam.stringValueList.push_back(*p);
++p;
}
}
else if (SANE_TYPE_INT == desp->type)
{
SANE_Int value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
devParam.valueType = HGLIB_OPTION_VALUETYPE_INT;
devParam.intValue = (int)value;
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTLIST;
const SANE_Word* p = desp->constraint.word_list;
for (SANE_Int i = 0; i < p[0]; ++i)
{
devParam.intValueList.push_back(p[i + 1]);
}
}
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_INTRANGE;
devParam.intValueMin = desp->constraint.range->min;
devParam.intValueMax = desp->constraint.range->max;
}
}
else if (SANE_TYPE_FIXED == desp->type)
{
SANE_Word value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
devParam.valueType = HGLIB_OPTION_VALUETYPE_DOUBLE;
devParam.doubleValue = SANE_UNFIX(value);
if (SANE_CONSTRAINT_WORD_LIST == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST;
const SANE_Word* p = desp->constraint.word_list;
for (SANE_Int i = 0; i < p[0]; ++i)
{
devParam.doubleValueList.push_back(SANE_UNFIX(p[i + 1]));
}
}
else if (SANE_CONSTRAINT_RANGE == desp->constraint_type)
{
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE;
devParam.doubleValueMin = SANE_UNFIX(desp->constraint.range->min);
devParam.doubleValueMax = SANE_UNFIX(desp->constraint.range->max);
}
}
else if (SANE_TYPE_BOOL == desp->type)
{
SANE_Bool value = 0;
sane_control_option(m_devHandle, i, SANE_ACTION_GET_VALUE, &value, NULL);
devParam.valueType = HGLIB_OPTION_VALUETYPE_BOOL;
devParam.boolValue = (bool)value;
devParam.rangeType = HGLIB_OPTION_VALUERANGETYPE_NULL;
}
assert(0 != devParam.valueType);
param = (HGLibDeviceParam*)malloc(sizeof(HGLibDeviceParam));
if (NULL != param)
{
param->option = GetOptionName(devParam.option.c_str());
2022-08-18 10:42:57 +00:00
param->type = devParam.valueType;
if (HGLIB_OPTION_VALUETYPE_INT == param->type)
2022-08-18 10:42:57 +00:00
param->intValue = devParam.intValue;
else if (HGLIB_OPTION_VALUETYPE_DOUBLE == param->type)
2022-08-18 10:42:57 +00:00
param->doubleValue = devParam.doubleValue;
else if (HGLIB_OPTION_VALUETYPE_BOOL == param->type)
2022-08-18 10:42:57 +00:00
param->boolValue = (HGBool)devParam.boolValue;
else if (HGLIB_OPTION_VALUETYPE_ENUM == param->type)
param->enumValue = GetOptionEnumValue(devParam.stringValue.c_str());
param->rangeType = devParam.rangeType;
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == param->rangeType)
{
param->intValueList.count = (HGUInt)devParam.intValueList.size();
param->intValueList.value = (HGInt*)malloc(param->intValueList.count * sizeof(HGInt));
if (NULL != param->intValueList.value)
{
for (int k = 0; k < (int)devParam.intValueList.size(); ++k)
{
param->intValueList.value[k] = devParam.intValueList[k];
}
}
}
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == param->rangeType)
{
param->doubleValueList.count = (HGUInt)devParam.doubleValueList.size();
param->doubleValueList.value = (HGDouble*)malloc(param->doubleValueList.count * sizeof(HGDouble));
if (NULL != param->doubleValueList.value)
{
for (int k = 0; k < (int)devParam.doubleValueList.size(); ++k)
{
param->doubleValueList.value[k] = devParam.doubleValueList[k];
}
}
}
else if (HGLIB_OPTION_VALUERANGETYPE_INTRANGE == param->rangeType)
{
param->intValueRange.minValue = devParam.intValueMin;
param->intValueRange.maxValue = devParam.intValueMax;
}
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLERANGE == param->rangeType)
{
param->doubleValueRange.minValue = devParam.doubleValueMin;
param->doubleValueRange.maxValue = devParam.doubleValueMax;
}
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == param->rangeType)
{
param->enumValueList.count = (HGUInt)devParam.stringValueList.size();
param->enumValueList.value = (HGUInt*)malloc(param->enumValueList.count * sizeof(HGUInt));
if (NULL != param->enumValueList.value)
{
for (int k = 0; k < (int)devParam.stringValueList.size(); ++k)
{
param->enumValueList.value[k] = GetOptionEnumValue(devParam.stringValueList[k].c_str());
}
}
}
}
break;
}
}
return param;
}
HGBool HGLibDeviceImpl::ReleaseParamGroupList(HGLibDeviceParamGroup* paramGroup, HGUInt count)
2022-07-19 09:09:52 +00:00
{
if (NULL == paramGroup || 0 == count)
{
return HGFALSE;
}
for (HGUInt i = 0; i < count; ++i)
{
for (HGUInt j = 0; j < paramGroup[i].paramCount; ++j)
{
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == paramGroup[i].param[j].rangeType)
free(paramGroup[i].param[j].intValueList.value);
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == paramGroup[i].param[j].rangeType)
free(paramGroup[i].param[j].doubleValueList.value);
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == paramGroup[i].param[j].rangeType)
free(paramGroup[i].param[j].enumValueList.value);
}
free(paramGroup[i].param);
}
free(paramGroup);
return HGTRUE;
2022-07-19 09:09:52 +00:00
}
HGBool HGLibDeviceImpl::ReleaseParam(HGLibDeviceParam* param)
{
if (NULL == param)
{
return HGFALSE;
}
if (HGLIB_OPTION_VALUERANGETYPE_INTLIST == param->rangeType)
free(param->intValueList.value);
else if (HGLIB_OPTION_VALUERANGETYPE_DOUBLELIST == param->rangeType)
free(param->doubleValueList.value);
else if (HGLIB_OPTION_VALUERANGETYPE_ENUMLIST == param->rangeType)
free(param->enumValueList.value);
free(param);
return HGTRUE;
}
2022-07-19 09:09:52 +00:00
HGBool HGLibDeviceImpl::ResetParam()
{
assert(NULL != m_devHandle);
HGBool ret = HGFALSE;
SANE_Int num_dev_options = 0;
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 = sane_get_option_descriptor(m_devHandle, i);
if (NULL == desp)
continue;
const char* title = desp->title;
while (' ' == *title)
++title;
if (0 == strcmp(OPTION_TITLE_HFMRSZ, title) && SANE_TYPE_BUTTON == desp->type)
{
if (SANE_STATUS_GOOD == sane_control_option(m_devHandle, i, SANE_ACTION_SET_VALUE, NULL, NULL))
ret = HGTRUE;
break;
}
}
return ret;
2022-07-19 09:09:52 +00:00
}
HGBool HGLibDeviceImpl::StartScan(HGLibDeviceScanEventFunc eventFunc, HGPointer eventParam,
HGLibDeviceScanImageFunc imageFunc, HGPointer imageParam)
{
if (m_scanning)
{
return HGFALSE;
}
HGBase_CreateEvent(HGFALSE, HGFALSE, &m_scanEvent);
assert(NULL != m_scanEvent);
m_eventFunc = eventFunc;
m_eventParam = eventParam;
m_imageFunc = imageFunc;
m_imageParam = imageParam;
SANE_Status status = sane_start(m_devHandle);
if (SANE_STATUS_GOOD != status)
{
m_eventFunc = NULL;
m_eventParam = NULL;
m_imageFunc = NULL;
m_imageParam = NULL;
HGBase_DestroyEvent(m_scanEvent);
m_scanEvent = NULL;
return HGFALSE;
}
m_scanning = HGTRUE;
return HGTRUE;
}
HGBool HGLibDeviceImpl::StopScan()
{
if (!m_scanning)
{
return HGFALSE;
}
sane_cancel(m_devHandle);
assert(NULL != m_scanEvent);
HGBase_WaitEvent(m_scanEvent);
HGBase_DestroyEvent(m_scanEvent);
m_scanEvent = NULL;
m_eventFunc = NULL;
m_eventParam = NULL;
m_imageFunc = NULL;
m_imageParam = NULL;
m_scanning = HGFALSE;
return HGTRUE;
}
const char* HGLibDeviceImpl::GetGroupName(HGUInt group)
{
if (group > HGLIB_GROUP_NAME_PAPERFEEDING)
return NULL;
return GROUP_NAME[group];
}
HGUInt HGLibDeviceImpl::GetGroupName(const char* group)
{
if (NULL == group)
return 0;
HGUInt ret = 0;
for (int i = 1; i < sizeof(GROUP_NAME) / sizeof(const char*); ++i)
{
if (0 == strcmp(group, GROUP_NAME[i]))
{
ret = i;
break;
}
}
return ret;
}
const char* HGLibDeviceImpl::GetOptionName(HGUInt option)
{
if (option > HGLIB_OPTION_NAME_DZSM)
return NULL;
return OPTION_NAME[option];
}
HGUInt HGLibDeviceImpl::GetOptionName(const char* option)
{
if (NULL == option)
return 0;
HGUInt ret = 0;
for (int i = 1; i < sizeof(OPTION_NAME) / sizeof(const char*); ++i)
{
if (0 == strcmp(option, OPTION_NAME[i]))
{
ret = i;
break;
}
}
return ret;
}
const char* HGLibDeviceImpl::GetOptionEnumValue(HGUInt enumValue)
{
if (enumValue > HGLIB_OPTION_ENUMVALUE_WGFX_ZDWBFXSB)
return NULL;
return OPTION_ENUMVALUE[enumValue];
}
HGUInt HGLibDeviceImpl::GetOptionEnumValue(const char* enumValue)
{
if (NULL == enumValue)
return 0;
HGUInt ret = 0;
for (int i = 1; i < sizeof(OPTION_ENUMVALUE) / sizeof(const char*); ++i)
{
if (0 == strcmp(enumValue, OPTION_ENUMVALUE[i]))
{
ret = i;
break;
}
}
return ret;
}
2022-07-19 03:51:00 +00:00
int HGLibDeviceImpl::sane_ex_callback(SANE_Handle hdev, int code, void* data, unsigned int* len, void* param)
{
switch (code)
{
case SANE_EVENT_DEVICE_ARRIVED:
{
SANE_Device* sane_dev = (SANE_Device*)data;
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_ARRIVED, name=%s", Utf8ToStdString(sane_dev->name).c_str());
if (NULL != m_hotPlugEventFunc)
m_hotPlugEventFunc(HGLIB_DEVHOTPLUG_EVENT_ARRIVE, sane_dev->name, m_hotPlugEventParam);
}
break;
case SANE_EVENT_DEVICE_LEFT:
{
SANE_Device* sane_dev = (SANE_Device*)data;
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_DEVICE_LEFT, name=%s", Utf8ToStdString(sane_dev->name).c_str());
2022-07-19 09:09:52 +00:00
if (NULL != m_hotPlugEventFunc)
m_hotPlugEventFunc(HGLIB_DEVHOTPLUG_EVENT_REMOVE, sane_dev->name, m_hotPlugEventParam);
}
break;
case SANE_EVENT_WORKING:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_WORKING, msg=%s", Utf8ToStdString((char*)data).c_str());
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
if (NULL != deviceImpl->m_eventFunc)
{
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_BEGIN,
HGFALSE, NULL, deviceImpl->m_eventParam);
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_INFO,
HGFALSE, (const char*)data, deviceImpl->m_eventParam);
}
}
break;
case SANE_EVENT_SCAN_FINISHED:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_SCAN_FINISHED, msg=%s", Utf8ToStdString((char*)data).c_str());
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
if (NULL != deviceImpl->m_eventFunc)
{
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_INFO,
(0 != *len), (const char*)data, deviceImpl->m_eventParam);
deviceImpl->m_eventFunc((HGLibDevice)deviceImpl, HGLIB_DEVSCAN_EVENT_END,
HGFALSE, NULL, deviceImpl->m_eventParam);
}
HGBase_SetEvent(deviceImpl->m_scanEvent);
}
break;
case SANE_EVENT_STATUS:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_STATUS, msg=%s", Utf8ToStdString((char*)data).c_str());
}
break;
case SANE_EVENT_ERROR:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_ERROR, msg=%s", Utf8ToStdString((char*)data).c_str());
}
break;
case SANE_EVENT_IMAGE_OK:
{
HGBase_WriteInfo(HGBASE_INFOTYPE_DESC, "SANE_EVENT_IMAGE_OK");
SANE_Image* sane_img = (SANE_Image*)data;
HGLibDeviceImpl* deviceImpl = m_deviceList[hdev];
if (NULL != deviceImpl->m_imageFunc)
{
HGUInt imgType = 0;
if (sane_img->header.format == SANE_FRAME_GRAY)
{
if (1 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_BINARY;
else if (8 == sane_img->header.depth)
imgType = HGBASE_IMGTYPE_GRAY;
}
else if (sane_img->header.format == SANE_FRAME_RGB)
imgType = HGBASE_IMGTYPE_RGB;
HGByte* data = sane_img->data;
HGImageInfo imgInfo = { (HGUInt)sane_img->header.pixels_per_line, (HGUInt)sane_img->header.lines,
imgType, (HGUInt)sane_img->header.bytes_per_line, HGBASE_IMGORIGIN_TOP };
HGImage img = NULL;
HGBase_CreateImageFromData(data, &imgInfo, NULL, 0, HGBASE_IMGORIGIN_TOP, &img);
if (NULL != img)
{
deviceImpl->m_imageFunc((HGLibDevice)deviceImpl, (HGLibImage)img, deviceImpl->m_imageParam);
HGBase_DestroyImage(img);
}
}
2022-07-19 03:51:00 +00:00
}
break;
}
return 0;
}