diff --git a/hgdriver/hgdev/hg_ipc.cpp b/hgdriver/hgdev/hg_ipc.cpp index 3eab170..f9c6e79 100644 --- a/hgdriver/hgdev/hg_ipc.cpp +++ b/hgdriver/hgdev/hg_ipc.cpp @@ -643,7 +643,7 @@ tiny_buffer::tiny_buffer(unsigned int size , const char* name_leading , const char* ext , unsigned int uniq_id) - : size_(size), buf_(nullptr), img_statu_(SANE_Image_Statu_OK) + : size_(size), buf_(nullptr), img_statu_(IMG_STATUS_OK) { init(tmp_path, name_leading, ext, uniq_id); } diff --git a/hgdriver/hgdev/hg_ipc.h b/hgdriver/hgdev/hg_ipc.h index ea4ee49..ebb3411 100644 --- a/hgdriver/hgdev/hg_ipc.h +++ b/hgdriver/hgdev/hg_ipc.h @@ -181,6 +181,7 @@ typedef struct _img_header int bits; int channels; int line_bytes; + int statu; // SANE_Image_Statu unsigned bytes; uint32_t src_id; }IMH; diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index f5da6fc..cb3cffa 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -166,7 +166,6 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i , firmware_sup_wait_paper_(false),firmware_sup_pick_strength_(false),firmware_sup_log_export_(false),firmware_sup_color_corr_(false),firmware_sup_wake_device_(false) , firmware_sup_double_img(false),firmware_sup_devs_lock_(false),firmware_sup_dpi_300(false),firmware_sup_dpi_600(false),firmware_sup_auto_speed_(false),firmware_sup_morr_(false) , firmware_sup_color_fill_(false),firmware_sup_history_cnt(false), is_discardblank(false) - , setting_jsn_(new device_option()) , auto_scan_restore_(false), auto_scan_prev_(is_auto_paper_scan) { #if !defined(_WIN32) && !defined(_WIN64) &&defined(x86_64) @@ -280,7 +279,6 @@ hg_scanner::~hg_scanner() name_ += lang_load_string(ID_STATU_DESC_SCANNER_ERR_DEVICE_IS_CLOSE, nullptr); notify_ui_working_status(name_.c_str(), SANE_EVENT_SCANNER_CLOSED); utils::to_log(LOG_LEVEL_DEBUG, "%s(%p) destroyed.\n", name_.c_str(), this); - delete setting_jsn_; // ->release(); } std::string hg_scanner::temporary_file(char* tail, char* head) @@ -704,18 +702,6 @@ void hg_scanner::init_setting_func_map(void) setting_map_[SANE_STD_OPT_NAME_MOTOR_VER] = &hg_scanner::setting_get_motor_ver; setting_map_[SANE_STD_OPT_NAME_INITIAL_BOOT_TIME] = &hg_scanner::setting_get_initial_boot_time; } -int hg_scanner::restore(const char* name) -{ - std::string type(setting_jsn_->get_option_value_type(name)), val(""); - int ret = SCANNER_ERR_OK, size = 0; - - if (type != JSON_SANE_TYPE_BOOL && type != JSON_SANE_TYPE_INT && type != JSON_SANE_TYPE_FIXED && type != JSON_SANE_TYPE_STRING) - return ret; - - ret = set_setting(name, nullptr, true); - - return ret; -} bool hg_scanner::is_to_file(void) { return resolution_ > 200 @@ -907,42 +893,6 @@ void hg_scanner::working_done(void*) test_1_paper_ = false; } -bool hg_scanner::jsn_reorganize() -{ - gb_json* paper = nullptr, * range = nullptr; - - if (!firmware_sup_wait_paper_ && pid_ == 0x239) - { - erase_option(SANE_STD_OPT_NAME_WAIT_TO_SCAN); - erase_option(SANE_STD_OPT_NAME_WAIT_SCAN_EXIT); - } - if (!firmware_sup_pick_strength_ && pid_ == 0x239) - { - erase_option(SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH); - erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE); - erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH); - } - if (!firmware_sup_color_fill_ && (pid_ == 0x239 || pid_ == 0x439)) - { - erase_option(SANE_STD_OPT_NAME_IS_FILL_COLOR); - } - if (!firmware_sup_color_corr_ && (pid_ == 0x239 || pid_ == 0x439)) - { - erase_option(SANE_STD_OPT_NAME_COLOR_CORRECTION); - } - if (!firmware_sup_morr_) - { - erase_option(SANE_STD_OPT_NAME_RID_MORR); - } - - if (pid_ == 0x239 || pid_ == 0x439) //固件不支持防止渗透等级 - { - erase_option(SANE_STD_OPT_NAME_ANTI_PERMEATE_LEVEL); - } - erase_option(SANE_STD_OPT_NAME_RID_GRID); //全系移除 除网纹 - - return true; -} int hg_scanner::hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type) { int ind = 0; @@ -975,7 +925,7 @@ int hg_scanner::invoke_setting_xxx(int(hg_scanner::*func)(void*, long*), void* d { if (it->second == func) { - ret = set_setting(it->first.c_str(), data, false); + ret = set_setting(it->first.c_str(), data); break; } ++it; @@ -985,11 +935,7 @@ int hg_scanner::invoke_setting_xxx(int(hg_scanner::*func)(void*, long*), void* d } int hg_scanner::setting_restore(void* data, long* len) { - // restore ... - notify_setting_result_ = false; - for (int i = 0; i < setting_jsn_->count(); ++i) - restore(setting_jsn_->get_name_by_sane_id(i + 1).c_str()); - notify_setting_result_ = true; + // move to scanner manager ... return SCANNER_ERR_CONFIGURATION_CHANGED; } @@ -1547,7 +1493,7 @@ int hg_scanner::setting_scan_mode(void* data, long* len) } else { - scan_count_ = *(int*)setting_jsn_->get_option_value(SANE_STD_OPT_NAME_SCAN_COUNT, OPT_VAL_CURRENT).c_str(); + scan_count_ = 1; // *(int*)setting_jsn_->get_option_value(SANE_STD_OPT_NAME_SCAN_COUNT, SANE_ACTION_GET_VALUE).c_str(); // 智学网设置该参数时,程序取消待纸扫描 if (!auto_scan_restore_) // 连续调用时,保留最初状态 @@ -1571,13 +1517,13 @@ int hg_scanner::setting_scan_mode(void* data, long* len) int hg_scanner::setting_scan_count(void* data, long* len) { int ret = SCANNER_ERR_OK; - std::string val(get_setting_item_string(SANE_STD_OPT_NAME_SCAN_MODE, "cur")); + //std::string val(get_setting_item_string(SANE_STD_OPT_NAME_SCAN_MODE, "cur")); - if (val == lang_load_string(ID_OPTION_VALUE_SMZS_LXSM, nullptr)) - { - scan_count_ = -1; - } - else + //if (val == lang_load_string(ID_OPTION_VALUE_SMZS_LXSM, nullptr)) + //{ + // scan_count_ = -1; + //} + //else { scan_count_ = *((int*)data); } @@ -2231,58 +2177,74 @@ hg_imgproc::IMGPRCPARAM hg_scanner::get_image_process_object(int model) } SANE_Image_Statu hg_scanner::last_usb_image_statu(int err) { - SANE_Image_Statu statu = SANE_Image_Statu_OK; + SANE_Image_Statu statu = IMG_STATUS_OK; if (!is_continue_when_double_paper(double_paper_handle_) && is_save_img_when_double_paper(double_paper_handle_)) { if (err == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) - statu = SANE_Image_Statu_Double; + statu = IMG_STATUS_DOUBLE; //else if (err == SCANNER_ERR_DEVICE_PAPER_JAMMED) //statu = SANE_Image_Statu_Jammed; } return statu; } -void hg_scanner::erase_option(const char* name) -{ - //erase_depend_.push_back(name); - //setting_jsn_->remove(name); -} void hg_scanner::init_settings(const char* json_setting_text) { - const char* lang = language_option_descriptor(); - bool empty = true; + std::string text(json_setting_text); + gb_json* jsn = new gb_json(); - if (lang && *lang) + // set fixed values ... dev-vid/dev-pid/dev-name/dev-model/roller-life + if (jsn->attach_text(&text[0])) { - std::string txt(json_setting_text); - size_t pos = txt.rfind('}'); - if (pos != std::string::npos) + gb_json* child = nullptr; + + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_VID, child); + if (child) { - txt[pos] = ','; + child->set_value("cur", io_->get_vid()); + child->set_value("default", io_->get_vid()); + child->release(); } - if (strstr(lang, "{")) - txt += strstr(lang, "{") + 1; - setting_jsn_->init(txt.c_str()); - empty = setting_jsn_->count() != 0; - } - if(empty) - { - std::string txt(json_setting_text); - setting_jsn_->init(txt.c_str()); + + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_PID, child); + if (child) + { + child->set_value("cur", io_->get_pid()); + child->set_value("default", io_->get_pid()); + child->release(); + } + + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_NAME, child); + if (child) + { + child->set_value("cur", name_.c_str()); + child->set_value("default", name_.c_str()); + child->release(); + } + + jsn->get_value(SANE_STD_OPT_NAME_DEVICE_MODEL, child); + if (child) + { + child->set_value("cur", io_->get_vid()); + child->set_value("default", io_->get_vid()); + child->release(); + } + + jsn->get_value(SANE_STD_OPT_NAME_ROLLER_LIFE, child); + if (child) + { + child->set_value("cur", 450000); + child->set_value("default", 450000); + child->release(); + } + + text = std::move(jsn->to_string()); } + jsn->release(); - jsn_reorganize(); - - - utils::to_log(LOG_LEVEL_ALL, "------>Initialize %d settings ...<------\n", setting_jsn_->count()); - notify_setting_result_ = false; - setting_restore(nullptr, nullptr); // restore to default value - utils::to_log(LOG_LEVEL_ALL, "------>Initialize %d settings ... OK<------\n", setting_jsn_->count()); - if (lang_get_cur_code_page() != DEFAULT_CODE_PAGE) - on_language_changed(); - notify_setting_result_ = true; + set_opt_json_text(&text[0]); } int hg_scanner::init_settings(int pid) { @@ -2304,10 +2266,6 @@ int hg_scanner::init_settings(int pid) return SCANNER_ERR_OK; } -std::string hg_scanner::get_setting_item_string(const char* name, const char* key) -{ - return std::move(setting_jsn_->get_option_field_string(name, key)); -} int hg_scanner::on_scann_error(int err) { status_ = err; @@ -2320,7 +2278,10 @@ int hg_scanner::on_scann_error(int err) } int hg_scanner::try_third_app_handle_start(bool& handled) { - int ret = SCANNER_ERR_OK; // status_ + int ret = SCANNER_ERR_OK; + + handled = false; + return ret; handled = !async_io_; if (handled) @@ -2369,13 +2330,14 @@ int hg_scanner::try_third_app_handle_start(bool& handled) } int hg_scanner::try_third_app_after_start(int err) { - if (!async_io_) - { - while (wait_img_.is_waiting() && !wait_usb_.is_waiting()) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - if (wait_img_.is_waiting() && wait_usb_.is_waiting()) - err = status_; - } + //if (!async_io_) + //{ + // while (wait_img_.is_waiting() && !wait_usb_.is_waiting()) + // std::this_thread::sleep_for(std::chrono::milliseconds(10)); + // if (wait_img_.is_waiting() && wait_usb_.is_waiting()) + // err = status_; + // + //} return err; } @@ -2728,36 +2690,13 @@ int hg_scanner::close(bool force) return ret; } -int hg_scanner::set_setting(const char* name, void* data, bool to_default) +int hg_scanner::set_setting(const char* name, void* data) { - int ret = SCANNER_ERR_OUT_OF_RANGE, refine = 0; - bool hit = false, del_mem = false; - long len = 0; std::string real_n(name); + int ret = SCANNER_ERR_OUT_OF_RANGE, refine = 0; + bool hit = setting_map_.count(real_n) > 0; + long len = 0; - if (to_default) - { - if (!setting_jsn_->is_auto_restore_default(name)) - return SCANNER_ERR_DEVICE_NOT_SUPPORT; - - int size = 0; - std::string val(setting_jsn_->get_option_value(name, OPT_VAL_DEFAULT, &size)); - - if (!data) - { - data = new char[size]; - memset(data, 0, size); - del_mem = true; - } - if (setting_jsn_->get_option_value_type(name) == JSON_SANE_TYPE_STRING) - strcpy((char*)data, val.c_str()); - else - memcpy(data, &val[0], val.length()); - } - else - refine = setting_jsn_->refine_data(real_n.c_str(), data); - - hit = setting_map_.count(real_n) > 0; if (hit) { ret = (this->*setting_map_[real_n])(data, &len); @@ -2767,67 +2706,14 @@ int hg_scanner::set_setting(const char* name, void* data, bool to_default) utils::to_log(LOG_LEVEL_WARNING, "Setting '%s' is not found in base setting functions.\n", real_n.c_str()); ret = set_setting_value(real_n.c_str(), data, &len); } - if (setting_jsn_->update_data(real_n.c_str(), data) == SCANNER_ERR_RELOAD_OPT_PARAM) - ret = SCANNER_ERR_RELOAD_OPT_PARAM; - - if (del_mem) - delete[] data; return ret; } -int hg_scanner::get_setting(const char* name, char* buf, int* len, int type) +int hg_scanner::get_setting(const char* name, char* buf, int* len) { if (!len) return SCANNER_ERR_INVALID_PARAMETER; - if (name == nullptr) - { - *len = setting_jsn_->count() + 1; - - return SCANNER_ERR_OK; - } - else if (name == PARAM_ALL) - { - std::string text(setting_jsn_->get_option_value(nullptr, OPT_VAL_JSON)); - - if (*len <= text.length()) - { - *len = text.length() + 4; - - return SCANNER_ERR_INSUFFICIENT_MEMORY; - } - ::strcpy(buf, text.c_str()); - *len = text.length(); - - return SCANNER_ERR_OK; - } - - std::string real_n(name); - - if (real_n.empty()) - { - return SCANNER_ERR_OUT_OF_RANGE; - } - else - { - int size = 0; - std::string val(setting_jsn_->get_option_value(name, OPT_VAL_CURRENT, &size)); - - if (val.empty()) - return SCANNER_ERR_INVALID_PARAMETER; - - if (*len < val.length()) - { - *len = size; - - return SCANNER_ERR_INSUFFICIENT_MEMORY; - } - - memcpy(buf, &val[0], val.length()); - if (setting_jsn_->get_option_value_type(name) == JSON_SANE_TYPE_STRING) - buf[val.length()] = 0; - } - return SCANNER_ERR_OK; } std::string hg_scanner::name(void) @@ -2850,13 +2736,100 @@ bool hg_scanner::is_online(void) void hg_scanner::on_language_changed(void) { // change the 'size' member of string settings ... - setting_jsn_->update_data(nullptr, nullptr); + //setting_jsn_->update_data(nullptr, nullptr); +} +int hg_scanner::wait_one_image_from_start(bool& handled) +{ + int ret = SCANNER_ERR_OK; + + handled = false; + if (!async_io_) // non-callback + { + while (is_running() != THREAD_RUNNING_IDLE) + { + handled = true; + if (final_imgs_.size()) + { + break; + } + } + + if (final_imgs_.size()) + { + IMH head = { 0 }; + + handled = true; + if (final_imgs_.front(&head)) + { + if (head.statu & IMG_STATUS_DOUBLE) + ret = SCANNER_ERR_DEVICE_DOUBLE_FEEDING; + else if (head.statu & IMG_STATUS_JAM) + ret = SCANNER_ERR_DEVICE_PAPER_JAMMED; + else if (head.statu & IMG_STATUS_STAPLE) + ret = SCANNER_ERR_DEVICE_STAPLE_ON; + else if (head.statu & IMG_STATUS_SIZE_ERR) + ret = SCANNER_ERR_DEVICE_SIZE_CHECK; + else if (head.statu & IMG_STATUS_DOGEAR) + ret = SCANNER_ERR_DEVICE_DOGEAR; + } + } + else if (handled) // overed normal or exception + { + if (status_ == SCANNER_ERR_OK + || status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) // 双张特殊处理,视为成功 + { + SANE_Bool has_paper = SANE_FALSE; + + get_scanner_paperon(has_paper); + if (has_paper == SANE_TRUE) + handled = false; + else + ret = SCANNER_ERR_DEVICE_NO_PAPER; + } + else + ret = status_; + } + } + + return ret; } int hg_scanner::start(void) { - user_cancel_ = false; + int ret = SCANNER_ERR_OK; + bool handled = false; - return status_; + if (user_cancel_) + { + user_cancel_ = false; // stopped by user, reset flag and starting a new scanning ... + utils::to_log(LOG_LEVEL_DEBUG, "start after user stopped just now while with %d image(s) in queue, a new scanning will to be started ...\n", final_imgs_.size()); + } + else + { + ret = wait_one_image_from_start(handled); + if (handled) + { + utils::to_log(LOG_LEVEL_DEBUG, "start in previous scanning and result is %s, image count %d\n", hg_scanner_err_description(ret), final_imgs_.size()); + return ret; + } + } + + // clear ... + imgs_.Clear(); + final_imgs_.clear(); + usb_img_index_ = final_img_index_ = 0; + status_ = SCANNER_ERR_OK; + + // start ... + ret = do_start(); + + if (ret == SCANNER_ERR_OK) + { + // wait ONE picture or stopped + ret = wait_one_image_from_start(handled); + } + utils::to_log(LOG_LEVEL_DEBUG, "start scanning result = %s\n", hg_scanner_err_description(ret)); + + return ret; } int hg_scanner::get_image_info(SANE_Parameters* ii) { @@ -2945,9 +2918,21 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len) } int hg_scanner::stop(void) { - user_cancel_ = true; + int ret = SCANNER_ERR_OK; - return status_; + user_cancel_ = true; + ret = do_stop(); + + // wait until really stopped ... + if (ret == SCANNER_ERR_OK) + { + while (is_running() != THREAD_RUNNING_IDLE) + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + ret = status_; + } + utils::to_log(LOG_LEVEL_DEBUG, "user stopped result = %s\n", hg_scanner_err_description(ret)); + + return ret; } int hg_scanner::reset(void) { @@ -2984,23 +2969,23 @@ int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len) } else if (code == IO_CTRL_CODE_GET_DEFAULT_VALUE) { - if (*len <= 0) - { - *len = setting_jsn_->count() + 1; + //if (*len <= 0) + //{ + // *len = setting_jsn_->count() + 1; + + // return SCANNER_ERR_OK; + //} + //else if (*len >= setting_jsn_->count()) + //{ + // return SCANNER_ERR_OUT_OF_RANGE; + //} + //else + //{ + // std::string val(setting_jsn_->get_option_value((int)*len, SANE_ACTION_GET_DEFAULT_VALUE)); + // memcpy(data, &val[0], val.length()); return SCANNER_ERR_OK; - } - else if (*len >= setting_jsn_->count()) - { - return SCANNER_ERR_OUT_OF_RANGE; - } - else - { - std::string val(setting_jsn_->get_option_value((int)*len, OPT_VAL_DEFAULT)); - memcpy(data, &val[0], val.length()); - - return SCANNER_ERR_OK; - } + //} } else if (code == IO_CTRL_CODE_SET_CLEAR_ROLLER_COUNT) { @@ -4239,4 +4224,31 @@ int hg_scanner::image_configuration(SCANCONF& ic) utils::to_log(LOG_LEVEL_DEBUG, "ic.is_colorcast =%d\r\n", ic.is_colorcast); utils::to_log(LOG_LEVEL_DEBUG, "ic.isuoloadexceptionimage=%d\r\n", ic.isuoloadexceptionimage); return ret; -} \ No newline at end of file +} + +std::string hg_scanner::get_value(const char* name, void* value, int* err) +{ + std::string val(""); + int result = SCANNER_ERR_OK; + + if (err) + *err = result; + + return std::move(val); +} +int hg_scanner::set_value(const char* name, void* val) +{ + int err = SCANNER_ERR_DEVICE_NOT_SUPPORT; + + if (setting_map_.count(name)) + { + long len = 0; + err = (this->*setting_map_[name])(val, &len); + } + + return err; +} +void hg_scanner::enable(const char* name, bool able) +{ + +} diff --git a/hgdriver/hgdev/hg_scanner.h b/hgdriver/hgdev/hg_scanner.h index cbb87f1..f20fac0 100644 --- a/hgdriver/hgdev/hg_scanner.h +++ b/hgdriver/hgdev/hg_scanner.h @@ -32,6 +32,8 @@ #endif + + #ifndef WIN32 #define __stdcall #endif @@ -71,7 +73,9 @@ typedef HGResult(__stdcall* SDKHGVersion_Free_)(HGVersionMgr mgr); class gb_json; class device_option; -class hg_scanner + +#include "../../sdk/hginclude/base_opt.h" +class hg_scanner : public sane_opt_provider { HGVersionMgr HGVersion_mgr_; SDKHGVersion_Init_ HGVersion_Init_; @@ -113,7 +117,6 @@ class hg_scanner void dump_image_real(hg_imgproc::HIMGPRC himg, const char* desc); void init_setting_func_map(void); - int restore(const char* name); bool is_to_file(void); void thread_handle_image_process(void); @@ -121,7 +124,6 @@ class hg_scanner void working_done(void*); void image_process(std::shared_ptr& buffer, uint32_t id); - bool jsn_reorganize(); // 固件版本不同 初始化gb_json要做出相对应的删除 public: @@ -282,8 +284,6 @@ protected: bool cb_mem_; bool test_1_paper_; // 是否为单张扫描模式 std::vector erase_depend_; //需要删除父依赖项 - //gb_json *setting_jsn_; - device_option *setting_jsn_; IMGPRCFIXPARAM image_prc_param_; int erase_bkg_range_; // 背景移除像素范围 @@ -390,10 +390,8 @@ protected: uint32_t fetching_id_; // for sane read image ext info. added on 2023-01-13 - void erase_option(const char* name); void init_settings(const char* json_setting_text); int init_settings(int pid); - std::string get_setting_item_string(const char* name, const char* key); int on_scann_error(int err); // 返回“0”忽略错误继续执行,其它值则停止后续工作 int try_third_app_handle_start(bool& handled); int try_third_app_after_start(int err); @@ -408,6 +406,7 @@ protected: int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1); void adjust_filling_hole(LPSCANCONF conf); + int wait_one_image_from_start(bool& handled); //////////////////////////////////////////////////////////////// // 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05 @@ -430,6 +429,9 @@ protected: bool is_white_0_; // 是否‘0’代表白色 public: + int start(void); + int stop(void); + void set_ui_callback(sane_callback cb, bool enable_async_io); void set_dev_family(const char* family); void set_read_over_with_no_data(bool no_data); @@ -438,8 +440,8 @@ public: int get_pid(void); int get_vid(void); int close(bool force); - int set_setting(const char* name, void* data, bool to_default); - int get_setting(const char* name, char* buf, int* len, int type); + int set_setting(const char* name, void* data); + int get_setting(const char* name, char* buf, int* len); int hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type); int image_configuration(SCANCONF &ic); std::string name(void); @@ -456,10 +458,10 @@ public: int is_running(void); // return thread_running public: - virtual int start(void); + virtual int do_start(void) = 0; + virtual int do_stop(void) = 0; virtual int get_image_info(SANE_Parameters* ii); virtual int read_image_data(unsigned char* buf, int* len); - virtual int stop(void); virtual int reset(void); virtual int device_io_control(unsigned long code, void* data, unsigned* len); virtual int discard_all_images(void) = 0; @@ -536,7 +538,18 @@ public: virtual int set_devs_time(string times); //设置设备时间 //3399设备支持 virtual int get_devs_time(string ×); //获取设备时间 //3399设备支持 + + // sane_opt_provider +public: + virtual std::string get_value(const char* name, void* value, int* err = nullptr); + virtual int set_value(const char* name, void* val); + virtual void enable(const char* name, bool able); + }; - //TEST 测试GIT切换 \ No newline at end of file + //TEST 测试GIT切换 + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// NEW diff --git a/hgdriver/hgdev/hg_scanner_200.cpp b/hgdriver/hgdev/hg_scanner_200.cpp index bd68603..a9dba4a 100644 --- a/hgdriver/hgdev/hg_scanner_200.cpp +++ b/hgdriver/hgdev/hg_scanner_200.cpp @@ -267,7 +267,7 @@ void hg_scanner_200::thread_handle_usb_read(void) } utils::to_log(LOG_LEVEL_DEBUG, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_description(status_)); } -int hg_scanner_200::start(void) +int hg_scanner_200::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), @@ -320,7 +320,7 @@ int hg_scanner_200::start(void) return ret; } -int hg_scanner_200::stop(void) +int hg_scanner_200::do_stop(void) { int ret = SCANNER_ERR_OK; diff --git a/hgdriver/hgdev/hg_scanner_200.h b/hgdriver/hgdev/hg_scanner_200.h index 84dabfc..c26d088 100644 --- a/hgdriver/hgdev/hg_scanner_200.h +++ b/hgdriver/hgdev/hg_scanner_200.h @@ -48,8 +48,8 @@ public: ~hg_scanner_200(); public: - virtual int start(void)override; - virtual int stop(void)override; + virtual int do_start(void) override; + virtual int do_stop(void) override; private: int initdevice(); @@ -57,7 +57,7 @@ private: int readusb(USBCB &usb); int pop_image(); int get_scanner_status(USBCB &usb); - int get_img_data(unsigned int bytes, SANE_Image_Statu statu = SANE_Image_Statu_OK); + int get_img_data(unsigned int bytes, SANE_Image_Statu statu = IMG_STATUS_OK); int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_DSP *d = NULL); void writedown_image_configuration(void); void printf_devconfig(setting_hardware::HGSCANCONF_DSP *d = NULL); diff --git a/hgdriver/hgdev/hg_scanner_239.cpp b/hgdriver/hgdev/hg_scanner_239.cpp index 10b7933..ca64bfb 100644 --- a/hgdriver/hgdev/hg_scanner_239.cpp +++ b/hgdriver/hgdev/hg_scanner_239.cpp @@ -23,8 +23,8 @@ static std::string device_opt_json[] = { "{\"restore\":{\"cat\":\"base\",\"group\":\"\",\"title\":\"\\u6062\\u590d\\u9ed8\\u8ba4\\u8bbe\\u7f6e\",\"desc\":\"\\u6062\\u590d\\u9ed8\\u8ba4\\u8bbe\\u7f6e\",\"type\":\"button\",\"fix-id\":34921,\"size\":4},\"help\":{\"cat\":\"base\",\"group\":\"\",\"title\":\"\\u5e2e\\u52a9\",\"desc\":\"\\u663e\\u793a\\u8f6f\\u4ef6\\u5e2e\\u52a9\\u6587\\u6863\",\"type\":\"button\",\"fix-id\":34897,\"size\":4},\"is-multiout\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34817,\"size\":4,\"cur\":false,\"default\":false},\"multiout-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"fix-id\":34818,\"enabled\":false,\"size\":66,\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend\":\"is-multiout==true\"},\"mode\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"size\":24,\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend\":\"is-multiout!=true\"},\"binary-threshold\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u9608\\u503c\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a1\\uff08\\u767d\\uff09\\uff0c\\u4f4e\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a0\\uff08\\u9ed1\\uff09\",\"type\":\"int\",\"fix-id\":34870,\"size\":4,\"cur\":127,\"default\":127,\"range\":{\"min\":0,\"max\":255,\"step\":1},\"depend\":\"(multiout-type.enabled&&multiout-type!=\\u5f69\\u8272+\\u7070\\u5ea6) || (mode.enabled && mode==\\u9ed1\\u767d)\"},\"reverse-bw\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u53cd\\u8272\\u8f93\\u51fa\",\"desc\":\"\\u8f93\\u51fa\\u7684\\u9ed1\\u767d\\u56fe\\u50cf\\u4ee5\\u201c1\\u201d\\u4ee3\\u8868\\u9ed1\\u8272\\uff0c\\u201c0\\u201d\\u4ee3\\u8868\\u767d\\u8272\",\"type\":\"bool\",\"fix-id\":34878,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"(multiout-type.enabled&&multiout-type!=\\u5f69\\u8272+\\u7070\\u5ea6) || (mode.enabled && mode==\\u9ed1\\u767d)\"},\"filter\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7070\\u5ea6\\u6216\\u9ed1\\u767d\\u56fe\\u50cf - \\u9664\\u8272\\u4e0e\\u589e\\u5f3a\",\"desc\":\"\\u6d88\\u9664\\u6216\\u589e\\u5f3a\\u6307\\u5b9a\\u8272\\u5f69\",\"type\":\"string\",\"fix-id\":34820,\"enabled\":false,\"size\":42,\"cur\":\"\\u4e0d\\u9664\\u8272\",\"default\":\"\\u4e0d\\u9664\\u8272\",\"range\":[\"\\u4e0d\\u9664\\u8272\",\"\\u9664\\u7ea2\\u8272\",\"\\u9664\\u7eff\\u8272\",\"\\u9664\\u84dd\\u8272\",\"\\u7ea2\\u8272\\u589e\\u5f3a\",\"\\u7eff\\u8272\\u589e\\u5f3a\",\"\\u84dd\\u8272\\u589e\\u5f3a\"],\"depend\":\"mode.enabled && (mode==256\\u7ea7\\u7070\\u5ea6 || mode==\\u9ed1\\u767d)\"},\"is-rid-multiout-red\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u591a\\u6d41\\u8f93\\u51fa\\u9664\\u7ea2\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u5f69\\u8272\\u56fe\\u50cf\\u548c\\u7070\\u5ea6\\u9664\\u7ea2\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34821,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"is-rid-answer-sheet-red\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u7b54\\u9898\\u5361\\u9664\\u7ea2\",\"desc\":\"\\u8f93\\u51fa\\u9664\\u7ea2\\u5f69\\u8272\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34822,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"is-erase-bkg\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u80cc\\u666f\\u79fb\\u9664\",\"desc\":\"\\u79fb\\u9664\\u6587\\u7a3f\\u80cc\\u666f\\u5e95\\u8272\",\"type\":\"bool\",\"fix-id\":34823,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"bkg-color-range\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\" \\u80cc\\u666f\\u8272\\u5f69\\u6d6e\\u52a8\\u8303\\u56f4\",\"desc\":\"\\u4e0e\\u80cc\\u666f\\u5e95\\u8272\\u504f\\u5dee\\u5728\\u8be5\\u503c\\u8303\\u56f4\\u5185\\u7684\\u989c\\u8272\\uff0c\\u90fd\\u5c06\\u88ab\\u79fb\\u9664\",\"type\":\"int\",\"fix-id\":34824,\"enabled\":false,\"size\":4,\"cur\":20,\"default\":20,\"range\":{\"min\":1,\"max\":128,\"step\":1},\"depend\":\"is-erase-bkg==true\"},\"sharpen\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9510\\u5316\\u4e0e\\u6a21\\u7cca\",\"desc\":\"\\u9009\\u62e9\\u9510\\u5316\\u6548\\u679c\\u6216\\u6a21\\u7cca\\u6548\\u679c\",\"type\":\"string\",\"fix-id\":34825,\"size\":20,\"cur\":\"\\u65e0\",\"default\":\"\\u65e0\",\"range\":[\"\\u65e0\",\"\\u9510\\u5316\",\"\\u8fdb\\u4e00\\u6b65\\u9510\\u5316\",\"\\u6a21\\u7cca\",\"\\u8fdb\\u4e00\\u6b65\\u6a21\\u7cca\"],\"depend\":\"mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-rid-morr\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u53bb\\u9664\\u6469\\u5c14\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u6469\\u5c14\\u7eb9\",\"type\":\"bool\",\"fix-id\":34826,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"resolution<500&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 && mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-rid-grid\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9664\\u7f51\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u7f51\\u7eb9\",\"type\":\"bool\",\"fix-id\":34827,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"resolution<500&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 && mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-err-extension\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9519\\u8bef\\u6269\\u6563\",\"desc\":\"\\u4ee5\\u70b9\\u9635\\u5f62\\u5f0f\\u6784\\u5efa\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34828,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled&&mode==\\u9ed1\\u767d\"},\"is-noise-optimize\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u566a\\u70b9\\u4f18\\u5316\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u5b64\\u7acb\\u9ed1\\u70b9\",\"type\":\"bool\",\"fix-id\":34829,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled&&mode==\\u9ed1\\u767d\"},\"noise-size\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\" \\u566a\\u70b9\\u4f18\\u5316\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u9700\\u8981\\u53bb\\u9664\\u7684\\u9ed1\\u8272\\u5b64\\u7acb\\u70b9\\u7684\\u8fde\\u901a\\u4e2a\\u6570\",\"type\":\"int\",\"fix-id\":34830,\"size\":4,\"cur\":10,\"default\":10,\"range\":{\"min\":1,\"max\":50,\"step\":1},\"depend\":\"is-noise-optimize==true\"},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"fix-id\":34831,\"size\":44,\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"16\\u5f00\",\"A5\",\"A6\",\"B4\",\"B5\",\"B6\",\"Letter\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\"},{\"resolution<500\":\"\\u4e09\\u8054\\u8bd5\\u5377\"}]},\"lateral\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u6a2a\\u5411\",\"desc\":\"\\u6a2a\\u5411\\u653e\\u7f6e\\u7eb8\\u5f20\",\"type\":\"bool\",\"fix-id\":34924,\"affect\":6,\"visible\":0,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper==A4 || paper==16\\u5f00 || paper==A5 || paper==A6 || paper==B5 || paper==B6 || paper==Letter\"},\"is-custom-area\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\",\"type\":\"bool\",\"fix-id\":34832,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper!=\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},\"tl-x\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4e0a\\u89d2x\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34833,\"unit\":\"mm\",\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.000000,\"max\":\"br-x\",\"step\":0.010000},\"depend\":\"is-custom-area==true && is-custom-area.enabled\"},\"br-x\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u53f3\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u53f3\\u4e0b\\u89d2x\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34834,\"unit\":\"mm\",\"size\":8,\"cur\":210.000000,\"default\":210.000000,\"range\":{\"min\":\"tl-x\",\"max\":210.000000,\"step\":0.010000},\"depend\":\"is-custom-area==true && is-custom-area.enabled\"},\"tl-y\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u4e0a\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4e0a\\u89d2y\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":", "34835,\"unit\":\"mm\",\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.000000,\"max\":\"br-y\",\"step\":0.010000},\"depend\":\"is-custom-area==true && is-custom-area.enabled\"},\"br-y\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u4e0b\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u53f3\\u4e0b\\u89d2y\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34836,\"unit\":\"mm\",\"size\":8,\"cur\":297.000000,\"default\":297.000000,\"range\":{\"min\":\"tl-y\",\"max\":297.000000,\"step\":0.010000},\"depend\":\"is-custom-area==true && is-custom-area.enabled\"},\"is-size-check\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5c3a\\u5bf8\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u7eb8\\u5f20\\u5b9e\\u9645\\u5c3a\\u5bf8\\u4e0e\\u8bbe\\u7f6e\\u662f\\u5426\\u5339\\u914d\",\"type\":\"bool\",\"fix-id\":34837,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper==A3||paper==A4||paper==A5||paper==A6||paper==B4||paper==B5||paper==B6||paper==Double Letter||paper==LEGAL||paper==Letter\"},\"page\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u9875\\u9762\",\"desc\":\"\\u8bbe\\u7f6e\\u9875\\u9762\\u626b\\u63cf\\u65b9\\u5f0f\",\"type\":\"string\",\"fix-id\":34838,\"size\":12,\"cur\":\"\\u53cc\\u9762\",\"default\":\"\\u53cc\\u9762\",\"range\":[\"\\u6b63\\u9762\",\"\\u80cc\\u9762\",\"\\u53cc\\u9762\",\"\\u5bf9\\u6298\"]},\"discardblank\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\",\"desc\":\"\",\"type\":\"bool\",\"fix-id\":34919,\"size\":4,\"cur\":false,\"default\":false},\"blank-sensitivity\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\" \\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\\u7075\\u654f\\u5ea6\",\"desc\":\"\\u6570\\u503c\\u8d8a\\u5927\\uff0c\\u5219\\u8d8a\\u5bb9\\u6613\\u8df3\\u8fc7\",\"type\":\"int\",\"fix-id\":34839,\"size\":4,\"cur\":30,\"default\":30,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend\":\"discardblank==true\"},\"fold-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5bf9\\u6298\\u6a21\\u5f0f\",\"desc\":\"\",\"type\":\"string\",\"fix-id\":34887,\"size\":16,\"cur\":\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"default\":\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"range\":[\"\\u5de6\\u53f3\\u5bf9\\u6298\",\"\\u4e0a\\u4e0b\\u5bf9\\u6298\",\"\\u81ea\\u52a8\\u5bf9\\u6298\"],\"depend\":\"page==\\u5bf9\\u6298\"},\"resolution\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"size\":4,\"cur\":200,\"default\":200,\"range\":{\"min\":100,\"max\":{\"default\":600,\"paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 || paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8 || paper==\\u4e09\\u8054\\u8bd5\\u5377\":500},\"step\":1}},\"image-quality\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u753b\\u8d28\",\"desc\":\"\\u9009\\u62e9\\u626b\\u63cf\\u4eea\\u7684\\u753b\\u8d28\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34841,\"size\":16,\"cur\":\"\\u753b\\u8d28\\u4f18\\u5148\",\"default\":\"\\u753b\\u8d28\\u4f18\\u5148\",\"range\":[\"\\u901f\\u5ea6\\u4f18\\u5148\",\"\\u753b\\u8d28\\u4f18\\u5148\"],\"depend\":\"resolution>=300\"},\"is-exchange\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u4ea4\\u6362\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u4ea4\\u6362\\u6bcf\\u5f20\\u6587\\u7a3f\\u7684\\u6b63\\u53cd\\u9762\\u51fa\\u56fe\\u987a\\u5e8f\",\"type\":\"bool\",\"fix-id\":34842,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"page==\\u53cc\\u9762\"},\"is-custom-gamma\":{\"cat\":\"base\",\"group\":\"bright\",\"title\":\"\\u542f\\u7528\\u8272\\u8c03\\u66f2\\u7ebf\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u56fe\\u50cf\\u8272\\u8c03\\u6548\\u679c\",\"type\":\"bool\",\"fix-id\":34845,\"size\":4,\"cur\":false,\"default\":false},\"brightness\":{\"cat\":\"base\",\"group\":\"bright\",\"title\":\"\\u4eae\\u5ea6\\u503c\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u4eae\\u5ea6\",\"type\":\"int\",\"fix-id\":34846,\"size\":4,\"cur\":128,\"default\":128,\"range\":{\"min\":1,\"max\":255,\"step\":1},\"depend\":\"is-custom-gamma==false\"},\"contrast\":{\"cat\":\"base\",\"group\":\"bright\",\"title\":\"\\u5bf9\\u6bd4\\u5ea6\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u5bf9\\u6bd4\\u5ea6\",\"type\":\"int\",\"fix-id\":34847,\"size\":4,\"cur\":4,\"default\":4,\"range\":{\"min\":1,\"max\":7,\"step\":1},\"depend\":\"is-custom-gamma==false\"},\"gamma\":{\"cat\":\"base\",\"group\":\"bright\",\"title\":\"\\u4f3d\\u9a6c\\u503c\",\"desc\":\"\\u8c03\\u6574\\u56fe\\u50cf\\u4f3d\\u739b\\u503c\",\"type\":\"float\",\"fix-id\":34848,\"size\":8,\"cur\":1.000000,\"default\":1.000000,\"range\":{\"min\":0.010000,\"max\":5.000000,\"step\":0.499000},\"depend\":\"is-custom-gamma==false\"},\"color-correction\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u8272\\u504f\\u6821\\u6b63\",\"desc\":\"\\u8272\\u5f69\\u8fd8\\u539f\\u5ea6\\u77eb\\u6b63\\u529f\\u80fd\",\"type\":\"bool\",\"fix-id\":34888,\"size\":4,\"cur\":false,\"default\":false},\"is-anti-skew\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u81ea\\u52a8\\u7ea0\\u504f\",\"desc\":\"\\u81ea\\u52a8\\u7ea0\\u6b63\\u6b6a\\u659c\\u9001\\u5165\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34844,\"size\":4,\"cur\":true,\"default\":true,\"depend\":\"page!=\\u5bf9\\u6298\"},\"is-split\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u56fe\\u50cf\\u62c6\\u5206\",\"desc\":\"\\u81ea\\u52a8\\u62c6\\u5206\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34843,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"page!=\\u5bf9\\u6298\"},\"is-erase-black-frame\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u6d88\\u9664\\u9ed1\\u6846\",\"desc\":\"\\u6d88\\u9664\\u6587\\u7a3f\\u8303\\u56f4\\u5916\\u7684\\u9ed1\\u8272\\u80cc\\u666f\",\"type\":\"bool\",\"fix-id\":34849,\"size\":4,\"cur\":true,\"default\":true},\"bkg-fill-mode\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u80cc\\u666f\\u586b\\u5145\\u65b9\\u5f0f\",\"type\":\"string\",\"fix-id\":34854,\"size\":16,\"cur\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"default\":\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"range\":[\"\\u51f8\\u591a\\u8fb9\\u5f62\",\"\\u51f9\\u591a\\u8fb9\\u5f62\"],\"depend\":\"is-erase-black-frame==true\"},\"is-fill-color\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u8272\\u5f69\\u586b\\u5145\",\"desc\":\"\\u542f\\u7528\\u540e\\u9ed1\\u6846\\u90e8\\u5206\\u5c06\\u586b\\u5145\\u4e3a\\u6587\\u7a3f\\u5e95\\u8272\",\"type\":\"bool\",\"fix-id\":34859,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"is-erase-black-frame==true\"},\"threshold\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u9608\\u503c\",\"desc\":\"\\u6587\\u7a3f\\u5e95\\u8272\\u4e0e\\u9ed1\\u8272\\u80cc\\u666f\\u7070\\u5ea6\\u503c\\u7684\\u5dee\\u503c\\u5927\\u4e8e\\u8be5\\u503c\\uff0c\\u624d\\u4f1a\\u88ab\\u8bc6\\u522b\\u4e3a\\u6587\\u7a3f\",\"type\":\"int\",\"fix-id\":34851,\"size\":4,\"cur\":40,\"default\":40,\"range\":{\"min\":30,\"max\":50,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"anti-noise-level\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u80cc\\u666f\\u6297\\u566a\\u7b49\\u7ea7\",\"desc\":\"\\u80fd\\u591f\\u5bb9\\u5fcd\\u7684\\u80cc\\u666f\\u6742\\u8272\\u6761\\u7eb9\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"fix-id\":34852,\"size\":4,\"cur\":8,\"default\":8,\"range\":{\"min\":2,\"max\":20,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"margin\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"desc\":\"\\u5bfb\\u627e\\u6587\\u7a3f\\u8fb9\\u7f18\\u65f6\\u5bf9\\u8fb9\\u7f18\\u7684\\u4fb5\\u5165\\u7a0b\\u5ea6\",\"type\":\"int\",\"fix-id\":34853,\"size\":4,\"cur\":5,\"default\":5,\"range\":{\"min\":2,\"max\":30,\"step\":1},\"depend\":\"is-erase-black-frame==true||paper==\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8||paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207||is-anti-skew==true\"},\"is-dark-sample\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u6df1\\u8272\\u6837\\u5f20\",\"desc\":\"\\u542f\\u7528\\u8be5\\u6a21\\u5f0f\\u9632\\u6b62\\u6df1\\u8272\\u5e95\\u8272\\u7684\\u6587\\u7a3f\\u56fe\\u50cf\\u88ab\\u8bef\\u5904\\u7406\",\"type\":\"bool\",\"fix-id\":34850,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"page!=\\u5bf9\\u6298&&is-erase-black-frame!=true&&paper!=\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207&&is-anti-skew!=true\"},\"is-anti-permeate\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u9632\\u6b62\\u6e17\\u900f\",\"desc\":\"\\u9632\\u6b62\\u80cc\\u9762\\u56fe\\u6848\\u6e17\\u900f\",\"type\":\"bool\",\"fix-id\":34855,\"size\":4,\"cur\":false,\"default\":false},\"permeate-level\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u9632\\u6b62\\u6e17\\u900f\\u7b49\\u7ea7\",\"desc\":\"\\u9009\\u62e9\\u9632\\u6b62\\u6e17\\u900f\\u7684\\u7b49\\u7ea7\",\"type\":\"string\",\"fix-id\":34856,\"size\":12,\"cur\":\"\\u8f83\\u5f31\",\"default\":\"\\u8f83\\u5f31\",\"range\":[\"\\u5f31\",\"\\u8f83\\u5f31\",\"\\u4e00\\u822c\",\"\\u8f83\\u5f3a\",\"\\u5f3a\"],\"depend\":\"is-anti-permeate==true\"},\"is-rid-hole-l\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u5de6\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u5de6\\u4fa7\",\"type\":\"bool\",\"fix-id\":34879,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-l\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u5de6\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e", - "45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34880,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-l==true\"},\"is-rid-hole-r\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u53f3\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u53f3\\u4fa7\",\"type\":\"bool\",\"fix-id\":34881,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-r\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u53f3\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34882,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-r==true\"},\"is-rid-hole-t\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0a\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0a\\u90e8\",\"type\":\"bool\",\"fix-id\":34883,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-t\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u4e0a\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34884,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-t==true\"},\"is-rid-hole-b\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0b\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0b\\u90e8\",\"type\":\"bool\",\"fix-id\":34885,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-b\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u4e0b\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34886,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-b==true\"},\"is-wait-scan\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e\\uff0c\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"fix-id\":34873,\"size\":4,\"cur\":false,\"default\":false},\"wait-scan-exit\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\\u9000\\u51fa\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u7ed3\\u675f\\u5f85\\u7eb8\\u626b\\u63cf\\u7684\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34920,\"size\":16,\"cur\":\"60s\",\"default\":\"60s\",\"range\":[\"15s\",\"30s\",\"60s\",\"2min\",\"4min\",\"8min\"],\"depend\":\"is-wait-scan==true\"},\"scan-mode\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"fix-id\":34862,\"size\":24,\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend\":\"is-wait-scan==false\"},\"scan-count\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"fix-id\":34863,\"size\":4,\"cur\":1,\"default\":1,\"depend\":\"scan-mode.enabled&&scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"},\"direction\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6587\\u7a3f\\u65b9\\u5411\",\"desc\":\"\\u8bbe\\u7f6e\\u56fe\\u50cf\\u7684\\u65b9\\u5411\",\"type\":\"string\",\"fix-id\":34864,\"size\":32,\"cur\":\"0\\u00b0\",\"default\":\"0\\u00b0\",\"range\":[\"0\\u00b0\",\"90\\u00b0\",\"180\\u00b0\",\"-90\\u00b0\",\"\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b\\u00b0\"]},\"is-rotate-bkg-180\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u80cc\\u9762\\u65cb\\u8f6c180\\u00b0\",\"desc\":\"\\u80cc\\u9762\\u626b\\u63cf\\u7684\\u56fe\\u50cf\\u65cb\\u8f6c180\\u00b0\",\"type\":\"bool\",\"fix-id\":34865,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"page!=\\u5bf9\\u6298&&direction!=\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b\\u00b0\"},\"is-ultrosonic\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u8d85\\u58f0\\u6ce2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u53cc\\u5f20\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34860,\"size\":4,\"cur\":true,\"default\":true},\"double-feed\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u53cc\\u5f20\\u56fe\\u7247\\u5904\\u7406\",\"desc\":\"\\u68c0\\u6d4b\\u5230\\u53cc\\u5f20\\u8fdb\\u7eb8\\u540e\\u7684\\u5904\\u7406\\u65b9\\u5f0f\",\"type\":\"string\",\"fix-id\":34872,\"size\":32,\"cur\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"default\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"range\":[\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"\\u4e0a\\u4f20\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\"],\"depend\":\"is-ultrosonic==true\"},\"is-staple\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u7c98\\u8fde\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34861,\"size\":4,\"cur\":false,\"default\":false},\"is-check-askew\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u6b6a\\u659c\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34868,\"size\":4,\"cur\":true,\"default\":true},\"askew-range\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34869,\"size\":4,\"cur\":3,\"default\":3,\"range\":{\"min\":1,\"max\":5,\"step\":1},\"depend\":\"is-check-askew==true\"},\"is-check-dog-ear\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6298\\u89d2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u6587\\u7a3f\\u662f\\u5426\\u5b58\\u5728\\u6298\\u89d2\",\"type\":\"bool\",\"fix-id\":34866,\"size\":4,\"cur\":false,\"default\":false},\"dog-ear-size\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u6298\\u89d2\\u5927\\u5c0f\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u68c0\\u6d4b\\u5230\\u7684\\u6298\\u89d2\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34867,\"size\":4,\"cur\":70,\"default\":70,\"range\":{\"min\":10,\"max\":300,\"step\":1},\"depend\":\"is-check-dog-ear==true\"},\"is-auto-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"fix-id\":34876,\"size\":4,\"cur\":false,\"default\":false},\"feed-strength-value\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"fix-id\":34877,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend\":\"is-auto-strength==true\"},\"feed-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"fix-id\":34874,\"size\":12,\"cur\":\"\\u4e00\\u822c\",\"default\":\"\\u4e00\\u822c\",\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"],\"depend\":\"is-auto-strength!=true\"},\"time-to-sleep\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34875,\"size\":16,\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"total-cnt\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5386\\u53f2\\u6eda\\u8f74\\u8ba1\\u6570\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u4f7f\\u7528\\u4ee5\\u6765\\u626b\\u63cf\\u7eb8\\u5f20\\u603b\\u6570\",\"type\":\"int\",\"fix-id\":34889,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"dev-vid\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"USB-VID\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\\u5728USB\\u7ec4\\u7ec7\\u7684ID\",\"type\":\"int\",\"fix-id\":34898,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"dev-pid\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"USB-PID\",\"desc\":\"\\u8bbe\\u5907\\u5728USB\\u7ec4\\u7ec7\\u4e2d\\u7684\\u4ea7\\u54c1ID\",\"type\":\"int\",\"fix-id\":34899,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"dev-name\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"desc\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34900,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"dev-model\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u4ea7\\u54c1\\u7cfb\\u5217\",\"desc\":\"\\u8bbe\\u5907\\u6240\\u5c5e\\u4ea7\\u54c1\\u7cfb\\u5217\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34901,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"", - "default\":\"0\"},\"dev-sn\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"type\":\"string\",\"fix-id\":34902,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"fmw-ver\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\",\"desc\":\"\\u8bbe\\u5907\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34903,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"ip-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"IP\",\"desc\":\"\\u8bbe\\u5907\\u8054\\u7f51\\u65f6\\u6240\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34904,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"mac-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"MAC\",\"desc\":\"\\u8bbe\\u5907\\u7f51\\u5361\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34905,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"roller-life\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u6eda\\u8f74\\u5bff\\u547d\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u6eda\\u8f74\\u8fc7\\u7eb8\\u7684\\u6700\\u5927\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34907,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"paper-on\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u6709\\u7eb8\",\"desc\":\"\\u8bbe\\u5907\\u4e0a\\u662f\\u5426\\u6709\\u7eb8\",\"type\":\"bool\",\"fix-id\":34912,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":false,\"default\":false},\"roll-cnt\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u6eda\\u8f74\\u8ba1\\u6570\",\"desc\":\"\\u5f53\\u524d\\u6eda\\u8f74\\u5df2\\u7ecf\\u8fc7\\u7eb8\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":39170,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"devs-log\":{\"cat\":\"base\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u8bbe\\u5907\\u65e5\\u5fd7\",\"desc\":\"\\u8bbe\\u5907\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"type\":\"string\",\"fix-id\":39172,\"visible\":1,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"}}" + "45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34880,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-l==true\"},\"is-rid-hole-r\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u53f3\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u53f3\\u4fa7\",\"type\":\"bool\",\"fix-id\":34881,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-r\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u53f3\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34882,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-r==true\"},\"is-rid-hole-t\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0a\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0a\\u90e8\",\"type\":\"bool\",\"fix-id\":34883,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-t\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u4e0a\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34884,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-t==true\"},\"is-rid-hole-b\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0b\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0b\\u90e8\",\"type\":\"bool\",\"fix-id\":34885,\"size\":4,\"cur\":false,\"default\":false},\"search-hole-range-b\":{\"cat\":\"base\",\"group\":\"imgp\",\"title\":\" \\u4e0b\\u4fa7\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"desc\":\"\\u7a7f\\u5b54\\u641c\\u7d22\\u8303\\u56f4\\u5360\\u5e45\\u9762\\u6bd4\\u4f8b\",\"type\":\"float\",\"fix-id\":34886,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend\":\"is-rid-hole-b==true\"},\"is-wait-scan\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\",\"desc\":\"\\u542f\\u7528\\u540e\\uff0c\\u6587\\u7a3f\\u653e\\u5165\\u626b\\u63cf\\u4eea\\u65f6\\u5c06\\u81ea\\u52a8\\u542f\\u52a8\\u626b\\u63cf\",\"type\":\"bool\",\"fix-id\":34873,\"size\":4,\"cur\":false,\"default\":false},\"wait-scan-exit\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5f85\\u7eb8\\u626b\\u63cf\\u9000\\u51fa\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u7ed3\\u675f\\u5f85\\u7eb8\\u626b\\u63cf\\u7684\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34920,\"size\":16,\"cur\":\"60s\",\"default\":\"60s\",\"range\":[\"15s\",\"30s\",\"60s\",\"2min\",\"4min\",\"8min\"],\"depend\":\"is-wait-scan==true\"},\"scan-mode\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u9009\\u62e9\\u6307\\u5b9a\\u6570\\u91cf\\u626b\\u63cf\\u6216\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"string\",\"fix-id\":34862,\"size\":24,\"cur\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"default\":\"\\u8fde\\u7eed\\u626b\\u63cf\",\"range\":[\"\\u8fde\\u7eed\\u626b\\u63cf\",\"\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"],\"depend\":\"is-wait-scan==false\"},\"scan-count\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u626b\\u63cf\\u6570\\u91cf\",\"desc\":\"\\u626b\\u63cf\\u6307\\u5b9a\\u6570\\u91cf\",\"type\":\"int\",\"fix-id\":34863,\"size\":4,\"cur\":1,\"default\":1,\"depend\":\"scan-mode.enabled&&scan-mode==\\u626b\\u63cf\\u6307\\u5b9a\\u5f20\\u6570\"},\"direction\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6587\\u7a3f\\u65b9\\u5411\",\"desc\":\"\\u8bbe\\u7f6e\\u56fe\\u50cf\\u7684\\u65b9\\u5411\",\"type\":\"string\",\"fix-id\":34864,\"size\":32,\"cur\":\"0\\u00b0\",\"default\":\"0\\u00b0\",\"range\":[\"0\\u00b0\",\"90\\u00b0\",\"180\\u00b0\",\"-90\\u00b0\",\"\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b\\u00b0\"]},\"is-rotate-bkg-180\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u80cc\\u9762\\u65cb\\u8f6c180\\u00b0\",\"desc\":\"\\u80cc\\u9762\\u626b\\u63cf\\u7684\\u56fe\\u50cf\\u65cb\\u8f6c180\\u00b0\",\"type\":\"bool\",\"fix-id\":34865,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"page!=\\u5bf9\\u6298&&direction!=\\u81ea\\u52a8\\u6587\\u672c\\u65b9\\u5411\\u8bc6\\u522b\\u00b0\"},\"is-ultrosonic\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u8d85\\u58f0\\u6ce2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u53cc\\u5f20\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34860,\"size\":4,\"cur\":true,\"default\":true},\"double-feed\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u53cc\\u5f20\\u56fe\\u7247\\u5904\\u7406\",\"desc\":\"\\u68c0\\u6d4b\\u5230\\u53cc\\u5f20\\u8fdb\\u7eb8\\u540e\\u7684\\u5904\\u7406\\u65b9\\u5f0f\",\"type\":\"string\",\"fix-id\":34872,\"size\":32,\"cur\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"default\":\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"range\":[\"\\u4e22\\u5f03\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\",\"\\u4e0a\\u4f20\\u56fe\\u50cf\\u5e76\\u505c\\u6b62\\u626b\\u63cf\"],\"depend\":\"is-ultrosonic==true\"},\"is-staple\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u88c5\\u8ba2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u7c98\\u8fde\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34861,\"size\":4,\"cur\":false,\"default\":false},\"is-check-askew\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u662f\\u5426\\u51fa\\u73b0\\u6b6a\\u659c\\u9001\\u5165\",\"type\":\"bool\",\"fix-id\":34868,\"size\":4,\"cur\":true,\"default\":true},\"askew-range\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6b6a\\u659c\\u5bb9\\u5fcd\\u5ea6\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u5bb9\\u5fcd\\u5f97\\u9001\\u5165\\u6587\\u7a3f\\u6b6a\\u659c\\u89d2\\u5ea6\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34869,\"size\":4,\"cur\":3,\"default\":3,\"range\":{\"min\":1,\"max\":5,\"step\":1},\"depend\":\"is-check-askew==true\"},\"is-check-dog-ear\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u6298\\u89d2\\u68c0\\u6d4b\",\"desc\":\"\\u68c0\\u6d4b\\u6587\\u7a3f\\u662f\\u5426\\u5b58\\u5728\\u6298\\u89d2\",\"type\":\"bool\",\"fix-id\":34866,\"size\":4,\"cur\":false,\"default\":false},\"dog-ear-size\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u6298\\u89d2\\u5927\\u5c0f\",\"desc\":\"\\u503c\\u8d8a\\u5c0f\\uff0c\\u80fd\\u68c0\\u6d4b\\u5230\\u7684\\u6298\\u89d2\\u8d8a\\u5c0f\",\"type\":\"int\",\"fix-id\":34867,\"size\":4,\"cur\":70,\"default\":70,\"range\":{\"min\":10,\"max\":300,\"step\":1},\"depend\":\"is-check-dog-ear==true\"},\"is-auto-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u81ea\\u52a8\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u81ea\\u52a8\\u4fee\\u6b63\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"bool\",\"fix-id\":34876,\"size\":4,\"cur\":false,\"default\":false},\"feed-strength-value\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\" \\u8fdb\\u7eb8\\u5931\\u8d25\\u7387\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u503c\\u65f6\\u626b\\u63cf\\u4eea\\u5c06\\u8c03\\u6574\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"float\",\"fix-id\":34877,\"size\":8,\"cur\":0.100000,\"default\":0.100000,\"range\":{\"min\":0.100000,\"max\":0.900000,\"step\":0.080000},\"depend\":\"is-auto-strength==true\"},\"feed-strength\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u5206\\u7eb8\\u5f3a\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u5206\\u7eb8\\u529b\\u5ea6\",\"type\":\"string\",\"fix-id\":34874,\"size\":12,\"cur\":\"\\u4e00\\u822c\",\"default\":\"\\u4e00\\u822c\",\"range\":[\"\\u5f31\",\"\\u4e00\\u822c\",\"\\u5f3a\"],\"depend\":\"is-auto-strength!=true\"},\"time-to-sleep\":{\"cat\":\"base\",\"group\":\"feeder\",\"title\":\"\\u4f11\\u7720\\u65f6\\u95f4\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u4eea\\u7684\\u4f11\\u7720\\u65f6\\u95f4\",\"type\":\"string\",\"fix-id\":34875,\"size\":16,\"cur\":\"\\u4e0d\\u4f11\\u7720\",\"default\":\"\\u4e0d\\u4f11\\u7720\",\"range\":[\"\\u4e0d\\u4f11\\u7720\",\"\\u4e94\\u5206\\u949f\",\"\\u5341\\u5206\\u949f\",\"\\u534a\\u5c0f\\u65f6\",\"\\u4e00\\u5c0f\\u65f6\",\"\\u4e24\\u5c0f\\u65f6\",\"\\u56db\\u5c0f\\u65f6\"]},\"total-cnt\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u5386\\u53f2\\u6eda\\u8f74\\u8ba1\\u6570\",\"desc\":\"\\u626b\\u63cf\\u4eea\\u4f7f\\u7528\\u4ee5\\u6765\\u626b\\u63cf\\u7eb8\\u5f20\\u603b\\u6570\",\"type\":\"int\",\"fix-id\":34889,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"dev-vid\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"USB-VID\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\\u5728USB\\u7ec4\\u7ec7\\u7684ID\",\"type\":\"int\",\"fix-id\":34898,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"dev-pid\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"USB-PID\",\"desc\":\"\\u8bbe\\u5907\\u5728USB\\u7ec4\\u7ec7\\u4e2d\\u7684\\u4ea7\\u54c1ID\",\"type\":\"int\",\"fix-id\":34899,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"dev-name\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"desc\":\"\\u8bbe\\u5907\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34900,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"dev-model\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u4ea7\\u54c1\\u7cfb\\u5217\",\"desc\":\"\\u8bbe\\u5907\\u6240\\u5c5e\\u4ea7\\u54c1\\u7cfb\\u5217\\u540d\\u79f0\",\"type\":\"string\",\"fix-id\":34901,\"readonly\":true,\"size\":96,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"dev-sn\":{\"cat\":\"base\",\"group", + "\":\"\\u5173\\u4e8e\",\"title\":\"\\u5e8f\\u5217\\u53f7\",\"desc\":\"\\u8bbe\\u5907\\u5e8f\\u5217\\u53f7\",\"type\":\"string\",\"fix-id\":34902,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"fmw-ver\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u56fa\\u4ef6\\u7248\\u672c\",\"desc\":\"\\u8bbe\\u5907\\u56fa\\u4ef6\\u7248\\u672c\\u53f7\",\"type\":\"string\",\"fix-id\":34903,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"ip-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"IP\",\"desc\":\"\\u8bbe\\u5907\\u8054\\u7f51\\u65f6\\u6240\\u5206\\u914d\\u7684IP\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34904,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"mac-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"MAC\",\"desc\":\"\\u8bbe\\u5907\\u7f51\\u5361\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34905,\"readonly\":true,\"size\":96,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"},\"roller-life\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u6eda\\u8f74\\u5bff\\u547d\",\"desc\":\"\\u8be5\\u8bbe\\u5907\\u6eda\\u8f74\\u8fc7\\u7eb8\\u7684\\u6700\\u5927\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":34907,\"readonly\":true,\"size\":4,\"auto\":false,\"cur\":0,\"default\":0},\"paper-on\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u6709\\u7eb8\",\"desc\":\"\\u8bbe\\u5907\\u4e0a\\u662f\\u5426\\u6709\\u7eb8\",\"type\":\"bool\",\"fix-id\":34912,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":false,\"default\":false},\"roll-cnt\":{\"cat\":\"base\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u6eda\\u8f74\\u8ba1\\u6570\",\"desc\":\"\\u5f53\\u524d\\u6eda\\u8f74\\u5df2\\u7ecf\\u8fc7\\u7eb8\\u5f20\\u6570\",\"type\":\"int\",\"fix-id\":39170,\"readonly\":true,\"size\":4,\"auto\":false,\"ownread\":true,\"cur\":0,\"default\":0},\"devs-log\":{\"cat\":\"base\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u8bbe\\u5907\\u65e5\\u5fd7\",\"desc\":\"\\u8bbe\\u5907\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"type\":\"string\",\"fix-id\":39172,\"visible\":1,\"size\":256,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}" }; static std::string device_opt_json439[] = { "{\"restore\":{\"cat\":\"base\",\"group\":\"\",\"title\":\"\\u6062\\u590d\\u9ed8\\u8ba4\\u8bbe\\u7f6e\",\"desc\":\"\\u6062\\u590d\\u9ed8\\u8ba4\\u8bbe\\u7f6e\",\"type\":\"button\",\"fix-id\":34921,\"size\":4},\"help\":{\"cat\":\"base\",\"group\":\"\",\"title\":\"\\u5e2e\\u52a9\",\"desc\":\"\\u663e\\u793a\\u8f6f\\u4ef6\\u5e2e\\u52a9\\u6587\\u6863\",\"type\":\"button\",\"fix-id\":34897,\"size\":4},\"is-multiout\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34817,\"size\":4,\"cur\":false,\"default\":false},\"multiout-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"fix-id\":34818,\"enabled\":false,\"size\":66,\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend\":\"is-multiout==true\"},\"mode\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"size\":54,\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend\":\"is-multiout!=true\"},\"binary-threshold\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u9608\\u503c\",\"desc\":\"\\u9ad8\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a1\\uff08\\u767d\\uff09\\uff0c\\u4f4e\\u4e8e\\u8be5\\u9608\\u503c\\u4e3a0\\uff08\\u9ed1\\uff09\",\"type\":\"int\",\"fix-id\":34870,\"size\":4,\"cur\":127,\"default\":127,\"range\":{\"min\":0,\"max\":255,\"step\":1},\"depend\":\"(multiout-type.enabled&&multiout-type!=\\u5f69\\u8272+\\u7070\\u5ea6) || (mode.enabled && mode==\\u9ed1\\u767d)\"},\"reverse-bw\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u53cd\\u8272\\u8f93\\u51fa\",\"desc\":\"\\u8f93\\u51fa\\u7684\\u9ed1\\u767d\\u56fe\\u50cf\\u4ee5\\u201c1\\u201d\\u4ee3\\u8868\\u9ed1\\u8272\\uff0c\\u201c0\\u201d\\u4ee3\\u8868\\u767d\\u8272\",\"type\":\"bool\",\"fix-id\":34878,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"(multiout-type.enabled&&multiout-type!=\\u5f69\\u8272+\\u7070\\u5ea6) || (mode.enabled && mode==\\u9ed1\\u767d)\"},\"filter\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7070\\u5ea6\\u6216\\u9ed1\\u767d\\u56fe\\u50cf - \\u9664\\u8272\\u4e0e\\u589e\\u5f3a\",\"desc\":\"\\u6d88\\u9664\\u6216\\u589e\\u5f3a\\u6307\\u5b9a\\u8272\\u5f69\",\"type\":\"string\",\"fix-id\":34820,\"enabled\":false,\"size\":42,\"cur\":\"\\u4e0d\\u9664\\u8272\",\"default\":\"\\u4e0d\\u9664\\u8272\",\"range\":[\"\\u4e0d\\u9664\\u8272\",\"\\u9664\\u7ea2\\u8272\",\"\\u9664\\u7eff\\u8272\",\"\\u9664\\u84dd\\u8272\",\"\\u7ea2\\u8272\\u589e\\u5f3a\",\"\\u7eff\\u8272\\u589e\\u5f3a\",\"\\u84dd\\u8272\\u589e\\u5f3a\"],\"depend\":\"mode.enabled && (mode==256\\u7ea7\\u7070\\u5ea6 || mode==\\u9ed1\\u767d)\"},\"is-rid-multiout-red\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u591a\\u6d41\\u8f93\\u51fa\\u9664\\u7ea2\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u5f69\\u8272\\u56fe\\u50cf\\u548c\\u7070\\u5ea6\\u9664\\u7ea2\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34821,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"is-rid-answer-sheet-red\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"24\\u4f4d\\u5f69\\u8272\\u56fe\\u50cf - \\u7b54\\u9898\\u5361\\u9664\\u7ea2\",\"desc\":\"\\u8f93\\u51fa\\u9664\\u7ea2\\u5f69\\u8272\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34822,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"is-erase-bkg\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u80cc\\u666f\\u79fb\\u9664\",\"desc\":\"\\u79fb\\u9664\\u6587\\u7a3f\\u80cc\\u666f\\u5e95\\u8272\",\"type\":\"bool\",\"fix-id\":34823,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled && mode==24\\u4f4d\\u5f69\\u8272\"},\"bkg-color-range\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\" \\u80cc\\u666f\\u8272\\u5f69\\u6d6e\\u52a8\\u8303\\u56f4\",\"desc\":\"\\u4e0e\\u80cc\\u666f\\u5e95\\u8272\\u504f\\u5dee\\u5728\\u8be5\\u503c\\u8303\\u56f4\\u5185\\u7684\\u989c\\u8272\\uff0c\\u90fd\\u5c06\\u88ab\\u79fb\\u9664\",\"type\":\"int\",\"fix-id\":34824,\"enabled\":false,\"size\":4,\"cur\":20,\"default\":20,\"range\":{\"min\":1,\"max\":128,\"step\":1},\"depend\":\"is-erase-bkg==true\"},\"sharpen\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9510\\u5316\\u4e0e\\u6a21\\u7cca\",\"desc\":\"\\u9009\\u62e9\\u9510\\u5316\\u6548\\u679c\\u6216\\u6a21\\u7cca\\u6548\\u679c\",\"type\":\"string\",\"fix-id\":34825,\"size\":48,\"cur\":\"\\u65e0\",\"default\":\"\\u65e0\",\"range\":[\"\\u65e0\",\"\\u9510\\u5316\",\"\\u8fdb\\u4e00\\u6b65\\u9510\\u5316\",\"\\u6a21\\u7cca\",\"\\u8fdb\\u4e00\\u6b65\\u6a21\\u7cca\"],\"depend\":\"mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-rid-morr\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u53bb\\u9664\\u6469\\u5c14\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u6469\\u5c14\\u7eb9\",\"type\":\"bool\",\"fix-id\":34826,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"resolution<500&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 && mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-rid-grid\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9664\\u7f51\\u7eb9\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u7f51\\u7eb9\",\"type\":\"bool\",\"fix-id\":34827,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"resolution<500&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 && mode.enabled&&(mode==24\\u4f4d\\u5f69\\u8272 || mode==256\\u7ea7\\u7070\\u5ea6)\"},\"is-err-extension\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9519\\u8bef\\u6269\\u6563\",\"desc\":\"\\u4ee5\\u70b9\\u9635\\u5f62\\u5f0f\\u6784\\u5efa\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34828,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled&&mode==\\u9ed1\\u767d\"},\"is-noise-optimize\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u9ed1\\u767d\\u56fe\\u50cf\\u566a\\u70b9\\u4f18\\u5316\",\"desc\":\"\\u53bb\\u9664\\u56fe\\u50cf\\u4e2d\\u7684\\u5b64\\u7acb\\u9ed1\\u70b9\",\"type\":\"bool\",\"fix-id\":34829,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"mode.enabled&&mode==\\u9ed1\\u767d\"},\"noise-size\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\" \\u566a\\u70b9\\u4f18\\u5316\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u9700\\u8981\\u53bb\\u9664\\u7684\\u9ed1\\u8272\\u5b64\\u7acb\\u70b9\\u7684\\u8fde\\u901a\\u4e2a\\u6570\",\"type\":\"int\",\"fix-id\":34830,\"size\":4,\"cur\":10,\"default\":10,\"range\":{\"min\":1,\"max\":50,\"step\":1},\"depend\":\"is-noise-optimize==true\"},\"paper\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"fix-id\":34831,\"size\":96,\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"A4\\u6a2a\\u5411\",\"16\\u5f00\",\"16\\u5f00\\u6a2a\\u5411\",\"A5\",\"A5\\u6a2a\\u5411\",\"A6\",\"A6\\u6a2a\\u5411\",\"B4\",\"B5\",\"B5\\u6a2a\\u5411\",\"B6\",\"B6\\u6a2a\\u5411\",\"Letter\",\"Letter\\u6a2a\\u5411\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},{\"resolution<500\":\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\"},{\"resolution<500\":\"\\u4e09\\u8054\\u8bd5\\u5377\"}]},\"is-custom-area\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\",\"type\":\"bool\",\"fix-id\":34832,\"size\":4,\"cur\":false,\"default\":false,\"depend\":\"paper!=\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8&&paper!=\\u4e09\\u8054\\u8bd5\\u5377&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8&&paper!=\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\"},\"tl-x\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4e0a\\u89d2x\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34833,\"unit\":\"mm\",\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.000000,\"max\":210.000000,\"step\":21.000000},\"depend\":\"is-custom-area==true\"},\"br-x\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u53f3\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u53f3\\u4e0b\\u89d2x\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34834,\"unit\":\"mm\",\"size\":8,\"cur\":210.000000,\"default\":210.000000,\"range\":{\"min\":0.000000,\"max\":210.000000,\"step\":21.000000},\"depend\":\"is-custom-area==true\"},\"tl-y\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u63cf\\u533a\\u57df\\u4e0a\\u4fa7\\uff08mm\\uff09\",\"desc\":\"\\u81ea\\u5b9a\\u4e49\\u626b\\u63cf\\u533a\\u57df\\u5de6\\u4e0a\\u89d2y\\u5750\\u6807\",\"type\":\"float\",\"fix-id\":34835,\"unit\":\"mm\",\"size\":8,\"cur\":0.000000,\"default\":0.000000,\"range\":{\"min\":0.000000,\"max\":297.000000,\"step\":29.700000},\"depend\":\"is-custom-area==true\"},\"br-y\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u626b\\u6", @@ -119,7 +119,7 @@ namespace settings {200.0f, 1}, {240.0f, 1}, {300.0f, 0}, - {600.0f, 1} //临时版本�? 原来�? + {600.0f, 1} //临时版本? 原来? }; bool is_equal(float l, float r) { @@ -521,10 +521,10 @@ void hg_scanner_239::init_version(void) { firmware_sup_wait_paper_ = year_date.compare("3B0629") >= 0 ? true : false; firmware_sup_log_export_ = true; - firmware_sup_pick_strength_ = false; //不支� + firmware_sup_pick_strength_ = false; //不支? firmware_sup_wake_device_ = year_date.compare("3C0518") >= 0 ? true : false; firmware_sup_color_corr_ = year.compare("3C") >= 0 ? true : false; - firmware_sup_double_img = false; //不支� + firmware_sup_double_img = false; //不支? firmware_sup_devs_lock_ = year.compare("3C") >= 0 ? true : false; firmware_sup_dpi_300 = false; firmware_sup_dpi_600 = true; @@ -608,7 +608,7 @@ int hg_scanner_239::writedown_device_configuration(bool type, setting_hardware: dev_conf->params_3399.is_fixedpaper = false; dev_conf->params_3399.en_autosize = true; } - if (!firmware_sup_auto_speed_ && image_prc_param_.bits.paper == PAPER_AUTO_MATCH)//3399 ,�?C之前的版�?匹配原始尺寸设置 12 + if (!firmware_sup_auto_speed_ && image_prc_param_.bits.paper == PAPER_AUTO_MATCH)//3399 ,?C之前的版?匹配原始尺寸设置 12 { dev_conf->params_3399.paper = 12; } @@ -901,7 +901,7 @@ int hg_scanner_239::on_resolution_changed(int& dpi) else dev_conf_.params_3399.dpi = dpi >= 500 ? 3 : (dpi < 500 && dpi> 299) ? 2 : 1; - //dev_conf_.params_3399.dpi = 1; //dpi 华凌cis和敦南cis 默认�?无需改变 + //dev_conf_.params_3399.dpi = 1; //dpi 华凌cis和敦南cis 默认?无需改变 int ret = writedown_device_configuration(); return ret; } @@ -959,7 +959,7 @@ int hg_scanner_239::on_skew_check_changed(bool& check) int hg_scanner_239::on_skew_check_level_changed(int& check) { int ret = SCANNER_ERR_OK, - val = check - 1,//上面设置的是1 - 5 ,接受范围值为0 - 4,默�? + val = check - 1,//上面设置的是1 - 5 ,接受范围值为0 - 4,默? old = dev_conf_.params_3399.screw_detect_level; setting_hardware::HGSCANCONF_3399 cf; @@ -1266,6 +1266,7 @@ void hg_scanner_239::thread_get_dves_image(void) { std::lock_guard lock(io_lock_); + memset(buf, 0, size); ret = io_->read_interrupt(buf, &size); io_->set_timeout(1000); } @@ -1283,7 +1284,7 @@ void hg_scanner_239::thread_get_dves_image(void) if (is_auto_paper_scan && sw.elapsed_s() >= is_auto_paper_scan_exit_time && is_auto_paper_scan_exit_time != 0) { - stop(); + do_stop(); notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN), SANE_EVENT_ERROR, status_); utils::to_log(LOG_LEVEL_DEBUG, "auto paper scan exit :%s\n", from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN)); } @@ -1343,10 +1344,10 @@ void hg_scanner_239::thread_get_dves_image(void) break; } } -////239 暂时先关闭双张存图弹窗提示,待到固件更新再确认是否需要弹�? +////239 暂时先关闭双张存图弹窗提示,待到固件更新再确认是否需要弹? //while ((count = get_image_count()) > 0) //{ - // int s = SANE_Image_Statu_OK; + // int s = IMG_STATUS_OK; // if (count <= 2) // { // if (image_prc_param_.bits.page == PAGE_SINGLE) @@ -1398,20 +1399,27 @@ void hg_scanner_239::thread_get_dves_image(void) // fetch all buffered images and exit ... //while(!is_dev_image_process_done()) - if (img_conf_.resolution_dst > 200 && is_quality_ == IMG_QUALITY) //删除这段代码,你可能需要考虑一下后�? + if (img_conf_.resolution_dst > 200 && is_quality_ == IMG_QUALITY) //删除这段代码,你可能需要考虑一下后? std::this_thread::sleep_for(std::chrono::milliseconds(5000)); else std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + int rest = 0; while (get_image_count() > 0) { ret = read_one_image_from_usb(); - count++; + rest++; if (ret != SCANNER_ERR_OK && ret != SCANNER_ERR_CREATE_FILE_FAILED && ret != SCANNER_ERR_WRITE_FILE_FAILED) break; } + count += rest; + if (rest) + { + utils::to_log(LOG_LEVEL_DEBUG, "STOPSCAN message is ahead of %d image(s)!\n", rest); + } + if (user_cancel_ && !is_auto_paper_scan) { if (status_ && status_ != SCANNER_ERR_DEVICE_STOPPED) // thread_handle_image_process maybe call stop() when insufficient memory occurs . @@ -1490,7 +1498,7 @@ void hg_scanner_239::thread_handle_usb_read(void) thread_get_dves_image(); } -int hg_scanner_239::start(void) +int hg_scanner_239::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), @@ -1509,7 +1517,7 @@ int hg_scanner_239::start(void) reset(); - //211220固件版本不支持返�? + //211220固件版本不支持返? ret = get_scan_is_sleep(val); if (!val && ret == SCANNER_ERR_OK) { @@ -1578,15 +1586,14 @@ int hg_scanner_239::start(void) return ret; } -int hg_scanner_239::stop(void) +int hg_scanner_239::do_stop(void) { int ret = SCANNER_ERR_OK; - user_cancel_ = true; - ret = write_command(setting3399::SC_STOP); io_->set_timeout(500); - return status_; + + return ret; } int hg_scanner_239::reset(void) { @@ -1963,7 +1970,7 @@ int hg_scanner_239::set_scan_lock_check_val(string check_str) { return SCANNER_ERR_INVALID_PARAMETER; } - int num = 32 - keys.size(); //保持32位下�? + int num = 32 - keys.size(); //保持32位下? if (num > 0) { std::string str(num, '0'); @@ -2023,7 +2030,7 @@ int hg_scanner_239::set_firmware_upgrade(std::string filename) return SCANNER_ERR_OPEN_FILE_FAILED; } fwname.seekg(0, std::ios::end); - int total = fwname.tellg();//记录总长�? + int total = fwname.tellg();//记录总长? fwname.seekg(0, std::ios::beg); int pos = fwname.tellg();//记录pos位置 @@ -2062,7 +2069,7 @@ int hg_scanner_239::set_firmware_upgrade(std::string filename) return SCANNER_ERR_DEVICE_UPGRADE_FAIL; int to_cnt = 0; - // 到这个位置已经能够升级成功了 后面对升级结果做下判�? + // 到这个位置已经能够升级成功了 后面对升级结果做下判? auto now = std::chrono::steady_clock::now(); while (std::chrono::duration(std::chrono::steady_clock::now() - now).count() < 70) { @@ -2129,7 +2136,7 @@ int hg_scanner_239::set_dev_islock_file(int islockfile) } if (islockfile != 0 && islockfile != 1) { - return SCANNER_ERR_INVALID_PARAMETER; //这个地方设置的参数必须保证正�? + return SCANNER_ERR_INVALID_PARAMETER; //这个地方设置的参数必须保证正? } string device_log_path = "/var/log/black_list_file.txt"; string str = std::to_string(islockfile); diff --git a/hgdriver/hgdev/hg_scanner_239.h b/hgdriver/hgdev/hg_scanner_239.h index cf82650..c889c18 100644 --- a/hgdriver/hgdev/hg_scanner_239.h +++ b/hgdriver/hgdev/hg_scanner_239.h @@ -41,7 +41,7 @@ class hg_scanner_239 : public hg_scanner int writedown_device_configuration(bool type = false, setting_hardware::HGSCANCONF_3399* dev_conf = NULL);//false 在start再把type置为true,其他做设置时不发 int writedown_image_configuration(void); int pop_first_image(void); - int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK); + int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK); bool is_dev_image_process_done(void); bool is_dev_image_keep_last_paper(void); @@ -60,15 +60,15 @@ protected: protected: virtual int on_color_mode_changed(int& color_mode) override; //颜色切换 virtual int on_paper_changed(int& paper) override; //纸张大小设置 - virtual int on_paper_check_changed(bool& check) override; //尺寸检测 - virtual int on_resolution_changed(int& dpi) override; //分辨率设置 - virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检测 - virtual int on_staple_check_changed(bool& check) override; //设置订书针检测 - virtual int on_skew_check_changed(bool& check) override; //设置歪斜检测 - virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强度 + virtual int on_paper_check_changed(bool& check) override; //尺寸检? + virtual int on_resolution_changed(int& dpi) override; //分辨率设? + virtual int on_ultrasonic_check_changed(bool& check) override; //设置超声波检? + virtual int on_staple_check_changed(bool& check) override; //设置订书针检? + virtual int on_skew_check_changed(bool& check) override; //设置歪斜检? + virtual int on_skew_check_level_changed(int& check) override; //设置歪斜检测强? virtual int on_get_feedmode(int& feedmode) override; //获取分纸强度 virtual int on_set_feedmode(int feedmode) override; //设置分纸强度 - virtual int on_pic_type(bool& pic)override; //照片模式或者文本模式 + virtual int on_pic_type(bool& pic)override; //照片模式或者文本模? virtual int on_pick_paper(bool autostrength)override; //自动分纸强度 virtual int on_pick_paper_threshold(double threshold)override; virtual int on_is_auto_paper(bool isautopaper)override; //待纸扫描 @@ -82,8 +82,8 @@ public: public: //virtual int get_image_info(IMG_PARAM* ii) override; //virtual int read_image_data(unsigned char* buf, int* len) override; - virtual int start(void) override; - virtual int stop(void) override; + virtual int do_start(void) override; + virtual int do_stop(void) override; virtual int reset(void) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; virtual int get_roller_life(void) override; @@ -96,44 +96,44 @@ public: virtual std::string get_device_model(void); virtual int set_device_model(string str); - virtual int set_serial_num(string str) override; //设置序列号 + virtual int set_serial_num(string str) override; //设置序列? virtual int set_vid_pid(int data) override; //设置vidpid virtual int get_vid_pid(int& data)override; //获取vidpid /////////////////成功返回:SCANNER_ERR_OK ///////////// - /////////////////失败返回:IO错误码 or SCANNER_ERR_DEVICE_NOT_SUPPORT ///////////// + /////////////////失败返回:IO错误?or SCANNER_ERR_DEVICE_NOT_SUPPORT ///////////// virtual int set_leaflet_scan(void) override; //单张扫描 virtual int set_clear_roller_num(void) override; //清除滚轴计数 virtual int set_clear_history_num(void) override; //清除历史张数 - virtual int get_device_code(void); //获取设备编码 不支持 + virtual int get_device_code(void); //获取设备编码 不支? virtual int get_scanner_paperon(SANE_Bool& type) override; //获取设备有无纸张 /*/ type : 0无纸 1有纸 */ - virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状态*/ - virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠) /*/ data > 0*/ - virtual int set_sleep_time(int data) override; //设置功耗模式(休眠) /*/ data > 0*/ + virtual int get_scan_is_sleep(SANE_Bool& type) override; //获取设备是否休眠当中 /*/ type : 0休眠 1唤醒状?/ + virtual int get_sleep_time(int& data) override; //获取功耗模式(休眠? /*/ data > 0*/ + virtual int set_sleep_time(int data) override; //设置功耗模式(休眠? /*/ data > 0*/ virtual int get_history_scan_count(int& data) override; //获取历史扫描张数 /*/ data > 0*/ virtual int get_roller_num(int& data) override; //获取滚轮张数 /*/ data > 0*/ virtual int set_notify_sleep(void) override; //唤醒设备 virtual int get_device_log(string& log) override; //获取设备日志 /*/ log :储存路径*/ virtual int set_devreboot(int data) override; //设置设备重启 virtual int set_devshtudown() override; //设置设备关机 - virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁,1锁定*/ - virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁,1锁定*/ - virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验码*/ - virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路径*/ + virtual int set_scan_islock(SANE_Bool type) override; //设置设备是否锁定 /*/ type:0解锁?锁定*/ + virtual int get_scan_islock(SANE_Bool& type) override; //获取设备是否锁定 /*/ type:0解锁?锁定*/ + virtual int set_scan_lock_check_val(string str) override; //获取设备是否锁定 /*/ str:校验?/ + virtual int set_firmware_upgrade(std::string str) override; //固件升级 /*/ str:文件名路?/ virtual int set_clean_paper_road() override; //清理纸道 - virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁,1 上锁。-1 未发现黑名单列表 -2列表没有信息*/ + virtual int get_dev_islock_file(int& data) override; //获取设备文件 /*/ data:0 未上锁,1 上锁?1 未发现黑名单列表 -2列表没有信息*/ virtual int set_dev_islock_file(int data) override; //设置设备文件 /*/ data:0 未上锁,1 上锁*/ - virtual int get_scan_mode(bool& type); //获取是否是计数模式 /*/ type : fasle计数模式 true非计数 */ + virtual int get_scan_mode(bool& type); //获取是否是计数模? /*/ type : fasle计数模式 true非计?*/ virtual int set_speed_mode(int data) override; //设置速度模式 /*/ data:100,110,120 virtual int get_speed_mode(int& data)override; //获取速度模式 /*/ data:100,110,120 - virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正值 - virtual int get_devs_distortion_check_val(float &data) override; //获取畸变矫正值 + virtual int set_devs_distortion_check_val(float data) override; //设置畸变矫正? + virtual int get_devs_distortion_check_val(float &data) override; //获取畸变矫正? virtual int set_auto_flat(int data); //设置自动平场校正 // data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color) diff --git a/hgdriver/hgdev/hg_scanner_300.cpp b/hgdriver/hgdev/hg_scanner_300.cpp index ef7161f..68eaa8f 100644 --- a/hgdriver/hgdev/hg_scanner_300.cpp +++ b/hgdriver/hgdev/hg_scanner_300.cpp @@ -116,7 +116,7 @@ void hg_scanner_300::thread_handle_usb_read(void) status = SCANNER_ERR_OK; StopWatch sw; sw.reset(); - SANE_Image_Statu statu = SANE_Image_Statu_OK; + SANE_Image_Statu statu = IMG_STATUS_OK; int img_num = 0; savestatus_.clear(); while (run_) @@ -160,7 +160,7 @@ void hg_scanner_300::thread_handle_usb_read(void) ret != SCANNER_ERR_DEVICE_AUTO_FAIL_OVER && ret != SCANNER_ERR_DEVICE_AUTO_FAIL_INFO) { - statu = SANE_Image_Statu_OK; + statu = IMG_STATUS_OK; } else if (ret == SCANNER_ERR_DEVICE_AUTO_FAIL_OVER) { @@ -313,7 +313,7 @@ int hg_scanner_300::get_roller_life(void) { return pid_ == 300 ? 150000 : 200000; } -int hg_scanner_300::start(void) +int hg_scanner_300::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop @@ -387,7 +387,7 @@ int hg_scanner_300::start(void) utils::to_log(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret)); return ret; } -int hg_scanner_300::stop(void) +int hg_scanner_300::do_stop(void) { int ret = SCANNER_ERR_OK; diff --git a/hgdriver/hgdev/hg_scanner_300.h b/hgdriver/hgdev/hg_scanner_300.h index 80831a9..174d7fa 100644 --- a/hgdriver/hgdev/hg_scanner_300.h +++ b/hgdriver/hgdev/hg_scanner_300.h @@ -48,8 +48,9 @@ public: hg_scanner_300(const char* dev_name,int pid, usb_io* io); ~hg_scanner_300(); public: - virtual int start(void)override; - virtual int stop(void)override; + virtual int do_start(void) override; + virtual int do_stop(void) override; + private: int set_kernelsnap_ver(); int agreement(TwSS tw,int align); diff --git a/hgdriver/hgdev/hg_scanner_302.cpp b/hgdriver/hgdev/hg_scanner_302.cpp index c749f6c..80b204f 100644 --- a/hgdriver/hgdev/hg_scanner_302.cpp +++ b/hgdriver/hgdev/hg_scanner_302.cpp @@ -967,7 +967,7 @@ void hg_scanner_302::thread_handle_usb_read(void) while ((count = get_image_count()) > 0) { - int s = SANE_Image_Statu_OK; + int s = IMG_STATUS_OK; if (count <= 2) { if (image_prc_param_.bits.page == PAGE_SINGLE) @@ -1005,7 +1005,7 @@ void hg_scanner_302::thread_handle_usb_read(void) utils::to_log(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code); { bool cancel = user_cancel_; - stop(); + do_stop(); user_cancel_ = cancel; go = false; } @@ -1037,7 +1037,7 @@ void hg_scanner_302::thread_handle_usb_read(void) } utils::to_log(LOG_LEVEL_DEBUG, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_name(status_)); } -int hg_scanner_302::start(void) +int hg_scanner_302::do_start(void) { bool handled = false; @@ -1114,7 +1114,7 @@ int hg_scanner_302::start(void) return ret; } -int hg_scanner_302::stop(void) +int hg_scanner_302::do_stop(void) { std::lock_guard lock(io_lock_); int ret = SCANNER_ERR_OK; @@ -1124,7 +1124,7 @@ int hg_scanner_302::stop(void) // io_->set_timeout(500); //final_imgs_.clear(); - return status_; + return ret; } int hg_scanner_302::reset(void) { diff --git a/hgdriver/hgdev/hg_scanner_302.h b/hgdriver/hgdev/hg_scanner_302.h index 20879a3..2eac176 100644 --- a/hgdriver/hgdev/hg_scanner_302.h +++ b/hgdriver/hgdev/hg_scanner_302.h @@ -51,7 +51,7 @@ class hg_scanner_302 : public hg_scanner int writedown_image_configuration(void); int pop_first_image(void); - int read_one_image_from_usb(SANE_Image_Statu statu = SANE_Image_Statu_OK); + int read_one_image_from_usb(SANE_Image_Statu statu = IMG_STATUS_OK); virtual int discard_all_images(); virtual int get_roller_life(void) override; @@ -82,10 +82,9 @@ public: ~hg_scanner_302(); public: - virtual int start(void) override; - //virtual int get_image_info(IMG_PARAM* ii) override; - //virtual int read_image_data(unsigned char* buf, int* len) override; - virtual int stop(void) override; + virtual int do_start(void) override; + virtual int do_stop(void) override; + virtual int reset(void) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; diff --git a/hgdriver/hgdev/image_process.cpp b/hgdriver/hgdev/image_process.cpp index bee702c..0f7f747 100644 --- a/hgdriver/hgdev/image_process.cpp +++ b/hgdriver/hgdev/image_process.cpp @@ -221,7 +221,7 @@ namespace hg_imgproc // construction public: imgproc(int pid, bool isx86_Advan) : pid_(pid),papersize_(pid_) - , img_statu_(SANE_Image_Statu_OK) + , img_statu_(IMG_STATUS_OK) , my_path_(utils::get_module_full_path()) ,ocrinit_(NULL),ocrgetdirectimage_(NULL) ,ocrexit_(NULL),HGBase_CreatImg(NULL) diff --git a/hgdriver/hgdev/scanner_manager.cpp b/hgdriver/hgdev/scanner_manager.cpp index 3cdad4d..93d614d 100644 --- a/hgdriver/hgdev/scanner_manager.cpp +++ b/hgdriver/hgdev/scanner_manager.cpp @@ -9,6 +9,8 @@ #include "user-opt/user.h" #include "user-opt/offline_opt.h" +#include "user-opt/device_opt.h" + #if !defined(WIN32) && !defined(_WIN64) #endif @@ -132,6 +134,75 @@ bool islang = false; /// + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// language option ... +class lang_opt : public sane_opt_provider +{ +public: + lang_opt() + { + set_where("language-option"); + + const char* lang = language_option_descriptor(); + if (lang && *lang) + { + std::string t(lang); + + set_opt_json_text(&t[0]); + } + } + +protected: + virtual ~lang_opt() + {} + +public: + virtual int set_value(const char* name, void* val) override + { + if (strcmp(name, "language")) + return SCANNER_ERR_NO_DATA; + + LANATTR** pla = lang_get_supported_languages(); + int err = SCANNER_ERR_OK; + + if (!pla) + err = SCANNER_ERR_DEVICE_NOT_SUPPORT; + else + { + std::string n(to_default_language((char*)val, nullptr)), now(""); + int id = -1, cur = lang_get_cur_code_page(); + for (int i = 0; pla[i]; ++i) + { + if (pla[i]->cp == cur) + now = pla[i]->name; + if (n == pla[i]->name) + { + id = pla[i]->cp; + break; + } + } + if (id == -1) + { + err = SCANNER_ERR_NOT_EXACT; + ::strcpy((char*)val, now.c_str()); + } + else if (cur != id) + { + err = SCANNER_ERR_CONFIGURATION_CHANGED; + lang_set_code_page(id); + } + } + + return err; + } +}; +static lang_opt* g_language = nullptr; + + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// hg_scanner_mgr* hg_scanner_mgr::inst_ = NULL; sane_callback hg_scanner_mgr::event_callback_ = NULL; bool hg_scanner_mgr::async_io_enabled_ = false; @@ -147,7 +218,7 @@ bool hg_scanner_mgr::read_over_with_eof_ = true; uint32_t hg_scanner_mgr::unique_img_id_ = 0;; std::mutex hg_scanner_mgr::mutex_img_id; -hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name("") +hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name(""), dev_opts_(new device_option()) { std::string cfgf(utils::get_local_data_path() + PATH_SEPARATOR + "config" + PATH_SEPARATOR + "debug.cfg"); char buf[260] = {0}; @@ -167,6 +238,9 @@ hg_scanner_mgr::hg_scanner_mgr() : same_ind_(1), cf_name("") user_ = new hguser(); offline_ = new offline_opts(user_); + g_language = new lang_opt(); + + reset_device_opts(); } hg_scanner_mgr::~hg_scanner_mgr() { @@ -177,9 +251,14 @@ hg_scanner_mgr::~hg_scanner_mgr() libusb_unref_device(v.dev); online_devices_.clear(); } + dev_opts_->clear(); + delete dev_opts_; + usb_manager::clear(); offline_->release(); delete user_; + + g_language->release(); } int hg_scanner_mgr::ui_default_callback(scanner_handle h, int ev, void* data, unsigned int* len, void* param) @@ -530,6 +609,17 @@ void hg_scanner_mgr::get_online_devices(std::vector& devs) devs = online_devices_; } +void hg_scanner_mgr::reset_device_opts(sane_opt_provider* scanner) +{ + dev_opts_->clear(); + + // Four sources: offline, language, algorithm, scanner + dev_opts_->add(dynamic_cast(offline_)); + dev_opts_->add(dynamic_cast(g_language)); + + if (scanner) + dev_opts_->add(scanner); +} void hg_scanner_mgr::set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url) { @@ -803,6 +893,8 @@ scanner_err hg_scanner_mgr::hg_scanner_open(scanner_handle* h, const char* name, scanner->set_ui_callback(&hg_scanner_mgr::ui_default_callback, hg_scanner_mgr::async_io_enabled_); scanner->set_dev_family(g_supporting_devices[it->ind].family.c_str()); scanner->set_read_over_with_no_data(hg_scanner_mgr::read_over_with_eof_); + + reset_device_opts(dynamic_cast(scanner)); } std::lock_guard lock(mutex_dev_); @@ -833,183 +925,72 @@ scanner_err hg_scanner_mgr::hg_scanner_close(scanner_handle h, bool force) } } + reset_device_opts(); SCAN_PTR(h)->close(force); - delete SCAN_PTR(h); + SCAN_PTR(h)->release(); + //delete SCAN_PTR(h); return SCANNER_ERR_OK; } scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const char* name, char* data, long* len, int type) { - scanner_err err = SCANNER_ERR_OK; + scanner_err err = SCANNER_ERR_INVALID_PARAMETER; - if (!len) - return SCANNER_ERR_INVALID_PARAMETER; - - if (!h) + if (len) { - if (name == PARAM_ALL) - { - std::string all(offline_->get_json_text()); - if (*len <= all.length()) - { - *len = all.length() + 1; + std::string raw(dev_opts_->get_option_value(name == PARAM_ALL ? nullptr : name, type, nullptr, data)); - err = SCANNER_ERR_INSUFFICIENT_MEMORY; - } - else - { - strcpy(data, all.c_str()); - *len = all.length(); - } + if (*len < raw.length()) + { + *len = raw.length(); + + err = SCANNER_ERR_INSUFFICIENT_MEMORY; } else - err = (scanner_err)offline_->get_value(name, data, (int*)len, type == OPT_VAL_CURRENT); - - return err; - } - else if (name && name != PARAM_ALL) - { - err = (scanner_err)offline_->get_value(name, data, (int*)len, type == OPT_VAL_CURRENT); - if (err != SCANNER_ERR_NO_DATA) - return err; - } - - // global options ... - if (!IS_PTR_NUMBER(name)) - { - // following options getting operation is implemented in 'set' ... { - if (strcmp(SANE_STD_OPT_NAME_DEVICE_VID, name) == 0 || - strcmp(SANE_STD_OPT_NAME_DEVICE_PID, name) == 0 || - strcmp(SANE_STD_OPT_NAME_DEVICE_NAME, name) == 0 || - strcmp(SANE_STD_OPT_NAME_DEVICE_MODEL, name) == 0 || - strcmp(SANE_STD_OPT_NAME_DEVICE_SERIAL_NO, name) == 0 || - strcmp(SANE_STD_OPT_NAME_FIRMWARE_VERSION, name) == 0 || - strcmp(SANE_STD_OPT_NAME_DEVICE_IP_ADDR, name) == 0 || - strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0 || - strcmp(SANE_STD_OPT_NAME_TOTAL_COUNT, name) == 0 || - strcmp(SANE_STD_OPT_NAME_MOTOR_VER, name) == 0 || - strcmp(SANE_STD_OPT_NAME_INITIAL_BOOT_TIME, name) == 0) - return (scanner_err)SCAN_PTR(h)->set_setting(name, data, false); - } - - if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0) - { - if (!data) - return SCANNER_ERR_INVALID_PARAMETER; - - if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) - { - char path[300] = { 0 }; - int l = LOG_FILE_DEVICE, - ret = hg_scanner_control(h, IO_CTRL_CODE_GET_LOG_FILE, path, (unsigned*)&l); - if (ret == SCANNER_ERR_OK) - { - { - std::ifstream in(path, ios::in | ios::binary); - std::ofstream out(data, ios::out | ios::binary); - out << in.rdbuf(); - } - remove(path); - } - - return (scanner_err)ret; - } - else - return SCANNER_ERR_ACCESS_DENIED; - } - else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_GAMMA, name) == 0) - return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_GET_CUSTOM_GAMMA, data, (unsigned int*)len); - - if (strcmp(SANE_STD_OPT_NAME_TRANSFORM_IMAGE_FORMAT, name) == 0 || - strcmp(SANE_STD_OPT_NAME_FREE_BUFFER, name) == 0) - return SCANNER_ERR_DEVICE_NOT_SUPPORT; - - if (strcmp(SANE_STD_OPT_NAME_ROLLER_LIFE, name) == 0) - { - if (*len < sizeof(SANE_Int)) - { - *len = sizeof(SANE_Int); - - return SCANNER_ERR_INSUFFICIENT_MEMORY; - } - - *(SANE_Int*)data = SCAN_PTR(h)->get_roller_life(); - - return SCANNER_ERR_OK; + memcpy(data, raw.c_str(), raw.length()); + *len = raw.length(); + err = SCANNER_ERR_OK; } } - int l = *len; - - err = (scanner_err)SCAN_PTR(h)->get_setting(name, data, &l, type); - *len = l; - return err; } scanner_err hg_scanner_mgr::hg_scanner_set_parameter(scanner_handle h, const char* name, void* data, bool to_default) { - scanner_err err = SCANNER_ERR_INVALID_PARAMETER; + scanner_err err = SCANNER_ERR_OK, se = SCANNER_ERR_OK; + std::string init(""); - if (!h) + // do restore here ? + if (name && strcmp(name, SANE_STD_OPT_NAME_RESTORE) == 0) { - if (name) - err = (scanner_err)offline_->set_value(name, data); - return err; } - else if (name) + else { - err = (scanner_err)offline_->set_value(name, data); - if (err != SCANNER_ERR_NO_DATA) - return err; - } - - if (!IS_PTR_NUMBER(name)) - { - if (strcmp(SANE_STD_OPT_NAME_DEVICE_LOG, name) == 0) + if (to_default) { - if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) + int size = 0; + init = dev_opts_->get_option_value(name, SANE_ACTION_GET_DEFAULT_VALUE, &size); + if (size > init.length()) { - return SCANNER_ERR_DEVICE_NOT_SUPPORT; + std::string t(std::move(init)); + init.reserve(size); + memset(&init[0], 0, size); + memcpy(&init[0], &t[0], t.length()); } - - return SCANNER_ERR_ACCESS_DENIED; + data = &init[0]; } - else if (strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0) + else { - if (user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) - { - int* len = nullptr; - return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_SET_CLEAR_ROLLER_COUNT, data, (unsigned*)len); - } - - return SCANNER_ERR_ACCESS_DENIED; - } - else if (strcmp(SANE_STD_OPT_NAME_CUSTOM_GAMMA, name) == 0) - { - int* len = nullptr; - return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_SET_CUSTOM_GAMMA, data, (unsigned int*)len); - } - else if (strcmp(SANE_STD_OPT_NAME_TRANSFORM_IMAGE_FORMAT, name) == 0) - { - int* len = nullptr; - return (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_CONVERT_IMAGE_FORMAT, data, (unsigned int*)len); - } - else if (strcmp(SANE_STD_OPT_NAME_FREE_BUFFER, name) == 0) - { - void* ptr = data ? *(void**)data : nullptr; - int* len = nullptr; - scanner_err ret = (scanner_err)SCAN_PTR(h)->device_io_control(IO_CTRL_CODE_FREE_MEMORY, ptr, (unsigned int*)len); - - if (data) - *(void**)data = nullptr; - - return ret; + err = dev_opts_->refine_data(name, data) ? SCANNER_ERR_NOT_EXACT : SCANNER_ERR_OK; } + se = (scanner_err)dev_opts_->update_data(name, data); + if (se != SCANNER_ERR_OK) + err = se; } - return (scanner_err)SCAN_PTR(h)->set_setting(name, data, to_default); + return err; } scanner_err hg_scanner_mgr::hg_scanner_start(scanner_handle h, void* async_event, int num) { diff --git a/hgdriver/hgdev/scanner_manager.h b/hgdriver/hgdev/scanner_manager.h index d87b30d..394044f 100644 --- a/hgdriver/hgdev/scanner_manager.h +++ b/hgdriver/hgdev/scanner_manager.h @@ -39,6 +39,8 @@ class hg_scanner; class hguser; class offline_opts; +class device_option; +class sane_opt_provider; class hg_scanner_mgr { @@ -68,6 +70,7 @@ class hg_scanner_mgr hguser* user_; offline_opts* offline_; + device_option* dev_opts_; static sane_callback event_callback_; static bool async_io_enabled_; @@ -90,6 +93,7 @@ class hg_scanner_mgr void on_hgscanner_pnp(usb_event ev, libusb_device* device, int vid, int pid, int usb_ver_h, int usb_ver_l, bool* retry); // usb_ver_h.usb_ver_l void get_online_devices(std::vector& devs); + void reset_device_opts(sane_opt_provider* scanner = nullptr); void set_appendix_info_for_about(SANE_About* about, char*& ptr, int& count, const char* key, const char* info, const char* url); scanner_err get_about_info(scanner_handle h, void* data, unsigned* len); diff --git a/hgdriver/hgdev/user-opt/base_opt.h b/hgdriver/hgdev/user-opt/base_opt.h deleted file mode 100644 index 2b71ffa..0000000 --- a/hgdriver/hgdev/user-opt/base_opt.h +++ /dev/null @@ -1,27 +0,0 @@ -#pragma once - -// SANE-Option -// -// created on 2022-09-22 -// - -#include -#include "../hg_ipc.h" // for refer - -class sane_opt_provider : public refer -{ -public: - sane_opt_provider() - {} - -protected: - virtual ~sane_opt_provider() - {} - -public: - virtual std::string get_json_text(void) = 0; - virtual int get_value(const char* name, void* buf, int* len, bool curval = true) = 0; - virtual int set_value(const char* name, void* value) = 0; - virtual bool has_option(const char* name) = 0; -}; - diff --git a/hgdriver/hgdev/user-opt/device_opt.cpp b/hgdriver/hgdev/user-opt/device_opt.cpp index ad600ef..af3eed5 100644 --- a/hgdriver/hgdev/user-opt/device_opt.cpp +++ b/hgdriver/hgdev/user-opt/device_opt.cpp @@ -1,8 +1,8 @@ #include "device_opt.h" -#include #include #include "../../../sdk/hginclude/huagaoxxx_warraper_ex.h" +#include "../../../sdk/hginclude/base_opt.h" #include #include #include @@ -230,7 +230,7 @@ bool device_option::condition_value::set_value(gb_json* jsn, const char* type, d std::string device_option::condition_value::value(bool(*compare)(const char*, void*), void* param) { if (parent_) - return parent_->get_option_value(vals_[0].value.c_str(), OPT_VAL_CURRENT); + return parent_->get_option_value(vals_[0].value.c_str(), SANE_ACTION_GET_VALUE); for (auto& v : vals_) { @@ -358,8 +358,8 @@ bool device_option::range_value::set_value(gb_json* jsn, const char* type, devic } -device_option::device_option(std::function user_priv) : origin_(nullptr), now_(nullptr) - , user_(user_priv) +device_option::device_option(std::function user_priv, std::function log) : origin_(nullptr), now_(nullptr) + , user_(user_priv), log_(log) {} device_option::~device_option() { @@ -792,13 +792,11 @@ bool device_option::calc_simple_logic_expression(const char* expr, void* param) return ret; } -void device_option::clear(void) +void device_option::clear_for_reconstruct(void) { - if (origin_) - origin_->release(); if (now_) now_->release(); - origin_ = now_ = nullptr; + now_ = nullptr; master_opts_.clear(); compare_.clear(); @@ -830,80 +828,259 @@ gb_json* device_option::group_opt(const char* title) return jsn; } -bool device_option::arrange_raw_json(const char* txt) +int device_option::next_group(int start) +{ + for (; start < origin_->children(); ++start) + { + gb_json* child = origin_->child(start); + std::string str(""); + + child->get_value("type", str); + child->release(); + + if (str == JSON_SANE_TYPE_GROUP) + break; + } + + return start; +} +int device_option::insert_group(const char* name, const char* title) +{ + gb_json* group = nullptr; + int ind = origin_->children(); + + origin_->get_value(name, group); + if (group) + { + ind = origin_->index(group); + group->release(); + } + else + { + for (auto& v : g_known_group_with_sn) + { + if (v.name == name) + { + title = v.title.c_str(); + break; + } + + gb_json* child = nullptr; + origin_->get_value(v.name.c_str(), child); + if (child) + { + if (group) + group->release(); + group = child; + } + } + + if (group) + { + ind = origin_->index(group) + 1; + group->release(); + } + else + ind = 0; + ind = next_group(ind); + group = group_opt(title); + origin_->insert(ind, name, group); + group->release(); + } + + return ind; +} +void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const char* group) +{ + // first compare version, reserve higher version + // second compare position, replace with last insertion + // last, sort by position + gb_json* existing = nullptr; + + origin_->get_value(opt->key().c_str(), existing); + if (existing) + { + int vo = 0, vn = 0; + opt->get_value("ver", vn); + existing->get_value("ver", vo); + if (vn > vo) + { + // replace and discard all following options ... + write_log("SANE-OPT: use %s::%s(ver: %d) replaced with %s::%s(ver: %d)\n", src_[existing->key()]->from().c_str(), existing->key().c_str(), vo + , from->from().c_str(), opt->key().c_str(), vn); + + vo = origin_->index(existing); + origin_->remove(vo); + if (src_.count(existing->key())) + { + src_[existing->key()]->release(); + src_.erase(existing->key()); + } + + origin_->insert(vo, opt->key().c_str(), opt); + opt->add_ref(); + + src_[opt->key()] = from; + from->add_ref(); + } + else if (vn == vo) + { + // insert into following queue ... + write_log("SANE-OPT: inserting %s::%s to provider queue ...\n", from->from().c_str(), opt->key().c_str()); + opt->get_value("pos", vn); + existing->get_value("pos", vo); + if (vo < vn) + { + sane_opt_provider* prev = src_[existing->key()], + *que = src_[existing->key()]->get_following(existing->key().c_str()); + + prev->add_ref(); + while (que) + { + std::string text(que->get_opt_json()); + gb_json* jsn = new gb_json(), *child = nullptr; + + jsn->attach_text(&text[0]); + jsn->get_value(existing->key().c_str(), child); + if (child) + { + child->get_value("ver", vo); + child->release(); + } + jsn->release(); + if (vo >= vn) + break; + prev->release(); + prev = que; + + que = que->get_following(existing->key().c_str()); + } + prev->set_following_provider(opt->key().c_str(), from); + if (vo == vn) + { + // replace ... + if(que) + { + sane_opt_provider* next = que->get_following(opt->key().c_str()); + que->set_following_provider(opt->key().c_str(), nullptr); + if (next) + { + from->set_following_provider(opt->key().c_str(), next); + next->release(); + } + que->release(); // release get_following reference + } + } + else + { + // insert ... + from->set_following_provider(opt->key().c_str(), que); + if (que) + que->release(); + } + prev->release(); + } + else if (vo > vn) + { + from->set_following_provider(opt->key().c_str(), src_[existing->key()]); + src_[existing->key()]->release(); + src_[opt->key()] = from; + from->add_ref(); + } + else + { + // replace ... + vo = origin_->index(existing); + origin_->remove(vo); + if (src_.count(existing->key())) + { + sane_opt_provider* next = src_[existing->key()]->get_following(existing->key().c_str()); + src_[existing->key()]->set_following_provider(existing->key().c_str(), nullptr); + src_[existing->key()]->release(); + src_.erase(existing->key()); + while (next) + { + sane_opt_provider* next1 = next->get_following(existing->key().c_str()); + next->set_following_provider(existing->key().c_str(), nullptr); + next->release(); + next = next1; + } + } + + origin_->insert(vo, opt->key().c_str(), opt); + opt->add_ref(); + + src_[opt->key()] = from; + from->add_ref(); + } + + { + write_log("SANE-OPT: option '%s' queue: %s", opt->key().c_str(), src_[opt->key().c_str()]->from().c_str()); + + sane_opt_provider* next = src_[opt->key().c_str()]->get_following(opt->key().c_str()); + while (next) + { + write_log(" -> %s", next->from().c_str()); + + sane_opt_provider* next1 = next; + next = next->get_following(opt->key().c_str()); + next1->release(); + } + write_log("\n"); + } + } + else + { + // discard new option ... + write_log("SANE-OPT: discard %s::%s(ver: %d) for %s::%s(ver: %d) existed!\n", from->from().c_str(), opt->key().c_str(), vn + , src_[existing->key()]->from().c_str(), existing->key().c_str(), vo); + } + + existing->release(); + } + else + { + int index = -1; + + if (group) + index = insert_group(group, group); + index = next_group(index + 1); + + origin_->insert(index, opt->key().c_str(), opt); + src_[opt->key()] = from; + from->add_ref(); + } +} +bool device_option::arrange_raw_json(sane_opt_provider* sop) { - std::vector groups; std::vector ungroup; std::map> ingroup; gb_json* jsn = new gb_json(), *child = nullptr; - std::string text(txt), str(""); + std::string text(sop->get_opt_json()), str(""); + bool ret = jsn->attach_text(&text[0]); - if (jsn->attach_text(&text[0])) + if (ret) { + if (!origin_) + origin_ = new gb_json(); + text.clear(); child = jsn->first_child(); while (child) { - child->get_value("group", str); - if (str.empty()) - ungroup.push_back(child); - else if (ingroup.count(str)) - ingroup[str].push_back(child); - else + child->get_value("type", str); + if (str != JSON_SANE_TYPE_GROUP) // omit group { - std::vector c; - c.push_back(child); - ingroup[str] = c; + child->get_value("group", str); + insert_option(child, sop, str.empty() ? nullptr : str.c_str()); } + child->release(); child = jsn->next_child(); } } jsn->release(); - if (ungroup.size() || ingroup.size()) - { - origin_ = new gb_json(); - for (auto& v : ungroup) - { - origin_->set_value(v->key().c_str(), v); - v->release(); - } - - // named group ... - int grpind = 1; - - for (auto& v : g_known_group_with_sn) - { - if (ingroup.count(v.name)) - { - gb_json* grp = group_opt(v.title.c_str()); - origin_->set_value(("grp-" + std::to_string(grpind++)).c_str(), grp); - grp->release(); - - for (auto& opt : ingroup[v.name]) - { - origin_->set_value(opt->key().c_str(), opt); - opt->release(); - } - ingroup.erase(v.name); - } - } - - for (auto& v : ingroup) - { - gb_json* grp = group_opt(v.first.c_str()); - origin_->set_value(("grp-" + std::to_string(grpind++)).c_str(), grp); - grp->release(); - - for (auto& opt : v.second) - { - origin_->set_value(opt->key().c_str(), opt); - opt->release(); - } - } - } - - return origin_ != nullptr; + return ret; } void device_option::init_depends(gb_json* opt) { @@ -1296,12 +1473,24 @@ std::string device_option::get_group(int ind, bool title) return ""; } -bool device_option::init(const char* opt_json) +void device_option::clear(void) +{ + clear_for_reconstruct(); + + if (origin_) + origin_->release(); + origin_ = nullptr; + + for (auto& v : src_) + v.second->release(); + src_.clear(); +} +bool device_option::add(sane_opt_provider* sop) { bool ret = false; - clear(); - if (arrange_raw_json(opt_json)) + clear_for_reconstruct(); + if (arrange_raw_json(sop)) { ret = to_now(true, nullptr); if (!ret) @@ -1348,64 +1537,84 @@ bool device_option::refine_data(const char* name, void* value) } int device_option::update_data(const char* name, void* value) { + int err = SCANNER_ERR_NO_DATA; + if (!name) { to_now(false, nullptr); - - return SCANNER_ERR_RELOAD_OPT_PARAM; + err = SCANNER_ERR_RELOAD_OPT_PARAM; } else if(now_) { std::string type(""); gb_json* child = nullptr; - + err = SCANNER_ERR_DEVICE_NOT_SUPPORT; now_->get_value(name, child); if (child) { - std::string pre(device_option::option_value(child, false)); - bool changed = false; + bool ro = false; + if (child->get_value("readonly", ro) && ro) + { + child->release(); - child->get_value("type", type); - if (type == JSON_SANE_TYPE_BOOL) - { - child->set_value("cur", *(bool*)value); - changed = *(bool*)value != *(bool*)pre.c_str(); + err = SCANNER_ERR_ACCESS_DENIED; } - else if (type == JSON_SANE_TYPE_INT) + else { - child->set_value("cur", *(int*)value); - changed = *(int*)value != *(int*)pre.c_str(); - } - else if (type == JSON_SANE_TYPE_FIXED) - { - child->set_value("cur", *(double*)value); - changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str()); - } - else if (type == JSON_SANE_TYPE_STRING) - { - child->set_value("cur", (char*)value); - changed = pre != (char*)value; - } - child->release(); + std::string pre(device_option::option_value(child, false)); + bool changed = false; - if (changed && // value has changed - std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end()) // can affect others - { - changed = false; + // pass to sane_opt_provider ... + err = SCANNER_ERR_OK; + if (src_.count(name)) + err = src_[name]->set_value(name, value); - do + if (err == SCANNER_ERR_OK || err == SCANNER_ERR_NOT_EXACT + || err == SCANNER_ERR_RELOAD_IMAGE_PARAM || err == SCANNER_ERR_RELOAD_OPT_PARAM) { - changed = false; - to_now(false, &changed); - } while (changed); + child->get_value("type", type); + if (type == JSON_SANE_TYPE_BOOL) + { + child->set_value("cur", *(bool*)value); + changed = *(bool*)value != *(bool*)pre.c_str(); + } + else if (type == JSON_SANE_TYPE_INT) + { + child->set_value("cur", *(int*)value); + changed = *(int*)value != *(int*)pre.c_str(); + } + else if (type == JSON_SANE_TYPE_FIXED) + { + child->set_value("cur", *(double*)value); + changed = !IS_DOUBLE_EQUAL(*(double*)value, *(double*)pre.c_str()); + } + else if (type == JSON_SANE_TYPE_STRING) + { + child->set_value("cur", (char*)value); + changed = pre != (char*)value; + } + child->release(); - return SCANNER_ERR_RELOAD_OPT_PARAM; - } - } - } + if (changed && // value has changed + std::find(master_opts_.begin(), master_opts_.end(), name) != master_opts_.end()) // can affect others + { + changed = false; - return SCANNER_ERR_OK; + do + { + changed = false; + to_now(false, &changed); + } while (changed); + + err = SCANNER_ERR_RELOAD_OPT_PARAM; + } + } // provider has processed right + } // not read-only option + } // has option named 'name' + } // has initialized + + return err; } int device_option::count(void) @@ -1468,7 +1677,7 @@ std::string device_option::get_option_value_type(const char* name) return std::move(value); } -std::string device_option::get_option_value(const char* name, int type, int* size) +std::string device_option::get_option_value(const char* name, int type, int* size, void* in_data) { std::string value(""); gb_json* jsn = now_ ? now_ : origin_; @@ -1482,14 +1691,20 @@ std::string device_option::get_option_value(const char* name, int type, int* siz else { gb_json* child = nullptr; + bool own_read = false; jsn->get_value(name, child); if (child) { - if (type == OPT_VAL_JSON) + if (type == SANE_ACTION_GET_ENTIRE_JSON) value = child->to_string(); + else if (child->get_value("ownread", own_read) && own_read) + { + if (src_.count(name)) + value = std::move(src_[name]->get_value(name, in_data)); + } else - value = device_option::option_value(child, type == OPT_VAL_DEFAULT); + value = device_option::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE); if (size) { @@ -1538,7 +1753,7 @@ std::string device_option::get_option_value_type(int sane_ind) return std::move(value); } -std::string device_option::get_option_value(int sane_ind, int type, int* size) +std::string device_option::get_option_value(int sane_ind, int type, int* size, void* in_data) { std::string value(""); @@ -1546,25 +1761,15 @@ std::string device_option::get_option_value(int sane_ind, int type, int* size) { if (sane_ind <= 0) { - value = now_->to_string(); + value = std::move(now_->to_string()); } else if(sane_ind - 1 < now_->children()) { gb_json* child = now_->child(sane_ind - 1); - - if (type == OPT_VAL_JSON) - value = child->to_string(); - else - value = device_option::option_value(child, type == OPT_VAL_DEFAULT); - - if (size) - { - int n = 0; - child->get_value("size", n); - *size = n; - } + std::string name(child->key()); child->release(); + value = std::move(get_option_value(name.c_str(), type, size, in_data)); } } diff --git a/hgdriver/hgdev/user-opt/device_opt.h b/hgdriver/hgdev/user-opt/device_opt.h index 759e5dd..ea5c0c1 100644 --- a/hgdriver/hgdev/user-opt/device_opt.h +++ b/hgdriver/hgdev/user-opt/device_opt.h @@ -15,14 +15,17 @@ #include "simple_logic.h" #include +class sane_opt_provider; class device_option { gb_json* origin_; gb_json* now_; + std::map src_; std::vector master_opts_; // options that value changed will affect others std::map slaver_; std::function user_; + std::function log_; typedef struct _expr_calc { @@ -155,9 +158,12 @@ class device_option static void init_condition(const char* expr, void* param); static bool calc_simple_logic_expression(const char* expr, void* param); - void clear(void); + void clear_for_reconstruct(void); gb_json* group_opt(const char* title); - bool arrange_raw_json(const char* txt); // create origin_ and re-arrange groups + int next_group(int start); // return index of the next group + int insert_group(const char* name, const char* title); // return index of the group + void insert_option(gb_json* opt, sane_opt_provider* from, const char* group = nullptr); + bool arrange_raw_json(sane_opt_provider* sop); // create origin_ and re-arrange groups void init_depends(gb_json* opt); gb_json* copy_opt(gb_json* from); int visibility(gb_json* jsn); @@ -308,54 +314,63 @@ protected: return refined; } + template + void write_log(const char* fmt, Args ... args) + { + if (log_) + { + size_t size = snprintf(nullptr, 0, fmt, args ...) + 2; + std::unique_ptr buf(new char[size]); + + snprintf(buf.get(), size, fmt, args ...); + log_(buf.get()); + } + } + public: - device_option(std::function user_priv = std::function()); + device_option(std::function user_priv = std::function() + , std::function log = std::function()); ~device_option(); static std::string trans_group(const char* utf8, bool to_title); static std::string get_group(int ind, bool title); public: - bool init(const char* opt_json); + void clear(void); + bool add(sane_opt_provider* sop); bool refine_data(const char* name, void* value); // return true if the 'value' is out of range and refined it in the range int update_data(const char* name, void* value); // return scanner_err. name and value would be null if invoked for language changed + int restore(sane_opt_provider* holder); // int count(void); // return option count bool is_auto_restore_default(const char* name); std::string get_name_by_sane_id(int sane_ind); std::string get_option_value_type(const char* name); - std::string get_option_value(const char* name, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null - std::string get_option_field_string(const char* name, const char* key); std::string get_option_value_type(int sane_ind); - std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr); // return whole json-text if name was null + std::string get_option_field_string(const char* name, const char* key); + std::string get_option_value(const char* name, int type/*OPT_VAL_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null + std::string get_option_value(int sane_ind, int type/*OPT_VAL_xxx*/, int* size = nullptr, void* in_data = nullptr); // return whole json-text if name was null }; //{ -// "noise-size": { +// "resolution": { // "cat": "base", // "group" : "base", -// "title" : " Żߴ", -// "desc" : "Ҫȥĺ", -// "ver" : 0, -// "pos" : 0, -// "fix-id" : 0, +// "title" : "ֱ", +// "desc" : "ɨͼķֱ", // "type" : "int", -// "unit" : "none", -// "affect" : 0, -// "readonly" : false, -// "visible" : true, -// "enabled" : false, +// "fix-id" : 34840, // "size" : 4, -// "cur" : 10, -// "default" : 10, +// "cur" : 200, +// "default" : 200, // "range" : { -// "min": 1, -// "max" : { -// "paper==A3": 50, // condition value -// "default": 45} , +// "min": 100, +// "max" : { +// "default": 600, +// "paper==ɨߴԶ || paper==ɨߴ || paper==Ծ" : 500 +// }, // "step" : 1 -// }, -// "depend_or": ["is-noise-optimize==true"] +// } // }, // // "paper": { @@ -363,20 +378,17 @@ public: // "group" : "base", // "title" : "ֽųߴ", // "desc" : "óͼС", -// "ver" : 0, -// "pos" : 0, -// "fix-id" : 0, // "type" : "string", -// "unit" : "none", -// "affect" : 0, -// "readonly" : false, -// "visible" : true, -// "enabled" : false, -// "size" : 96, +// "fix-id" : 34831, +// "size" : 44, // "cur" : "ƥԭʼߴ", // "default" : "ƥԭʼߴ", -// "range" : ["A3", "8", { -// "mode==24λɫ": "A4" // condition value -// }, "A4", "16", "16", "A5", "A5", "A6", "A6", "B4", "B5", "B5", "B6", "B6", "Letter", "Letter", "Double Letter", "LEGAL", "ƥԭʼߴ", "ɨߴԶ", "ɨߴ", "Ծ"] +// "range" : ["A3", "8", "A4", "16", "A5", "A6", "B4", "B5", "B6", "Letter", "Double Letter", "LEGAL", "ƥԭʼߴ", { +// "resolution<500": "ɨߴԶ" +// }, { +// "resolution<500": "ɨߴ" +// }, { +// "resolution<500": "Ծ" +// }] // } -//} \ No newline at end of file +//} diff --git a/hgdriver/hgdev/user-opt/offline_opt.cpp b/hgdriver/hgdev/user-opt/offline_opt.cpp index 0bb7c24..544576c 100644 --- a/hgdriver/hgdev/user-opt/offline_opt.cpp +++ b/hgdriver/hgdev/user-opt/offline_opt.cpp @@ -12,7 +12,7 @@ #include "user.h" static std::string device_opt_json[] = { - "{\"company\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"ver\":0,\"pos\":0,\"fix-id\":34891,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"ver\":0,\"pos\":0,\"fix-id\":34892,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34893,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"ver\":0,\"pos\":0,\"fix-id\":34894,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34895,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"ver\":0,\"pos\":0,\"fix-id\":34896,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"ver\":0,\"pos\":0,\"fix-id\":34890,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39168,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u53ea\\u8bfb\\u5c5e\\u6027\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"ver\":0,\"pos\":0,\"fix-id\":39169,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"readonly\":true,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"ver\":0,\"pos\":0,\"fix-id\":39171,\"type\":\"string\",\"unit\":\"none\",\"affect\":0,\"visible\":1,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"}}" + "{\"company\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u5236\\u9020\\u5546\",\"desc\":\"\\u8bbe\\u5907\\u5236\\u9020\\u5546\",\"type\":\"string\",\"fix-id\":34891,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"copyright\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u7248\\u672c\\u4fe1\\u606f\",\"desc\":\"\\u7248\\u6743\\u58f0\\u660e\\u7b49\\u4fe1\\u606f\",\"type\":\"string\",\"fix-id\":34892,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-url\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u7f51\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5b98\\u7f51\\u6216\\u552e\\u540e\\u670d\\u52a1\\u7f51\\u7ad9\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34893,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-tel\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u7535\\u8bdd\",\"desc\":\"\\u516c\\u53f8\\u8054\\u7cfb\\u7535\\u8bdd\",\"type\":\"string\",\"fix-id\":34894,\"readonly\":true,\"size\":129,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-addr\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8\\u5730\\u5740\",\"desc\":\"\\u516c\\u53f8\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34895,\"readonly\":true,\"size\":128,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"co-gps\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u516c\\u53f8GPS\",\"desc\":\"\\u516c\\u53f8\\u5730\\u56fe\\u5730\\u5740\",\"type\":\"string\",\"fix-id\":34896,\"readonly\":true,\"size\":256,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"drv-ver\":{\"cat\":\"base\",\"group\":\"\\u5173\\u4e8e\",\"title\":\"\\u9a71\\u52a8\\u7248\\u672c\\u53f7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u7a0b\\u5e8f\\u7248\\u672c\",\"type\":\"string\",\"fix-id\":34890,\"readonly\":true,\"size\":48,\"auto\":false,\"cur\":\"0\",\"default\":\"0\"},\"login\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u767b\\u5f55\",\"desc\":\"\\u7528\\u6237\\u767b\\u5f55\\u64cd\\u4f5c\",\"type\":\"string\",\"fix-id\":39168,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"logout\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u767b\\u51fa\",\"desc\":\"\\u7528\\u6237\\u767b\\u51fa\\u64cd\\u4f5c\",\"type\":\"string\",\"fix-id\":39169,\"visible\":1,\"size\":64,\"auto\":false,\"cur\":\"false\",\"default\":\"false\"},\"drv-log\":{\"cat\":\"advanced\",\"group\":\"\\u7528\\u6237\",\"title\":\"\\u9a71\\u52a8\\u65e5\\u5fd7\",\"desc\":\"PC\\u7aef\\u9a71\\u52a8\\u5de5\\u4f5c\\u65e5\\u5fd7\",\"type\":\"string\",\"fix-id\":39171,\"visible\":1,\"size\":256,\"auto\":false,\"ownread\":true,\"cur\":\"0\",\"default\":\"0\"}}" }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -27,6 +27,7 @@ offline_opts::offline_opts(hguser* user) : user_(user) + "." + std::to_string(ll); init(); + set_where("offline_opts"); } offline_opts::~offline_opts() { @@ -34,160 +35,57 @@ offline_opts::~offline_opts() void offline_opts::init(void) { - gb_json* child = nullptr, * jsn_ = new gb_json(); + gb_json* child = nullptr, * jsn = new gb_json(); std::string text(""); for (auto& v : device_opt_json) text += v; - jsn_->attach_text(&text[0]); + jsn->attach_text(&text[0]); + #define INIT_SIMPLE_VAL(n, v) \ - jsn_->get_value(SANE_STD_OPT_NAME_##n, child); \ + jsn->get_value(SANE_STD_OPT_NAME_##n, child); \ if (child) \ { \ - auto func = [this](bool read, void* buf, int* len, bool curval) -> int \ - { \ - if (!read) \ - return SCANNER_ERR_DEVICE_NOT_SUPPORT; \ - if (!len) \ - return SCANNER_ERR_INVALID_PARAMETER; \ - \ - std::string val(from_default_language(v)); \ - if (*len < val.length()) \ - { \ - *len = val.length() + 1; \ - \ - return SCANNER_ERR_INSUFFICIENT_MEMORY; \ - } \ - \ - strcpy((char*)buf, val.c_str()); \ - \ - return SCANNER_ERR_OK; \ - }; \ - oper_[SANE_STD_OPT_NAME_##n] = func; \ + child->set_value("cur", v); \ + child->set_value("default", v); \ \ child->release(); \ } - INIT_SIMPLE_VAL(MANUFACTURER, COMPANY_NAME); - INIT_SIMPLE_VAL(CO_URL, BRAND_COMPANY_URL); - INIT_SIMPLE_VAL(CO_TEL, BRAND_COMPANY_TEL); - INIT_SIMPLE_VAL(CO_ADDR, BRAND_COMPANY_ADDRESS); - INIT_SIMPLE_VAL(CO_GPS, BRAND_URL_GPS); + INIT_SIMPLE_VAL(MANUFACTURER , COMPANY_NAME); + INIT_SIMPLE_VAL(CO_URL , BRAND_COMPANY_URL); + INIT_SIMPLE_VAL(CO_TEL , BRAND_COMPANY_TEL); + INIT_SIMPLE_VAL(CO_ADDR , BRAND_COMPANY_ADDRESS); + INIT_SIMPLE_VAL(CO_GPS , BRAND_URL_GPS); + INIT_SIMPLE_VAL(COPYRIGHT , BRAND_COPYRIGHT); + INIT_SIMPLE_VAL(DRIVER_VERSION , drv_ver_.c_str()); - INIT_SIMPLE_VAL(COPYRIGHT, BRAND_COPYRIGHT); - INIT_SIMPLE_VAL(DRIVER_VERSION, drv_ver_.c_str()); + text = std::move(jsn->to_string()); + set_opt_json_text(&text[0]); - // driver log - jsn_->get_value(SANE_STD_OPT_NAME_DRIVER_LOG, child); - if (child) - { - auto func = [this](bool read, void* buf, int* len, bool curval) -> int - { - if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) - { - if (read) - { - if (!buf) - return SCANNER_ERR_INVALID_PARAMETER; - - return utils::copy_log_file_to((char*)buf); - } - else - { - return utils::clear_log_file(); - } - } - else - { - return SCANNER_ERR_ACCESS_DENIED; - } - }; - oper_[SANE_STD_OPT_NAME_DRIVER_LOG] = func; - - child->release(); - } - - // login && logout - jsn_->get_value(SANE_STD_OPT_NAME_LOGIN, child); - if (child) - { - if (user_) - { - auto login = [this](bool read, void* buf, int* len, bool curval) -> int - { - if (read) - return SCANNER_ERR_DEVICE_NOT_SUPPORT; - - if (!buf) - return SCANNER_ERR_INVALID_PARAMETER; - - char* n = (char*)buf, - * pwd = n + 32; - - scanner_err ret = (scanner_err)user_->login(n, pwd); - - if (ret == SCANNER_ERR_OK) - ret = SCANNER_ERR_RELOAD_OPT_PARAM; - - return ret; - }; - auto logout = [this](bool read, void* buf, int* len, bool curval) -> int - { - if (read) - return SCANNER_ERR_DEVICE_NOT_SUPPORT; - - if (!buf) - return SCANNER_ERR_INVALID_PARAMETER; - - char* n = (char*)buf, - * pwd = n + 32; - - scanner_err ret = (scanner_err)user_->logout(n, pwd); - - if (ret == SCANNER_ERR_OK) - ret = SCANNER_ERR_RELOAD_OPT_PARAM; - - return ret; - }; - - oper_[SANE_STD_OPT_NAME_LOGIN] = login; - oper_[SANE_STD_OPT_NAME_LOGOUT] = logout; - } - child->release(); - } - - jsn_->release(); + jsn->release(); } -std::string offline_opts::get_json_text(void) +std::string offline_opts::get_value(const char* name, void* value, int* err) { - std::string text(""); + std::string ret(""); - for (auto& v : device_opt_json) - text += v; - - if (user_ && !user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) + if (IS_SANE_OPT(name, DRIVER_LOG)) { - gb_json* jsn = new gb_json(); - if (jsn->attach_text(&text[0])) + if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) { - jsn->remove(SANE_STD_OPT_NAME_LOGOUT); - jsn->remove(SANE_STD_OPT_NAME_DRIVER_LOG); - text = jsn->to_string(); - } - jsn->release(); - } - return std::move(text); -} -int offline_opts::get_value(const char* name, void* buf, int* len, bool curval) -{ - int ret = SCANNER_ERR_NO_DATA; + int e = utils::copy_log_file_to((char*)value); - if (oper_.count(name)) - { - ret = oper_[name](true, buf, len, curval); + ret = (char*)value; + if (err) + *err = e; + } + else if (err) + *err = SCANNER_ERR_ACCESS_DENIED; } + else if (err) + *err = SCANNER_ERR_NO_DATA; return ret; } @@ -195,14 +93,40 @@ int offline_opts::set_value(const char* name, void* value) { int ret = SCANNER_ERR_NO_DATA; - if (oper_.count(name)) + if (IS_SANE_OPT(name, DRIVER_LOG)) { - ret = oper_[name](false, value, nullptr, true); + if (user_ && user_->has_privilege(USER_PRIVILEGE_LOCAL_MGR)) + { + ret = utils::clear_log_file(); + } + else + { + ret = SCANNER_ERR_ACCESS_DENIED; + } } + else if (IS_SANE_OPT(name, LOGIN) || IS_SANE_OPT(name, LOGOUT)) + { + char* n = (char*)value, + * pwd = n + 32; + + scanner_err ret = IS_SANE_OPT(name, LOGIN) ? (scanner_err)user_->login(n, pwd) : (scanner_err)user_->logout(n, pwd); + + if (ret == SCANNER_ERR_OK) + ret = SCANNER_ERR_RELOAD_OPT_PARAM; + } + else if (IS_SANE_OPT(name, MANUFACTURER) + || IS_SANE_OPT(name, CO_URL) + || IS_SANE_OPT(name, CO_TEL) + || IS_SANE_OPT(name, CO_ADDR) + || IS_SANE_OPT(name, CO_GPS) + || IS_SANE_OPT(name, COPYRIGHT) + || IS_SANE_OPT(name, DRIVER_VERSION) + ) + ret = SCANNER_ERR_ACCESS_DENIED; return ret; } -bool offline_opts::has_option(const char* name) +void offline_opts::enable(const char* name, bool able) { - return oper_.count(name) > 0; -} + +} \ No newline at end of file diff --git a/hgdriver/hgdev/user-opt/offline_opt.h b/hgdriver/hgdev/user-opt/offline_opt.h index 80771c3..23808a1 100644 --- a/hgdriver/hgdev/user-opt/offline_opt.h +++ b/hgdriver/hgdev/user-opt/offline_opt.h @@ -6,15 +6,12 @@ // #include "base_opt.h" -#include -#include class hguser; class offline_opts : public sane_opt_provider { hguser* user_; std::string drv_ver_; - std::map> oper_; void init(void); @@ -25,9 +22,8 @@ protected: virtual ~offline_opts(); public: - virtual std::string get_json_text(void) override; - virtual int get_value(const char* name, void* buf, int* len, bool curval = true) override; + virtual std::string get_value(const char* name, void* value, int* err = nullptr) override; virtual int set_value(const char* name, void* value) override; - virtual bool has_option(const char* name) override; + virtual void enable(const char* name, bool able) override; }; diff --git a/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp b/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp index ac88841..779d77a 100644 --- a/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp +++ b/hgdriver/wrapper/huagaoxxx_warraper_ex.cpp @@ -375,10 +375,14 @@ extern "C" const char* hg_scanner_image_statu_name(int img_statu) { - RETURN_IF(img_statu, SANE_Image_Statu_OK); - RETURN_IF(img_statu, SANE_Image_Statu_Blank); - RETURN_IF(img_statu, SANE_Image_Statu_Double); - RETURN_IF(img_statu, SANE_Image_Statu_Jammed); + RETURN_IF(img_statu, IMG_STATUS_OK); + RETURN_IF(img_statu, IMG_STATUS_BLANK); + RETURN_IF(img_statu, IMG_STATUS_DOUBLE); + RETURN_IF(img_statu, IMG_STATUS_JAM); + RETURN_IF(img_statu, IMG_STATUS_STAPLE); + RETURN_IF(img_statu, IMG_STATUS_SIZE_ERR); + RETURN_IF(img_statu, IMG_STATUS_DOGEAR); + RETURN_IF(img_statu, IMG_STATUS_DOGEAR_PARTIAL); // NOTE: multi-thread unsafe here static char g_unk_statu[80] = { 0 }; diff --git a/hgsane/sane_hg_mdw.cpp b/hgsane/sane_hg_mdw.cpp index 4f753d3..426f7f6 100644 --- a/hgsane/sane_hg_mdw.cpp +++ b/hgsane/sane_hg_mdw.cpp @@ -220,12 +220,10 @@ hg_sane_middleware::hg_sane_middleware(void) : init_ok_(false), offline_(nullptr init_ok_ = true; sprintf(sane_ver, "%u.%u.%u", SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD); -#if defined(WIN32) - hg_scanner_set_sane_info("sane", sane_ver); -#else +#if !defined(WIN32) signal(SIGUSR1, &hg_sane_middleware::device_pnp); - hg_scanner_set_sane_info(GET_BACKEND_NAME, sane_ver); #endif + hg_scanner_set_sane_info(MODULE_NAME_SANE, sane_ver); hg_scanner_initialize(local_utility::ui_cb, nullptr); // initialize offline options with scanner_handle nullptr: @@ -395,12 +393,12 @@ bool hg_sane_middleware::reload_options(LPDEVINST inst) { long len = 0; char *buf = nullptr; - scanner_err err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, OPT_VAL_JSON); + scanner_err err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, SANE_ACTION_GET_ENTIRE_JSON); if (err == SCANNER_ERR_INSUFFICIENT_MEMORY) { buf = new char[len + 4]; - err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, OPT_VAL_JSON); + err = hg_scanner_get_option(inst->dev, PARAM_ALL, buf, &len, SANE_ACTION_GET_ENTIRE_JSON); } if (err == SCANNER_ERR_OK && len) @@ -422,7 +420,7 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S { bool v = false; long len = sizeof(v); - err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT); + err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE); if (value) *(SANE_Bool*)value = v ? SANE_TRUE : SANE_FALSE; } @@ -430,7 +428,7 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S { int v = 0; long len = sizeof(v); - err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT); + err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE); if (value) *(SANE_Int*)value = v; } @@ -438,14 +436,14 @@ scanner_err hg_sane_middleware::read_value(scanner_handle h, const char* name, S { double v = .0f; long len = sizeof(v); - err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT); + err = hg_scanner_get_option(h, name, (char*)&v, &len, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE); if (value) *(SANE_Fixed*)value = hg_sane_middleware::double_2_sane_fixed(v); } else { long l = len; - err = hg_scanner_get_option(h, name, (char*)value, &l, to_default ? OPT_VAL_DEFAULT : OPT_VAL_CURRENT); + err = hg_scanner_get_option(h, name, (char*)value, &l, to_default ? SANE_ACTION_GET_DEFAULT_VALUE : SANE_ACTION_GET_VALUE); } return err; diff --git a/sdk/hginclude/base_opt.cpp b/sdk/hginclude/base_opt.cpp new file mode 100644 index 0000000..b0aa883 --- /dev/null +++ b/sdk/hginclude/base_opt.cpp @@ -0,0 +1,97 @@ +#include "base_opt.h" + +#include "../json/gb_json.h" +#include "../../../sdk/include/huagao/hgscanner_error.h" + + +sane_opt_provider::sane_opt_provider() +{ + set_where(nullptr); +} + +sane_opt_provider::~sane_opt_provider() +{ + for (auto& v : following_) + v.second->release(); + following_.clear(); +} + +bool sane_opt_provider::set_opt_json_text(char* txt) +{ + gb_json* jsn = new gb_json(); + bool ret = jsn->attach_text(txt); + + jsn->release(); + if (ret) + opt_jsn_txt_ = txt; + else + opt_jsn_txt_ = ""; + + return ret; +} +void sane_opt_provider::set_where(const char* where) +{ + if (where && *where) + { + where_ = where; + } + else + { + char buf[20] = { 0 }; + + sprintf(buf, "%p", this); + where_ = buf; + } +} + +std::string sane_opt_provider::get_opt_json(void) +{ + return opt_jsn_txt_; +} +std::string sane_opt_provider::from(void) +{ + return where_; +} +void sane_opt_provider::set_following_provider(const char* name, sane_opt_provider* following) +{ + if (following_.count(name)) + { + following_[name]->release(); + following_.erase(name); + } + + if (following) + { + following_[name] = following; + following->add_ref(); + } +} +sane_opt_provider* sane_opt_provider::get_following(const char* name) +{ + sane_opt_provider* prvd = nullptr; + + if (following_.count(name)) + { + prvd = following_[name]; + if (prvd) + prvd->add_ref(); + } + + return prvd; +} +std::string sane_opt_provider::get_value(const char* name, void* value, int* err) +{ + if (err) + *err = SCANNER_ERR_DEVICE_NOT_SUPPORT; + + return ""; +} +int sane_opt_provider::set_value(const char* name, void* val) +{ + if (following_.count(name)) + return following_[name]->set_value(name, val); + else + return SCANNER_ERR_DEVICE_NOT_SUPPORT; +} +void sane_opt_provider::enable(const char* name, bool able) +{} diff --git a/sdk/hginclude/base_opt.h b/sdk/hginclude/base_opt.h new file mode 100644 index 0000000..0d5fe6c --- /dev/null +++ b/sdk/hginclude/base_opt.h @@ -0,0 +1,41 @@ +#pragma once + +// SANE-Option +// +// created on 2022-10-24 +// + +#include +#include +#include "utils.h" // for refer +#include "../../../sdk/include/sane/sane_ex.h" + +class sane_opt_provider : public refer +{ + std::string opt_jsn_txt_; + std::string where_; + +protected: + std::map following_; + +public: + sane_opt_provider(); + +protected: + virtual ~sane_opt_provider(); + + bool set_opt_json_text(char* txt); + void set_where(const char* where); + +public: + std::string get_opt_json(void); + std::string from(void); + void set_following_provider(const char* name, sane_opt_provider* following); // when option has provided by more than one + sane_opt_provider* get_following(const char* name); // caller should ->release returned value + +public: + virtual std::string get_value(const char* name, void* value, int* err = nullptr); + virtual int set_value(const char* name, void* val); + virtual void enable(const char* name, bool able); +}; + diff --git a/sdk/hginclude/huagaoxxx_warraper_ex.h b/sdk/hginclude/huagaoxxx_warraper_ex.h index f47def2..1f7f627 100644 --- a/sdk/hginclude/huagaoxxx_warraper_ex.h +++ b/sdk/hginclude/huagaoxxx_warraper_ex.h @@ -177,12 +177,6 @@ enum hg_control_code HG_CONTROL_CODE_OPTION_ENABLE = IO_CTRL_CODE_LAST + 1, // 配置项使能状态改变. data - OPTEN*, len - unused, be NULL }; -enum option_value -{ - OPT_VAL_CURRENT = 0, - OPT_VAL_DEFAULT, - OPT_VAL_JSON, -}; // // 可变参数数据,使用JSON格式配置,utf-8编码 // @@ -325,12 +319,12 @@ extern "C"{ // 如果“name==null”,则返回最大可配置的参数号 // 该参数必须非空,如果为NULL,则会返回 EPARAMETERINVAL 的错误 // - // type - 获取的值类型:0 - 当前值;1 - 默认值;…… + // type - 获取的值类型:SANE_Action // // Return: 错误代码,E_OK or E_INSUFFICIENTMEM or E_PARAMETERINVAL or E_DEVICENOTFOUND or E_OUTOFRANGE // // NOTE: 'data'空间由用户分配,如果空间太小(包含传入NULL),会在len中返回所需要的最小空间字节数,并返回 EINSUFFICIENTMEM - scanner_err hg_scanner_get_option(scanner_handle h, const char* name, char* data, long* len, int type = OPT_VAL_CURRENT); + scanner_err hg_scanner_get_option(scanner_handle h, const char* name, char* data, long* len, int type = SANE_ACTION_GET_VALUE); // Function: 设置设备的配置参数 // diff --git a/sdk/json/gb_json.cpp b/sdk/json/gb_json.cpp index 9ffbc29..07146ea 100644 --- a/sdk/json/gb_json.cpp +++ b/sdk/json/gb_json.cpp @@ -731,6 +731,34 @@ int gb_json::index_move_to(gb_json* child, int ind) return ind; } +int gb_json::insert(int ind, const char* key, gb_json* child) +{ + int i = index(child); + + if (i == -1) + { + if (ind < 0) + ind = 0; + else if (ind > arr_val_.size()) + ind = arr_val_.size(); + + child->key() = key ? key : ""; + arr_val_.insert(arr_val_.begin() + ind, child); + child->add_ref(); + } + else if(i != ind) + { + arr_val_.erase(arr_val_.begin() + i); + if (ind < 0) + ind = 0; + if (ind > arr_val_.size()) + ind = arr_val_.size(); + child->key() = key ? key : ""; + arr_val_.insert(arr_val_.begin() + ind, child); + } + + return ind; +} bool gb_json::value(bool& val) { diff --git a/sdk/json/gb_json.h b/sdk/json/gb_json.h index 95f1156..deee386 100644 --- a/sdk/json/gb_json.h +++ b/sdk/json/gb_json.h @@ -98,9 +98,10 @@ public: bool remove(gb_json* child); bool remove(int ind); - // position management + // position management, return index int index(gb_json* child); int index_move_to(gb_json* child, int ind); + int insert(int ind, const char* key, gb_json* child); // leaf node value ... bool value(bool& val); diff --git a/twain/ds/huagaods.cpp b/twain/ds/huagaods.cpp index 9fbd38c..364b3e9 100644 --- a/twain/ds/huagaods.cpp +++ b/twain/ds/huagaods.cpp @@ -3904,10 +3904,13 @@ int huagao_ds::handle_scanner_event(int ev, bool from_event_proc) utils::log_info(msg, 1); } } - else - { - notifyXferReady(); // scan from UI, should notify this state mannually - } + //else + //{ + // notifyXferReady(); // scan from UI, should notify this state mannually + //} + break; + case SANE_EVENT_TWAIN_XFER_READY: + notifyXferReady(); // notify ready when the first image arrived break; } diff --git a/twain/ds/scanned_img.cpp b/twain/ds/scanned_img.cpp index 715da6e..a056d0e 100644 --- a/twain/ds/scanned_img.cpp +++ b/twain/ds/scanned_img.cpp @@ -188,7 +188,7 @@ int image_buf::read(void* buf, size_t* bytes, unsigned long long off) // class scanned_img scanned_img::scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const char* tmp_file , twain_xfer xfer, SANE_FinalImgFormat* fmt) : head_(head), dpi_(dpi), header_size_(0) - , file_(tmp_file ? tmp_file : ""), dev_(dev), status_(SANE_Image_Statu_OK) + , file_(tmp_file ? tmp_file : ""), dev_(dev), status_(IMG_STATUS_OK) { const bool prepare_data = true; diff --git a/twain/ds/scanner.cpp b/twain/ds/scanner.cpp index e5c3ef0..55ff48a 100644 --- a/twain/ds/scanner.cpp +++ b/twain/ds/scanner.cpp @@ -324,6 +324,37 @@ bool scanner::is_option_float(int sn, void* param) else return false; } +void scanner::scan_done(void) +{ + std::string msg(scan_msg_); + + while (images_.count()) + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + + if (ui_notify) + ui_notify(SANE_EVENT_SCAN_FINISHED, &msg[0], err_); + else + is_scanning_ = false; + //else + //{ + // if (err_) + // { + // if (callback::show_messagebox_ui) + // { + // callback::show_messagebox_ui(app_wnd_, SANE_EVENT_SCAN_FINISHED, (void*)&msg[0], 0); + // } + // else // windows message box ... + // { + // std::wstring text(local_trans::a2u(msg.c_str(), CP_UTF8)); + // if (!IsWindow(app_wnd_)) + // callback::bring_message_box_topmost(local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str()); + // MessageBoxW(app_wnd_, text.c_str(), local_trans::lang_trans_between_hz936(CONST_STRING_ERROR).c_str(), MB_OK); + // } + // } + // on_ui_event(SANE_EVENT_SCAN_FINISHED, (void*)SANE_EVENT_SCAN_FINISHED); + //} + // is_scanning_ = false; +} int scanner::transfer_id(int id) { @@ -514,6 +545,10 @@ int scanner::open(void) } int scanner::close(void) { + images_.clear(); + if (done_.get() && done_->joinable()) + done_->join(); + scanner_ev_handler_ = nullptr; ui_hide(); callback::unreg_callback(this); @@ -1351,6 +1386,10 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len) if (ui_notify) ui_notify(ev_code, data, img_ind_); + // notifyXferReady 改为有图片才通知,防止部分APP在imgGetInfo中返回错误不能退出的问题 - 22023-10-25 + if (img_ind_ == 1) + on_ui_event(SANE_EVENT_TWAIN_XFER_READY, nullptr); + { char msg[128] = { 0 }; sprintf_s(msg, _countof(msg) - 1, "New image(%u) received with %u bytes\r\n", img_ind_, simg->bytes); @@ -1367,19 +1406,11 @@ int scanner::handle_device_event(int ev_code, void* data, unsigned int* len) else if (ev_code == SANE_EVENT_SCAN_FINISHED) { err_ = *len; - if (ui_notify) - ui_notify(ev_code, data, *len); - else - { - if (*len) - { - if (callback::show_messagebox_ui) - { - callback::show_messagebox_ui(app_wnd_, ev_code, (void*)data, 0); - } - } - on_ui_event(ev_code, (void*)ev_code); - } + scan_msg_ = data ? (char*)data : "OK"; + + if (done_.get() && done_->joinable()) + done_->join(); + done_.reset(new std::thread(&scanner::scan_done, this)); // is_scanning_ = false; { diff --git a/twain/ds/scanner.h b/twain/ds/scanner.h index a83b99b..11c2ac0 100644 --- a/twain/ds/scanner.h +++ b/twain/ds/scanner.h @@ -40,6 +40,7 @@ class scanner : public ISaneInvoker, virtual public refer SANE_FinalImgFormat img_fmt_; bool twain_set_; SANEAPI sane_api_; + std::unique_ptr done_; std::function ui_notify; int(* scanner_ev_handler_)(int, void*); void* evh_param_; @@ -117,6 +118,8 @@ class scanner : public ISaneInvoker, virtual public refer static void ui_callback(int uev, void* sender, void* param); static bool is_option_float(int sn, void* param); + void scan_done(void); + int language_id_; public: