From 1205559eaf1c4eabad62669e728e9e69b4012cf9 Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Wed, 15 Jun 2022 17:07:51 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85TWAIN=E5=B1=9E=E6=80=A7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- sane/s2t_api.h | 106 +++---- sane/scanner.cpp | 2 +- twain/twain/huagaods.cpp | 623 ++++++++++++++++++--------------------- twain/twain/huagaods.hpp | 1 + 4 files changed, 349 insertions(+), 383 deletions(-) diff --git a/sane/s2t_api.h b/sane/s2t_api.h index 995d4b4..a67cf3d 100644 --- a/sane/s2t_api.h +++ b/sane/s2t_api.h @@ -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(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(blank_page_threshold); // 跳过空白页灵敏度 - 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_filling_color); // 色彩填充 - 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(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(blank_page_threshold); // 跳过空白页灵敏度 + 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); // 自定义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(scan_mode); // 扫描张数 + SANE_OPTION_ID_API(scan_count); // 扫描数量 + 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 diff --git a/sane/scanner.cpp b/sane/scanner.cpp index 13fe82d..1becdc6 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -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); diff --git a/twain/twain/huagaods.cpp b/twain/twain/huagaods.cpp index 9fe5a0d..1b50f62 100644 --- a/twain/twain/huagaods.cpp +++ b/twain/twain/huagaods.cpp @@ -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(m_caps.size()); auto arr = data.array(); + std::vector 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(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 org; \ - ctype now, init; \ - std::list vals; \ - ttype Now, Init; \ - UInt32 ni, ii; \ - sane_opts::get_opts op(&now, &init, NULL, &org); \ - scanner_->get_value(sn, sane_opts::set_opt_value, &op);\ - if(msg == Msg::Set || msg == Msg::Reset) { \ - ctype item; \ - if(msg == Msg::Reset) \ - item = init; \ - else \ - copy_type(item, data.currentItem()); \ - 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); \ - vals.push_back(Init); \ - } \ - copy_type(Init, init); \ - return cap_get_enum_values(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 op(&now, &init, NULL, NULL, &lower, &upper, &step); \ - scanner_->get_value(sn, sane_opts::set_opt_value, &op); \ - if(msg == Msg::Set || msg == Msg::Reset) { \ - ctype item = (ctype)data.currentItem(); \ - if(msg == Msg::Reset) \ - item = init; \ - return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - 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(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(); \ - return scanner_->set_value(sn, (bool*)&item) == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - bool init = false, now = false; \ - sane_opts::get_opts op(&now, &init, NULL, NULL); \ - scanner_->get_value(sn, sane_opts::set_opt_value, &op); \ - BYTE v = now; \ - return CapSupGetAllResetEx(msg, data, v, init); \ - }; +#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::vector all; \ + GET_SANE_OPT(ctype, scanner_, name, &now, &init, &all, NULL); \ + if (msg == Msg::Set || msg == Msg::Reset) \ + { \ + if (msg == Msg::Set) \ + { \ + ttype v = data.currentItem(); \ + 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((CapType)CAP_EX_SANE_##name, t); \ + return { ReturnCode::Success, ConditionCode::Success }; \ + } \ + else \ + { \ + ttype Now, Init, t; \ + std::list vals; \ + UInt32 ni = 0, ii = 0, ind = 0; \ + copy_type(Now, now); \ + copy_type(Init, init); \ + 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((CapType)CAP_EX_SANE_##name, vals, ni, ii); \ + return { ReturnCode::Success, ConditionCode::Success }; \ + } \ + }; \ -#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 op(&now, &init); \ - scanner_->get_value(sn, sane_opts::set_opt_value, &op); \ - if(msg == Msg::Set || msg == Msg::Reset) { \ - ctype item; \ - copy_type(item, data.currentItem()); \ - if(msg == Msg::Reset) \ - item = init; \ - return scanner_->set_value(sn, &item) == SCANNER_ERR_OK ? success() : badValue(); \ - } \ - copy_type(Now, now); \ - copy_type(Init, init); \ - return cap_get_one_value(msg, data, Now, Init, NULL, NULL, NULL); \ - }; +#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 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(); \ + 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((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); \ + data = Capability::createRange((CapType)CAP_EX_SANE_##name, Lower, Upper, Step, Now, Init);\ + } \ + }; \ -#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) \ - { \ - 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); } \ - else \ - { SET_CAP(sn, int, Int32, CAP_TYPE_EX_##sn); } \ - } \ - 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); } \ - } \ - 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 op(&val, NULL, NULL, NULL, NULL); \ - scanner_->get_value(sn, sane_opts::set_opt_value, &op); \ - Str255 str; \ - str.setData(val.c_str()); \ - data = Capability::createOneValue((CapType)CapTypeEx::CAP_TYPE_EX_##sn, str); \ - return success(); \ - }; \ - } \ - } \ - else if(type == VAL_TYPE_BUTTON) \ - { \ - 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(); \ - } \ - return enmGet(msg, data, true); \ - }; \ - } \ - } +#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(); \ + 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((CapType)CAP_EX_SANE_##name, t); \ + return { ReturnCode::Success, ConditionCode::Success }; \ + } \ + else \ + { \ + ttype Now; \ + copy_type(Now, now); \ + data = Capability::createOneValue((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) \ + { \ + SET_SANE_CAP_ENUM(float, Fix32, name) \ + } \ + else \ + { \ + SET_SANE_CAP_ENUM(std::string, Str64, name) \ + } \ + } \ + else if(limit == VAL_LIMIT_RANGE) \ + { \ + if(type == VAL_TYPE_INT) \ + { \ + SET_SANE_CAP_RANGE(int, Int32, name) \ + } \ + 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) { diff --git a/twain/twain/huagaods.hpp b/twain/twain/huagaods.hpp index 5ae5443..a221e2d 100644 --- a/twain/twain/huagaods.hpp +++ b/twain/twain/huagaods.hpp @@ -50,6 +50,7 @@ class huagao_ds : public Twpp::SourceFromThis { void init_support_caps_ex(void); void on_scan_event(int sane_event, void* data, unsigned int* len); + public: huagao_ds(); virtual ~huagao_ds();