diff --git a/sane/gb_json.cpp b/sane/gb_json.cpp index add68b7..78bcedb 100644 --- a/sane/gb_json.cpp +++ b/sane/gb_json.cpp @@ -1190,6 +1190,20 @@ namespace gb return val; } + sane_config_schm* sane_config_schm::copy(void) + { + sane_config_schm *cp = new sane_config_schm(scanner_); + std::string val(jsn_->to_string(false)); + + cp->scheme_name_ = scheme_name_; + cp->file_ = file_; + cp->jsn_->attach_text(&val[0]); + cp->id_name_ = id_name_; + val = def_val_->to_string(false); + cp->def_val_->attach_text(&val[0]); + + return cp; + } bool sane_config_schm::load_from_file(const char* file) { clear(); @@ -1246,6 +1260,16 @@ namespace gb id_name_[sn] = name; def_val_->set_value(name, to_hex_letter(val, bytes).c_str()); } + void sane_config_schm::copy_default_value(sane_config_schm* from) + { + if(from) + { + std::string t(from->def_val_->to_string(false)); + + id_name_ = from->id_name_; + def_val_->attach_text(&t[0]); + } + } bool sane_config_schm::first_config(std::string& name, std::string& val) { bool ret = false; @@ -1274,6 +1298,18 @@ namespace gb return ret; } + bool sane_config_schm::get_config(const char* name, std::string& val) + { + bool ret = jsn_ ? jsn_->get_value(name, val) : false; + + if(!ret && def_val_) + ret = def_val_->get_value(name, val); + + if(ret) + val = sane_config_schm::from_hex_letter(val.c_str(), val.length()); + + return ret; + } void sane_config_schm::begin_setting(bool restore) { if (bkp_) @@ -1332,6 +1368,36 @@ namespace gb else jsn_->set_value(name, hex_v.c_str()); } + bool sane_config_schm::has_changed(void) + { + if(!bkp_) + return false; + + std::map old; + std::string n(""), v(""); + if(bkp_->first_child(v, &n)) + { + do + { + old[n] = v; + }while(bkp_->next_child(v, &n)); + } + + if(jsn_->first_child(v, &n)) + { + do + { + if(old.count(n) == 0) + return true; + if(old[n]!=v) + return true; + + old.erase(n); + }while(jsn_->next_child(v, &n)); + } + + return old.size() > 0; + } void sane_config_schm::end_setting(bool cancel) { if (in_setting_) @@ -1401,7 +1467,7 @@ namespace gb { scheme_name_ = name ? name : ""; } - void sane_config_schm::update(bool(__stdcall* is_float)(int, void*), void* param, const char* (__stdcall* t2n)(const char*), std::string* discard) + void sane_config_schm::update(bool(* is_float)(int, void*), void* param, const char* (* t2n)(const char*), std::string* discard) { if (!jsn_) return; @@ -1541,7 +1607,7 @@ namespace gb return; cJSON* next = first->next; - std::string name(first->string ? "" : first->string), + std::string name(first->string ? first->string : ""), cont(""); CFGSCHM sch; @@ -1576,11 +1642,13 @@ namespace gb if (ret == 0) ret = load_mem(cont.c_str()); - if (ret == 0 && scanner_name_.empty()) + // if (ret == 0 && scanner_name_.empty()) { const char* name = strrchr(file, PATH_SYMBOL[0]); if (name++ == nullptr) name = file; + else + path_ = std::string(file, name - file); scanner_name_ = name; ret = scanner_name_.rfind('.'); @@ -1593,10 +1661,17 @@ namespace gb } int scanner_cfg::load_mem(const char* mem) { - cJSON* root = cJSON_Parse(mem); + base64 b64; + std::string text(b64.decode(mem, strlen(mem))); + cJSON* root = cJSON_Parse(text.c_str()); if (!root) + { + FILE* dst = fopen((path_ + "err_cfg.txt").c_str(), "wb"); + fwrite(text.c_str(), 1, text.length(), dst); + fclose(dst); return EINVAL; + } clear(); walk_sibling_schemes(root->child); @@ -1610,7 +1685,7 @@ namespace gb return EINVAL; std::string cont("{\"" + scanner_cfg::global_name_ + "\":"), - f(file ? file : path_ + scanner_name_), + f(file ? file : path_ + scanner_name_ + ".cfg"), v(""); int sel = -1; @@ -1650,7 +1725,7 @@ namespace gb { sane_config_schm* found = nullptr; - if (scheme_name) + if (scheme_name && *scheme_name) { std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name); if (it != schemes_.end()) @@ -1670,6 +1745,16 @@ namespace gb return found; } + std::string scanner_cfg::get_current_scheme_name(void) + { + int ind = -1; + + global_->get_value(scanner_cfg::cur_sel_.c_str(), ind); + if (ind >= 0 && ind < schemes_.size()) + return schemes_[ind].name; + else + return scanner_cfg::default_setting_name_; + } bool scanner_cfg::remove_scheme(const char* scheme_name) { std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name); @@ -1692,9 +1777,16 @@ namespace gb return false; } + void scanner_cfg::remove_all_schemes(void) + { + for(auto& v: schemes_) + v.schm->release(); + + schemes_.clear(); + } bool scanner_cfg::select_scheme(const char* scheme_name) { - std::vector::iterator it = std::find(schemes_.begin(), schemes_.end(), scheme_name); + std::vector::iterator it = scheme_name ? std::find(schemes_.begin(), schemes_.end(), scheme_name) : schemes_.end(); if (it == schemes_.end()) global_->set_value(scanner_cfg::cur_sel_.c_str(), -1); @@ -1725,19 +1817,38 @@ namespace gb } bool scanner_cfg::add_scheme(sane_config_schm* schm, const char* name) { - if (name && std::find(schemes_.begin(), schemes_.end(), name) != schemes_.end()) + CFGSCHM cs; + + cs.name = name ? name : schm->get_scheme_name(); + if(cs.name.empty() || cs.name == scanner_cfg::global_name_) return false; - CFGSCHM cs; - cs.name = name ? name : schm->get_scheme_name(); - cs.schm = schm; - if (cs.name == scanner_cfg::global_name_) + if (std::find(schemes_.begin(), schemes_.end(), cs.name.c_str()) != schemes_.end()) return false; + cs.schm = schm; + schemes_.push_back(cs); schm->set_scheme_name(cs.name.c_str()); schm->add_ref(); return true; } + bool scanner_cfg::rename_scheme(const char* from, const char* to) + { + if (to && std::find(schemes_.begin(), schemes_.end(), to) != schemes_.end()) + return false; + + for(auto& v: schemes_) + { + if(v.name == from) + { + v.name = to; + v.schm->set_scheme_name(to); + return true; + } + } + + return false; + } } diff --git a/sane/gb_json.h b/sane/gb_json.h index 35ffec5..75f7940 100644 --- a/sane/gb_json.h +++ b/sane/gb_json.h @@ -2,16 +2,21 @@ #if defined(WIN32) || defined(_WIN64) #include +#include "../../code_device/hgsane/cJSON.h" #define PATH_SYMBOL "\\" #else +#include "cJSON.h" #define PATH_SYMBOL "/" +#define NULL nullptr +#define DWORD_PTR char* +#define _countof(a) sizeof(a) / sizeof(a[0]) #endif -// #include "cJSON.h" -#include "../../code_device/hgsane/cJSON.h" +// #include #include #include +#include namespace gb { @@ -130,24 +135,28 @@ namespace gb static bool is_option_data(std::string& name); // reset baase option name into 'name' if name was option data, and return true public: + sane_config_schm* copy(void); bool load_from_file(const char* file); bool load_from_mem(const char* mem, bool in_b64 = true); bool save_to(const char* file); void set_default_value(int sn, const char* name, const char* val, size_t bytes); + void copy_default_value(sane_config_schm* from); bool first_config(std::string& name, std::string& val); bool next_config(std::string& name, std::string& val); + bool get_config(const char* name, std::string& val); void begin_setting(bool restore = false); void config_changed(const char* name, const char* val, size_t bytes, bool extra = false); void config_changed(int sn, const char* val, size_t bytes, bool extra = false); void remove_config(const char* name); void set_value(const char* name, const char* val, size_t bytes, bool extra = false); + bool has_changed(void); void end_setting(bool cancel); int id_from_name(const char* name); std::string to_text_stream(bool b64 = true, bool with_ver = true); std::string get_version(void); std::string get_scheme_name(void); void set_scheme_name(const char* name); - void update(bool(__stdcall* is_float)(int, void*), void* param, const char*(__stdcall* t2n)(const char*), std::string* discard = NULL); + void update(bool(* is_float)(int, void*), void* param, const char*(* t2n)(const char*), std::string* discard = NULL); }; class scanner_cfg : public refer @@ -198,8 +207,8 @@ namespace gb typedef struct _update_func { - void(__stdcall* trans_number)(const char* name, std::string& val, void* param); - const char* (__stdcall* title2name)(const char* title, void* param); + void(* trans_number)(const char* name, std::string& val, void* param); + const char* (* title2name)(const char* title, void* param); std::string discard_msg; // update failed items ... void* func_param; }UDF, *LPUDF; @@ -212,10 +221,13 @@ namespace gb void get_all_schemes(std::vector& schemes); // return all schemes name queue, the first is always be 'Default settings' sane_config_schm* get_scheme(const char* scheme_name = nullptr/*return current scheme if was null*/); // call sane_config_schm::release() if not use anymore + std::string get_current_scheme_name(void); bool remove_scheme(const char* scheme_name); + void remove_all_schemes(void); bool select_scheme(const char* scheme_name); sane_config_schm* copy_scheme(const char* cp_from_name); // for UI setting, call release() if not use anymore bool add_scheme(sane_config_schm* schm, const char* name = nullptr); + bool rename_scheme(const char* from, const char* to); }; -} +}; diff --git a/sane/scanner.cpp b/sane/scanner.cpp index 447ea51..f3c856e 100644 --- a/sane/scanner.cpp +++ b/sane/scanner.cpp @@ -201,7 +201,7 @@ namespace callback , {SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH , "\350\207\252\345\212\250\346\220\223\347\272\270\345\274\272\345\272\246"} // 自动搓纸强度 , {SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE , "\346\220\223\347\272\270\351\230\210\345\200\274"} // " 搓纸阈值" }; - const char* __stdcall option_title_2_name(const char* title) + const char* option_title_2_name(const char* title) { while (*title == ' ') title++; @@ -492,7 +492,7 @@ void __stdcall scanner::ui_callback(int uev, void* sender, void* param) { ((scanner*)param)->on_ui_event(uev, sender); } -bool __stdcall scanner::is_option_float(int sn, void* param) +bool scanner::is_option_float(int sn, void* param) { SANE_Option_Descriptor* desc = hg_sane_middleware::instance()->get_option_descriptor((SANE_Handle)param, sn); diff --git a/sane/scanner.h b/sane/scanner.h index 6ef08ca..999551e 100644 --- a/sane/scanner.h +++ b/sane/scanner.h @@ -184,7 +184,7 @@ class scanner : public ISaneInvoker, virtual public refer static int __stdcall to_int(SANE_Int v); static float __stdcall to_float(SANE_Fixed v); static void __stdcall ui_callback(int uev, void* sender, void* param); - static bool __stdcall is_option_float(int sn, void* param); + static bool is_option_float(int sn, void* param); public: scanner(SCANNERID id); diff --git a/twain/twain/huagaods.cpp b/twain/twain/huagaods.cpp index 7f7962c..133a280 100644 --- a/twain/twain/huagaods.cpp +++ b/twain/twain/huagaods.cpp @@ -1000,7 +1000,12 @@ Result huagao_ds::imageInfoGet(const Identity&, ImageInfo& data) if (m_compression == Compression::Group4) data.setPixelType(PixelType::BlackWhite); else - data.setPixelType(head.format == SANE_FRAME_RGB ? PixelType::Rgb : PixelType::Gray); + { + if (head.format == SANE_FRAME_RGB) + data.setPixelType(PixelType::Rgb); + else if(head.format == SANE_FRAME_GRAY) + data.setPixelType(head.depth == 1 ? PixelType::BlackWhite : PixelType::Gray); + } data.setPlanar(false); data.setWidth(head.pixels_per_line);