补充TWAIN属性

This commit is contained in:
gb 2022-06-15 17:07:51 +08:00
parent 12ba0f8979
commit 1205559eaf
4 changed files with 349 additions and 383 deletions

View File

@ -161,59 +161,59 @@ __declspec(novtable) struct ISaneInvoker : public IRef
COM_API_DECLARE(int, set_value(int sn, void* val)); COM_API_DECLARE(int, set_value(int sn, void* val));
// SANE options ID ... // SANE options ID ...
SANE_OPTION_ID_API(is_multiout); SANE_OPTION_ID_API(is_multiout); // 多流输出
SANE_OPTION_ID_API(multiout_type); SANE_OPTION_ID_API(multiout_type); // 多流输出类型
SANE_OPTION_ID_API(color_mode); SANE_OPTION_ID_API(color_mode); // 颜色模式
SANE_OPTION_ID_API(erase_color); SANE_OPTION_ID_API(erase_color); // 除色或增强
SANE_OPTION_ID_API(erase_multiout_red); SANE_OPTION_ID_API(erase_multiout_red); // 多流输出除红
SANE_OPTION_ID_API(erase_paper_red); SANE_OPTION_ID_API(erase_paper_red); // 试卷除红
SANE_OPTION_ID_API(is_erase_background); SANE_OPTION_ID_API(is_erase_background); // 背景移除
SANE_OPTION_ID_API(background_color_range); SANE_OPTION_ID_API(background_color_range); // 背景色彩范围
SANE_OPTION_ID_API(sharpen); SANE_OPTION_ID_API(sharpen); // 锐化与模糊
SANE_OPTION_ID_API(erase_morr); SANE_OPTION_ID_API(erase_morr); // 除摩尔纹
SANE_OPTION_ID_API(erase_grids); // 除网纹 SANE_OPTION_ID_API(erase_grids); // 除网纹
SANE_OPTION_ID_API(error_extend); SANE_OPTION_ID_API(error_extend); // 错误扩散
SANE_OPTION_ID_API(is_noise_modify); SANE_OPTION_ID_API(is_noise_modify); // 噪点优化
SANE_OPTION_ID_API(noise_threshold); SANE_OPTION_ID_API(noise_threshold); // 噪点优化尺寸
SANE_OPTION_ID_API(paper); SANE_OPTION_ID_API(paper); // 纸张尺寸
SANE_OPTION_ID_API(is_custom_area); SANE_OPTION_ID_API(is_custom_area); // 自定义扫描区域
SANE_OPTION_ID_API(curstom_area_l); SANE_OPTION_ID_API(curstom_area_l); // 自定义扫描区域 左
SANE_OPTION_ID_API(curstom_area_r); SANE_OPTION_ID_API(curstom_area_r); // 自定义扫描区域 右
SANE_OPTION_ID_API(curstom_area_t); SANE_OPTION_ID_API(curstom_area_t); // 自定义扫描区域 上
SANE_OPTION_ID_API(curstom_area_b); SANE_OPTION_ID_API(curstom_area_b); // 自定义扫描区域 下
SANE_OPTION_ID_API(is_size_check); SANE_OPTION_ID_API(is_size_check); // 尺寸检测
SANE_OPTION_ID_API(page); SANE_OPTION_ID_API(page); // 扫描页面
SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度 SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度
SANE_OPTION_ID_API(resolution); SANE_OPTION_ID_API(resolution); // 分辨率
SANE_OPTION_ID_API(image_quality); SANE_OPTION_ID_API(image_quality); // 图像质量
SANE_OPTION_ID_API(is_swap); // 交换正反面 SANE_OPTION_ID_API(is_swap); // 交换正反面
SANE_OPTION_ID_API(is_split); // 图像拆分 SANE_OPTION_ID_API(is_split); // 图像拆分
SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏 SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏
SANE_OPTION_ID_API(is_custom_gamma); SANE_OPTION_ID_API(is_custom_gamma); // 自定义gamma
SANE_OPTION_ID_API(bright); SANE_OPTION_ID_API(bright); // 亮度
SANE_OPTION_ID_API(contrast); SANE_OPTION_ID_API(contrast); // 对比度
SANE_OPTION_ID_API(gamma); SANE_OPTION_ID_API(gamma); // gamma
SANE_OPTION_ID_API(is_erase_black_frame); // bool SANE_OPTION_ID_API(is_erase_black_frame); // 消除黑框
SANE_OPTION_ID_API(deep_sample); SANE_OPTION_ID_API(deep_sample); // 深色样张
SANE_OPTION_ID_API(threshold); SANE_OPTION_ID_API(threshold); // 阈值
SANE_OPTION_ID_API(anti_noise); // 抗噪等级 SANE_OPTION_ID_API(anti_noise); // 背景抗噪等级
SANE_OPTION_ID_API(margin); SANE_OPTION_ID_API(margin); // 边缘缩进
SANE_OPTION_ID_API(fill_background); SANE_OPTION_ID_API(fill_background); // 背景填充方式
SANE_OPTION_ID_API(is_anti_permeate); SANE_OPTION_ID_API(is_anti_permeate); // 防止渗透
SANE_OPTION_ID_API(anti_permeate_level); SANE_OPTION_ID_API(anti_permeate_level); // 防止渗透等级
SANE_OPTION_ID_API(is_erase_hole); SANE_OPTION_ID_API(is_erase_hole); // 穿孔移除
SANE_OPTION_ID_API(search_hole_range); SANE_OPTION_ID_API(search_hole_range); // 穿孔搜索范围
SANE_OPTION_ID_API(is_filling_color); // 色彩填充 SANE_OPTION_ID_API(is_filling_color); // 色彩填充
SANE_OPTION_ID_API(is_ultrasonic_check); SANE_OPTION_ID_API(is_ultrasonic_check); // 超声波检测
SANE_OPTION_ID_API(is_check_staple); SANE_OPTION_ID_API(is_check_staple); // 装订检测
SANE_OPTION_ID_API(scan_mode); // 扫描张数 SANE_OPTION_ID_API(scan_mode); // 扫描张数
SANE_OPTION_ID_API(scan_count); // 扫描数量 SANE_OPTION_ID_API(scan_count); // 扫描数量
SANE_OPTION_ID_API(text_direction); SANE_OPTION_ID_API(text_direction); // 文稿方向
SANE_OPTION_ID_API(is_rotate_bkg180); SANE_OPTION_ID_API(is_rotate_bkg180); // 背面旋转180度
SANE_OPTION_ID_API(is_check_dogear); SANE_OPTION_ID_API(is_check_dogear); // 折角检测
SANE_OPTION_ID_API(dogear_size); SANE_OPTION_ID_API(dogear_size); // 折角检测大小
SANE_OPTION_ID_API(is_check_skew); SANE_OPTION_ID_API(is_check_skew); // 歪斜检测
SANE_OPTION_ID_API(skew_range); SANE_OPTION_ID_API(skew_range); // 歪斜容忍度
// SANE-ex option ID: // SANE-ex option ID:
SANE_OPTION_ID_API_EX(multiout_type); // int SANE_OPTION_ID_API_EX(multiout_type); // int

