补充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));
// SANE options ID ...
SANE_OPTION_ID_API(is_multiout);
SANE_OPTION_ID_API(multiout_type);
SANE_OPTION_ID_API(color_mode);
SANE_OPTION_ID_API(erase_color);
SANE_OPTION_ID_API(erase_multiout_red);
SANE_OPTION_ID_API(erase_paper_red);
SANE_OPTION_ID_API(is_erase_background);
SANE_OPTION_ID_API(background_color_range);
SANE_OPTION_ID_API(sharpen);
SANE_OPTION_ID_API(erase_morr);
SANE_OPTION_ID_API(is_multiout); // 多流输出
SANE_OPTION_ID_API(multiout_type); // 多流输出类型
SANE_OPTION_ID_API(color_mode); // 颜色模式
SANE_OPTION_ID_API(erase_color); // 除色或增强
SANE_OPTION_ID_API(erase_multiout_red); // 多流输出除红
SANE_OPTION_ID_API(erase_paper_red); // 试卷除红
SANE_OPTION_ID_API(is_erase_background); // 背景移除
SANE_OPTION_ID_API(background_color_range); // 背景色彩范围
SANE_OPTION_ID_API(sharpen); // 锐化与模糊
SANE_OPTION_ID_API(erase_morr); // 除摩尔纹
SANE_OPTION_ID_API(erase_grids); // 除网纹
SANE_OPTION_ID_API(error_extend);
SANE_OPTION_ID_API(is_noise_modify);
SANE_OPTION_ID_API(noise_threshold);
SANE_OPTION_ID_API(paper);
SANE_OPTION_ID_API(is_custom_area);
SANE_OPTION_ID_API(curstom_area_l);
SANE_OPTION_ID_API(curstom_area_r);
SANE_OPTION_ID_API(curstom_area_t);
SANE_OPTION_ID_API(curstom_area_b);
SANE_OPTION_ID_API(is_size_check);
SANE_OPTION_ID_API(page);
SANE_OPTION_ID_API(error_extend); // 错误扩散
SANE_OPTION_ID_API(is_noise_modify); // 噪点优化
SANE_OPTION_ID_API(noise_threshold); // 噪点优化尺寸
SANE_OPTION_ID_API(paper); // 纸张尺寸
SANE_OPTION_ID_API(is_custom_area); // 自定义扫描区域
SANE_OPTION_ID_API(curstom_area_l); // 自定义扫描区域 左
SANE_OPTION_ID_API(curstom_area_r); // 自定义扫描区域 右
SANE_OPTION_ID_API(curstom_area_t); // 自定义扫描区域 上
SANE_OPTION_ID_API(curstom_area_b); // 自定义扫描区域 下
SANE_OPTION_ID_API(is_size_check); // 尺寸检测
SANE_OPTION_ID_API(page); // 扫描页面
SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度
SANE_OPTION_ID_API(resolution);
SANE_OPTION_ID_API(image_quality);
SANE_OPTION_ID_API(resolution); // 分辨率
SANE_OPTION_ID_API(image_quality); // 图像质量
SANE_OPTION_ID_API(is_swap); // 交换正反面
SANE_OPTION_ID_API(is_split); // 图像拆分
SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏
SANE_OPTION_ID_API(is_custom_gamma);
SANE_OPTION_ID_API(bright);
SANE_OPTION_ID_API(contrast);
SANE_OPTION_ID_API(gamma);
SANE_OPTION_ID_API(is_erase_black_frame); // bool
SANE_OPTION_ID_API(deep_sample);
SANE_OPTION_ID_API(threshold);
SANE_OPTION_ID_API(anti_noise); // 抗噪等级
SANE_OPTION_ID_API(margin);
SANE_OPTION_ID_API(fill_background);
SANE_OPTION_ID_API(is_anti_permeate);
SANE_OPTION_ID_API(anti_permeate_level);
SANE_OPTION_ID_API(is_erase_hole);
SANE_OPTION_ID_API(search_hole_range);
SANE_OPTION_ID_API(is_custom_gamma); // 自定义gamma
SANE_OPTION_ID_API(bright); // 亮度
SANE_OPTION_ID_API(contrast); // 对比度
SANE_OPTION_ID_API(gamma); // gamma
SANE_OPTION_ID_API(is_erase_black_frame); // 消除黑框
SANE_OPTION_ID_API(deep_sample); // 深色样张
SANE_OPTION_ID_API(threshold); // 阈值
SANE_OPTION_ID_API(anti_noise); // 背景抗噪等级
SANE_OPTION_ID_API(margin); // 边缘缩进
SANE_OPTION_ID_API(fill_background); // 背景填充方式
SANE_OPTION_ID_API(is_anti_permeate); // 防止渗透
SANE_OPTION_ID_API(anti_permeate_level); // 防止渗透等级
SANE_OPTION_ID_API(is_erase_hole); // 穿孔移除
SANE_OPTION_ID_API(search_hole_range); // 穿孔搜索范围
SANE_OPTION_ID_API(is_filling_color); // 色彩填充
SANE_OPTION_ID_API(is_ultrasonic_check);
SANE_OPTION_ID_API(is_check_staple);
SANE_OPTION_ID_API(is_ultrasonic_check); // 超声波检测
SANE_OPTION_ID_API(is_check_staple); // 装订检测
SANE_OPTION_ID_API(scan_mode); // 扫描张数
SANE_OPTION_ID_API(scan_count); // 扫描数量
SANE_OPTION_ID_API(text_direction);
SANE_OPTION_ID_API(is_rotate_bkg180);
SANE_OPTION_ID_API(is_check_dogear);
SANE_OPTION_ID_API(dogear_size);
SANE_OPTION_ID_API(is_check_skew);
SANE_OPTION_ID_API(skew_range);
SANE_OPTION_ID_API(text_direction); // 文稿方向
SANE_OPTION_ID_API(is_rotate_bkg180); // 背面旋转180度
SANE_OPTION_ID_API(is_check_dogear); // 折角检测
SANE_OPTION_ID_API(dogear_size); // 折角检测大小
SANE_OPTION_ID_API(is_check_skew); // 歪斜检测
SANE_OPTION_ID_API(skew_range); // 歪斜容忍度
// SANE-ex option ID:
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];
memset(buf, 0, size + 4);
strcpy(buf, (char*)data);
strcpy(buf, ((std::string*)data)->c_str());
data = buf;
}
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
#pragma warning(disable: 4700)
using namespace Twpp;
using namespace std::placeholders;
@ -65,107 +66,63 @@ enum CapTypeEx : unsigned short {
CAP_TYPE_EX_SCAN_WITH_HOLE = 0x8114,
CAP_TYPE_EX_IP = 0x8200,
CAP_TYPE_EX_0 = (int)CapType::CustomBase + 0x800,
CAP_TYPE_EX_1,
CAP_TYPE_EX_2,
CAP_TYPE_EX_3,
CAP_TYPE_EX_4,
CAP_TYPE_EX_5,
CAP_TYPE_EX_6,
CAP_TYPE_EX_7,
CAP_TYPE_EX_8,
CAP_TYPE_EX_9,
CAP_TYPE_EX_10,
CAP_TYPE_EX_11,
CAP_TYPE_EX_12,
CAP_TYPE_EX_13,
CAP_TYPE_EX_14,
CAP_TYPE_EX_15,
CAP_TYPE_EX_16,
CAP_TYPE_EX_17,
CAP_TYPE_EX_18,
CAP_TYPE_EX_19,
CAP_TYPE_EX_20,
CAP_TYPE_EX_21,
CAP_TYPE_EX_22,
CAP_TYPE_EX_23,
CAP_TYPE_EX_24,
CAP_TYPE_EX_25,
CAP_TYPE_EX_26,
CAP_TYPE_EX_27,
CAP_TYPE_EX_28,
CAP_TYPE_EX_29,
CAP_TYPE_EX_30,
CAP_TYPE_EX_31,
CAP_TYPE_EX_32,
CAP_TYPE_EX_33,
CAP_TYPE_EX_34,
CAP_TYPE_EX_35,
CAP_TYPE_EX_36,
CAP_TYPE_EX_37,
CAP_TYPE_EX_38,
CAP_TYPE_EX_39,
CAP_TYPE_EX_40,
CAP_TYPE_EX_41,
CAP_TYPE_EX_42,
CAP_TYPE_EX_43,
CAP_TYPE_EX_44,
CAP_TYPE_EX_45,
CAP_TYPE_EX_46,
CAP_TYPE_EX_47,
CAP_TYPE_EX_48,
CAP_TYPE_EX_49,
CAP_TYPE_EX_50,
CAP_TYPE_EX_51,
CAP_TYPE_EX_52,
CAP_TYPE_EX_53,
CAP_TYPE_EX_54,
CAP_TYPE_EX_55,
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,
// SANE设备层原始设置项透传属性
CAP_EX_SANE = (int)CapType::CustomBase + 0x800,
CAP_EX_SANE_is_multiout,
CAP_EX_SANE_multiout_type,
CAP_EX_SANE_color_mode,
CAP_EX_SANE_erase_color,
CAP_EX_SANE_erase_multiout_red,
CAP_EX_SANE_erase_paper_red,
CAP_EX_SANE_is_erase_background,
CAP_EX_SANE_background_color_range,
CAP_EX_SANE_sharpen,
CAP_EX_SANE_erase_morr,
CAP_EX_SANE_erase_grids,
CAP_EX_SANE_error_extend,
CAP_EX_SANE_is_noise_modify,
CAP_EX_SANE_noise_threshold,
CAP_EX_SANE_paper,
CAP_EX_SANE_is_custom_area,
CAP_EX_SANE_curstom_area_l,
CAP_EX_SANE_curstom_area_r,
CAP_EX_SANE_curstom_area_t,
CAP_EX_SANE_curstom_area_b,
CAP_EX_SANE_is_size_check,
CAP_EX_SANE_page,
CAP_EX_SANE_blank_page_threshold,
CAP_EX_SANE_resolution,
CAP_EX_SANE_image_quality,
CAP_EX_SANE_is_swap,
CAP_EX_SANE_is_split,
CAP_EX_SANE_is_auto_deskew,
CAP_EX_SANE_is_custom_gamma,
CAP_EX_SANE_bright,
CAP_EX_SANE_contrast,
CAP_EX_SANE_gamma,
CAP_EX_SANE_is_erase_black_frame,
CAP_EX_SANE_deep_sample,
CAP_EX_SANE_threshold,
CAP_EX_SANE_anti_noise,
CAP_EX_SANE_margin,
CAP_EX_SANE_fill_background,
CAP_EX_SANE_is_anti_permeate,
CAP_EX_SANE_anti_permeate_level,
CAP_EX_SANE_is_erase_hole,
CAP_EX_SANE_search_hole_range,
CAP_EX_SANE_is_filling_color,
CAP_EX_SANE_is_ultrasonic_check,
CAP_EX_SANE_is_check_staple,
CAP_EX_SANE_scan_mode,
CAP_EX_SANE_scan_count,
CAP_EX_SANE_text_direction,
CAP_EX_SANE_is_rotate_bkg180,
CAP_EX_SANE_is_check_dogear,
CAP_EX_SANE_dogear_size,
CAP_EX_SANE_is_check_skew,
CAP_EX_SANE_skew_range,
// END for SANE设备层原始设置项透传属性
/////////////////////////////////////////////////////////////////////////
};
@ -1125,9 +1082,13 @@ void huagao_ds::init_support_caps(void)
if ((msg == Msg::Get) || (Msg::GetCurrent == msg) || (Msg::GetDefault == msg)) {
data = Capability::createArray<CapType::SupportedCaps>(m_caps.size());
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;
for (const auto& kv : m_caps) {
arr[i] = kv.first;
for (const auto& kv : all) {
arr[i] = (CapType)kv;
i++;
}
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);
};
//SET_EXISTING_EXTENSION(ex_color_enhance, (CapType)CapTypeEx::CAP_TYPE_EX_ENHANCE_COLOR);
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 {
int cur = FILTER_NONE, def = FILTER_NONE;
@ -2184,11 +2145,10 @@ void huagao_ds::init_support_caps(void)
if(op_ind != -1) \
{ \
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;
// SET_EXISTING_EXTENSION(paper, CapType::ISupportedSizes);
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_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(threshold, CapTypeEx::CAP_TYPE_EX_THRESHOLD);
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(noise_threshold, CapTypeEx::CAP_TYPE_EX_DETACH_NOISE_THRESHOLD);
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)
{
#define SET_CAP_ENUM(sn, ctype, ttype, cap) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
std::list<ctype> org; \
#define SET_SANE_CAP_ENUM(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; \
std::list<ttype> vals; \
ttype Now, Init; \
UInt32 ni, ii; \
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) \
std::vector<ctype> all; \
GET_SANE_OPT(ctype, scanner_, name, &now, &init, &all, NULL); \
if (msg == Msg::Set || msg == Msg::Reset) \
{ \
copy_type(Init, v); \
vals.push_back(Init); \
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, t; \
std::list<ttype> vals; \
UInt32 ni = 0, ii = 0, ind = 0; \
copy_type(Now, now); \
copy_type(Init, init); \
return cap_get_enum_values<ttype, (CapType)cap>(msg, data, vals, Now, Init, ni, ii); \
};
#define SET_CAP_RANGE(sn, ctype, ttype, cap) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
ctype now, init, lower, upper, step; \
ttype Now, Init, Lower, Upper, Step; \
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(); \
for (auto& v : all) \
{ \
copy_type(t, v); \
vals.push_back(t); \
if (v == now) \
ni = ind; \
if (v == init) \
ii = ind; \
ind++; \
} \
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(Init, init); \
copy_type(Lower, lower); \
copy_type(Upper, upper); \
copy_type(Step, step); \
return cap_get_one_value<ttype, (CapType)cap>(msg, data, Now, Init, &Lower, &Upper, &Step); \
};
#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(); \
data = Capability::createRange<ttype>((CapType)CAP_EX_SANE_##name, Lower, Upper, Step, Now, Init);\
} \
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) \
m_query[(CapType)cap] = msgSupportGetAllSetReset; \
m_caps[(CapType)cap] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
ctype now, init; \
ttype Now, Init; \
sane_opts::get_opts<ctype> op(&now, &init); \
scanner_->get_value(sn, sane_opts::set_opt_value<ctype>, &op); \
if(msg == Msg::Set || msg == Msg::Reset) { \
ctype item; \
copy_type(item, data.currentItem<ttype>()); \
if(msg == Msg::Reset) \
item = init; \
return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \
#define SET_SANE_CAP(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; \
GET_SANE_OPT(ctype, scanner_, name, &now, &init, NULL, NULL); \
if (msg == Msg::Set || msg == Msg::Reset) \
{ \
if (msg == Msg::Set) \
{ \
ttype v = data.currentItem<ttype>(); \
copy_type(init, v); \
} \
copy_type(Now, now); \
copy_type(Init, init); \
return cap_get_one_value<ttype, (CapType)cap>(msg, data, Now, Init, NULL, NULL, NULL); \
};
#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); \
int ret = SCANNER_ERR_OK; \
SET_SANE_OPT(ret, scanner_, name, &init); \
return ret == SCANNER_ERR_OK ? success() : badValue(); \
} \
else if(type == VAL_TYPE_INT) \
else if (msg == Msg::GetCurrent || msg == Msg::GetDefault) \
{ \
if(vl == VAL_LIMIT_RANGE) \
{ SET_CAP_RANGE(sn, int, Int32, CAP_TYPE_EX_##sn); } \
else if(vl == VAL_LIMIT_ENUM) \
{ SET_CAP_ENUM(sn, int, Int32, CAP_TYPE_EX_##sn); } \
ttype t; \
if(msg == Msg::GetCurrent) \
copy_type(t, now); \
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) \
{ \
if(vl == VAL_LIMIT_RANGE) \
{ 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); } \
SET_SANE_CAP_ENUM(float, Fix32, name) \
} \
else if(type == VAL_TYPE_STR) \
{ \
if(vl == VAL_LIMIT_ENUM) \
{ SET_CAP_ENUM(sn, std::string, Twpp::Str64, CAP_TYPE_EX_##sn); } \
else \
{ \
m_query[(CapType)CAP_TYPE_EX_##sn] = MsgSupport::Get; \
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(); \
}; \
SET_SANE_CAP_ENUM(std::string, Str64, name) \
} \
} \
else if(type == VAL_TYPE_BUTTON) \
else if(limit == VAL_LIMIT_RANGE) \
{ \
m_query[(CapType)CAP_TYPE_EX_##sn] = MsgSupport::Set | MsgSupport::Reset; \
m_caps[(CapType)CAP_TYPE_EX_##sn] = [this](Msg msg, Capability& data) -> Result { \
if (!scanner_.get()) \
return seqError(); \
if(msg == Msg::Set || msg == Msg::Reset) { \
scanner_->set_value(sn, NULL); \
return success(); \
if(type == VAL_TYPE_INT) \
{ \
SET_SANE_CAP_RANGE(int, Int32, name) \
} \
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 ...
ADD_CAP(1);
ADD_CAP(2);
ADD_CAP(3);
ADD_CAP(4);
ADD_CAP(5);
ADD_CAP(6);
ADD_CAP(7);
ADD_CAP(8);
ADD_CAP(9);
ADD_CAP(10);
ADD_CAP(11);
ADD_CAP(12);
ADD_CAP(13);
ADD_CAP(14);
ADD_CAP(15);
ADD_CAP(16);
ADD_CAP(17);
ADD_CAP(18);
ADD_CAP(19);
ADD_CAP(20);
ADD_CAP(21);
ADD_CAP(22);
ADD_CAP(23);
ADD_CAP(24);
ADD_CAP(25);
ADD_CAP(26);
ADD_CAP(27);
ADD_CAP(28);
ADD_CAP(29);
ADD_CAP(30);
ADD_CAP(31);
ADD_CAP(32);
ADD_CAP(33);
ADD_CAP(34);
ADD_CAP(35);
ADD_CAP(36);
ADD_CAP(37);
ADD_CAP(38);
ADD_CAP(39);
ADD_CAP(40);
ADD_CAP(41);
ADD_CAP(42);
ADD_CAP(43);
ADD_CAP(44);
ADD_CAP(45);
ADD_CAP(46);
ADD_CAP(47);
ADD_CAP(48);
ADD_CAP(49);
ADD_CAP(50);
ADD_CAP(51);
ADD_CAP(52);
ADD_CAP(53);
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);
ADD_SANE_CAP(is_multiout);
ADD_SANE_CAP(multiout_type);
ADD_SANE_CAP(color_mode);
ADD_SANE_CAP(erase_color);
ADD_SANE_CAP(erase_multiout_red);
ADD_SANE_CAP(erase_paper_red);
ADD_SANE_CAP(is_erase_background);
ADD_SANE_CAP(background_color_range);
ADD_SANE_CAP(sharpen);
ADD_SANE_CAP(erase_morr);
ADD_SANE_CAP(erase_grids);
ADD_SANE_CAP(error_extend);
ADD_SANE_CAP(is_noise_modify);
ADD_SANE_CAP(noise_threshold);
ADD_SANE_CAP(paper);
ADD_SANE_CAP(is_custom_area);
ADD_SANE_CAP(curstom_area_l);
ADD_SANE_CAP(curstom_area_r);
ADD_SANE_CAP(curstom_area_t);
ADD_SANE_CAP(curstom_area_b);
ADD_SANE_CAP(is_size_check);
ADD_SANE_CAP(page);
ADD_SANE_CAP(blank_page_threshold);
ADD_SANE_CAP(resolution);
ADD_SANE_CAP(image_quality);
ADD_SANE_CAP(is_swap);
ADD_SANE_CAP(is_split);
ADD_SANE_CAP(is_auto_deskew);
ADD_SANE_CAP(is_custom_gamma);
ADD_SANE_CAP(bright);
ADD_SANE_CAP(contrast);
ADD_SANE_CAP(gamma);
ADD_SANE_CAP(is_erase_black_frame);
ADD_SANE_CAP(deep_sample);
ADD_SANE_CAP(threshold);
ADD_SANE_CAP(anti_noise);
ADD_SANE_CAP(margin);
ADD_SANE_CAP(fill_background);
ADD_SANE_CAP(is_anti_permeate);
ADD_SANE_CAP(anti_permeate_level);
ADD_SANE_CAP(is_erase_hole);
ADD_SANE_CAP(search_hole_range);
ADD_SANE_CAP(is_filling_color);
ADD_SANE_CAP(is_ultrasonic_check);
ADD_SANE_CAP(is_check_staple);
ADD_SANE_CAP(scan_mode);
ADD_SANE_CAP(scan_count);
ADD_SANE_CAP(text_direction);
ADD_SANE_CAP(is_rotate_bkg180);
ADD_SANE_CAP(is_check_dogear);
ADD_SANE_CAP(dogear_size);
ADD_SANE_CAP(is_check_skew);
ADD_SANE_CAP(skew_range);
}
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 on_scan_event(int sane_event, void* data, unsigned int* len);
public:
huagao_ds();
virtual ~huagao_ds();