sane_opt_provider接口调整,支持跨模块

This commit is contained in:
gb 2023-11-15 11:30:32 +08:00
parent 363fbf5517
commit 9b8100d8df
10 changed files with 109 additions and 35 deletions

View File

@ -4277,7 +4277,7 @@ int hg_scanner::image_configuration(SCANCONF& ic)
return ret;
}
std::string hg_scanner::get_value(const char* name, void* value, int* err)
char* hg_scanner::get_value(const char* name, void* value, size_t* size, int* err)
{
std::string val("");
int result = SCANNER_ERR_OK, nv = 0;
@ -4322,7 +4322,22 @@ std::string hg_scanner::get_value(const char* name, void* value, int* err)
if (err)
*err = result;
return std::move(val);
if (size)
*size = val.length();
if (val.length())
{
char* buf = (char*)malloc(val.length() + 1);
memcpy(buf, val.c_str(), val.length());
buf[val.length()] = 0;
return buf;
}
else
{
return nullptr;
}
}
int hg_scanner::set_value(const char* name, void* val)
{

View File

@ -543,9 +543,9 @@ public:
// sane_opt_provider
public:
virtual std::string get_value(const char* name, void* value, int* err = nullptr);
virtual int set_value(const char* name, void* val);
virtual void enable(const char* name, bool able);
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
virtual int set_value(const char* name, void* val) override;
virtual void enable(const char* name, bool able) override;
};

View File

@ -67,7 +67,7 @@ void offline_opts::init(void)
jsn->release();
}
std::string offline_opts::get_value(const char* name, void* value, int* err)
char* offline_opts::get_value(const char* name, void* value, size_t* size, int* err)
{
std::string ret("");
@ -87,7 +87,19 @@ std::string offline_opts::get_value(const char* name, void* value, int* err)
else if (err)
*err = SCANNER_ERR_NO_DATA;
return ret;
if (size)
*size = ret.length();
if (ret.length())
{
char* buf = (char*)malloc(ret.length() + 1);
memcpy(buf, ret.c_str(), ret.length());
buf[ret.length()] = 0;
return buf;
}
else
return nullptr;
}
int offline_opts::set_value(const char* name, void* value)
{

View File

@ -22,7 +22,7 @@ protected:
virtual ~offline_opts();
public:
virtual std::string get_value(const char* name, void* value, int* err = nullptr) override;
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr) override;
virtual int set_value(const char* name, void* value) override;
virtual void enable(const char* name, bool able) override;
};

View File

@ -1,6 +1,7 @@
#include "img_processor.h"
#include <json/gb_json.h>
#include <huagao/hgscanner_error.h>
@ -41,4 +42,7 @@ bool image_processor::set_opt_json_text(char* txt)
int image_processor::process(LPPROCIIM* in, size_t cnt, bool(*result)(LPPROCIIM, void*), void* param)
{
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
}

View File

@ -52,11 +52,23 @@ typedef struct _hg_img_info
uint32_t bits : 6;
uint32_t reserved : 13;
}HGIMGINFO;
typedef struct _proc_img_info_
{
HGIMGINFO info;
cv::Mat img;
}PROCIMGINFO, *LPPROCIMGINFO;
typedef struct _proc_img_info_modules // 跨模块参数
{
HGIMGINFO info;
uint32_t width; // in px
uint32_t height; // in px
uint32_t channels;
uint32_t bits; // bits per channel
uint32_t bytes_per_line;
uint8_t* data; // size = bytes_per_line * height
}PROCIIM, *LPPROCIIM;
#pragma pack(pop)
class image_processor : public sane_opt_provider
@ -80,5 +92,8 @@ public:
int get_position(void) { return pos_; }
virtual int process(std::vector<PROCIMGINFO>& in, std::vector<PROCIMGINFO>& out) = 0;
// 跨模块图像处理接口。回调函数返回false则停止处理void*参数同 'param'。
virtual int process(LPPROCIIM* in, size_t cnt, bool(*result)(LPPROCIIM, void*), void* param);
};

View File