View File

@ -440,7 +440,7 @@ int scanner::set_option_value(int sn, SANE_Value_Type type, int size, void* data
{ {
buf = new char[size + 4]; buf = new char[size + 4];
memset(buf, 0, size + 4); memset(buf, 0, size + 4);
strcpy(buf, (char*)data); strcpy(buf, ((std::string*)data)->c_str());
data = buf; data = buf;
} }
ret = hg_sane_middleware::instance()->set_option(handle_, sn, SANE_ACTION_SET_VALUE, data, &after); ret = hg_sane_middleware::instance()->set_option(handle_, sn, SANE_ACTION_SET_VALUE, data, &after);

View File

@ -20,6 +20,7 @@ using namespace std;
#define enum2str(R) #R #define enum2str(R) #R
#pragma warning(disable: 4700)
using namespace Twpp; using namespace Twpp;
using namespace std::placeholders; using namespace std::placeholders;
@ -65,107 +66,63 @@ enum CapTypeEx : unsigned short {
CAP_TYPE_EX_SCAN_WITH_HOLE = 0x8114, CAP_TYPE_EX_SCAN_WITH_HOLE = 0x8114,
CAP_TYPE_EX_IP = 0x8200, CAP_TYPE_EX_IP = 0x8200,
CAP_TYPE_EX_0 = (int)CapType::CustomBase + 0x800, // SANE设备层原始设置项透传属性
CAP_TYPE_EX_1, CAP_EX_SANE = (int)CapType::CustomBase + 0x800,
CAP_TYPE_EX_2, CAP_EX_SANE_is_multiout,
CAP_TYPE_EX_3, CAP_EX_SANE_multiout_type,
CAP_TYPE_EX_4, CAP_EX_SANE_color_mode,
CAP_TYPE_EX_5, CAP_EX_SANE_erase_color,
CAP_TYPE_EX_6, CAP_EX_SANE_erase_multiout_red,
CAP_TYPE_EX_7, CAP_EX_SANE_erase_paper_red,
CAP_TYPE_EX_8, CAP_EX_SANE_is_erase_background,
CAP_TYPE_EX_9, CAP_EX_SANE_background_color_range,
CAP_TYPE_EX_10, CAP_EX_SANE_sharpen,
CAP_TYPE_EX_11, CAP_EX_SANE_erase_morr,
CAP_TYPE_EX_12, CAP_EX_SANE_erase_grids,
CAP_TYPE_EX_13, CAP_EX_SANE_error_extend,
CAP_TYPE_EX_14, CAP_EX_SANE_is_noise_modify,
CAP_TYPE_EX_15, CAP_EX_SANE_noise_threshold,
CAP_TYPE_EX_16, CAP_EX_SANE_paper,
CAP_TYPE_EX_17, CAP_EX_SANE_is_custom_area,
CAP_TYPE_EX_18, CAP_EX_SANE_curstom_area_l,
CAP_TYPE_EX_19, CAP_EX_SANE_curstom_area_r,
CAP_TYPE_EX_20, CAP_EX_SANE_curstom_area_t,
CAP_TYPE_EX_21, CAP_EX_SANE_curstom_area_b,
CAP_TYPE_EX_22, CAP_EX_SANE_is_size_check,
CAP_TYPE_EX_23, CAP_EX_SANE_page,
CAP_TYPE_EX_24, CAP_EX_SANE_blank_page_threshold,
CAP_TYPE_EX_25, CAP_EX_SANE_resolution,
CAP_TYPE_EX_26, CAP_EX_SANE_image_quality,
CAP_TYPE_EX_27, CAP_EX_SANE_is_swap,
CAP_TYPE_EX_28, CAP_EX_SANE_is_split,
CAP_TYPE_EX_29, CAP_EX_SANE_is_auto_deskew,
CAP_TYPE_EX_30, CAP_EX_SANE_is_custom_gamma,
CAP_TYPE_EX_31, CAP_EX_SANE_bright,
CAP_TYPE_EX_32, CAP_EX_SANE_contrast,
CAP_TYPE_EX_33, CAP_EX_SANE_gamma,
CAP_TYPE_EX_34, CAP_EX_SANE_is_erase_black_frame,
CAP_TYPE_EX_35, CAP_EX_SANE_deep_sample,
CAP_TYPE_EX_36, CAP_EX_SANE_threshold,
CAP_TYPE_EX_37, CAP_EX_SANE_anti_noise,
CAP_TYPE_EX_38, CAP_EX_SANE_margin,
CAP_TYPE_EX_39, CAP_EX_SANE_fill_background,
CAP_TYPE_EX_40, CAP_EX_SANE_is_anti_permeate,
CAP_TYPE_EX_41, CAP_EX_SANE_anti_permeate_level,
CAP_TYPE_EX_42, CAP_EX_SANE_is_erase_hole,
CAP_TYPE_EX_43, CAP_EX_SANE_search_hole_range,
CAP_TYPE_EX_44, CAP_EX_SANE_is_filling_color,
CAP_TYPE_EX_45, CAP_EX_SANE_is_ultrasonic_check,
CAP_TYPE_EX_46, CAP_EX_SANE_is_check_staple,
CAP_TYPE_EX_47, CAP_EX_SANE_scan_mode,
CAP_TYPE_EX_48, CAP_EX_SANE_scan_count,
CAP_TYPE_EX_49, CAP_EX_SANE_text_direction,
CAP_TYPE_EX_50, CAP_EX_SANE_is_rotate_bkg180,
CAP_TYPE_EX_51, CAP_EX_SANE_is_check_dogear,
CAP_TYPE_EX_52, CAP_EX_SANE_dogear_size,
CAP_TYPE_EX_53, CAP_EX_SANE_is_check_skew,
CAP_TYPE_EX_54, CAP_EX_SANE_skew_range,
CAP_TYPE_EX_55, // END for SANE设备层原始设置项透传属性
CAP_TYPE_EX_56, /////////////////////////////////////////////////////////////////////////
CAP_TYPE_EX_57,
CAP_TYPE_EX_58,
CAP_TYPE_EX_59,
CAP_TYPE_EX_60,
CAP_TYPE_EX_61,
CAP_TYPE_EX_62,
CAP_TYPE_EX_63,
CAP_TYPE_EX_64,
CAP_TYPE_EX_65,
CAP_TYPE_EX_66,
CAP_TYPE_EX_67,
CAP_TYPE_EX_68,
CAP_TYPE_EX_69,
CAP_TYPE_EX_70,
CAP_TYPE_EX_71,
CAP_TYPE_EX_72,
CAP_TYPE_EX_73,
CAP_TYPE_EX_74,
CAP_TYPE_EX_75,
CAP_TYPE_EX_76,
CAP_TYPE_EX_77,
CAP_TYPE_EX_78,
CAP_TYPE_EX_79,
CAP_TYPE_EX_80,
CAP_TYPE_EX_81,
CAP_TYPE_EX_82,
CAP_TYPE_EX_83,
CAP_TYPE_EX_84,
CAP_TYPE_EX_85,
CAP_TYPE_EX_86,
CAP_TYPE_EX_87,
CAP_TYPE_EX_88,
CAP_TYPE_EX_89,
CAP_TYPE_EX_90,
CAP_TYPE_EX_91,
CAP_TYPE_EX_92,
CAP_TYPE_EX_93,
CAP_TYPE_EX_94,
CAP_TYPE_EX_95,
CAP_TYPE_EX_96,
CAP_TYPE_EX_97,
CAP_TYPE_EX_98,
CAP_TYPE_EX_99,
CAP_TYPE_EX_100,
}; };
@ -1125,9 +1082,13 @@ void huagao_ds::init_support_caps(void)
if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) { if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) {
data = Capability::createArray<CapType::SupportedCaps>(m_caps.size()); data = Capability::createArray<CapType::SupportedCaps>(m_caps.size());
auto arr = data.array<CapType::SupportedCaps>(); auto arr = data.array<CapType::SupportedCaps>();
std::vector<unsigned int> all;
for (const auto& v : m_caps)
all.push_back((int)v.first);
std::sort(all.begin(), all.end());
UInt32 i = 0; UInt32 i = 0;
for (const auto& kv : m_caps) { for (const auto& kv : all) {
arr[i] = kv.first; arr[i] = (CapType)kv;
i++; i++;
} }
return success(); return success();
@ -2122,7 +2083,7 @@ void huagao_ds::init_support_caps(void)
} }
return CapSupGetAllResetEx<Int32, Int32, (CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN>(msg, data, vals, now, init, curInd, defInd); return CapSupGetAllResetEx<Int32, Int32, (CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN>(msg, data, vals, now, init, curInd, defInd);
}; };
//SET_EXISTING_EXTENSION(ex_color_enhance, (CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR);
m_query[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = msgSupportGetAllSetReset; m_query[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = msgSupportGetAllSetReset;
m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = [this](Msg msg, Capability& data)->Result { m_caps[(CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR] = [this](Msg msg, Capability& data)->Result {
int cur = FILTER_NONE, def = FILTER_NONE; int cur = FILTER_NONE, def = FILTER_NONE;
@ -2184,11 +2145,10 @@ void huagao_ds::init_support_caps(void)
if(op_ind != -1) \ if(op_ind != -1) \
{ \ { \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \ m_query[(CapType)cap] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = m_caps[CapType((int)CAP_TYPE_EX_0 + op_ind)]; \ m_caps[(CapType)cap] = m_caps[CapType((int)CAP_EX_SANE_##scan_ind)]; \
} }
int op_ind = -1; int op_ind = -1;
// SET_EXISTING_EXTENSION(paper, CapType::ISupportedSizes);
SET_EXISTING_EXTENSION(is_swap, CapTypeEx::CAP_TYPE_EX_FLIP); SET_EXISTING_EXTENSION(is_swap, CapTypeEx::CAP_TYPE_EX_FLIP);
SET_EXISTING_EXTENSION(is_rotate_bkg180, CapTypeEx::CAP_TYPE_EX_ROTATE_BKG_180); SET_EXISTING_EXTENSION(is_rotate_bkg180, CapTypeEx::CAP_TYPE_EX_ROTATE_BKG_180);
SET_EXISTING_EXTENSION(is_filling_color, CapTypeEx::CAP_TYPE_EX_FILL_BLACK_BKG); SET_EXISTING_EXTENSION(is_filling_color, CapTypeEx::CAP_TYPE_EX_FILL_BLACK_BKG);
@ -2196,10 +2156,6 @@ void huagao_ds::init_support_caps(void)
SET_EXISTING_EXTENSION(anti_noise, CapTypeEx::CAP_TYPE_EX_ANTI_NOISE); SET_EXISTING_EXTENSION(anti_noise, CapTypeEx::CAP_TYPE_EX_ANTI_NOISE);
SET_EXISTING_EXTENSION(threshold, CapTypeEx::CAP_TYPE_EX_THRESHOLD); SET_EXISTING_EXTENSION(threshold, CapTypeEx::CAP_TYPE_EX_THRESHOLD);
SET_EXISTING_EXTENSION(is_erase_hole, CapTypeEx::CAP_TYPE_EX_FILL_HOLE); SET_EXISTING_EXTENSION(is_erase_hole, CapTypeEx::CAP_TYPE_EX_FILL_HOLE);
//SET_EXISTING_EXTENSION(ex_fill_background, CapTypeEx::CAP_TYPE_EX_BKG_FILLING_METHOD);
//SET_EXISTING_EXTENSION(ex_sharpen, (CapType)CapTypeEx::CAP_TYPE_EX_SHARPEN);
//SET_EXISTING_EXTENSION(ex_color_enhance, (CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR);
//SET_EXISTING_EXTENSION(search_hole_range, CapTypeEx::CAP_TYPE_EX_FILL_HOLE_RATIO);
SET_EXISTING_EXTENSION(is_noise_modify, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE); SET_EXISTING_EXTENSION(is_noise_modify, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE);
SET_EXISTING_EXTENSION(noise_threshold, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE_THRESHOLD); SET_EXISTING_EXTENSION(noise_threshold, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE_THRESHOLD);
SET_EXISTING_EXTENSION(erase_multiout_red, CapTypeEx::CAP_TYPE_EX_RID_RED); SET_EXISTING_EXTENSION(erase_multiout_red, CapTypeEx::CAP_TYPE_EX_RID_RED);
@ -2217,229 +2173,238 @@ void huagao_ds::init_support_caps(void)
} }
void huagao_ds::init_support_caps_ex(void) void huagao_ds::init_support_caps_ex(void)
{ {
#define SET_CAP_ENUM(sn, ctype, ttype, cap) \ #define SET_SANE_CAP_ENUM(ctype, ttype, name) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \ m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \ m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
std::list<ctype> org; \
ctype now, init; \ ctype now, init; \
std::list<ttype> vals; \ std::vector<ctype> all; \
ttype Now, Init; \ GET_SANE_OPT(ctype, scanner_, name, &now, &init, &all, NULL); \
UInt32 ni, ii; \ if (msg == Msg::Set || msg == Msg::Reset) \
sane_opts::get_opts<ctype> op(&now, &init, NULL, &org); \
scanner_->get_value(sn, sane_opts::set_opt_value<ctype>, &op);\
if(msg == Msg::Set || msg == Msg::Reset) { \
ctype item; \
if(msg == Msg::Reset) \
item = init; \
else \
copy_type(item, data.currentItem<ttype>()); \
return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \
} \
ni = std::distance(org.begin(), std::find(org.begin(), org.end(), now)); \
ii = std::distance(org.begin(), std::find(org.begin(), org.end(), init)); \
copy_type(Now, now); \
for(const auto& v: org) \
{ \ { \
copy_type(Init, v); \ if (msg == Msg::Set) \
vals.push_back(Init); \ { \
ttype v = data.currentItem<ttype>(); \
copy_type(init, v); \
} \ } \
int ret = SCANNER_ERR_OK; \
SET_SANE_OPT(ret, scanner_, name, &init); \
return ret == SCANNER_ERR_OK ? success() : badValue(); \
} \
else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \
{ \
ttype t; \
if(msg == Msg::GetCurrent) \
copy_type(t, now); \
else \
copy_type(t, init); \
data = Capability::createOneValue<ttype>((CapType)CAP_EX_SANE_##name, t); \
return { ReturnCode::Success, ConditionCode::Success }; \
} \
else \
{ \
ttype Now, Init, t; \
std::list<ttype> vals; \
UInt32 ni = 0, ii = 0, ind = 0; \
copy_type(Now, now); \
copy_type(Init, init); \ copy_type(Init, init); \
return cap_get_enum_values<ttype, (CapType)cap>(msg, data, vals, Now, Init, ni, ii); \ for (auto& v : all) \
}; { \
#define SET_CAP_RANGE(sn, ctype, ttype, cap) \ copy_type(t, v); \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \ vals.push_back(t); \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \ if (v == now) \
if (!scanner_.get()) \ ni = ind; \
return seqError(); \ if (v == init) \
ctype now, init, lower, upper, step; \ ii = ind; \
ttype Now, Init, Lower, Upper, Step; \ ind++; \
sane_opts::get_opts<ctype> op(&now, &init, NULL, NULL, &lower, &upper, &step); \
scanner_->get_value(sn, sane_opts::set_opt_value<ctype>, &op); \
if(msg == Msg::Set || msg == Msg::Reset) { \
ctype item = (ctype)data.currentItem<ttype>(); \
if(msg == Msg::Reset) \
item = init; \
return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \
} \ } \
data = Capability::createEnumeration<ttype>((CapType)CAP_EX_SANE_##name, vals, ni, ii); \
return { ReturnCode::Success, ConditionCode::Success }; \
} \
}; \
#define SET_SANE_CAP_RANGE(ctype, ttype, name) \
m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \
m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \
ctype now, init, lower, upper, step; \
std::vector<ctype> all; \
GET_SANE_OPT_RANGE(ctype, scanner_, name, &now, &init, &lower, &upper, &step); \
if (msg == Msg::Set || msg == Msg::Reset) \
{ \
if (msg == Msg::Set) \
{ \
ttype v = data.currentItem<ttype>(); \
copy_type(init, v); \
} \
int ret = SCANNER_ERR_OK; \
SET_SANE_OPT(ret, scanner_, name, &init); \
return ret == SCANNER_ERR_OK ? success() : badValue(); \
} \
else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \
{ \
ttype t; \
if(msg == Msg::GetCurrent) \
copy_type(t, now); \
else \
copy_type(t, init); \
data = Capability::createOneValue<ttype>((CapType)CAP_EX_SANE_##name, t); \
return { ReturnCode::Success, ConditionCode::Success }; \
} \
else \
{ \
ttype Now, Init, Lower, Upper, Step; \
copy_type(Now, now); \ copy_type(Now, now); \
copy_type(Init, init); \ copy_type(Init, init); \
copy_type(Lower, lower); \ copy_type(Lower, lower); \
copy_type(Upper, upper); \ copy_type(Upper, upper); \
copy_type(Step, step); \ copy_type(Step, step); \
return cap_get_one_value<ttype, (CapType)cap>(msg, data, Now, Init, &Lower, &Upper, &Step); \ data = Capability::createRange<ttype>((CapType)CAP_EX_SANE_##name, Lower, Upper, Step, Now, Init);\
};
#define SET_BOOL(sn, cap) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
if(msg == Msg::Set) { \
auto item = data.currentItem<Bool>(); \
return scanner_->set_value(sn, (bool*)&item) == SCANNER_ERR_OK ? success() : badValue(); \
} \ } \
bool init = false, now = false; \ }; \
sane_opts::get_opts<bool> op(&now, &init, NULL, NULL); \
scanner_->get_value(sn, sane_opts::set_opt_value<bool>, &op); \
BYTE v = now; \
return CapSupGetAllResetEx<BYTE, Bool, (CapType)cap>(msg, data, v, init); \
};
#define SET_CAP(sn, ctype, ttype, cap) \ #define SET_SANE_CAP(ctype, ttype, name) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \ m_query[(CapType)CAP_EX_SANE_##name] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \ m_caps[(CapType)CAP_EX_SANE_##name] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \ ctype now, init, lower, upper, step; \
return seqError(); \ GET_SANE_OPT(ctype, scanner_, name, &now, &init, NULL, NULL); \
ctype now, init; \ if (msg == Msg::Set || msg == Msg::Reset) \
ttype Now, Init; \ { \
sane_opts::get_opts<ctype> op(&now, &init); \ if (msg == Msg::Set) \
scanner_->get_value(sn, sane_opts::set_opt_value<ctype>, &op); \ { \
if(msg == Msg::Set || msg == Msg::Reset) { \ ttype v = data.currentItem<ttype>(); \
ctype item; \ copy_type(init, v); \
copy_type(item, data.currentItem<ttype>()); \
if(msg == Msg::Reset) \
item = init; \
return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \
} \ } \
copy_type(Now, now); \ int ret = SCANNER_ERR_OK; \
copy_type(Init, init); \ SET_SANE_OPT(ret, scanner_, name, &init); \
return cap_get_one_value<ttype, (CapType)cap>(msg, data, Now, Init, NULL, NULL, NULL); \ return ret == SCANNER_ERR_OK ? success() : badValue(); \
};
#define ADD_CAP(sn) \
{ \
value_limit vl = VAL_LIMIT_NONE; \
value_type type = VAL_TYPE_NONE; \
int bytes = 0; \
if(!scanner_->get_option_info(sn, &type, &vl, &bytes)) \
return; \
if(type == VAL_TYPE_BOOL) \
{ \
SET_BOOL(sn, CAP_TYPE_EX_##sn); \
} \ } \
else if(type == VAL_TYPE_INT) \ else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \
{ \ { \
if(vl == VAL_LIMIT_RANGE) \ ttype t; \
{ SET_CAP_RANGE(sn, int, Int32, CAP_TYPE_EX_##sn); } \ if(msg == Msg::GetCurrent) \
else if(vl == VAL_LIMIT_ENUM) \ copy_type(t, now); \
{ SET_CAP_ENUM(sn, int, Int32, CAP_TYPE_EX_##sn); } \
else \ else \
{ SET_CAP(sn, int, Int32, CAP_TYPE_EX_##sn); } \ copy_type(t, init); \
data = Capability::createOneValue<ttype>((CapType)CAP_EX_SANE_##name, t); \
return { ReturnCode::Success, ConditionCode::Success }; \
} \
else \
{ \
ttype Now; \
copy_type(Now, now); \
data = Capability::createOneValue<ttype>((CapType)CAP_EX_SANE_##name, Now); \
return { ReturnCode::Success, ConditionCode::Success }; \
} \
}; \
#define ADD_SANE_CAP(name) \
do \
{ \
int sn = scanner_->sane_opt_id_##name(); \
if(sn == -1) break; \
value_type type; \
value_limit limit; \
if(!scanner_->get_option_info(sn, &type, &limit, NULL)) break; \
if(limit == VAL_LIMIT_ENUM) \
{ \
if(type == VAL_TYPE_INT) \
{ \
SET_SANE_CAP_ENUM(int, Int32, name) \
} \ } \
else if(type == VAL_TYPE_FLOAT) \ else if(type == VAL_TYPE_FLOAT) \
{ \ { \
if(vl == VAL_LIMIT_RANGE) \ SET_SANE_CAP_ENUM(float, Fix32, name) \
{ SET_CAP_RANGE(sn, float, Fix32, CAP_TYPE_EX_##sn); } \
else if(vl == VAL_LIMIT_ENUM) \
{ SET_CAP_ENUM(sn, float, Fix32, CAP_TYPE_EX_##sn); } \
else \
{ SET_CAP(sn, float, Fix32, CAP_TYPE_EX_##sn); } \
} \ } \
else if(type == VAL_TYPE_STR) \
{ \
if(vl == VAL_LIMIT_ENUM) \
{ SET_CAP_ENUM(sn, std::string, Twpp::Str64, CAP_TYPE_EX_##sn); } \
else \ else \
{ \ { \
m_query[(CapType)CAP_TYPE_EX_##sn] = MsgSupport::Get; \ SET_SANE_CAP_ENUM(std::string, Str64, name) \
m_caps[(CapType)CAP_TYPE_EX_##sn] = [this](Msg msg, Capability& data) -> Result { \
std::string val(""); \
sane_opts::get_opts<std::string> op(&val, NULL, NULL, NULL, NULL); \
scanner_->get_value(sn, sane_opts::set_opt_value<std::string>, &op); \
Str255 str; \
str.setData(val.c_str()); \
data = Capability::createOneValue<Str255>((CapType)CapTypeEx::CAP_TYPE_EX_##sn, str); \
return success(); \
}; \
} \ } \
} \ } \
else if(type == VAL_TYPE_BUTTON) \ else if(limit == VAL_LIMIT_RANGE) \
{ \ { \
m_query[(CapType)CAP_TYPE_EX_##sn] = MsgSupport::Set | MsgSupport::Reset; \ if(type == VAL_TYPE_INT) \
m_caps[(CapType)CAP_TYPE_EX_##sn] = [this](Msg msg, Capability& data) -> Result { \ { \
if (!scanner_.get()) \ SET_SANE_CAP_RANGE(int, Int32, name) \
return seqError(); \
if(msg == Msg::Set || msg == Msg::Reset) { \
scanner_->set_value(sn, NULL); \
return success(); \
} \ } \
return enmGet<Bool>(msg, data, true); \ else if(type == VAL_TYPE_FLOAT) \
}; \ { \
SET_SANE_CAP_RANGE(float, Fix32, name) \
} \ } \
} } \
else \
{ \
if(type == VAL_TYPE_BOOL) \
{ \
SET_SANE_CAP(bool, Bool, name) \
} \
else if(type == VAL_TYPE_INT) \
{ \
SET_SANE_CAP(int, Int32, name) \
} \
else if(type == VAL_TYPE_FLOAT) \
{ \
SET_SANE_CAP(float, Fix32, name) \
} \
else \
{ \
SET_SANE_CAP(std::string, Str255, name) \
} \
} \
}while (0);
// setting items ... // setting items ...
ADD_CAP(1); ADD_SANE_CAP(is_multiout);
ADD_CAP(2); ADD_SANE_CAP(multiout_type);
ADD_CAP(3); ADD_SANE_CAP(color_mode);
ADD_CAP(4); ADD_SANE_CAP(erase_color);
ADD_CAP(5); ADD_SANE_CAP(erase_multiout_red);
ADD_CAP(6); ADD_SANE_CAP(erase_paper_red);
ADD_CAP(7); ADD_SANE_CAP(is_erase_background);
ADD_CAP(8); ADD_SANE_CAP(background_color_range);
ADD_CAP(9); ADD_SANE_CAP(sharpen);
ADD_CAP(10); ADD_SANE_CAP(erase_morr);
ADD_CAP(11); ADD_SANE_CAP(erase_grids);
ADD_CAP(12); ADD_SANE_CAP(error_extend);
ADD_CAP(13); ADD_SANE_CAP(is_noise_modify);
ADD_CAP(14); ADD_SANE_CAP(noise_threshold);
ADD_CAP(15); ADD_SANE_CAP(paper);
ADD_CAP(16); ADD_SANE_CAP(is_custom_area);
ADD_CAP(17); ADD_SANE_CAP(curstom_area_l);
ADD_CAP(18); ADD_SANE_CAP(curstom_area_r);
ADD_CAP(19); ADD_SANE_CAP(curstom_area_t);
ADD_CAP(20); ADD_SANE_CAP(curstom_area_b);
ADD_CAP(21); ADD_SANE_CAP(is_size_check);
ADD_CAP(22); ADD_SANE_CAP(page);
ADD_CAP(23); ADD_SANE_CAP(blank_page_threshold);
ADD_CAP(24); ADD_SANE_CAP(resolution);
ADD_CAP(25); ADD_SANE_CAP(image_quality);
ADD_CAP(26); ADD_SANE_CAP(is_swap);
ADD_CAP(27); ADD_SANE_CAP(is_split);
ADD_CAP(28); ADD_SANE_CAP(is_auto_deskew);
ADD_CAP(29); ADD_SANE_CAP(is_custom_gamma);
ADD_CAP(30); ADD_SANE_CAP(bright);
ADD_CAP(31); ADD_SANE_CAP(contrast);
ADD_CAP(32); ADD_SANE_CAP(gamma);
ADD_CAP(33); ADD_SANE_CAP(is_erase_black_frame);
ADD_CAP(34); ADD_SANE_CAP(deep_sample);
ADD_CAP(35); ADD_SANE_CAP(threshold);
ADD_CAP(36); ADD_SANE_CAP(anti_noise);
ADD_CAP(37); ADD_SANE_CAP(margin);
ADD_CAP(38); ADD_SANE_CAP(fill_background);
ADD_CAP(39); ADD_SANE_CAP(is_anti_permeate);
ADD_CAP(40); ADD_SANE_CAP(anti_permeate_level);
ADD_CAP(41); ADD_SANE_CAP(is_erase_hole);
ADD_CAP(42); ADD_SANE_CAP(search_hole_range);
ADD_CAP(43); ADD_SANE_CAP(is_filling_color);
ADD_CAP(44); ADD_SANE_CAP(is_ultrasonic_check);
ADD_CAP(45); ADD_SANE_CAP(is_check_staple);
ADD_CAP(46); ADD_SANE_CAP(scan_mode);
ADD_CAP(47); ADD_SANE_CAP(scan_count);
ADD_CAP(48); ADD_SANE_CAP(text_direction);
ADD_CAP(49); ADD_SANE_CAP(is_rotate_bkg180);
ADD_CAP(50); ADD_SANE_CAP(is_check_dogear);
ADD_CAP(51); ADD_SANE_CAP(dogear_size);
ADD_CAP(52); ADD_SANE_CAP(is_check_skew);
ADD_CAP(53); ADD_SANE_CAP(skew_range);
ADD_CAP(54);
ADD_CAP(55);
ADD_CAP(56);
ADD_CAP(57);
ADD_CAP(58);
ADD_CAP(59);
ADD_CAP(60);
ADD_CAP(61);
ADD_CAP(62);
ADD_CAP(63);
ADD_CAP(64);
ADD_CAP(65);
ADD_CAP(66);
ADD_CAP(67);
ADD_CAP(68);
ADD_CAP(69);
ADD_CAP(70);
} }
void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len) void huagao_ds::on_scan_event(int sane_event, void* data, unsigned int* len)
{ {

View File

@ -50,6 +50,7 @@ class huagao_ds : public Twpp::SourceFromThis<huagao_ds> {
void init_support_caps_ex(void); void init_support_caps_ex(void);
void on_scan_event(int sane_event, void* data, unsigned int* len); void on_scan_event(int sane_event, void* data, unsigned int* len);
public: public:
huagao_ds(); huagao_ds();
virtual ~huagao_ds(); virtual ~huagao_ds();