diff --git a/device/gxx-linux/packages/common.pkg/include/commondef.h b/device/gxx-linux/packages/common.pkg/include/commondef.h index 671b0b5..9b90e35 100644 --- a/device/gxx-linux/packages/common.pkg/include/commondef.h +++ b/device/gxx-linux/packages/common.pkg/include/commondef.h @@ -509,6 +509,8 @@ enum Scanner_Reg_Defs SR_SCAN_DPI = 0x600, SR_SCAN_CNT, + SR_SCAN_PAPER, + SR_SCAN_PIXEL, }; typedef union Ctrol_Description{ diff --git a/device/gxx-linux/scanner/scannerregs.cpp b/device/gxx-linux/scanner/scannerregs.cpp index 1abe04b..57dfb0c 100644 --- a/device/gxx-linux/scanner/scannerregs.cpp +++ b/device/gxx-linux/scanner/scannerregs.cpp @@ -100,7 +100,7 @@ ScannerRegAccess::~ScannerRegAccess() bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) { static uint64_t img_cb = 0, img_param = 0; - static uint32_t scan_dpi = 200, scan_cnt = -1; + static uint32_t scan_dpi = 200, scan_cnt = -1, paper_type = 0, pixel_type = 0; if(addr == (unsigned int)-1) { @@ -192,6 +192,12 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) case SR_SCAN_CNT: scan_cnt = val; return true; + case SR_SCAN_PAPER: + paper_type = val; + return true; + case SR_SCAN_PIXEL: + pixel_type = val; + return true; case SR_CONFIF_IMGPROCPARAM: { printf("\nSR_CONFIF_IMGPROCPARAM size =%d\n",val); @@ -200,9 +206,15 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) GScanCap cap = *(GScanCap*)&cfg[0]; cap.resolution_dst = scan_dpi; - cap.resolution_native = 200; + if(scan_dpi < 300.0f) + cap.resolution_native = 200.0f; + else if(scan_dpi < 500.0f) + cap.resolution_native = 300.0f; + else + cap.resolution_native = 600.0f; cap.scannum = scan_cnt; - cap.pixtype = 0; + cap.pixtype = pixel_type; + cap.papertype = paper_type; usbimages->set_dpi(scan_dpi, scan_dpi); printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt); #else diff --git a/device/gxx-linux/usb/inc/usbdevice.h b/device/gxx-linux/usb/inc/usbdevice.h index 9baeb2e..379f6e7 100644 --- a/device/gxx-linux/usb/inc/usbdevice.h +++ b/device/gxx-linux/usb/inc/usbdevice.h @@ -31,6 +31,8 @@ public: int set_dpi(int *dpix, int* dpiy); int set_scan_num(int num); int set_img_receiver(void* api, void* param); + int set_paper_type(int type); + int set_pixel_type(int *type); #endif public: diff --git a/device/gxx-linux/usb/src/async_model/common/log_util.cpp b/device/gxx-linux/usb/src/async_model/common/log_util.cpp index e8036a5..962f113 100644 --- a/device/gxx-linux/usb/src/async_model/common/log_util.cpp +++ b/device/gxx-linux/usb/src/async_model/common/log_util.cpp @@ -160,6 +160,7 @@ int32_t log_cls::log_when_err(int32_t err, const char* oper_desc, log_level leve return err; } +#if !defined(WIN32) && !defined(_WIN64) void log_cls::log_memory_usage(const char* tag, bool print_screen, const char* prog_name) { std::string memu("--Memory usage of "); @@ -172,6 +173,7 @@ void log_cls::log_memory_usage(const char* tag, bool print_screen, const char* p else if (log_cls::inst_) log_cls::inst_->log(LOG_LEVEL_DEBUG, "%s\n", memu.c_str()); } +#endif log_level log_cls::get_log_level(void) { if (log_cls::inst_) diff --git a/device/gxx-linux/usb/src/async_model/common/log_util.h b/device/gxx-linux/usb/src/async_model/common/log_util.h index b8e5bd2..a4395e9 100644 --- a/device/gxx-linux/usb/src/async_model/common/log_util.h +++ b/device/gxx-linux/usb/src/async_model/common/log_util.h @@ -60,7 +60,9 @@ public: } } static int32_t log_when_err(int32_t err, const char* oper_desc, log_level level = LOG_LEVEL_WARNING); // log as: oper_desc = strerror(errno)\n. return real error number errno +#if !defined(WIN32) && !defined(_WIN64) static void log_memory_usage(const char* tag, bool print_screen = false/*call printf if this was true, or write down to file*/, const char* prog_name = "scan"); +#endif static log_level get_log_level(void); static std::string get_log_file(void); diff --git a/device/gxx-linux/usb/src/async_model/common/packet.h b/device/gxx-linux/usb/src/async_model/common/packet.h index 00d1948..f632a69 100644 --- a/device/gxx-linux/usb/src/async_model/common/packet.h +++ b/device/gxx-linux/usb/src/async_model/common/packet.h @@ -17,6 +17,9 @@ #define FLOAT_PRECISION .000001f #define IS_FLOAT_EQUAL(x, y) (-FLOAT_PRECISION <= (x) - (y) && (x) - (y) <= FLOAT_PRECISION) #define MAKE_WORD(b0, b1) (((b0) & 0xff) | (((b1) << 8) & 0x0ff00)) +#define MAKE_STR(str) #str +#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) + #define ROGER(cmd) cmd##_ROGER #define PAIR_COMMAND(cmd) \ cmd, \ @@ -224,6 +227,12 @@ enum clr_channel COLOR_CHANNEL_BLUE, COLOR_CHANNEL_ALPHA, }; +enum color_mode +{ + COLOR_MODE_BW = 0, + COLOR_MODE_GRAY, + COLOR_MODE_RGB, +}; #pragma pack(push) #pragma pack(1) diff --git a/device/gxx-linux/usb/src/async_model/common/paper.cpp b/device/gxx-linux/usb/src/async_model/common/paper.cpp new file mode 100644 index 0000000..a6236ea --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/common/paper.cpp @@ -0,0 +1,122 @@ +#include "paper.h" + +#include "common/packet.h" +#include "../packages/common.pkg/include/commondef.h" + + + + + + + + + + + + + + + + + + + + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// exporting api: +#define CM_PER_INCH 2.54f + +static struct paper_size +{ + const char* name; + TwSS type; + double w; + double h; +}g_paper_size[] = { + {"A3", TwSS::A3, 29.7f, 42.0f}, + {"A4", TwSS::A4, 21.0f, 29.7f}, + {"A5", TwSS::A5, 14.8f, 21.0f}, + {"A6", TwSS::A6, 10.5f, 14.8f}, + {"B4", TwSS::B4, 25.7f, 36.4f}, + {"B5", TwSS::B5, 17.6f, 25.0f}, // {PAPER_B5, {182, 257}}, + {"B6", TwSS::B6, 12.5f, 17.6f}, + {"8\xE5\xBC\x80", TwSS::K8, 29.7f, 42.0f}, + {"16\xE5\xBC\x80", TwSS::K16, 21.0f, 28.5f}, + {"Letter", TwSS::A4Letter, 21.6f, 27.9f}, + {"Legal", TwSS::USLegal, 21.6f, 35.6f}, + {"Double-Letter", TwSS::USLedger, 43.2f, 27.9f}, + {"\xE4\xB8\x89\xE8\x81\x94\xE8\xAF\x95\xE5\x8D\xB7", TwSS::Trigeminy, 29.7f, 42.0f}, // fixed me ... + {"\xE5\x8C\xB9\xE9\x85\x8D\xE5\x8E\x9F\xE5\xA7\x8B\xE5\xB0\xBA\xE5\xAF\xB8", TwSS::None, 29.7f, 42.0f}, //\xfixed\xme\x... + {"\xE6\x9C\x80\xE5\xA4\xA7\xE6\x89\xAB\xE6\x8F\x8F\xE5\xB0\xBA\xE5\xAF\xB8\xE8\x87\xAA\xE5\x8A\xA8\xE8\xA3\x81\xE5\x88\x87", TwSS::USStatement, 29.7f, 42.0f}, //\xfixed\xme\x... + {"\xE6\x9C\x80\xE5\xA4\xA7\xE6\x89\xAB\xE6\x8F\x8F\xE5\xB0\xBA\xE5\xAF\xB8", TwSS::MaxSize, 29.7f, 42.0f}, //\xfixed\xme\x... + }; + +namespace paper +{ + double inch_2_cm(double inch) + { + return inch * CM_PER_INCH; + } + double cm_2_inch(double cm) + { + return cm / CM_PER_INCH; + } + int inch_2_pixel(double inch, double dpi) + { + return inch * dpi + .5f; + } + double pixel_2_inch(int pixel, double dpi) + { + return pixel / dpi; + } + int cm_2_pixel(double cm, double dpi) + { + return inch_2_pixel(cm_2_inch(cm), dpi); + } + double pixel_2_cm(int pixel, double dpi) + { + return inch_2_cm(pixel_2_inch(pixel, dpi)); + } + + // Function: get known paper-type size in cm + // + // Parameter: name - paper type name, such as "A3", "A4", ... + // + // w - to receive width in cm + // + // h - to receive height in cm + // + // Return: true if 'name' was supported, or else false + bool paper_size(const char* name, double* w, double* h, int* type) + { + bool fit = false; + + for(auto& v: g_paper_size) + { + if(strcmp(v.name, name) == 0) + { + if(w) + *w = v.w; + if(h) + *h = v.h; + if(type) + *type = v.type; + fit = true; + break; + } + } + + if(!fit) + { + // A3 - 2338(29.7), 3307(42.0) + if(w) + *w = g_paper_size[0].w; + if(h) + *h = g_paper_size[0].h; + if(type) + *type = g_paper_size[0].type; + } + + return fit; + } +}; diff --git a/device/gxx-linux/usb/src/async_model/common/paper.h b/device/gxx-linux/usb/src/async_model/common/paper.h new file mode 100644 index 0000000..b791a21 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/common/paper.h @@ -0,0 +1,32 @@ +#pragma once + +// Objects for paper size ... +// +// created on 2023-05-02 + + + + +namespace paper +{ + double inch_2_cm(double inch); + double cm_2_inch(double cm); + int inch_2_pixel(double inch, double dpi = 200.0f); + double pixel_2_inch(int pixel, double dpi = 200.0f); + int cm_2_pixel(double cm, double dpi = 200.0f); + double pixel_2_cm(int pixel, double dpi = 200.0f); + + // Function: get known paper-type size in cm + // + // Parameter: name - paper type name, such as "A3", "A4", ... + // + // w - to receive width in cm + // + // h - to receive height in cm + // + // type - to receive paper type of TwSS + // + // Return: true if 'name' was supported, or else false + bool paper_size(const char* name, double* w, double* h, int* type = nullptr); +}; + diff --git a/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp b/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp index 67e4fb2..c954cd3 100644 --- a/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp +++ b/device/gxx-linux/usb/src/async_model/common/sane_cfg.cpp @@ -288,7 +288,7 @@ bool sane_cfg_provider::sane_refine_range(gb_json* jsn, void* data, size_t* len) return ok; } -void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function get_opt) +void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function get_opt) { gb_json* depends = nullptr, *item = nullptr; bool able = true, oper_and = false; @@ -322,6 +322,7 @@ void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function< } depends->release(); opt->set_value("enabled", able); + log_cls::log(LOG_LEVEL_DEBUG, "%s enabled: %s. (%s = %s)\n", opt->key().c_str(), able ? "true" : "false", name.c_str(), val.c_str()); } } data_type sane_cfg_provider::type_from_string(const char* type_desc) @@ -337,7 +338,7 @@ data_type sane_cfg_provider::type_from_string(const char* type_desc) return DATA_TYPE_CUSTOM; } - bool sane_cfg_provider::raw_value_in_json(gb_json* root, const char* key, std::string& val) + bool sane_cfg_provider::raw_value_in_json(gb_json* root, const char* key, std::string& val, uint32_t* type) { bool ret = true, bv = false; int nv = 0; @@ -346,24 +347,32 @@ data_type sane_cfg_provider::type_from_string(const char* type_desc) if(root->get_value(key, bv)) { val = std::string((char*)&bv, sizeof(bv)); + if(*type) + *type = DATA_TYPE_BOOL; } else if(root->get_value(key, nv)) { val = std::string((char*)&nv, sizeof(nv)); + if(*type) + *type = DATA_TYPE_INT4; } else if(root->get_value(key, fv)) { val = std::string((char*)&fv, sizeof(fv)); + if(*type) + *type = DATA_TYPE_FLOAT; } else { ret = root->get_value(key, val); + if(type) + *type = ret ? DATA_TYPE_STRING : DATA_TYPE_CUSTOM; } return ret; } -bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) { bool oper_not = false, calc = true, handled = false; size_t pos = exp.find("=="); @@ -381,20 +390,8 @@ bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type handled = true; if(pos) { - std::string types(""); - char buf[40] = {0}, *mem = nullptr; - size_t l = sizeof(buf) - 1; - *name = exp.substr(0, pos); - get_opt(name->c_str(), buf, &l, "type"); - *type = sane_cfg_provider::type_from_string(buf); - l = 0; - get_opt(name->c_str(), mem, &l, "cur"); - mem = new char[l + 4]; - l += 4; - get_opt(name->c_str(), mem, &l, "cur"); - *val = std::string(mem, l); - delete[] mem; + get_opt(name->c_str(), "cur", *val, (uint32_t*)type); } exp.erase(0, pos + 2); @@ -450,7 +447,7 @@ bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type return handled; } -bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) { bool oper_not = false, calc = true, handled = false; size_t pos = exp.find(">"); @@ -468,20 +465,8 @@ bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type handled = true; if(pos) { - std::string types(""); - char buf[40] = {0}, *mem = nullptr; - size_t l = sizeof(buf) - 1; - *name = exp.substr(0, pos); - get_opt(name->c_str(), buf, &l, "type"); - *type = sane_cfg_provider::type_from_string(buf); - l = 0; - get_opt(name->c_str(), mem, &l, "cur"); - mem = new char[l + 4]; - l += 4; - get_opt(name->c_str(), mem, &l, "cur"); - *val = std::string(mem, l); - delete[] mem; + get_opt(name->c_str(), "cur", *val, (uint32_t*)type); } exp.erase(0, pos + 1 + oper_not); @@ -503,7 +488,7 @@ bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type return handled; } -bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) +bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result) { bool oper_not = false, calc = true, handled = false; size_t pos = exp.find("<"); @@ -521,20 +506,8 @@ bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, handled = true; if(pos) { - std::string types(""); - char buf[40] = {0}, *mem = nullptr; - size_t l = sizeof(buf) - 1; - *name = exp.substr(0, pos); - get_opt(name->c_str(), buf, &l, "type"); - *type = sane_cfg_provider::type_from_string(buf); - l = 0; - get_opt(name->c_str(), mem, &l, "cur"); - mem = new char[l + 4]; - l += 4; - get_opt(name->c_str(), mem, &l, "cur"); - *val = std::string(mem, l); - delete[] mem; + get_opt(name->c_str(), "cur", *val, (uint32_t*)type); } exp.erase(0, pos + 1 + oper_not); @@ -556,7 +529,7 @@ bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, return handled; } -bool sane_cfg_provider::is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt) +bool sane_cfg_provider::is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt) { // ==, >, < // !=, <=, >= @@ -790,32 +763,17 @@ std::string sane_cfg_mgr::get_all_configurations(void) } void sane_cfg_mgr::update_enable_status(void) { - auto get_opt = [&](const char* cfg_name, void* buf, size_t* len, const char* key) -> int32_t + auto get_opt = [&](const char* cfg_name, const char* key, std::string& val, uint32_t* type) -> int32_t { - std::string val(""); int32_t ret = 0; for(auto& v: sane_waiters_) { - ret = v->get_value(cfg_name, key, val); + ret = v->get_raw_value(cfg_name, key, val, type); if(ret != ENOENT) break; } - if(ret == 0) - { - if(*len < val.length()) - { - *len = val.length(); - ret = ENOMEM; - } - else - { - memcpy(buf, val.c_str(), val.length()); - *len = val.length(); - } - } - return ret; }; diff --git a/device/gxx-linux/usb/src/async_model/common/sane_cfg.h b/device/gxx-linux/usb/src/async_model/common/sane_cfg.h index 25d571e..3140acf 100644 --- a/device/gxx-linux/usb/src/async_model/common/sane_cfg.h +++ b/device/gxx-linux/usb/src/async_model/common/sane_cfg.h @@ -14,40 +14,27 @@ #include -//{ -// "paper": { -// "category": "base", -// "readonly": false, -// "affect": 0, -// "group": "base", -// "visible": true, -// "field": "Common", -// "ver": 1, -// "pos": 0, -// "unit": "None", -// "title": "纸张尺寸", -// "desc": "设置出图大小", -// "type": "string", -// "cur": "匹配原始尺寸", -// "default": "匹配原始尺寸", -// "size": 48, -// "range": ["A3", "8开", "A4", "A4横向", "16开", "16开横向", "A5", "A5横向", "A6", "A6横向", "B4", "B5", "B5横向", "B6", "B6横向", "Letter", "Letter横向", "Double Letter", "LEGAL", "匹配原始尺寸", "最大扫描尺寸自动裁切", "最大扫描尺寸", "三联试卷"] -// }, -//} -enum sane_after_do -{ - SANE_AFTER_DO_NOTHING = 0, - SANE_AFTER_DO_RELOAD_PARAM, - SANE_AFTER_DO_RELOAD_OPTION, -}; +// proto of getting raw value of sane-option +// +// cfg_name - option name +// +// key - the value key in JSON, e.g.: current value key is "cur" +// +// val - to receive the raw value +// +// type - to receive the value type +// +#define GET_SANE_OPT_PROTO int32_t(const char* cfg_name, const char* key, std::string& val, uint32_t* type) + + class gb_json; class sane_cfg_provider : public refer { - static bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); - static bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); - static bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); - static bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt); + static bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt, bool* result); + static bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function get_opt); public: sane_cfg_provider(); @@ -60,9 +47,9 @@ public: static std::string sane_option_value_get(gb_json* jsn, const char* key = "cur"/*cur, default*/, std::string* strval = nullptr/*convert value into string*/); static bool sane_option_value_set(gb_json* jsn, void* data, const char* key = "cur"/*cur, default*/); static bool sane_refine_range(gb_json* jsn, void* data, size_t* len); // if 'data' is accept then return true, or else return false and new data set in 'data' and 'len' - static void update_option_enable_status(gb_json* opt, std::function get_opt); + static void update_option_enable_status(gb_json* opt, std::function get_opt); static data_type type_from_string(const char* type_desc); - static bool raw_value_in_json(gb_json* root, const char* key, std::string& val); + static bool raw_value_in_json(gb_json* root, const char* key, std::string& val, uint32_t* type = nullptr/*data_type*/); protected: int32_t inner_get_config(gb_json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval); @@ -106,16 +93,8 @@ public: // // Parameters: get_opt - function to get option value, return value is the same as get_config // - // cfg_name - option name - // - // buf - buffer to receive the option value - // - // len - [in]: length of 'buf'; [out]: real size of value - // - // key - the value key in JSON, e.g.: current value key is "cur" - // // Return: none - virtual void update_enabled(std::function get_opt) = 0; + virtual void update_enabled(std::function get_opt) = 0; // Function: get value of given key // @@ -125,9 +104,11 @@ public: // // val = to receive the raw value. e.g. std::string(&bool, sizeof(bool)) // + // type - to receive the value type (data_type) + // // Return: 0 - success, // ENOENT - not found - virtual int32_t get_value(const char* name, const char* key, std::string& val) = 0; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) = 0; }; class sane_cfg_mgr : public refer diff --git a/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp b/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp index 8df685f..8337b44 100644 --- a/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp +++ b/device/gxx-linux/usb/src/async_model/hardware/hardware.cpp @@ -1,272 +1,15 @@ #include "hardware.h" #include "common/json/gb_json.h" -//{ -// "cis-mode": { -// "category": "base", -// "readonly" : false, -// "affect" : 2, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "CIS����ģʽ", -// "desc" : "����CIS��ɫ���߻ҶȵĹ���ģʽ", -// "type" : "string", -// "cur" : "��ɫ", -// "default" : "��ɫ", -// "size" : 12, -// "range": ["��ɫ", "�Ҷ�"] -// }, -// "cis-dpi": { -// "category": "base", -// "readonly" : false, -// "affect" : 2, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "CIS�ֱ���", -// "desc" : "����CIS�ɼ��ķֱ���", -// "type" : "int", -// "cur" : 200, -// "default" : 200, -// "size" : 4, -// "range": [200, 300] -// }, -// "cis-sample": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "CIS����Ƶ��", -// "desc" : "����CIS��ͷ�����Ĺ���Ƶ��", -// "type" : "int", -// "cur" : 256, -// "default" : 256, -// "size" : 4, -// "range": [128, 256, 512] -// }, -// "frame-h": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "CIS֡�߶�", -// "desc" : "����CISÿһ֡�ĸ߶�", -// "type" : "int", -// "cur" : 12, -// "default" : 12, -// "size" : 4, -// "range": [4, 8, 12, 16] -// }, -// "gain-front": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "��������", -// "desc" : "����CIS���澵ͷ������", -// "type" : "int", -// "cur" : 256, -// "default" : 256, -// "size" : 4, -// "range": [100, 200, 300, 600] -// }, -// "gain-back": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "��������", -// "desc" : "����CIS���澵ͷ������", -// "type" : "int", -// "cur" : 256, -// "default" : 256, -// "size" : 4, -// "range": [100, 200, 300, 600] -// }, -// "offset-front": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "����ƫ��", -// "desc" : "����CIS�����ƫ�ƾ���", -// "type" : "int", -// "cur" : 150, -// "default" : 150, -// "size" : 4, -// "range": [0, 50, 100, 150, 200] -// }, -// "offset-back": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "����ƫ��", -// "desc" : "����CIS�����ƫ�ƾ���", -// "type" : "int", -// "cur" : 150, -// "default" : 150, -// "size" : 4, -// "range": [0, 50, 100, 150, 200] -// }, -// "exposure-f-r": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "�����ɫ�����ع��", -// "desc" : "���������ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -// "exposure-f-g": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "������ɫ�����ع��", -// "desc" : "����������ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -// "exposure-f-b": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "������ɫ�����ع��", -// "desc" : "����������ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -// "exposure-b-r": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "�����ɫ�����ع��", -// "desc" : "�����������ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -// "exposure-b-g": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "������ɫ�����ع��", -// "desc" : "���ñ�����ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -// "exposure-b-b": { -// "category": "base", -// "readonly" : false, -// "affect" : 0, -// "group" : "base", -// "visible" : false, -// "field" : "cis", -// "pos" : 0, -// "unit" : "None", -// "title" : "������ɫ�����ع��", -// "desc" : "���ñ�����ɫ�������ع�ǿ��", -// "type" : "int", -// "cur" : 0, -// "default" : 0, -// "size" : 4, -// "range": { -// "min": -1000, -// "max": 1000, -// "step": 200 -// } -// }, -//} -static std::string json_text = - "{\"cis-mode\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u5f69\\u8272\\u6216\\u8005\\u7070\\u5ea6\\u7684\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u5f69\\u8272\",\"default\":\"\\u5f69\\u8272\",\"size\":12,\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"cis-dpi\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u91c7\\u96c6\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[200,300]},\"cis-sample\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u955c\\u5934\\u91c7\\u6837\\u7684\\u5de5\\u4f5c\\u9891\\u7387\",\"type\":\"int\",\"cur\":256,\"default\":256,\"size\":4,\"range\":[128,256,512]},\"frame-h\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6bcf\\u4e00\\u5e27\\u7684\\u9ad8\\u5ea6\",\"type\":\"int\",\"cur\":12,\"default\":12,\"size\":4,\"range\":[4,8,12,16]},\"gain-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"gain-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"offset-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"offset-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"exposure-f-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"scan-count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":true,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u7684\\u7eb8\\u5f20\\u6570\\u91cf\uFF0C\\u201C-1\\u201D\\u4e3a\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"int\",\"cur\":-1,\"default\":-1,\"size\":4,\"range\":[-1,1,2,3,4,5,6,7,8,9,10]}}"; +#include "common/paper.h" +#include "common/log_util.h" + + + + + +static std::string hardware_json = + "{\"cis-mode\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u5f69\\u8272\\u6216\\u8005\\u7070\\u5ea6\\u7684\\u5de5\\u4f5c\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"\\u5f69\\u8272\",\"default\":\"\\u5f69\\u8272\",\"size\":12,\"range\":[\"\\u5f69\\u8272\",\"\\u7070\\u5ea6\"]},\"cis-dpi\":{\"category\":\"base\",\"readonly\":false,\"affect\":2,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u91c7\\u96c6\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[200,300]},\"cis-sample\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u91c7\\u6837\\u9891\\u7387\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u955c\\u5934\\u91c7\\u6837\\u7684\\u5de5\\u4f5c\\u9891\\u7387\",\"type\":\"int\",\"cur\":256,\"default\":256,\"size\":4,\"range\":[128,256,512]},\"frame-h\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"CIS\\u5e27\\u9ad8\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6bcf\\u4e00\\u5e27\\u7684\\u9ad8\\u5ea6\",\"type\":\"int\",\"cur\":12,\"default\":12,\"size\":4,\"range\":[4,8,12,16]},\"gain-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"gain-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u589e\\u76ca\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u955c\\u5934\\u7684\\u589e\\u76ca\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":[100,200,300,600]},\"offset-front\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u6b63\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"offset-back\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u504f\\u79fb\",\"desc\":\"\\u8bbe\\u7f6eCIS\\u80cc\\u9762\\u7684\\u504f\\u79fb\\u8ddd\\u79bb\",\"type\":\"int\",\"cur\":150,\"default\":150,\"size\":4,\"range\":[0,50,100,150,200]},\"exposure-f-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-f-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-r\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u6b63\\u80cc\\u9762\\u7ea2\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-g\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u7eff\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"exposure-b-b\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"CIS\",\"visible\":false,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u66dd\\u5149\\u5ea6\",\"desc\":\"\\u8bbe\\u7f6e\\u80cc\\u9762\\u84dd\\u8272\\u5206\\u91cf\\u7684\\u66dd\\u5149\\u5f3a\\u5ea6\",\"type\":\"int\",\"cur\":0,\"default\":0,\"size\":4,\"range\":{\"min\":-1000,\"max\":1000,\"step\":200}},\"paper\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"common\",\"group\":\"base\",\"pos\":0,\"affect\":6,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7eb8\\u5f20\\u5c3a\\u5bf8\",\"desc\":\"\\u8bbe\\u7f6e\\u51fa\\u56fe\\u5927\\u5c0f\",\"type\":\"string\",\"cur\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"default\":\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"size\":48,\"range\":[\"A3\",\"8\\u5f00\",\"A4\",\"16\\u5f00\",\"A5\",\"A6\",\"B4\",\"B5\",\"B6\",\"Letter\",\"Double Letter\",\"LEGAL\",\"\\u5339\\u914d\\u539f\\u59cb\\u5c3a\\u5bf8\",\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207\",\"\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\",\"\\u4e09\\u8054\\u8bd5\\u5377\"]},\"lateral\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"common\",\"group\":\"base\",\"pos\":0,\"enable\":false,\"affect\":4,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u6a2a\\u5411\",\"desc\":\"\\u6a2a\\u5411\\u653e\\u7eb8\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4,\"depend_or\":[\"paper==A4\",\"==A5\",\"==A6\",\"==B5\",\"==B6\",\"==Letter\"]},\"paper-w\":{\"category\":\"base\",\"readonly\":true,\"visible\":false,\"field\":\"common\",\"group\":\"base\",\"pos\":0,\"unit\":\"pixel\",\"ver\":1,\"title\":\"\\u7eb8\\u5f20\\u5bbd\\u5ea6\",\"desc\":\"\\u9009\\u62e9\\u7684\\u56fa\\u5b9a\\u5927\\u5c0f\\u7eb8\\u5f20\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"cur\":1654,\"default\":1654,\"size\":4},\"paper-h\":{\"category\":\"base\",\"readonly\":true,\"visible\":false,\"field\":\"common\",\"group\":\"base\",\"pos\":0,\"unit\":\"pixel\",\"ver\":1,\"title\":\"\\u7eb8\\u5f20\\u5bbd\\u5ea6\",\"desc\":\"\\u9009\\u62e9\\u7684\\u56fa\\u5b9a\\u5927\\u5c0f\\u7eb8\\u5f20\\u7684\\u5bbd\\u5ea6\",\"type\":\"int\",\"cur\":2339,\"default\":2339,\"size\":4},\"scan-count\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"base\",\"visible\":true,\"field\":\"cis\",\"pos\":0,\"ver\":1,\"unit\":\"None\",\"title\":\"\\u626b\\u63cf\\u5f20\\u6570\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u7684\\u7eb8\\u5f20\\u6570\\u91cf\\uFF0C\\u201C-1\\u201D\\u4e3a\\u8fde\\u7eed\\u626b\\u63cf\",\"type\":\"int\",\"cur\":-1,\"default\":-1,\"size\":4,\"range\":[-1,1,2,3,4,5,6,7,8,9,10]}}"; ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // class image_capture @@ -275,12 +18,14 @@ extern int32_t (*scan_start)(void); extern int32_t (*scan_stop)(void); extern int32_t (*set_dpi)(int*, int*); extern int32_t (*set_scan_num)(int); +extern int32_t (*set_paper_type)(int); +extern int32_t (*set_pixel_type)(int*); #endif image_capture::image_capture(std::function receiver) - : img_keeper_(receiver), cfg_(new gb_json()) + : img_keeper_(receiver), cfg_(new gb_json()), dpi_x_(200.0f), dpi_y_(200.0f) { - cfg_->attach_text(&json_text[0]); + cfg_->attach_text(&hardware_json[0]); memset(&api_, 0, sizeof(api_)); } image_capture::~image_capture() @@ -298,7 +43,7 @@ int32_t image_capture::set(const char* name, void* data, size_t* len) if(cfg_->get_value(name, child) && child) { - sane_cfg_provider::sane_refine_range(child, data, len); + bool exact = sane_cfg_provider::sane_refine_range(child, data, len); if (n == "cis-mode") { @@ -398,6 +143,19 @@ int32_t image_capture::set(const char* name, void* data, size_t* len) { set_scan_num(*(int*)data); child->set_value("cur", *(int*)data); + ret = exact ? 0 : EUCLEAN; + } + else if(n == "paper") + { + child->set_value("cur", (char*)data); + refresh_paper_size(true); + ret = exact ? 0 : EUCLEAN; + } + else if(n == "lateral") + { + child->set_value("cur", *(bool*)data); + refresh_paper_size(); + ret = 0; } child->release(); } @@ -415,6 +173,55 @@ int32_t image_capture::set(const char* name, void* data, size_t* len) return ret; } +void image_capture::refresh_paper_size(bool from_paper_type) +{ + gb_json* child = nullptr; + int w = 0, + h = 0, + type = 0; + double width = .0f, + height = .0f; + std::string pp(""); + + if(cfg_->get_value("paper", child) && child) + { + child->get_value("cur", pp); + child->release(); + } + + paper::paper_size(pp.c_str(), &width, &height, &type); + if(from_paper_type) + set_paper_type(type); + if(cfg_->get_value("lateral", child) && child) + { + bool enable = false; + if(child->get_value("enable", enable) && enable) + { + if(child->get_value("cur", enable) && enable) + { + double v = width; + width = height; + height = v; + pp += " Lateral"; + } + } + child->release(); + } + w = paper::cm_2_pixel(width, dpi_x_); + h = paper::cm_2_pixel(height, dpi_y_); + log_cls::log(LOG_LEVEL_ALL, "'%s' in DPI(%f, %f) size is: (%u, %u)\n", pp.c_str(), dpi_x_, dpi_y_, w, h); + + if(cfg_->get_value("paper-w", child) && child) + { + child->set_value("cur", w); + child->release(); + } + if(cfg_->get_value("paper-h", child) && child) + { + child->set_value("cur", h); + child->release(); + } +} int32_t image_capture::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) { @@ -434,8 +241,9 @@ int32_t image_capture::set_config(const char* cfg_name, void* data, size_t* len, sane_option_value_set(child, data); if (afterdo) { - child->get_value("affect", ret); - *afterdo = ret; + int v = 0; + child->get_value("affect", v); + *afterdo = v; } if(!exact) ret = EUCLEAN; @@ -445,19 +253,27 @@ int32_t image_capture::set_config(const char* cfg_name, void* data, size_t* len, return ret; } -void image_capture::update_enabled(std::function get_opt) +void image_capture::update_enabled(std::function get_opt) { - sane_cfg_provider::update_option_enable_status(cfg_, get_opt); + gb_json* child = cfg_->first_child(); + + while(child) + { + sane_cfg_provider::update_option_enable_status(child, get_opt); + child->release(); + child = cfg_->next_child(); + } } -int32_t image_capture::get_value(const char* name, const char* key, std::string& val) +int32_t image_capture::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { gb_json* child = nullptr; int32_t ret = ENOENT; if(cfg_->get_value(name, child) && child) { - if(sane_cfg_provider::raw_value_in_json(child, key, val)) + if(sane_cfg_provider::raw_value_in_json(child, key, val, type)) ret = 0; + child->release(); } return ret; @@ -481,5 +297,20 @@ int32_t image_capture::stop(void) } int image_capture::set_dpi(int* dpi_x, int* dpi_y) { + if(dpi_x) + dpi_x_ = *dpi_x; + if(dpi_y) + dpi_y_ = *dpi_y; + refresh_paper_size(); + return ::set_dpi(dpi_x, dpi_y); +} +int image_capture::set_color_mode(color_mode* mode) +{ + int val = *mode, + ret = 0; + + ret = set_pixel_type(&val); + + return ret; } \ No newline at end of file diff --git a/device/gxx-linux/usb/src/async_model/hardware/hardware.h b/device/gxx-linux/usb/src/async_model/hardware/hardware.h index 4ee6361..a044dbb 100644 --- a/device/gxx-linux/usb/src/async_model/hardware/hardware.h +++ b/device/gxx-linux/usb/src/async_model/hardware/hardware.h @@ -33,13 +33,383 @@ typedef struct _cis_api CIS_API set_exposure_back_blue; }CISAPI, *LPCISAPI; + +// { +// "cis-mode": { +// "category": "base", +// "readonly": false, +// "affect": 2, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "CIS\u5de5\u4f5c\u6a21\u5f0f", +// "desc": "\u8bbe\u7f6eCIS\u5f69\u8272\u6216\u8005\u7070\u5ea6\u7684\u5de5\u4f5c\u6a21\u5f0f", +// "type": "string", +// "cur": "\u5f69\u8272", +// "default": "\u5f69\u8272", +// "size": 12, +// "range": ["\u5f69\u8272", "\u7070\u5ea6"] +// }, +// "cis-dpi": { +// "category": "base", +// "readonly": false, +// "affect": 2, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "CIS\u5206\u8fa8\u7387", +// "desc": "\u8bbe\u7f6eCIS\u91c7\u96c6\u7684\u5206\u8fa8\u7387", +// "type": "int", +// "cur": 200, +// "default": 200, +// "size": 4, +// "range": [200, 300] +// }, +// "cis-sample": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "CIS\u91c7\u6837\u9891\u7387", +// "desc": "\u8bbe\u7f6eCIS\u955c\u5934\u91c7\u6837\u7684\u5de5\u4f5c\u9891\u7387", +// "type": "int", +// "cur": 256, +// "default": 256, +// "size": 4, +// "range": [128, 256, 512] +// }, +// "frame-h": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "CIS\u5e27\u9ad8\u5ea6", +// "desc": "\u8bbe\u7f6eCIS\u6bcf\u4e00\u5e27\u7684\u9ad8\u5ea6", +// "type": "int", +// "cur": 12, +// "default": 12, +// "size": 4, +// "range": [4, 8, 12, 16] +// }, +// "gain-front": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u6b63\u9762\u589e\u76ca", +// "desc": "\u8bbe\u7f6eCIS\u6b63\u9762\u955c\u5934\u7684\u589e\u76ca", +// "type": "int", +// "cur": 200, +// "default": 200, +// "size": 4, +// "range": [100, 200, 300, 600] +// }, +// "gain-back": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u80cc\u9762\u589e\u76ca", +// "desc": "\u8bbe\u7f6eCIS\u80cc\u9762\u955c\u5934\u7684\u589e\u76ca", +// "type": "int", +// "cur": 200, +// "default": 200, +// "size": 4, +// "range": [100, 200, 300, 600] +// }, +// "offset-front": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u6b63\u9762\u504f\u79fb", +// "desc": "\u8bbe\u7f6eCIS\u6b63\u9762\u7684\u504f\u79fb\u8ddd\u79bb", +// "type": "int", +// "cur": 150, +// "default": 150, +// "size": 4, +// "range": [0, 50, 100, 150, 200] +// }, +// "offset-back": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u80cc\u9762\u504f\u79fb", +// "desc": "\u8bbe\u7f6eCIS\u80cc\u9762\u7684\u504f\u79fb\u8ddd\u79bb", +// "type": "int", +// "cur": 150, +// "default": 150, +// "size": 4, +// "range": [0, 50, 100, 150, 200] +// }, +// "exposure-f-r": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u6b63\u9762\u7ea2\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u6b63\u9762\u7ea2\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-f-g": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u6b63\u9762\u7eff\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u6b63\u9762\u7eff\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-f-b": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u6b63\u9762\u84dd\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u6b63\u9762\u84dd\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-r": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u80cc\u9762\u7ea2\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u6b63\u80cc\u9762\u7ea2\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-g": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u80cc\u9762\u7eff\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u80cc\u9762\u7eff\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "exposure-b-b": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": false, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u80cc\u9762\u84dd\u8272\u5206\u91cf\u66dd\u5149\u5ea6", +// "desc": "\u8bbe\u7f6e\u80cc\u9762\u84dd\u8272\u5206\u91cf\u7684\u66dd\u5149\u5f3a\u5ea6", +// "type": "int", +// "cur": 0, +// "default": 0, +// "size": 4, +// "range": { +// "min": -1000, +// "max": 1000, +// "step": 200 +// } +// }, +// "paper": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "common", +// "group": "base", +// "pos": 0, +// "affect": 6, +// "unit": "none", +// "ver": 1, +// "title": "\u7eb8\u5f20\u5c3a\u5bf8", +// "desc": "\u8bbe\u7f6e\u51fa\u56fe\u5927\u5c0f", +// "type": "string", +// "cur": "\u5339\u914d\u539f\u59cb\u5c3a\u5bf8", +// "default": "\u5339\u914d\u539f\u59cb\u5c3a\u5bf8", +// "size": 48, +// "range": ["A3", "8\u5f00", "A4", "16\u5f00", "A5", "A6", "B4", "B5", "B6", "Letter", "Double Letter", "LEGAL", "\u5339\u914d\u539f\u59cb\u5c3a\u5bf8", "\u6700\u5927\u626b\u63cf\u5c3a\u5bf8\u81ea\u52a8\u88c1\u5207", "\u6700\u5927\u626b\u63cf\u5c3a\u5bf8", "\u4e09\u8054\u8bd5\u5377"] +// }, +// "lateral": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "common", +// "group": "base", +// "pos": 0, +// "affect": 4, +// "unit": "none", +// "ver": 1, +// "title": "\u6a2a\u5411", +// "desc": "\u6a2a\u5411\u653e\u7eb8", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4, +// "depend_or": ["paper==A4", "==A5", "==A6", "==B5", "==B6", "==Letter"] +// }, +// "paper-w": { +// "category": "base", +// "readonly": true, +// "visible": false, +// "field": "common", +// "group": "base", +// "pos": 0, +// "unit": "pixel", +// "ver": 1, +// "title": "\u7eb8\u5f20\u5bbd\u5ea6", +// "desc": "\u9009\u62e9\u7684\u56fa\u5b9a\u5927\u5c0f\u7eb8\u5f20\u7684\u5bbd\u5ea6", +// "type": "int", +// "cur": 1654, +// "default": 1654, +// "size": 4 +// }, +// "paper-h": { +// "category": "base", +// "readonly": true, +// "visible": false, +// "field": "common", +// "group": "base", +// "pos": 0, +// "unit": "pixel", +// "ver": 1, +// "title": "\u7eb8\u5f20\u5bbd\u5ea6", +// "desc": "\u9009\u62e9\u7684\u56fa\u5b9a\u5927\u5c0f\u7eb8\u5f20\u7684\u5bbd\u5ea6", +// "type": "int", +// "cur": 2339, +// "default": 2339, +// "size": 4 +// }, +// "scan-count": { +// "category": "base", +// "readonly": false, +// "affect": 0, +// "group": "CIS", +// "visible": true, +// "field": "cis", +// "pos": 0, +// "ver": 1, +// "unit": "None", +// "title": "\u626b\u63cf\u5f20\u6570", +// "desc": "\u8bbe\u7f6e\u626b\u63cf\u7684\u7eb8\u5f20\u6570\u91cf\uFF0C\u201C-1\u201D\u4e3a\u8fde\u7eed\u626b\u63cf", +// "type": "int", +// "cur": -1, +// "default": -1, +// "size": 4, +// "range": [-1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10] +// } +// } + + class image_capture : public sane_cfg_provider { gb_json* cfg_; CISAPI api_; + double dpi_x_; + double dpi_y_; std::function img_keeper_; int32_t set(const char* name, void* data, size_t* len); + void refresh_paper_size(bool from_paper_type = false); public: image_capture(std::function receiver); @@ -51,8 +421,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: void set_api(LPCISAPI api); @@ -69,5 +439,12 @@ public: // // Return: always 0. if input value is not accessible, the exact value is stored into the var int set_dpi(int* dpi_x, int* dpi_y); + + // Function: set resolution of hardware/CIS + // + // Parameters: mode - [in]color to be set; [out]applied value + // + // Return: always 0. if input value is not accessible, the exact value is stored into the var + int set_color_mode(color_mode* mode); }; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.cpp new file mode 100644 index 0000000..7e785ad --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.cpp @@ -0,0 +1,185 @@ +#include "auto_crop.h" + + +#include "common/json/gb_json.h" +#include "imageprocess/ImageApplyAutoCrop.h" + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + + +static std::string auto_crop_jsn = + ""; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_algs +auto_crop::auto_crop() : root_(new gb_json()) + , name_("is-discard-blank"), pos_(0), ver_(0), enable_(false) + , threshold_(40), indent_(30), stroke_(50), bg_clr_(200), noise_(11), universal_(true) +{ + root_->attach_text(&auto_crop_jsn[0]); + init_value_from_json(); +} +auto_crop::~auto_crop() +{ + root_->release(); +} + +void auto_crop::init_value_from_json(void) +{ + gb_json* child = nullptr; + + if(root_->get_value(name_.c_str(), child) && child) + { + int val = 0; + child->get_value("cur", enable_); + child->get_value("ver", val); + ver_ = val; + child->get_value("pos", val); + pos_ = val; + + child->release(); + } + if(root_->get_value("discard-blank", child) && child) + { + std::string val(""); + child->get_value("cur", val); + universal_ = val != "\xE5\x8F\x91\xE7\xA5\xA8\xE7\xBA\xB8"; + child->release(); + } + if(root_->get_value("blank-sensitivity", child) && child) + { + child->get_value("cur", stroke_); + child->release(); + } + + if(root_->get_value("blank-threshold", child) && child) + { + child->get_value("cur", threshold_); + child->release(); + } + if(root_->get_value("blank-indent", child) && child) + { + child->get_value("cur", indent_); + child->release(); + } + if(root_->get_value("blank-bg-clr", child) && child) + { + child->get_value("cur", bg_clr_); + child->release(); + } + if(root_->get_value("blank-noise", child) && child) + { + child->get_value("cur", noise_); + child->release(); + } +} + +int32_t auto_crop::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + { + return inner_get_config(root_, buf, len, cfg_name, strval); + } + else + { + if(!len) + return EINVAL; + + std::string val(root_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + + return ENOMEM; + } + + strcpy((char*)buf, val.c_str()); + *len = val.length(); + } + + return 0; +} +int32_t auto_crop::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(root_->get_value(cfg_name, child) && child) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + init_value_from_json(); + if(strcmp(cfg_name, "discard-blank") == 0) + { + noise_ = universal_ ? 200 : 150; + } + + if(afterdo) + { + int val = 0; + child->get_value("affect", val); + *afterdo = val; + } + + child->release(); + } + + return ret; +} +void auto_crop::update_enabled(std::function get_opt) +{ + gb_json* child = root_->first_child(); + while(child) + { + sane_cfg_provider::update_option_enable_status(child, get_opt); + child->release(); + child = root_->next_child(); + } +} +int32_t auto_crop::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) +{ + int32_t ret = ENOENT; + gb_json* child = nullptr; + + if(root_->get_value(name, child) && child) + { + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; + child->release(); + } + + return ret; +} + +img_one_paper* auto_crop::execute(img_one_paper* img) +{ + for(auto& v : img->images_queue()) + { + // CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(v.img, threshold_, indent_, stroke_, bg_clr_, noise_); + } + img->add_ref(); + + return img; +} +bool auto_crop::is_enabled(std::function get_opt_value) +{ + return enable_; +} + +uint32_t auto_crop::position(void) +{ + return pos_; +} +uint32_t auto_crop::version(void) +{ + return ver_; +} +const char* auto_crop::option_name(void) +{ + return name_.c_str(); +} + + diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.h b/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.h new file mode 100644 index 0000000..bbaea51 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/auto_crop.h @@ -0,0 +1,53 @@ +#pragma once + +// auto_crop algorithm +// +// created on 2023-04-23 +// + +#include "img_algorithm.h" + + + + + + +class gb_json; + +class auto_crop : public img_alg +{ + gb_json* root_; + + std::string name_; + uint32_t pos_; + uint32_t ver_; + bool enable_; + + int threshold_; + int indent_; + int stroke_; // sensitivity + int bg_clr_; + int noise_; + bool universal_; + + void init_value_from_json(void); + +public: + auto_crop(void); +protected: + ~auto_crop(); + +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; + +public: + img_one_paper* execute(img_one_paper* img) override; + bool is_enabled(std::function get_opt_value) override; + + uint32_t position(void) override; + uint32_t version(void) override; + const char* option_name(void) override; +}; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.cpp new file mode 100644 index 0000000..e0b2718 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.cpp @@ -0,0 +1,191 @@ +#include "discard_blank.h" + + +#include "common/json/gb_json.h" +#include "imageprocess/ImageApplyDiscardBlank.h" + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + + +static std::string discard_blank_jsn = + "{\"is-discard-blank\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"affect\":2,\"pos\":200,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\",\"desc\":\"\\u5982\\u679c\\u68c0\\u6d4b\\u5230\\u56fe\\u50cf\\u4e3a\\u7a7a\\u767d\\uFF0C\\u5219\\u4e22\\u5f03\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"discard-blank\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":201,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\\u7c7b\\u578b\",\"desc\":\"\\u901a\\u7528\\u548c\\u53d1\\u7968\\uFF0C\\u5176\\u4e2d\\u4e4b\\u4e00\",\"type\":\"string\",\"cur\":\"\\u901a\\u7528\",\"default\":\"\\u901a\\u7528\",\"size\":40,\"range\":[\"\\u901a\\u7528\",\"\\u53d1\\u7968\\u7eb8\"],\"depend_or\":[\"is-discard-blank==true\"]},\"blank-sensitivity\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":202,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u8df3\\u8fc7\\u7a7a\\u767d\\u9875\\u7075\\u654f\\u5ea6\",\"desc\":\"\\u6570\\u503c\\u8d8a\\u5927\\uFF0C\\u5219\\u8d8a\\u5bb9\\u6613\\u8df3\\u8fc7\",\"type\":\"int\",\"cur\":50,\"default\":50,\"size\":4,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend_or\":[\"is-discard-blank==true\"]},\"blank-threshold\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":210,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u8f6e\\u5ed3\\u9608\\u503c\",\"desc\":\"\\u8f6e\\u5ed3\\u9608\\u503c\",\"type\":\"int\",\"cur\":40,\"default\":40,\"size\":4,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend_or\":[\"is-discard-blank==true\"]},\"blank-indent\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":211,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7a\\u767d\\u9875\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"desc\":\"\\u7a7a\\u767d\\u9875\\u8fb9\\u7f18\\u7f29\\u8fdb\",\"type\":\"int\",\"cur\":30,\"default\":30,\"size\":4,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend_or\":[\"is-discard-blank==true\"]},\"blank-bg-clr\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":212,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u80cc\\u666f\\u8272\\u9608\\u503c\",\"desc\":\"\\u4f4e\\u4e8e\\u8be5\\u503c\\uFF0C\\u88ab\\u89c6\\u4f5c\\u80cc\\u666f\\u989c\\u8272\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":{\"min\":1,\"max\":255,\"step\":1},\"depend_or\":[\"is-discard-blank==true\"]},\"blank-noise\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":213,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7eb8\\u5f20\\u6742\\u70b9\",\"desc\":\"\\u5ffd\\u7565\\u7eb8\\u5f20\\u6742\\u70b9\\u3002\\u22641\\u65f6\\u4e0d\\u751f\\u6548\\uFF0C\\u503c\\u8d8a\\u5927\\u8d8a\\u5bb9\\u6613\\u5ffd\\u7565\\u6742\\u70b9\",\"type\":\"int\",\"cur\":11,\"default\":11,\"size\":4,\"range\":{\"min\":1,\"max\":100,\"step\":1},\"depend_or\":[\"is-discard-blank==true\"]}}"; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_algs +discard_blank::discard_blank() : root_(new gb_json()) + , name_("is-discard-blank"), pos_(0), ver_(0), enable_(false) + , threshold_(40), indent_(30), stroke_(50), bg_clr_(200), noise_(11), universal_(true) +{ + root_->attach_text(&discard_blank_jsn[0]); + init_value_from_json(); +} +discard_blank::~discard_blank() +{ + root_->release(); +} + +void discard_blank::init_value_from_json(void) +{ + gb_json* child = nullptr; + + if(root_->get_value(name_.c_str(), child) && child) + { + int val = 0; + child->get_value("cur", enable_); + child->get_value("ver", val); + ver_ = val; + child->get_value("pos", val); + pos_ = val; + + child->release(); + } + if(root_->get_value("discard-blank", child) && child) + { + std::string val(""); + child->get_value("cur", val); + universal_ = val != "\xE5\x8F\x91\xE7\xA5\xA8\xE7\xBA\xB8"; + child->release(); + } + if(root_->get_value("blank-sensitivity", child) && child) + { + child->get_value("cur", stroke_); + child->release(); + } + + if(root_->get_value("blank-threshold", child) && child) + { + child->get_value("cur", threshold_); + child->release(); + } + if(root_->get_value("blank-indent", child) && child) + { + child->get_value("cur", indent_); + child->release(); + } + if(root_->get_value("blank-bg-clr", child) && child) + { + child->get_value("cur", bg_clr_); + child->release(); + } + if(root_->get_value("blank-noise", child) && child) + { + child->get_value("cur", noise_); + child->release(); + } +} + +int32_t discard_blank::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + { + return inner_get_config(root_, buf, len, cfg_name, strval); + } + else + { + if(!len) + return EINVAL; + + std::string val(root_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + + return ENOMEM; + } + + strcpy((char*)buf, val.c_str()); + *len = val.length(); + } + + return 0; +} +int32_t discard_blank::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(root_->get_value(cfg_name, child) && child) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + init_value_from_json(); + if(strcmp(cfg_name, "discard-blank") == 0) + { + noise_ = universal_ ? 200 : 150; + } + + if(afterdo) + { + int val = 0; + child->get_value("affect", val); + *afterdo = val; + } + + child->release(); + } + + return ret; +} +void discard_blank::update_enabled(std::function get_opt) +{ + gb_json* child = root_->first_child(); + while(child) + { + sane_cfg_provider::update_option_enable_status(child, get_opt); + child->release(); + child = root_->next_child(); + } +} +int32_t discard_blank::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) +{ + int32_t ret = ENOENT; + gb_json* child = nullptr; + + if(root_->get_value(name, child) && child) + { + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; + child->release(); + } + + return ret; +} + +img_one_paper* discard_blank::execute(img_one_paper* img) +{ + int val = universal_ ? stroke_ : stroke_ * 1.5f + .5f; + + if(enable_) + { + for(auto& v : img->images_queue()) + { + if(CImageApplyDiscardBlank::apply(v.img, threshold_, indent_, val, bg_clr_, noise_)) + v.head.pos.status |= IMG_STATUS_BLANK; + } + } + img->add_ref(); + + return img; +} +bool discard_blank::is_enabled(std::function get_opt_value) +{ + return enable_; +} + +uint32_t discard_blank::position(void) +{ + return pos_; +} +uint32_t discard_blank::version(void) +{ + return ver_; +} +const char* discard_blank::option_name(void) +{ + return name_.c_str(); +} + + diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.h b/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.h new file mode 100644 index 0000000..5200a35 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/discard_blank.h @@ -0,0 +1,199 @@ +#pragma once + +// discard_blank algorithm +// +// created on 2023-04-23 +// + +#include "img_algorithm.h" + + + +// { +// "is-discard-blank": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "affect": 2, +// "pos": 200, +// "unit": "none", +// "ver": 1, +// "title": "跳过空白页", +// "desc": "如果检测到图像为空白,则丢弃", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "discard-blank": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 201, +// "unit": "none", +// "ver": 1, +// "title": "跳过空白页类型", +// "desc": "通用和发票,其中之一", +// "type": "string", +// "cur": "通用", +// "default": "通用", +// "size": 40, +// "range": ["通用", "发票纸"], +// "depend_or": ["is-discard-blank==true"] +// }, +// "blank-sensitivity": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 202, +// "unit": "none", +// "ver": 1, +// "title": "跳过空白页灵敏度", +// "desc": "数值越大,则越容易跳过", +// "type": "int", +// "cur": 50, +// "default": 50, +// "size": 4, +// "range": { +// "min": 1, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-discard-blank==true"] +// }, +// "blank-threshold": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 210, +// "unit": "none", +// "ver": 1, +// "title": "轮廓阈值", +// "desc": "轮廓阈值", +// "type": "int", +// "cur": 40, +// "default": 40, +// "size": 4, +// "range": { +// "min": 1, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-discard-blank==true"] +// }, +// "blank-indent": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 211, +// "unit": "none", +// "ver": 1, +// "title": "空白页边缘缩进", +// "desc": "空白页边缘缩进", +// "type": "int", +// "cur": 30, +// "default": 30, +// "size": 4, +// "range": { +// "min": 1, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-discard-blank==true"] +// }, +// "blank-bg-clr": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 212, +// "unit": "none", +// "ver": 1, +// "title": "背景色阈值", +// "desc": "低于该值,被视作背景颜色", +// "type": "int", +// "cur": 200, +// "default": 200, +// "size": 4, +// "range": { +// "min": 1, +// "max": 255, +// "step": 1 +// }, +// "depend_or": ["is-discard-blank==true"] +// }, +// "blank-noise": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 213, +// "unit": "none", +// "ver": 1, +// "title": "纸张杂点", +// "desc": "忽略纸张杂点。≤1时不生效,值越大越容易忽略杂点", +// "type": "int", +// "cur": 11, +// "default": 11, +// "size": 4, +// "range": { +// "min": 1, +// "max": 100, +// "step": 1 +// }, +// "depend_or": ["is-discard-blank==true"] +// } +// } + + +class gb_json; + +class discard_blank : public img_alg +{ + gb_json* root_; + + std::string name_; + uint32_t pos_; + uint32_t ver_; + bool enable_; + + int threshold_; + int indent_; + int stroke_; // sensitivity + int bg_clr_; + int noise_; + bool universal_; + + void init_value_from_json(void); + +public: + discard_blank(void); +protected: + ~discard_blank(); + +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; + +public: + img_one_paper* execute(img_one_paper* img) override; + bool is_enabled(std::function get_opt_value) override; + + uint32_t position(void) override; + uint32_t version(void) override; + const char* option_name(void) override; +}; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp index 3ce2341..65fb172 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.cpp @@ -140,7 +140,7 @@ int32_t dogear::set_config(const char* cfg_name, void* data, size_t* len, uint32 return ret; } -void dogear::update_enabled(std::function get_opt) +void dogear::update_enabled(std::function get_opt) { gb_json* child = root_->first_child(); while(child) @@ -150,14 +150,14 @@ void dogear::update_enabled(std::functionnext_child(); } } -int32_t dogear::get_value(const char* name, const char* key, std::string& val) +int32_t dogear::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { int32_t ret = ENOENT; gb_json* child = nullptr; if(root_->get_value(name, child) && child) { - ret = sane_cfg_provider::raw_value_in_json(child, key, val) ? 0 : ENOENT; + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; child->release(); } diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h index 0d5692e..968655f 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/dogear.h @@ -176,8 +176,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: img_one_paper* execute(img_one_paper* img) override; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp index df10937..0f9e594 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.cpp @@ -1,12 +1,16 @@ #include "img_algorithm.h" - -#include "dogear.h" #include "common/json/gb_json.h" #include "../capimage/hgutils.h" +#include "dogear.h" +#include "remove_hole.h" +#include "discard_blank.h" +#include "auto_crop.h" + #ifdef TEMPORARY_API extern int32_t (*set_dpi)(int*, int*); +extern int32_t (*set_pixel_type)(int*); #endif ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -95,6 +99,15 @@ img_alg* img_alg::create_image_algorithm(img_alg_type type) return dynamic_cast(new img_resizer()); if(type == IMG_ALG_ADJUST_COLOR) return dynamic_cast(new color_correct()); + if(type == IMG_ALG_REMOVE_HOLE) + return dynamic_cast(new rm_hole()); + if(type == IMG_ALG_DISCARD_BLANK) + return dynamic_cast(new discard_blank()); + if(type == IMG_ALG_COLOR_TRANSFER) + return dynamic_cast(new img_color_transfer()); + // if(type == IMG_ALG_AUTO_CROP) + // return dynamic_cast(new auto_crop()); + return nullptr; } @@ -117,7 +130,7 @@ const char* img_alg::option_name(void) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class img_resizer +// class color_correct // { // "color-correct": { // "category": "base", @@ -125,7 +138,7 @@ const char* img_alg::option_name(void) // "visible": true, // "field": "imgproc", // "group": "imgproc", -// "pos": 100, +// "pos": 400, // "unit": "none", // "ver": 1, // "title": "颜色校正", @@ -138,7 +151,7 @@ const char* img_alg::option_name(void) // } // } static std::string color_correct_json = - "{\"color-correct\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":100,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u989c\\u8272\\u6821\\u6b63\",\"desc\":\"\\u6821\\u6b63\\u7531\\u4e8e\\u786c\\u4ef6\\u7279\\u6027\\u4ea7\\u751f\\u7684\\u8272\\u504f\\uFF0C\\u4f7f\\u56fe\\u7247\\u989c\\u8272\\u66f4\\u63a5\\u8fd1\\u771f\\u5b9e\",\"type\":\"string\",\"cur\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"default\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"size\":20,\"range\":[\"\\u4e0d\\u6821\\u6b63\",\"\\u666e\\u901a\\u6a21\\u5f0f\",\"\\u589e\\u5f3a\\u6a21\\u5f0f\"]}}"; + "{\"color-correct\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":400,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u989c\\u8272\\u6821\\u6b63\",\"desc\":\"\\u6821\\u6b63\\u7531\\u4e8e\\u786c\\u4ef6\\u7279\\u6027\\u4ea7\\u751f\\u7684\\u8272\\u504f\\uFF0C\\u4f7f\\u56fe\\u7247\\u989c\\u8272\\u66f4\\u63a5\\u8fd1\\u771f\\u5b9e\",\"type\":\"string\",\"cur\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"default\":\"\\u666e\\u901a\\u6a21\\u5f0f\",\"size\":20,\"range\":[\"\\u4e0d\\u6821\\u6b63\",\"\\u666e\\u901a\\u6a21\\u5f0f\",\"\\u589e\\u5f3a\\u6a21\\u5f0f\"]}}"; color_correct::color_correct() : enable_(true), enhance_(false) { @@ -201,28 +214,22 @@ int32_t color_correct::set_config(const char* cfg_name, void* data, size_t* len, if(cfg_->get_value(cfg_name, child) && child) { sane_cfg_provider::sane_refine_range(child, data, len); - if(name_ == cfg_name) - { - std::string val((char*)data); - - on_cur_val_changed(val); - child->set_value("cur", val.c_str()); - child->release(); - } + sane_cfg_provider::sane_option_value_set(child, data); + child->release(); } return ret; } -void color_correct::update_enabled(std::function get_opt) +void color_correct::update_enabled(std::function get_opt) {} -int32_t color_correct::get_value(const char* name, const char* key, std::string& val) +int32_t color_correct::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { gb_json *child = nullptr; int32_t ret = ENOENT; if(cfg_->get_value(name, child) && child) { - sane_cfg_provider::raw_value_in_json(child, key, val); + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; child->release(); } @@ -276,7 +283,7 @@ bool color_correct::is_enabled(std::functionset_value("cur", dpi_); - child->release(); int x = *(int*)data, y = x; set_dpi(&x, &y); enable_ = x != dpi_ || y != dpi_; } + child->release(); } return ret; } -void img_resizer::update_enabled(std::function get_opt) +void img_resizer::update_enabled(std::function get_opt) {} -int32_t img_resizer::get_value(const char* name, const char* key, std::string& val) +int32_t img_resizer::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { gb_json *child = nullptr; int32_t ret = ENOENT; if(cfg_->get_value(name, child) && child) { - sane_cfg_provider::raw_value_in_json(child, key, val); + if(sane_cfg_provider::raw_value_in_json(child, key, val, type)) + ret = 0; child->release(); } @@ -384,13 +392,147 @@ bool img_resizer::is_enabled(std::function +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_color_transfer +// { +// "mode": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "base", +// "pos": 500, +// "unit": "none", +// "affect": 6, +// "ver": 1, +// "title": "颜色模式", +// "desc": "选择色彩模式", +// "type": "string", +// "cur": "24位彩色", +// "default": "24位彩色", +// "size": 32, +// "range": ["24位彩色", "256级灰度", "黑白", "颜色自动识别"] +// } +// } +static std::string color_mode_json = + "{\"mode\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"base\",\"pos\":500,\"unit\":\"none\",\"affect\":6,\"ver\":1,\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"size\":32,\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"]}}"; + +img_color_transfer::img_color_transfer() : enable_(false) +{ + name_ = "mode"; + cfg_ = new gb_json(); + cfg_->attach_text(&color_mode_json[0]); + + gb_json* child = nullptr; + + if(cfg_->get_value(name_.c_str(), child) && child) + { + std::string val(""); + + child->get_value("cur", val); + child->get_value("ver", ver_); + child->get_value("pos", pos_); + check_enable(val.c_str()); + child->release(); + } +} +img_color_transfer::~img_color_transfer() +{ + cfg_->release(); +} + +void img_color_transfer::check_enable(const char* val) +{ + enable_ = strcmp(val, "\xE9\xA2\x9C\xE8\x89\xB2\xE8\x87\xAA\xE5\x8A\xA8\xE8\xAF\x86\xE5\x88\xAB") == 0; +} + +int32_t img_color_transfer::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + return inner_get_config(cfg_, buf, len, cfg_name, strval); + else + { + std::string val(cfg_->to_string()); + + if(strval) + *strval = val; + if(*len < val.length()) + { + *len = val.length() + 4; + + return ENOMEM; + } + + memcpy(buf, val.c_str(), val.length()); + *len = val.length(); + + return 0; + } +} +int32_t img_color_transfer::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(cfg_name, child) && child) + { + int mode = COLOR_MODE_RGB; + + sane_cfg_provider::sane_refine_range(child, data, len); + sane_cfg_provider::sane_option_value_set(child, data); + if(strcmp((char*)data, "\xE9\xBB\x91\xE7\x99\xBD") == 0) + mode = COLOR_MODE_BW; + else if(strcmp((char*)data, "256\xE7\xBA\xA7\xE7\x81\xB0\xE5\xBA\xA6") == 0) + mode = COLOR_MODE_GRAY; + set_pixel_type(&mode); + check_enable((char*)data); + child->release(); + } + + return ret; +} +void img_color_transfer::update_enabled(std::function get_opt) +{} +int32_t img_color_transfer::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) +{ + gb_json *child = nullptr; + int32_t ret = ENOENT; + + if(cfg_->get_value(name, child) && child) + { + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; + child->release(); + } + + return ret; +} +img_one_paper* img_color_transfer::execute(img_one_paper* img) +{ + if(enable_) + { + // for(auto& v: img->images_queue()) + // { + // } + } + img->add_ref(); + + return img; +} +bool img_color_transfer::is_enabled(std::function get_opt_value) +{ + return enable_; +} + + + + ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -// class img_alg +// class img_encoder // { // "img-format": { // "category": "base", -// "readonly": true, +// "readonly": false, // "affect": 0, // "group": "output", // "visible": true, @@ -408,7 +550,7 @@ bool img_resizer::is_enabled(std::function // } // } static std::string fmt_json = - "{\"img-format\":{\"category\":\"base\",\"readonly\":true,\"affect\":0,\"group\":\"output\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fe\\u7247\\u683c\\u5f0f\",\"desc\":\"\\u8bbe\\u5907\\u8f93\\u51fa\\u7684\\u56fe\\u7247\\u6587\\u4ef6\\u683c\\u5f0f\",\"type\":\"string\",\"cur\":\"JPEG\",\"default\":\"JPEG\",\"size\":20,\"ver\":1,\"range\":[\"JPEG\",\"PNG\",\"TIFF\"]}}"; + "{\"img-format\":{\"category\":\"base\",\"readonly\":false,\"affect\":0,\"group\":\"output\",\"visible\":true,\"field\":\"Common\",\"pos\":0,\"unit\":\"None\",\"title\":\"\\u56fe\\u7247\\u683c\\u5f0f\",\"desc\":\"\\u8bbe\\u5907\\u8f93\\u51fa\\u7684\\u56fe\\u7247\\u6587\\u4ef6\\u683c\\u5f0f\",\"type\":\"string\",\"cur\":\"JPEG\",\"default\":\"JPEG\",\"size\":20,\"ver\":1,\"range\":[\"JPEG\",\"PNG\",\"TIFF\"]}}"; img_encoder::img_encoder() : fmt_("JPEG") { @@ -477,18 +619,18 @@ int32_t img_encoder::set_config(const char* cfg_name, void* data, size_t* len, u return ret; } -void img_encoder::update_enabled(std::function get_opt) +void img_encoder::update_enabled(std::function get_opt) {} -int32_t img_encoder::get_value(const char* name, const char* key, std::string& val) +int32_t img_encoder::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { gb_json* child = nullptr; int32_t ret = ENOENT; if(cfg_->get_value(name, child) && child) { - val = std::move(sane_cfg_provider::sane_option_value_get(child, key)); + if(sane_cfg_provider::raw_value_in_json(child, key, val, type)) + ret = 0; child->release(); - ret = val.empty() ? ENOENT : 0; } return ret; diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h index 5d74563..1fb866c 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/img_algorithm.h @@ -64,9 +64,10 @@ enum img_alg_type IMG_ALG_NONE = 0, IMG_ALG_DOGEAR, IMG_ALG_SIZE_CHECK, - IMG_ALG_FILL_HOLE, + IMG_ALG_REMOVE_HOLE, + IMG_ALG_DISCARD_BLANK, IMG_ALG_AUTO_CROP, - IMG_ALG_BLANK, + IMG_ALG_COLOR_TRANSFER, IMG_ALG_CUSTOM_AREA, IMG_ALG_FADE_BACK, IMG_ALG_FILTER, @@ -126,8 +127,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: virtual img_one_paper* execute(img_one_paper* img) override; @@ -149,8 +150,32 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; + +public: + virtual img_one_paper* execute(img_one_paper* img) override; + virtual bool is_enabled(std::function get_opt_value) override; +}; + + +class img_color_transfer : public img_alg +{ + gb_json* cfg_; + bool enable_; + + void check_enable(const char* val); + +public: + img_color_transfer(); +protected: + ~img_color_transfer(); + +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: virtual img_one_paper* execute(img_one_paper* img) override; @@ -171,8 +196,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: MemoryPtr encode(PROCIMG* img); diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.cpp b/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.cpp new file mode 100644 index 0000000..d25ed1f --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.cpp @@ -0,0 +1,199 @@ +#include "remove_hole.h" + + +#include "common/json/gb_json.h" +#include "imageprocess/ImageApplyOutHole.h" + + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// + + + +static std::string remove_hole_jsn = + "{\"is-rid-hole-l\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"affect\":2,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":100,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u5de6\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u5de6\\u4fa7\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-l\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":101,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u5de6\\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\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-l==true\"]},\"is-rid-hole-r\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"affect\":2,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":110,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u53f3\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u4e0a\\u7684\\u53f3\\u4fa7\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-r\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":111,\"unit\":\"none\",\"ver\":1,\"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\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-r==true\"]},\"is-rid-hole-t\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"affect\":2,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":120,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0a\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0a\\u90e8\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-t\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":121,\"unit\":\"none\",\"ver\":1,\"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\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-t==true\"]},\"is-rid-hole-b\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"affect\":2,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":130,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u2014\\u4e0b\\u4fa7\",\"desc\":\"\\u7a7f\\u5b54\\u5728\\u7eb8\\u5f20\\u7684\\u4e0b\\u90e8\",\"type\":\"bool\",\"cur\":false,\"default\":false,\"size\":4},\"search-hole-range-b\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":131,\"unit\":\"none\",\"ver\":1,\"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\",\"cur\":0.100000,\"default\":0.100000,\"size\":4,\"range\":{\"min\":0.000000,\"max\":0.500000,\"step\":0.050000},\"depend_and\":[\"is-rid-hole-b==true\"]},\"hole-side-len\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":140,\"unit\":\"pixel\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u8fb9\\u957f\\u9608\\u503c\",\"desc\":\"\\u7a7f\\u5b54\\u8fb9\\u957f\\u8d85\\u51fa\\u8be5\\u9608\\u503c\\u65f6\\uFF0C\\u5c06\\u88ab\\u79fb\\u9664\",\"type\":\"float\",\"cur\":25.0,\"default\":25.0,\"size\":4,\"range\":{\"min\":10.0,\"max\":50.0,\"step\":5}},\"hole-bin-threshold\":{\"category\":\"base\",\"readonly\":false,\"visible\":false,\"field\":\"imgproc\",\"group\":\"imgproc\",\"pos\":141,\"unit\":\"none\",\"ver\":1,\"title\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u4e2d\\uFF0C\\u4e8c\\u503c\\u5316\\u56fe\\u50cf\\u7684\\u9608\\u503c\",\"desc\":\"\\u7a7f\\u5b54\\u79fb\\u9664\\u7b97\\u6cd5\\u4e2d\\uFF0C\\u4e8c\\u503c\\u5316\\u56fe\\u50cf\\u65f6\\uFF0C\\u91c7\\u7528\\u7684\\u9608\\u503c\",\"type\":\"int\",\"cur\":50,\"default\":50,\"size\":4,\"range\":{\"min\":0,\"max\":255,\"step\":1}}}"; + +///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// class img_algs +rm_hole::rm_hole() : holer_(nullptr), root_(new gb_json()) + , name_("is-rid-hole-l"), pos_(0), ver_(0), enable_(true) + , hole_side_len_(25.0f), percent_l_(.0f), percent_r_(.0f), percent_t_(.0f), percent_b_(.0f), bin_threshold_(50) +{ + gb_json* child = nullptr; + root_->attach_text(&remove_hole_jsn[0]); + + init_value_from_json(); + if(root_->get_value(name_.c_str(), child) && child) + { + int val = 0; + child->get_value("ver", val); + ver_ = val; + child->get_value("pos", val); + pos_ = val; + child->release(); + } + holer_ = new CImageApplyOutHole(hole_side_len_, {(float)percent_t_, (float)percent_b_, (float)percent_l_, (float)percent_r_}, bin_threshold_); +} +rm_hole::~rm_hole() +{ + root_->release(); + if(holer_) + delete holer_; +} + +void rm_hole::init_value_from_json(void) +{ + gb_json* child = nullptr, *childv = nullptr; + bool enable = true; + +#define GET_SIDE(s) \ + if(root_->get_value(MAKE_STR(is-rid-hole\x2d##s), child) && child) \ + { \ + if(child->get_value("cur", enable)) \ + { \ + if(enable) \ + { \ + if(root_->get_value(MAKE_STR(search-hole-range\x2d##s), childv) && childv) \ + { \ + childv->get_value("cur", percent_##s##_); \ + childv->release(); \ + } \ + } \ + else \ + percent_##s##_ = .0f; \ + } \ + child->release(); \ + } \ + enable_ |= enable; + + GET_SIDE(l); + GET_SIDE(r); + GET_SIDE(t); + GET_SIDE(b); + + if(root_->get_value("hole-side-len", child) && child) + { + child->get_value("cur", hole_side_len_); + child->release(); + } + + if(root_->get_value("hole-bin-threshold", child) && child) + { + child->get_value("cur", bin_threshold_); + child->release(); + } +} + +int32_t rm_hole::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) +{ + if(cfg_name) + { + return inner_get_config(root_, buf, len, cfg_name, strval); + } + else + { + if(!len) + return EINVAL; + + std::string val(root_->to_string()); + + if(*len < val.length()) + { + *len = val.length() + 4; + + return ENOMEM; + } + + strcpy((char*)buf, val.c_str()); + *len = val.length(); + } + + return 0; +} +int32_t rm_hole::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) +{ + gb_json* child = nullptr; + int32_t ret = ENOENT; + + if(root_->get_value(cfg_name, child) && child) + { + ret = sane_cfg_provider::sane_refine_range(child, data, len) ? 0 : EUCLEAN; + sane_cfg_provider::sane_option_value_set(child, data); + + if(afterdo) + { + int val = 0; + + child->get_value("affect", val); + *afterdo = val; + } + + child->release(); + init_value_from_json(); + } + + return ret; +} +void rm_hole::update_enabled(std::function get_opt) +{ + gb_json* child = root_->first_child(); + while(child) + { + sane_cfg_provider::update_option_enable_status(child, get_opt); + child->release(); + child = root_->next_child(); + } +} +int32_t rm_hole::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) +{ + int32_t ret = ENOENT; + gb_json* child = nullptr; + + if(root_->get_value(name, child) && child) + { + ret = sane_cfg_provider::raw_value_in_json(child, key, val, type) ? 0 : ENOENT; + child->release(); + } + + return ret; +} + +img_one_paper* rm_hole::execute(img_one_paper* img) +{ + if(enable_) + { + std::vector imgs; + + for(auto& v: img->images_queue()) + imgs.push_back(v.img); + + holer_->set_parameters(hole_side_len_, {(float)percent_t_, (float)percent_b_, (float)percent_l_, (float)percent_r_}, bin_threshold_); + holer_->apply(imgs, true); + + for(size_t i = 0; i < img->images_queue().size() && i < imgs.size(); ++i) + img->images_queue()[i].img = imgs[i]; + } + + img->add_ref(); + + return img; +} +bool rm_hole::is_enabled(std::function get_opt_value) +{ + return enable_; +} + +uint32_t rm_hole::position(void) +{ + return pos_; +} +uint32_t rm_hole::version(void) +{ + return ver_; +} +const char* rm_hole::option_name(void) +{ + return name_.c_str(); +} + + diff --git a/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.h b/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.h new file mode 100644 index 0000000..e188610 --- /dev/null +++ b/device/gxx-linux/usb/src/async_model/img_process/algs/remove_hole.h @@ -0,0 +1,253 @@ +#pragma once + +// remove hole algorithm +// +// created on 2023-05-02 +// + +#include "img_algorithm.h" + + + +// { +// "is-rid-hole-l": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "affect": 2, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 100, +// "unit": "none", +// "ver": 1, +// "title": "穿孔移除—左侧", +// "desc": "穿孔在纸张上的左侧", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "search-hole-range-l": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 101, +// "unit": "none", +// "ver": 1, +// "title": "左侧穿孔搜索范围占幅面比例", +// "desc": "穿孔搜索范围占幅面比例", +// "type": "float", +// "cur": 0.100000, +// "default": 0.100000, +// "size": 4, +// "range": { +// "min": 0.000000, +// "max": 0.500000, +// "step": 0.050000 +// }, +// "depend_and": ["is-rid-hole-l==true"] +// }, +// "is-rid-hole-r": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "affect": 2, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 110, +// "unit": "none", +// "ver": 1, +// "title": "穿孔移除—右侧", +// "desc": "穿孔在纸张上的右侧", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "search-hole-range-r": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 111, +// "unit": "none", +// "ver": 1, +// "title": "右侧穿孔搜索范围占幅面比例", +// "desc": "穿孔搜索范围占幅面比例", +// "type": "float", +// "cur": 0.100000, +// "default": 0.100000, +// "size": 4, +// "range": { +// "min": 0.000000, +// "max": 0.500000, +// "step": 0.050000 +// }, +// "depend_and": ["is-rid-hole-r==true"] +// }, +// "is-rid-hole-t": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "affect": 2, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 120, +// "unit": "none", +// "ver": 1, +// "title": "穿孔移除—上侧", +// "desc": "穿孔在纸张的上部", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "search-hole-range-t": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 121, +// "unit": "none", +// "ver": 1, +// "title": "上侧穿孔搜索范围占幅面比例", +// "desc": "穿孔搜索范围占幅面比例", +// "type": "float", +// "cur": 0.100000, +// "default": 0.100000, +// "size": 4, +// "range": { +// "min": 0.000000, +// "max": 0.500000, +// "step": 0.050000 +// }, +// "depend_and": ["is-rid-hole-t==true"] +// }, +// "is-rid-hole-b": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "affect": 2, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 130, +// "unit": "none", +// "ver": 1, +// "title": "穿孔移除—下侧", +// "desc": "穿孔在纸张的下部", +// "type": "bool", +// "cur": false, +// "default": false, +// "size": 4 +// }, +// "search-hole-range-b": { +// "category": "base", +// "readonly": false, +// "visible": true, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 131, +// "unit": "none", +// "ver": 1, +// "title": "下侧穿孔搜索范围占幅面比例", +// "desc": "穿孔搜索范围占幅面比例", +// "type": "float", +// "cur": 0.100000, +// "default": 0.100000, +// "size": 4, +// "range": { +// "min": 0.000000, +// "max": 0.500000, +// "step": 0.050000 +// }, +// "depend_and": ["is-rid-hole-b==true"] +// }, +// "hole-side-len": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 140, +// "unit": "pixel", +// "ver": 1, +// "title": "穿孔边长阈值", +// "desc": "穿孔边长超出该阈值时,将被移除", +// "type": "float", +// "cur": 25.0, +// "default": 25.0, +// "size": 4, +// "range": { +// "min": 10.0, +// "max": 50.0, +// "step": 5 +// } +// }, +// "hole-bin-threshold": { +// "category": "base", +// "readonly": false, +// "visible": false, +// "field": "imgproc", +// "group": "imgproc", +// "pos": 141, +// "unit": "none", +// "ver": 1, +// "title": "穿孔移除中,二值化图像的阈值", +// "desc": "穿孔移除算法中,二值化图像时,采用的阈值", +// "type": "int", +// "cur": 50, +// "default": 50, +// "size": 4, +// "range": { +// "min": 0, +// "max": 255, +// "step": 1 +// } +// } +// } + +class CImageApplyOutHole; +class gb_json; + +class rm_hole : public img_alg +{ + CImageApplyOutHole* holer_; + gb_json* root_; + + std::string name_; + uint32_t pos_; + uint32_t ver_; + bool enable_; + + double hole_side_len_; // side length threshold, [10.0, 50.0], default 25.0 + double percent_l_; // percentage of the left side, [0.0, 0.5], default 0.0 + double percent_r_; // percentage of the right side, [0.0, 0.5], default 0.0 + double percent_t_; // percentage of the top side, [0.0, 0.5], default 0.0 + double percent_b_; // percentage of the bottom side, [0.0, 0.5], default 0.0 + int bin_threshold_; // binary threshold, [0, 255], default 50 + + void init_value_from_json(void); + +public: + rm_hole(void); +protected: + ~rm_hole(); + +public: + virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; + virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; + +public: + img_one_paper* execute(img_one_paper* img) override; + bool is_enabled(std::function get_opt_value) override; + + uint32_t position(void) override; + uint32_t version(void) override; + const char* option_name(void) override; +}; diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp index 82ec64a..57425ba 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp @@ -195,7 +195,7 @@ int32_t cis_pre_do::set_config(const char* cfg_name, void* data, size_t* len, ui return ret; } -void cis_pre_do::update_enabled(std::function get_opt) +void cis_pre_do::update_enabled(std::function get_opt) { gb_json* root = new gb_json(); @@ -207,7 +207,7 @@ void cis_pre_do::update_enabled(std::functionrelease(); } -int32_t cis_pre_do::get_value(const char* name, const char* key, std::string& val) +int32_t cis_pre_do::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { gb_json* root = new gb_json(), *child = nullptr; int32_t ret = ENOENT; @@ -216,7 +216,7 @@ int32_t cis_pre_do::get_value(const char* name, const char* key, std::string& va { if(root->get_value(name, child) && child) { - if(sane_cfg_provider::raw_value_in_json(child, key, val)) + if(sane_cfg_provider::raw_value_in_json(child, key, val, type)) ret = 0; child->release(); } diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h index 5d6cb0f..6689978 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h @@ -32,8 +32,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: img_one_paper* execute(img_one_paper* img); diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp index 0e570e3..dec958d 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp @@ -102,10 +102,11 @@ void img_processor::load_processors(void) CREATE_ALG(IMG_ALG_DOGEAR); CREATE_ALG(IMG_ALG_SIZE_CHECK); - CREATE_ALG(IMG_ALG_FILL_HOLE); + CREATE_ALG(IMG_ALG_REMOVE_HOLE); CREATE_ALG(IMG_ALG_AUTO_CROP); - CREATE_ALG(IMG_ALG_BLANK); + CREATE_ALG(IMG_ALG_DISCARD_BLANK); CREATE_ALG(IMG_ALG_CUSTOM_AREA); + CREATE_ALG(IMG_ALG_COLOR_TRANSFER); CREATE_ALG(IMG_ALG_FADE_BACK); CREATE_ALG(IMG_ALG_FILTER); CREATE_ALG(IMG_ALG_ADJUST_COLOR); @@ -314,7 +315,7 @@ int32_t img_processor::set_config(const char* cfg_name, void* data, size_t* len, return ret; } -void img_processor::update_enabled(std::function get_opt) +void img_processor::update_enabled(std::function get_opt) { // sane_cfg_provider::update_option_enable_status(cfg_, get_opt); cis_pre_->update_enabled(get_opt); @@ -325,18 +326,18 @@ void img_processor::update_enabled(std::functionupdate_enabled(get_opt); } -int32_t img_processor::get_value(const char* name, const char* key, std::string& val) +int32_t img_processor::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { - int32_t ret = cis_pre_->get_value(name, key, val); + int32_t ret = cis_pre_->get_raw_value(name, key, val, type); if(ret == ENOENT) { - ret = encoder_->get_value(name, key, val); + ret = encoder_->get_raw_value(name, key, val, type); if(ret == ENOENT) { for(auto& v: all_proc_) { - ret = v->get_value(name, key, val); + ret = v->get_raw_value(name, key, val, type); if(ret != ENOENT) break; } diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.h b/device/gxx-linux/usb/src/async_model/img_process/img_process.h index e4f42a1..d4fcd78 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/img_process.h +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.h @@ -62,8 +62,8 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; public: int32_t push_image(img_one_paper* img/*scan status if 'over' was true*/, bool over = false); diff --git a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp index d075ae2..d3f2398 100644 --- a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp +++ b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp @@ -324,7 +324,7 @@ dyn_mem_ptr async_scanner::handle_get_opt_value(LPPACK_BASE pack, uint32_t* used uint32_t err = cfg_mgr_->get_config(val, pack->payload, &str); LPCFGVAL cfg = nullptr; - log_cls::log(LOG_LEVEL_ALL, "Option '%s' value: %s\n", pack->payload, str.c_str()); + // log_cls::log(LOG_LEVEL_ALL, "Option '%s' value: %s\n", pack->payload, str.c_str()); reply = dyn_mem::memory(base_head_size + sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1); pk = (LPPACK_BASE)reply->ptr(); BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); @@ -807,7 +807,7 @@ uint32_t async_scanner::stop(void) // return ret; // } -// void async_scanner::update_enabled(std::function get_opt) +// void async_scanner::update_enabled(std::function get_opt) // { // gb_json *jsn = new gb_json(); // int32_t ret = EINVAL; diff --git a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h index b11bd41..303610f 100644 --- a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h +++ b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.h @@ -56,7 +56,7 @@ public: // virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; // virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - // virtual void update_enabled(std::function get_opt) override; + // virtual void update_enabled(std::function get_opt) override; // virtual int32_t get_value(const char* name, const char* key, std::string& val) override; void push_image(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over); diff --git a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp index b95ebca..d358f13 100644 --- a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp +++ b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.cpp @@ -96,16 +96,16 @@ int32_t readonly_cfg::set_config(const char* cfg_name, void* data, size_t* len, // read-only attributes not support this operation !!! return EINVAL; } -void readonly_cfg::update_enabled(std::function get_opt) +void readonly_cfg::update_enabled(std::function get_opt) {} -int32_t readonly_cfg::get_value(const char* name, const char* key, std::string& val) +int32_t readonly_cfg::get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type) { int32_t ret = ENOENT; gb_json* child = nullptr; if(jsn_->get_value(name, child) && child) { - if(sane_cfg_provider::raw_value_in_json(child, key, val)) + if(sane_cfg_provider::raw_value_in_json(child, key, val, type)) ret = 0; child->release(); diff --git a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h index a32a5c6..e033ba9 100644 --- a/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h +++ b/device/gxx-linux/usb/src/async_model/scanner/readonly_opts.h @@ -26,6 +26,6 @@ protected: public: virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) override; virtual int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override; - virtual void update_enabled(std::function get_opt) override; - virtual int32_t get_value(const char* name, const char* key, std::string& val) override; + virtual void update_enabled(std::function get_opt) override; + virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override; }; diff --git a/device/gxx-linux/usb/src/usbdevice.cpp b/device/gxx-linux/usb/src/usbdevice.cpp index 83cf57e..a6ec362 100644 --- a/device/gxx-linux/usb/src/usbdevice.cpp +++ b/device/gxx-linux/usb/src/usbdevice.cpp @@ -22,6 +22,8 @@ int32_t (*scan_start)(void) = nullptr; int32_t (*scan_stop)(void) = nullptr; int32_t (*set_dpi)(int*, int*) = nullptr; int32_t (*set_scan_num)(int) = nullptr; +int32_t (*set_paper_type)(int) = nullptr; +int32_t (*set_pixel_type)(int*) = nullptr; int32_t (*set_image_receiver)(void(*rcv)(int data_type, void* data, size_t w, size_t h, int, int, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param), void* param) = nullptr; #endif @@ -91,6 +93,14 @@ int32_t call_set_scan_num(int num) { return inst->set_scan_num(num); } +int32_t call_set_paper_type(int type) +{ + return inst->set_paper_type(type); +} +int32_t call_set_pixel_type(int *type) +{ + return inst->set_pixel_type(type); +} int32_t call_set_image_receiver(void(*rcv)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, void* param), void* param) { return inst->set_img_receiver((void*)rcv, param); @@ -364,6 +374,8 @@ UsbDevice::UsbDevice(std::function *t = new thread_pool(this); t->thread_new(&UsbDevice::do_system_command, R"(echo linaro | sudo -S sh -c "echo fe900000.dwc3 > /opt/cfg/usb_gadget/g1/UDC")"); @@ -1442,4 +1454,12 @@ int UsbDevice::set_img_receiver(void* api, void* param) return ctrl_handler(-1, (usb_ctrlrequest*)-1, (unsigned char*)cb) ? 0 : EBADF; } +int UsbDevice::set_paper_type(int type) +{ + return ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_PAPER, (unsigned char*)type) ? 0 : EBADF; +} +int UsbDevice::set_pixel_type(int *type) +{ + return ctrl_handler(-1, (usb_ctrlrequest*)SR_SCAN_PIXEL, (unsigned char*)*type) ? 0 : EBADF; +} #endif diff --git a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe index 39cc9be..466f705 100644 Binary files a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe and b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe differ diff --git a/pc/code_twain/sln/usb_tools/scanner/opt_ui/DlgPage.cpp b/pc/code_twain/sln/usb_tools/scanner/opt_ui/DlgPage.cpp index 6cb6040..3ce41b3 100644 --- a/pc/code_twain/sln/usb_tools/scanner/opt_ui/DlgPage.cpp +++ b/pc/code_twain/sln/usb_tools/scanner/opt_ui/DlgPage.cpp @@ -885,6 +885,12 @@ HWND dlg_page::create_control_bool(int sn, const SANE_Option_Descriptor* desc, v if (now) SendMessage(wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); + if (IS_CAP_READONLY(desc->cap)) + { + if (IsWindow(wnd)) + EnableWindow(wnd, FALSE); + } + return wnd; } HWND dlg_page::create_control_int(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) @@ -910,7 +916,7 @@ HWND dlg_page::create_control_int(int sn, const SANE_Option_Descriptor* desc, vo vals.push_back(text); } swprintf_s(text, _countof(text) - 1, L"%d", now); - wnd = create_combox(sn, x, pos_.y, vals, text, &size); + wnd = create_combox(sn, x, pos_.y - 1, vals, text, &size); x += size.cx; } else @@ -934,6 +940,18 @@ HWND dlg_page::create_control_int(int sn, const SANE_Option_Descriptor* desc, vo } text_size->cx = x + dlg_page::gap_x; + if (IS_CAP_READONLY(desc->cap)) + { + if (IsWindow(label)) + EnableWindow(label, FALSE); + if (IsWindow(slider)) + EnableWindow(slider, FALSE); + if (IsWindow(wnd)) + EnableWindow(wnd, FALSE); + if (IsWindow(spin)) + EnableWindow(spin, FALSE); + } + return wnd; } HWND dlg_page::create_control_float(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) @@ -961,7 +979,7 @@ HWND dlg_page::create_control_float(int sn, const SANE_Option_Descriptor* desc, if (v[i + 1] == *(SANE_Word*)cur_val) wcscpy_s(cur, _countof(cur) - 1, text); } - wnd = create_combox(sn, x, pos_.y, vals, cur, &size); + wnd = create_combox(sn, x, pos_.y - 1, vals, cur, &size); x += size.cx; } else @@ -985,15 +1003,27 @@ HWND dlg_page::create_control_float(int sn, const SANE_Option_Descriptor* desc, } text_size->cx = x + dlg_page::gap_x; + if (IS_CAP_READONLY(desc->cap)) + { + if (IsWindow(label)) + EnableWindow(label, FALSE); + if (IsWindow(slider)) + EnableWindow(slider, FALSE); + if (IsWindow(wnd)) + EnableWindow(wnd, FALSE); + if (IsWindow(spin)) + EnableWindow(spin, FALSE); + } + return wnd; } HWND dlg_page::create_control_string(int sn, const SANE_Option_Descriptor* desc, void* cur_val, const wchar_t* title, LPSIZE text_size) { - HWND wnd = NULL; + HWND wnd = NULL, lable = NULL; int x = pos_.x; std::wstring now(local_trans::a2u((char*)cur_val, CP_UTF8)); - create_label(sn, title, x, pos_.y, *text_size); + lable = create_label(sn, title, x, pos_.y, *text_size); x += text_size->cx + dlg_page::gap_x; if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) @@ -1007,7 +1037,7 @@ HWND dlg_page::create_control_string(int sn, const SANE_Option_Descriptor* desc, std::wstring text(local_trans::a2u(str[i], CP_UTF8)); vals.push_back(text); } - wnd = create_combox(sn, x, pos_.y, vals, now.c_str(), &size); + wnd = create_combox(sn, x, pos_.y - 1, vals, now.c_str(), &size); x += size.cx; } else @@ -1015,8 +1045,13 @@ HWND dlg_page::create_control_string(int sn, const SANE_Option_Descriptor* desc, wnd = create_edit(sn, x, pos_.y, text_size->cy, 200); SetWindowTextW(wnd, now.c_str()); x += 200; - if (IS_CAP_READONLY(desc->cap)) - SendMessage(wnd, EM_SETREADONLY, 1, 0); + } + + if (IS_CAP_READONLY(desc->cap)) + { + //SendMessage(wnd, EM_SETREADONLY, 1, 0); + EnableWindow(lable, FALSE); + EnableWindow(wnd, FALSE); } text_size->cx = x + dlg_page::gap_x; @@ -1115,9 +1150,9 @@ BOOL dlg_page::on_notify(int ctrl_id, LPNMHDR pnmh) { if (pnmh->code != NM_RELEASEDCAPTURE) { - if (pnmh->code == NM_CUSTOMDRAW && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) && GetFocus() == pnmh->hwndFrom) // drag track ... - ; - else + //if (pnmh->code == NM_CUSTOMDRAW && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) && GetFocus() == pnmh->hwndFrom) // drag track ... + // ; + //else return FALSE; } } @@ -1627,13 +1662,15 @@ bool dlg_page::refresh(int sn, const SANE_Option_Descriptor* desc, void* cur_val { if (GetWindowLong(ctrls_[ind], GWL_ID) != sn) break; + + BOOL en = ((desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE) && !(IS_CAP_READONLY(desc->cap)); set_ctrl_value(ctrls_[ind], desc->type, cur_val, true); - EnableWindow(ctrls_[ind], (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE); + EnableWindow(ctrls_[ind], en); HWND host = (HWND)GetPropW(ctrls_[ind], dlg_page::property_host.c_str()); if (IsWindow(host)) { BOOL checked = SendMessage(host, BM_GETCHECK, 0, 0) == BST_CHECKED; - checked &= (desc->cap & SANE_CAP_INACTIVE) != SANE_CAP_INACTIVE; + checked &= en; if (sn - dlg_page::dyn_id_base == id_custom_area_) { EnableWindow(ctrls_[ind], checked);