添加从/usr/local/huago/cameraparam.json导入校正数据功能;清除滚轴计数&关机确认菜单,默认选中取消选项

This commit is contained in:
gb 2024-02-21 17:44:32 +08:00
parent bb2988848f
commit 38c60264c5
10 changed files with 516 additions and 15 deletions

View File

@ -1,6 +1,259 @@
#include "cis_param.h" #include "cis_param.h"
#include <vector>
#include <string>
#include <base/utils.h>
#include <json/gb_json.h>
#include <sane/sane_name.h>
#include <base/words.h>
namespace correct
{
typedef struct _cond_data
{
bool clr;
int dpi;
int val;
}CONDDATA;
typedef struct _correct_data
{
std::string name;
std::vector<CONDDATA> 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<CORDATA>& 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<CORDATA>& 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<CORDATA> load_old_correct_data(const char* file)
{
std::vector<CORDATA> 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 namespace cis
{ {
@ -22,5 +275,172 @@ namespace cis
return l; 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<correct::CORDATA> 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();
}
} }

View File

@ -3,9 +3,12 @@
// Date: 2024-01-19 // Date: 2024-01-19
#pragma once #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 namespace cis
{ {
// Function: how many pixels one sector generated // Function: how many pixels one sector generated
@ -23,4 +26,15 @@ namespace cis
// //
// color - true: color, false: gray // color - true: color, false: gray
int get_line_stream_length(int dpi, bool color); 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);
}; };

View File

@ -49,6 +49,7 @@ scanner_hw::scanner_hw() : mb_events_("motorboard-event")
CLEAN_ARRAY(exposure_); CLEAN_ARRAY(exposure_);
CLEAN_ARRAY(gain_); CLEAN_ARRAY(gain_);
CLEAN_ARRAY(off_); CLEAN_ARRAY(off_);
cis::update_correct_data();
init(); init();
} }
@ -64,6 +65,7 @@ void scanner_hw::init(void)
for(auto& v: device_opt_json) for(auto& v: device_opt_json)
text += v; text += v;
init_version(text); init_version(text);
load_correct_data(text);
set_opt_json_text(&text[0]); set_opt_json_text(&text[0]);
#define OPT_HANDLER(name) \ #define OPT_HANDLER(name) \
@ -348,6 +350,17 @@ void scanner_hw::init_version(std::string& text)
} }
jsn->release(); 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) void scanner_hw::thread_image_capture(bool paper_ready)
{ {
PACKIMAGE img(img_base_); PACKIMAGE img(img_base_);
@ -399,7 +412,6 @@ void scanner_hw::thread_image_capture(bool paper_ready)
motor_->pick_paper(); motor_->pick_paper();
// scanning ONE turn ... // scanning ONE turn ...
int turn_cnt = 0;
while(scanning_ && motor_->wait_paper_out(to_paper_out_)) while(scanning_ && motor_->wait_paper_out(to_paper_out_))
{ {
uint32_t pass = watch.elapse_ms(); 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); err = trans_motorboard_err_2_hg_error(mbev.second, true);
if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING) if(err != SCANNER_ERR_DEVICE_DOUBLE_FEEDING)
break; break;
turn_cnt++;
} }
else if(mbev.first == MOTOR_BORD_EVENT_SCAN_DONE) 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)); devui::send_message(devui::UI_STATUS_PAPER_CNT, (uint8_t*)&pass, sizeof(pass));
err = SCANNER_ERR_OK; err = SCANNER_ERR_OK;
turn_cnt++;
} }
img.pos.paper_ind++; img.pos.paper_ind++;

View File

@ -99,6 +99,7 @@ class scanner_hw : public sane_opt_provider
void init(void); void init(void);
void init_version(std::string& text); void init_version(std::string& text);
void load_correct_data(std::string& text);
void thread_image_capture(bool paper_ready); void thread_image_capture(bool paper_ready);
int get_image_real_height(int minh); int get_image_real_height(int minh);
bool is_scan_fatal(void); bool is_scan_fatal(void);

View File

@ -235,11 +235,12 @@ namespace devui
std::string rcv(""); std::string rcv("");
char buf[300] = {0}; char buf[300] = {0};
LPMSGSTREAM pack = nullptr; LPMSGSTREAM pack = nullptr;
bool offline = false; chronograph watch;
printf("ui-receiver running ...\n"); printf("ui-receiver running ...\n");
while(run_) while(run_)
{ {
watch.reset();
int r = read(fdi_, buf, _countof(buf)); int r = read(fdi_, buf, _countof(buf));
if(r == -1) if(r == -1)
{ {
@ -251,17 +252,15 @@ namespace devui
else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code else if(r == 0 /*&& errno == ENOENT*/) // errno maybe ZERO, here ommit the error code
{ {
// peer closed, wait 10ms ... // peer closed, wait 10ms ...
if(!offline) if(watch.elapse_ms() > 10)
{ {
printf("PIPE: peer closed(read ZERO byte and error = %d).\n", errno); 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); 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)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
continue; continue;
} }
offline = false;
rcv += std::string(buf, r); rcv += std::string(buf, r);
if(rcv.length()) if(rcv.length())
{ {

View File

@ -883,8 +883,22 @@ namespace utils
FILE* dst = fopen(file, append ? "a+b" : "wb"); FILE* dst = fopen(file, append ? "a+b" : "wb");
int err = 0; 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; return errno;
}
if(append && max_size != -1 && ftell(dst) >= max_size) if(append && max_size != -1 && ftell(dst) >= max_size)
fseek(dst, 0, SEEK_SET); fseek(dst, 0, SEEK_SET);
@ -1242,6 +1256,40 @@ namespace utils
return err; 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) int get_memory_usage(uint64_t* peak, uint64_t* now, uint64_t* phymem, uint32_t pid)
{ {

View File

@ -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 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 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 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); 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); void print_memory_usage(const char* tips, bool to_log_file);

View File

@ -158,7 +158,11 @@ bool dev_menu::select(const char* txt)
} }
void dev_menu::reset_pos(void) 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) 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; 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); root_->add_menu(WORDS_MENU_RESET_ROLLOER_CNT, child);
child->release(); child->release();
} }
@ -845,7 +850,8 @@ void ui_mgr::init(void)
}; };
handler_[menu_command::MENU_CMD_ID_SHUTDOWN] = f; 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); root_->add_menu(WORDS_MENU_SHUTDOWN, child);
child->release(); child->release();
} }

View File

@ -43,8 +43,9 @@ class dev_menu : public refer
}; };
}MITEM; }MITEM;
std::vector<MITEM> items_; std::vector<MITEM> items_;
int cur_ = 0; int init_pos_ = 0;
int sel_ = -1; int cur_ = 0; // focus item
int sel_ = -1; // current checked item
bool check_item_ = false; bool check_item_ = false;
bool need_ret_parent_ = true; 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 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); bool select(const char* txt);
void reset_pos(void); void reset_pos(void);
void set_default_pos(int pos = 0);
// Function: access current menu // Function: access current menu
// //

View File

@ -61,7 +61,7 @@ add_defines("BUILD_AS_DEVICE")
add_defines("VER_MAIN=2") add_defines("VER_MAIN=2")
add_defines("VER_FAMILY=200") add_defines("VER_FAMILY=200")
add_defines("VER_DATE=20240221") add_defines("VER_DATE=20240221")
add_defines("VER_BUILD=9") add_defines("VER_BUILD=24")
target("conf") target("conf")
set_kind("phony") set_kind("phony")