From 38c60264c51d4d03e3d7beb81ad89c598d5394cb Mon Sep 17 00:00:00 2001 From: gb <741021719@qq.com> Date: Wed, 21 Feb 2024 17:44:32 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E4=BB=8E/usr/local/huago/cam?= =?UTF-8?q?eraparam.json=E5=AF=BC=E5=85=A5=E6=A0=A1=E6=AD=A3=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=8A=9F=E8=83=BD=EF=BC=9B=E6=B8=85=E9=99=A4=E6=BB=9A?= =?UTF-8?q?=E8=BD=B4=E8=AE=A1=E6=95=B0&=E5=85=B3=E6=9C=BA=E7=A1=AE?= =?UTF-8?q?=E8=AE=A4=E8=8F=9C=E5=8D=95=EF=BC=8C=E9=BB=98=E8=AE=A4=E9=80=89?= =?UTF-8?q?=E4=B8=AD=E5=8F=96=E6=B6=88=E9=80=89=E9=A1=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- hardware/cis/cis_param.cpp | 420 +++++++++++++++++++++++++++++++++++++ hardware/cis/cis_param.h | 16 +- hardware/hardware.cpp | 16 +- hardware/hardware.h | 1 + sdk/base/ui.cpp | 7 +- sdk/base/utils.cpp | 50 ++++- sdk/base/utils.h | 1 + ui/dev_menu.cpp | 12 +- ui/dev_menu.h | 6 +- xmake.lua | 2 +- 10 files changed, 516 insertions(+), 15 deletions(-) diff --git a/hardware/cis/cis_param.cpp b/hardware/cis/cis_param.cpp index 901c211..fea04df 100644 --- a/hardware/cis/cis_param.cpp +++ b/hardware/cis/cis_param.cpp @@ -1,6 +1,259 @@ #include "cis_param.h" +#include +#include +#include +#include +#include +#include +namespace correct +{ + typedef struct _cond_data + { + bool clr; + int dpi; + int val; + }CONDDATA; + typedef struct _correct_data + { + std::string name; + std::vector data; + }CORDATA; + + const char* names[] = {SANE_OPT_NAME(CIS_SP) + , SANE_OPT_NAME(CIS_EXPO_FB), SANE_OPT_NAME(CIS_EXPO_FG), SANE_OPT_NAME(CIS_EXPO_FR) + , SANE_OPT_NAME(CIS_EXPO_BB), SANE_OPT_NAME(CIS_EXPO_BG), SANE_OPT_NAME(CIS_EXPO_BR) + // , SANE_OPT_NAME(CIS_STRETCH_H), SANE_OPT_NAME(CIS_STRETCH_V) + }, + *names_plus[] = {SANE_OPT_NAME(CIS_GAIN_FRONT), SANE_OPT_NAME(CIS_GAIN_BACK) + , SANE_OPT_NAME(CIS_OFFSET_FRONT), SANE_OPT_NAME(CIS_OFFSET_BACK) + }; + + static bool add_data(std::vector& que, const char* name, CONDDATA& data) + { + bool found = false; + + for(auto& v: que) + { + if(v.name == name) + { + found = true; + v.data.push_back(data); + break; + } + } + + return found; + } + static void parse_mode(gb_json* root, std::vector& que, CONDDATA& data) + { + gb_json *child = nullptr, *leaf = nullptr; + + root->get_value("ExposureF", child); + if(child) + { + // R - G - B + if(child->children() >= 3) + { + leaf = child->first_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_FR), data); + + leaf = child->next_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_FG), data); + + leaf = child->next_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_FB), data); + } + child->release(); + } + + root->get_value("ExposureB", child); + if(child) + { + // R - G - B + if(child->children() >= 3) + { + leaf = child->first_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_BR), data); + + leaf = child->next_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_BG), data); + + leaf = child->next_child(); + leaf->value(data.val); + leaf->release(); + add_data(que, SANE_OPT_NAME(CIS_EXPO_BB), data); + } + child->release(); + } + + root->get_value("GainF", child); + if(child) + { + int ind = 0; + leaf = child->first_child(); + while(leaf) + { + std::string n(SANE_OPT_NAME(CIS_GAIN_FRONT)); + + leaf->value(data.val); + leaf->release(); + + n += "-" + std::to_string(++ind); + if(!add_data(que, n.c_str(), data)) + break; + + leaf = child->next_child(); + } + child->release(); + } + + root->get_value("GainB", child); + if(child) + { + int ind = 0; + leaf = child->first_child(); + while(leaf) + { + std::string n(SANE_OPT_NAME(CIS_GAIN_BACK)); + + leaf->value(data.val); + leaf->release(); + + n += "-" + std::to_string(++ind); + if(!add_data(que, n.c_str(), data)) + break; + + leaf = child->next_child(); + } + child->release(); + } + + root->get_value("OffsetF", child); + if(child) + { + int ind = 0; + leaf = child->first_child(); + while(leaf) + { + std::string n(SANE_OPT_NAME(CIS_OFFSET_FRONT)); + + leaf->value(data.val); + leaf->release(); + + n += "-" + std::to_string(++ind); + if(!add_data(que, n.c_str(), data)) + break; + + leaf = child->next_child(); + } + child->release(); + } + + root->get_value("OffsetB", child); + if(child) + { + int ind = 0; + leaf = child->first_child(); + while(leaf) + { + std::string n(SANE_OPT_NAME(CIS_OFFSET_BACK)); + + leaf->value(data.val); + leaf->release(); + + n += "-" + std::to_string(++ind); + if(!add_data(que, n.c_str(), data)) + break; + + leaf = child->next_child(); + } + child->release(); + } + + if(root->get_value("Sp", data.val)) + add_data(que, SANE_OPT_NAME(CIS_SP), data); + } + + std::vector load_old_correct_data(const char* file) + { + std::vector old; + std::string cont(utils::load_mini_file(file, nullptr)); + gb_json *root = new gb_json(); + + for(auto& v: names) + { + CORDATA cd; + cd.name = v; + old.push_back(cd); + } + for(auto& v: names_plus) + { + for(int i = 0; i < CIS_SECTOR_COUNT; ++i) + { + CORDATA cd; + cd.name = v; + cd.name += "-" + std::to_string(i + 1); + old.push_back(cd); + } + } + + if(root->attach_text(&cont[0])) + { + gb_json* child = root->first_child(); + while(child) + { + CONDDATA data; + int val = 0; + if(child->get_value("ColorMode", val)) + { + data.clr = val; + if(child->get_value("DpiMode", val)) + { + if(val == 1) + data.dpi = 200; + else if(val == 2) + data.dpi = 300; + else if(val == 3) + data.dpi = 600; + else + data.dpi = 0; + if(data.dpi) + { + parse_mode(child, old, data); + } + } + } + child->release(); + child = root->next_child(); + } + } + root->release(); + + for(int i = 0; i < old.size(); ++i) + { + if(old[i].data.size() == 0) + { + printf("No correct data for '%s'\n", old[i].name.c_str()); + old.erase(old.begin() + i); + i--; + } + } + + return std::move(old); + } +}; namespace cis { @@ -22,5 +275,172 @@ namespace cis return l; } + + void update_correct_data(int init_dpi, bool init_clr, bool force) + { + std::string src("/usr/local/huago/cameraparam.json"), + root(CIS_CORRECT_DATA_PATH); + uint64_t src_m = 0, + dst_m = 0; + std::vector old(correct::load_old_correct_data(src.c_str())); + + if(utils::get_file_time(src.c_str(), nullptr, &src_m, nullptr) && !force) + return; + + for(auto& v: correct::names) + { + std::string fn(root + v + ".json"); + if(!force && utils::get_file_time(fn.c_str(), nullptr, &dst_m, nullptr) == 0 && + dst_m >= src_m) + { + printf("%s is up-to-date.\n", fn.c_str()); + continue; + } + + for(auto& n: old) + { + if(n.name == v) + { + gb_json *init = new gb_json(); + correct::CONDDATA def; + + for(auto& item: n.data) + { + if(item.clr == init_clr && item.dpi == init_dpi) + def = item; + else + { + std::string key(SANE_OPT_NAME(CIS_MODE)); + + key += "=="; + if(item.clr) + key += WORDS_COLOR_COLOR; + else + key += WORDS_COLOR_GRAY; + key += "&&"; + key += SANE_OPT_NAME(CIS_DPI); + key += "==" + std::to_string(item.dpi); + init->set_value(key.c_str(), item.val); + } + } + init->set_value("default", def.val); + + std::string cont(init->to_string()); + + init->release(); + utils::save_2_file(&cont[0], cont.length(), fn.c_str()); + break; + } + } + } + + for(auto& v: correct::names_plus) + { + for(int i = 0; i < CIS_SECTOR_COUNT; ++i) + { + std::string fn(std::string(v) + "-" + std::to_string(i + 1)); + if(!force && utils::get_file_time((root + fn + ".json").c_str(), nullptr, &dst_m, nullptr) == 0 && + dst_m >= src_m) + { + printf("%s is up-to-date.\n", fn.c_str()); + continue; + } + + for(auto& n: old) + { + if(n.name == fn) + { + gb_json *init = new gb_json(); + correct::CONDDATA def; + + for(auto& item: n.data) + { + if(item.clr == init_clr && item.dpi == init_dpi) + def = item; + else + { + std::string key(SANE_OPT_NAME(CIS_MODE)); + + key += "=="; + if(item.clr) + key += WORDS_COLOR_COLOR; + else + key += WORDS_COLOR_GRAY; + key += "&&"; + key += SANE_OPT_NAME(CIS_DPI); + key += "==" + std::to_string(item.dpi); + init->set_value(key.c_str(), item.val); + } + } + init->set_value("default", def.val); + + std::string cont(init->to_string()); + + init->release(); + utils::save_2_file(&cont[0], cont.length(), (root + fn + ".json").c_str()); + break; + } + } + } + } + } + + void load_correct_data_to_json(gb_json* jsn) + { + std::string root(CIS_CORRECT_DATA_PATH); + gb_json *child = nullptr; + gb_json *last = new gb_json(); + + for(auto& v: correct::names) + { + jsn->get_value(v, child); + if(child) + { + std::string data(utils::load_mini_file((root + v + ".json").c_str(), nullptr)); + if(last->attach_text(&data[0])) + { + gb_json* def = nullptr; + child->get_value("default", def); + if(def) + { + printf("Before: %s\n", child->to_string().c_str()); + def->attach_text(&data[0]); + def->key() = "default"; + def->release(); + printf("After: %s\n", child->to_string().c_str()); + } + } + child->release(); + } + } + + for(auto& v: correct::names_plus) + { + for(int i = 0; i < CIS_SECTOR_COUNT; ++i) + { + std::string fn(v); + + fn += "-" + std::to_string(i + 1); + jsn->get_value(fn.c_str(), child); + if(child) + { + std::string data(utils::load_mini_file((root + fn + ".json").c_str(), nullptr)); + if(last->attach_text(&data[0])) + { + gb_json* def = nullptr; + child->get_value("default", def); + if(def) + { + def->attach_text(&data[0]); + def->key() = "default"; + def->release(); + } + } + child->release(); + } + } + } + last->release(); + } } diff --git a/hardware/cis/cis_param.h b/hardware/cis/cis_param.h index 444c638..e95d3a4 100644 --- a/hardware/cis/cis_param.h +++ b/hardware/cis/cis_param.h @@ -3,9 +3,12 @@ // Date: 2024-01-19 #pragma once -#define CIS_SECTOR_COUNT 6 // how many sectors of ONE CIS +#define CIS_SECTOR_COUNT 6 // how many sectors of ONE CIS +#define CIS_CORRECT_DATA_PATH "/usr/local/huago2/" +class gb_json; + namespace cis { // Function: how many pixels one sector generated @@ -23,4 +26,15 @@ namespace cis // // color - true: color, false: gray int get_line_stream_length(int dpi, bool color); + + // Function: update correct data + // + // Parameter: init_dpi - default DPI + // + // init_clr - default color mode, true: color; false: gray + // + // force - ignore file time and force update + void update_correct_data(int init_dpi = 200, bool init_clr = true, bool force = false); + + void load_correct_data_to_json(gb_json* jsn); }; diff --git a/hardware/hardware.cpp b/hardware/hardware.cpp index 26a0f39..1de35d8 100644 --- a/hardware/hardware.cpp +++ b/hardware/hardware.cpp @@ -49,6 +49,7 @@ scanner_hw::scanner_hw() : mb_events_("motorboard-event") CLEAN_ARRAY(exposure_); CLEAN_ARRAY(gain_); CLEAN_ARRAY(off_); + cis::update_correct_data(); init(); } @@ -64,6 +65,7 @@ void scanner_hw::init(void) for(auto& v: device_opt_json) text += v; init_version(text); + load_correct_data(text); set_opt_json_text(&text[0]); #define OPT_HANDLER(name) \ @@ -348,6 +350,17 @@ void scanner_hw::init_version(std::string& text) } jsn->release(); } +void scanner_hw::load_correct_data(std::string& text) +{ + gb_json *root = new gb_json(); + + if(root->attach_text(&text[0])) + { + cis::load_correct_data_to_json(root); + text = root->to_string(); + } + root->release(); +} void scanner_hw::thread_image_capture(bool paper_ready) { PACKIMAGE img(img_base_); @@ -399,7 +412,6 @@ void scanner_hw::thread_image_capture(bool paper_ready) motor_->pick_paper(); // scanning ONE turn ... - int turn_cnt = 0; while(scanning_ && motor_->wait_paper_out(to_paper_out_)) { uint32_t pass = watch.elapse_ms(); @@ -413,7 +425,6 @@ void scanner_hw::thread_image_capture(bool paper_ready) err = trans_motorboard_err_2_hg_error(mbev.second, true); if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING) break; - turn_cnt++; } else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE) { @@ -424,7 +435,6 @@ void scanner_hw::thread_image_capture(bool paper_ready) { devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass)); err = SCANNER_ERR_OK; - turn_cnt++; } img.pos.paper_ind++; diff --git a/hardware/hardware.h b/hardware/hardware.h index 226d177..397c601 100644 --- a/hardware/hardware.h +++ b/hardware/hardware.h @@ -99,6 +99,7 @@ class scanner_hw : public sane_opt_provider void init(void); void init_version(std::string& text); + void load_correct_data(std::string& text); void thread_image_capture(bool paper_ready); int get_image_real_height(int minh); bool is_scan_fatal(void); diff --git a/sdk/base/ui.cpp b/sdk/base/ui.cpp index 2cb30d5..461d947 100644 --- a/sdk/base/ui.cpp +++ b/sdk/base/ui.cpp @@ -235,11 +235,12 @@ namespace devui std::string rcv(""); char buf[300] = {0}; LPMSGSTREAM pack = nullptr; - bool offline = false; + chronograph watch; printf("ui-receiver running ...\n"); while(run_) { + watch.reset(); int r = read(fdi_, buf, _countof(buf)); if(r == -1) { @@ -251,17 +252,15 @@ namespace devui else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code { // peer closed, wait 10ms ... - if(!offline) + if(watch.elapse_ms() > 10) { printf("PIPE: peer closed(read ZERO byte and error = %d).\n", errno); utils::to_log(LOG_LEVEL_DEBUG, "PIPE: peer closed(read ZERO byte and error = %d).\n", errno); } - offline = true; std::this_thread::sleep_for(std::chrono::milliseconds(10)); continue; } - offline = false; rcv += std::string(buf, r); if(rcv.length()) { diff --git a/sdk/base/utils.cpp b/sdk/base/utils.cpp index afe04a7..3590f9c 100644 --- a/sdk/base/utils.cpp +++ b/sdk/base/utils.cpp @@ -883,8 +883,22 @@ namespace utils FILE* dst = fopen(file, append ? "a+b" : "wb"); int err = 0; - if (!dst) + while (!dst) + { + std::string dir(file); + size_t pos = dir.rfind(PATH_SEPARATOR[0]); + + if(pos != std::string::npos) + { + dir.erase(pos); + create_folder(dir.c_str()); + dst = fopen(file, append ? "a+b" : "wb"); + if(dst) + break; + } + return errno; + } if(append && max_size != -1 && ftell(dst) >= max_size) fseek(dst, 0, SEEK_SET); @@ -1242,6 +1256,40 @@ namespace utils return err; } + int get_file_time(const char* file, uint64_t* born, uint64_t* modify, uint64_t* last_access) + { + int err = 0; + +#if OS_WIN +#else + if(born) + { + std::string str(get_command_result((std::string("stat -c %W ") + file).c_str())); + if(str.empty()) + err = ENOENT; + else + *born = atoi(str.c_str()); + } + if(modify && err == 0) + { + std::string str(get_command_result((std::string("stat -c %Y ") + file).c_str())); + if(str.empty()) + err = ENOENT; + else + *modify = atoi(str.c_str()); + } + if(last_access && err == 0) + { + std::string str(get_command_result((std::string("stat -c %X ") + file).c_str())); + if(str.empty()) + err = ENOENT; + else + *last_access = atoi(str.c_str()); + } +#endif + + return err; + } int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid) { diff --git a/sdk/base/utils.h b/sdk/base/utils.h index 1e3436d..db5573d 100644 --- a/sdk/base/utils.h +++ b/sdk/base/utils.h @@ -92,6 +92,7 @@ namespace utils int enum_file(const char* folder, bool recursive, bool/*return false to stop enumeration*/(STDCALL* found)(const char* path_name, bool dir, void* param), void* param); int move_file(const char* from, const char* to); int make_file_size(const char* file, uint64_t size); // truncate or extend file size to 'size', create if not exist + int get_file_time(const char* file, uint64_t* born, uint64_t* modify, uint64_t* last_access); // all time are both in seconds from 1970-01-01 00:00:00 int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid = -1); void print_memory_usage(const char* tips, bool to_log_file); diff --git a/ui/dev_menu.cpp b/ui/dev_menu.cpp index 8eb4f6b..46b89e2 100644 --- a/ui/dev_menu.cpp +++ b/ui/dev_menu.cpp @@ -158,7 +158,11 @@ bool dev_menu::select(const char* txt) } void dev_menu::reset_pos(void) { - cur_ = sel_ == -1 ? 0 : sel_; + cur_ = sel_ == -1 ? init_pos_ : sel_; +} +void dev_menu::set_default_pos(int pos) +{ + init_pos_ = pos; } dev_menu* dev_menu::enter(int* id) @@ -798,7 +802,8 @@ void ui_mgr::init(void) }; handler_[menu_command::MENU_CMD_ID_CLEAR_ROLLER_CNT] = f; } - child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL); + child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL); + child->set_default_pos(1); root_->add_menu(WORDS_MENU_RESET_ROLLOER_CNT, child); child->release(); } @@ -845,7 +850,8 @@ void ui_mgr::init(void) }; handler_[menu_command::MENU_CMD_ID_SHUTDOWN] = f; } - child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL); + child->add_menu(WORDS_MENU_NO, menu_command::MENU_CMD_ID_CANCEL); + child->set_default_pos(1); root_->add_menu(WORDS_MENU_SHUTDOWN, child); child->release(); } diff --git a/ui/dev_menu.h b/ui/dev_menu.h index d5dadd3..6a0c034 100644 --- a/ui/dev_menu.h +++ b/ui/dev_menu.h @@ -43,8 +43,9 @@ class dev_menu : public refer }; }MITEM; std::vector items_; - int cur_ = 0; - int sel_ = -1; + int init_pos_ = 0; + int cur_ = 0; // focus item + int sel_ = -1; // current checked item bool check_item_ = false; bool need_ret_parent_ = true; @@ -66,6 +67,7 @@ public: bool move_to(bool next); // true - move to next, false - move to previous. if at end position of move direction, return false bool select(const char* txt); void reset_pos(void); + void set_default_pos(int pos = 0); // Function: access current menu // diff --git a/xmake.lua b/xmake.lua index 3b1e67c..f66dc30 100644 --- a/xmake.lua +++ b/xmake.lua @@ -61,7 +61,7 @@ add_defines("BUILD_AS_DEVICE") add_defines("VER_MAIN=2") add_defines("VER_FAMILY=200") add_defines("VER_DATE=20240221") -add_defines("VER_BUILD=9") +add_defines("VER_BUILD=24") target("conf") set_kind("phony")