@ -344,8 +344,13 @@ int imgproc_mgr::process(HGIMGINFO* info, uint8_t* data, size_t bytes, std::vect
{
try
{
ret = v->process(*src, *dst);
(this->*dumpf_)(*dst, v->from().c_str(), v->get_position());
if (v->is_in_another_module())
{
// use LPPROCIIM function ...
}
else
ret = v->process(*src, *dst);
(this->*dumpf_)(*dst, v->from(), v->get_position());
if (ret)
break;
@ -356,17 +361,17 @@ int imgproc_mgr::process(HGIMGINFO* info, uint8_t* data, size_t bytes, std::vect
catch (const std::exception& e)
{
ret = SCANNER_ERR_THROW_EXCEPTION;
utils::to_log(LOG_LEVEL_DEBUG, "FATAL: image %d process '%s' throws exception: %s!\n", info->paper_ind, v->from().c_str(), e.what());
std::string f(dump_usb_img_real(data, bytes, info, v->from().c_str()));
utils::to_log(LOG_LEVEL_WARNING, "FATAL: process image %d failed on '%s', source content save to file '%s'\n", info->paper_ind, v->from().c_str(), f.c_str());
utils::to_log(LOG_LEVEL_DEBUG, "FATAL: image %d process '%s' throws exception: %s!\n", info->paper_ind, v->from(), e.what());
std::string f(dump_usb_img_real(data, bytes, info, v->from()));
utils::to_log(LOG_LEVEL_WARNING, "FATAL: process image %d failed on '%s', source content save to file '%s'\n", info->paper_ind, v->from(), f.c_str());
break;
}
catch (...)
{
ret = SCANNER_ERR_THROW_EXCEPTION;
utils::to_log(LOG_LEVEL_DEBUG, "FATAL: image process '%s' throws unknown exception!\n", v->from().c_str());
std::string f(dump_usb_img_real(data, bytes, info, v->from().c_str()));
utils::to_log(LOG_LEVEL_WARNING, "FATAL: process image %d failed on '%s', source content save to file '%s'\n", info->paper_ind, v->from().c_str(), f.c_str());
utils::to_log(LOG_LEVEL_DEBUG, "FATAL: image process '%s' throws unknown exception!\n", v->from());
std::string f(dump_usb_img_real(data, bytes, info, v->from()));
utils::to_log(LOG_LEVEL_WARNING, "FATAL: process image %d failed on '%s', source content save to file '%s'\n", info->paper_ind, v->from(), f.c_str());
break;
}
}

View File

@ -44,13 +44,13 @@ void sane_opt_provider::set_where(const char* where)
}
}
std::string sane_opt_provider::get_opt_json(void)
const char* sane_opt_provider::get_opt_json(void)
{
return opt_jsn_txt_;
return opt_jsn_txt_.c_str();
}
std::string sane_opt_provider::from(void)
const char* sane_opt_provider::from(void)
{
return where_;
return where_.c_str();
}
void sane_opt_provider::set_following_provider(const char* name, sane_opt_provider* following)
{
@ -79,12 +79,15 @@ sane_opt_provider* sane_opt_provider::get_following(const char* name)
return prvd;
}
std::string sane_opt_provider::get_value(const char* name, void* value, int* err)
char* sane_opt_provider::get_value(const char* name, void* value, size_t* size, int* err)
{
if (err)
*err = SCANNER_ERR_DEVICE_NOT_SUPPORT;
return "";
if (size)
*size = 0;
return nullptr;
}
int sane_opt_provider::set_value(const char* name, void* val)
{

View File

@ -12,6 +12,8 @@
class sane_opt_provider : public refer
{
bool is_in_another_module_;
std::string opt_jsn_txt_;
std::string where_;
@ -28,13 +30,15 @@ protected:
void set_where(const char* where);
public:
std::string get_opt_json(void);
std::string from(void);
const char* get_opt_json(void); // if no content, return "" plz.
const char* from(void); // if no content, return "" plz.
bool is_in_another_module(void) { return is_in_another_module_; }
void set_following_provider(const char* name, sane_opt_provider* following); // when option has provided by more than one
sane_opt_provider* get_following(const char* name); // caller should ->release returned value
public:
virtual std::string get_value(const char* name, void* value, int* err = nullptr);
// return malloc(), real data size stored in parameter 'size'. invoker should free() the returned value
virtual char* get_value(const char* name, void* value, size_t* size, int* err = nullptr);
virtual int set_value(const char* name, void* val);
virtual void enable(const char* name, bool able);
};

View File

@ -1001,8 +1001,8 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
if (vn > vo)
{
// replace and discard all following options ...
write_log("SANE-OPT: use %s::%s(ver: %d) replaced with %s::%s(ver: %d)\n", src_[existing->key()]->from().c_str(), existing->key().c_str(), vo
, from->from().c_str(), opt->key().c_str(), vn);
write_log("SANE-OPT: use %s::%s(ver: %d) replaced with %s::%s(ver: %d)\n", src_[existing->key()]->from(), existing->key().c_str(), vo
, from->from(), opt->key().c_str(), vn);
vo = origin_->index(existing);
origin_->remove(vo);
@ -1033,7 +1033,7 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
else if (vn == vo)
{
// insert into following queue ...
write_log("SANE-OPT: inserting %s::%s to provider queue ...\n", from->from().c_str(), opt->key().c_str());
write_log("SANE-OPT: inserting %s::%s to provider queue ...\n", from->from(), opt->key().c_str());
opt->get_value("pos", vn);
existing->get_value("pos", vo);
if (vo < vn)
@ -1128,7 +1128,7 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
sane_opt_provider* next = src_[opt->key().c_str()]->get_following(opt->key().c_str());
while (next)
{
logi += " -> " + next->from();
logi += std::string(" -> ") + next->from();
sane_opt_provider* next1 = next;
next = next->get_following(opt->key().c_str());
@ -1140,8 +1140,8 @@ void device_option::insert_option(gb_json* opt, sane_opt_provider* from, const c
else
{
// discard new option ...
write_log("SANE-OPT: discard %s::%s(ver: %d) for %s::%s(ver: %d) existed!\n", from->from().c_str(), opt->key().c_str(), vn
, src_[existing->key()]->from().c_str(), existing->key().c_str(), vo);
write_log("SANE-OPT: discard %s::%s(ver: %d) for %s::%s(ver: %d) existed!\n", from->from(), opt->key().c_str(), vn
, src_[existing->key()]->from(), existing->key().c_str(), vo);
// disable discarded option
from->enable(existing->key().c_str(), false);
@ -1764,11 +1764,19 @@ int device_option::update_data(const char* name, void* value, bool reorder_if_ne
{
if (src_.count(SANE_STD_OPT_NAME_PAPER_W))
{
std::string w(src_[SANE_STD_OPT_NAME_PAPER_W]->get_value(SANE_STD_OPT_NAME_PAPER_W, nullptr)),
h(src_[SANE_STD_OPT_NAME_PAPER_H]->get_value(SANE_STD_OPT_NAME_PAPER_H, nullptr)),
size_t wl = 0, hl = 0;
char *ws = src_[SANE_STD_OPT_NAME_PAPER_W]->get_value(SANE_STD_OPT_NAME_PAPER_W, nullptr, &wl),
*hs = src_[SANE_STD_OPT_NAME_PAPER_H]->get_value(SANE_STD_OPT_NAME_PAPER_H, nullptr, &hl);
std::string w(ws ? std::string(ws, wl) : ""),
h(hs ? std::string(hs, hl) : ""),
lateral(get_option_value(SANE_STD_OPT_NAME_LATERAL, SANE_ACTION_GET_VALUE));
gb_json *jsnl = nullptr;
if (ws)
free(ws);
if (hs)
free(hs);
now_->get_value(SANE_STD_OPT_NAME_LATERAL, jsnl);
if (jsnl)
{
@ -1938,7 +1946,15 @@ std::string device_option::get_option_value(const char* name, int type, int* siz
else if (child->get_value("ownread", own_read) && own_read)
{
if (src_.count(name))
value = std::move(src_[name]->get_value(name, in_data));
{
size_t len = 0;
char* v = src_[name]->get_value(name, in_data, &len);
if (v)
{
value = std::string(v, len);
free(v);
}
}
}
else
value = device_option::option_value(child, type == SANE_ACTION_GET_DEFAULT_VALUE);