add mode, paper, ... options

This commit is contained in:
gb 2023-05-03 11:21:41 +08:00
parent 3d125bc978
commit acc4c2e8e9
33 changed files with 2094 additions and 459 deletions

View File

@ -509,6 +509,8 @@ enum Scanner_Reg_Defs
SR_SCAN_DPI = 0x600, SR_SCAN_DPI = 0x600,
SR_SCAN_CNT, SR_SCAN_CNT,
SR_SCAN_PAPER,
SR_SCAN_PIXEL,
}; };
typedef union Ctrol_Description{ typedef union Ctrol_Description{

View File

@ -100,7 +100,7 @@ ScannerRegAccess::~ScannerRegAccess()
bool ScannerRegAccess::write(unsigned int addr, const unsigned int val) bool ScannerRegAccess::write(unsigned int addr, const unsigned int val)
{ {
static uint64_t img_cb = 0, img_param = 0; 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) if(addr == (unsigned int)-1)
{ {
@ -192,6 +192,12 @@ bool ScannerRegAccess::write(unsigned int addr, const unsigned int val)
case SR_SCAN_CNT: case SR_SCAN_CNT:
scan_cnt = val; scan_cnt = val;
return true; return true;
case SR_SCAN_PAPER:
paper_type = val;
return true;
case SR_SCAN_PIXEL:
pixel_type = val;
return true;
case SR_CONFIF_IMGPROCPARAM: case SR_CONFIF_IMGPROCPARAM:
{ {
printf("\nSR_CONFIF_IMGPROCPARAM size =%d\n",val); 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]; GScanCap cap = *(GScanCap*)&cfg[0];
cap.resolution_dst = scan_dpi; 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.scannum = scan_cnt;
cap.pixtype = 0; cap.pixtype = pixel_type;
cap.papertype = paper_type;
usbimages->set_dpi(scan_dpi, scan_dpi); usbimages->set_dpi(scan_dpi, scan_dpi);
printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt); printf("DPI: %d, Count: %d\n", scan_dpi, scan_cnt);
#else #else

View File

@ -31,6 +31,8 @@ public:
int set_dpi(int *dpix, int* dpiy); int set_dpi(int *dpix, int* dpiy);
int set_scan_num(int num); int set_scan_num(int num);
int set_img_receiver(void* api, void* param); int set_img_receiver(void* api, void* param);
int set_paper_type(int type);
int set_pixel_type(int *type);
#endif #endif
public: public:

View File

@ -160,6 +160,7 @@ int32_t log_cls::log_when_err(int32_t err, const char* oper_desc, log_level leve
return err; return err;
} }
#if !defined(WIN32) && !defined(_WIN64)
void log_cls::log_memory_usage(const char* tag, bool print_screen, const char* prog_name) void log_cls::log_memory_usage(const char* tag, bool print_screen, const char* prog_name)
{ {
std::string memu("--Memory usage of "); 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_) else if (log_cls::inst_)
log_cls::inst_->log(LOG_LEVEL_DEBUG, "%s\n", memu.c_str()); log_cls::inst_->log(LOG_LEVEL_DEBUG, "%s\n", memu.c_str());
} }
#endif
log_level log_cls::get_log_level(void) log_level log_cls::get_log_level(void)
{ {
if (log_cls::inst_) if (log_cls::inst_)

View File

@ -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 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"); 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 log_level get_log_level(void);
static std::string get_log_file(void); static std::string get_log_file(void);

View File

@ -17,6 +17,9 @@
#define FLOAT_PRECISION .000001f #define FLOAT_PRECISION .000001f
#define IS_FLOAT_EQUAL(x, y) (-FLOAT_PRECISION <= (x) - (y) && (x) - (y) <= FLOAT_PRECISION) #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_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 ROGER(cmd) cmd##_ROGER
#define PAIR_COMMAND(cmd) \ #define PAIR_COMMAND(cmd) \
cmd, \ cmd, \
@ -224,6 +227,12 @@ enum clr_channel
COLOR_CHANNEL_BLUE, COLOR_CHANNEL_BLUE,
COLOR_CHANNEL_ALPHA, COLOR_CHANNEL_ALPHA,
}; };
enum color_mode
{
COLOR_MODE_BW = 0,
COLOR_MODE_GRAY,
COLOR_MODE_RGB,
};
#pragma pack(push) #pragma pack(push)
#pragma pack(1) #pragma pack(1)

View File

@ -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;
}
};

View File

@ -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);
};

View File

@ -288,7 +288,7 @@ bool sane_cfg_provider::sane_refine_range(gb_json* jsn, void* data, size_t* len)
return ok; return ok;
} }
void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void sane_cfg_provider::update_option_enable_status(gb_json* opt, std::function<GET_SANE_OPT_PROTO> get_opt)
{ {
gb_json* depends = nullptr, *item = nullptr; gb_json* depends = nullptr, *item = nullptr;
bool able = true, oper_and = false; 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(); depends->release();
opt->set_value("enabled", able); 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) 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; 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; bool ret = true, bv = false;
int nv = 0; 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)) if(root->get_value(key, bv))
{ {
val = std::string((char*)&bv, sizeof(bv)); val = std::string((char*)&bv, sizeof(bv));
if(*type)
*type = DATA_TYPE_BOOL;
} }
else if(root->get_value(key, nv)) else if(root->get_value(key, nv))
{ {
val = std::string((char*)&nv, sizeof(nv)); val = std::string((char*)&nv, sizeof(nv));
if(*type)
*type = DATA_TYPE_INT4;
} }
else if(root->get_value(key, fv)) else if(root->get_value(key, fv))
{ {
val = std::string((char*)&fv, sizeof(fv)); val = std::string((char*)&fv, sizeof(fv));
if(*type)
*type = DATA_TYPE_FLOAT;
} }
else else
{ {
ret = root->get_value(key, val); ret = root->get_value(key, val);
if(type)
*type = ret ? DATA_TYPE_STRING : DATA_TYPE_CUSTOM;
} }
return ret; return ret;
} }
bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result) bool sane_cfg_provider::try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result)
{ {
bool oper_not = false, calc = true, handled = false; bool oper_not = false, calc = true, handled = false;
size_t pos = exp.find("=="); 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; handled = true;
if(pos) if(pos)
{ {
std::string types("");
char buf[40] = {0}, *mem = nullptr;
size_t l = sizeof(buf) - 1;
*name = exp.substr(0, pos); *name = exp.substr(0, pos);
get_opt(name->c_str(), buf, &l, "type"); get_opt(name->c_str(), "cur", *val, (uint32_t*)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;
} }
exp.erase(0, pos + 2); 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; return handled;
} }
bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result) bool sane_cfg_provider::try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result)
{ {
bool oper_not = false, calc = true, handled = false; bool oper_not = false, calc = true, handled = false;
size_t pos = exp.find(">"); 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; handled = true;
if(pos) if(pos)
{ {
std::string types("");
char buf[40] = {0}, *mem = nullptr;
size_t l = sizeof(buf) - 1;
*name = exp.substr(0, pos); *name = exp.substr(0, pos);
get_opt(name->c_str(), buf, &l, "type"); get_opt(name->c_str(), "cur", *val, (uint32_t*)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;
} }
exp.erase(0, pos + 1 + oper_not); 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; return handled;
} }
bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result) bool sane_cfg_provider::try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result)
{ {
bool oper_not = false, calc = true, handled = false; bool oper_not = false, calc = true, handled = false;
size_t pos = exp.find("<"); 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; handled = true;
if(pos) if(pos)
{ {
std::string types("");
char buf[40] = {0}, *mem = nullptr;
size_t l = sizeof(buf) - 1;
*name = exp.substr(0, pos); *name = exp.substr(0, pos);
get_opt(name->c_str(), buf, &l, "type"); get_opt(name->c_str(), "cur", *val, (uint32_t*)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;
} }
exp.erase(0, pos + 1 + oper_not); 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; return handled;
} }
bool sane_cfg_provider::is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) bool sane_cfg_provider::is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt)
{ {
// ==, >, < // ==, >, <
// !=, <=, >= // !=, <=, >=
@ -790,32 +763,17 @@ std::string sane_cfg_mgr::get_all_configurations(void)
} }
void sane_cfg_mgr::update_enable_status(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; int32_t ret = 0;
for(auto& v: sane_waiters_) 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) if(ret != ENOENT)
break; 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; return ret;
}; };

View File

@ -14,40 +14,27 @@
#include <functional> #include <functional>
//{ // proto of getting raw value of sane-option
// "paper": { //
// "category": "base", // cfg_name - option name
// "readonly": false, //
// "affect": 0, // key - the value key in JSON, e.g.: current value key is "cur"
// "group": "base", //
// "visible": true, // val - to receive the raw value
// "field": "Common", //
// "ver": 1, // type - to receive the value type
// "pos": 0, //
// "unit": "None", #define GET_SANE_OPT_PROTO int32_t(const char* cfg_name, const char* key, std::string& val, uint32_t* type)
// "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,
};
class gb_json; class gb_json;
class sane_cfg_provider : public refer class sane_cfg_provider : public refer
{ {
static bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result); static bool try_equal(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result);
static bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result); static bool try_great(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result);
static bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt, bool* result); static bool try_less(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt, bool* result);
static bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt); static bool is_depends_item_ok(std::string& exp, std::string* name, int* type, std::string* val, std::function<GET_SANE_OPT_PROTO> get_opt);
public: public:
sane_cfg_provider(); 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 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_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 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<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt); static void update_option_enable_status(gb_json* opt, std::function<GET_SANE_OPT_PROTO> get_opt);
static data_type type_from_string(const char* type_desc); 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: protected:
int32_t inner_get_config(gb_json* root, void* buf, size_t* len, const char* cfg_name, std::string* strval); 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 // 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 // Return: none
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) = 0; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) = 0;
// Function: get value of given key // Function: get value of given key
// //
@ -125,9 +104,11 @@ public:
// //
// val = to receive the raw value. e.g. std::string(&bool, sizeof(bool)) // val = to receive the raw value. e.g. std::string(&bool, sizeof(bool))
// //
// type - to receive the value type (data_type)
//
// Return: 0 - success, // Return: 0 - success,
// ENOENT - not found // 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 class sane_cfg_mgr : public refer

File diff suppressed because one or more lines are too long

View File

@ -33,13 +33,383 @@ typedef struct _cis_api
CIS_API set_exposure_back_blue; CIS_API set_exposure_back_blue;
}CISAPI, *LPCISAPI; }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 class image_capture : public sane_cfg_provider
{ {
gb_json* cfg_; gb_json* cfg_;
CISAPI api_; CISAPI api_;
double dpi_x_;
double dpi_y_;
std::function<CAPTURED_IMG_RECEIVER_PROTO> img_keeper_; std::function<CAPTURED_IMG_RECEIVER_PROTO> img_keeper_;
int32_t set(const char* name, void* data, size_t* len); int32_t set(const char* name, void* data, size_t* len);
void refresh_paper_size(bool from_paper_type = false);
public: public:
image_capture(std::function<CAPTURED_IMG_RECEIVER_PROTO> receiver); image_capture(std::function<CAPTURED_IMG_RECEIVER_PROTO> receiver);
@ -51,8 +421,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
void set_api(LPCISAPI api); 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 // 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); 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);
}; };

View File

@ -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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> 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();
}

View File

@ -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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> get_opt_value) override;
uint32_t position(void) override;
uint32_t version(void) override;
const char* option_name(void) override;
};

View File

@ -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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> 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();
}

View File

@ -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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> get_opt_value) override;
uint32_t position(void) override;
uint32_t version(void) override;
const char* option_name(void) override;
};

View File

@ -140,7 +140,7 @@ int32_t dogear::set_config(const char* cfg_name, void* data, size_t* len, uint32
return ret; return ret;
} }
void dogear::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void dogear::update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt)
{ {
gb_json* child = root_->first_child(); gb_json* child = root_->first_child();
while(child) while(child)
@ -150,14 +150,14 @@ void dogear::update_enabled(std::function<int32_t(const char* cfg_name, void* bu
child = root_->next_child(); child = root_->next_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; int32_t ret = ENOENT;
gb_json* child = nullptr; gb_json* child = nullptr;
if(root_->get_value(name, child) && child) 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(); child->release();
} }

View File

@ -176,8 +176,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
img_one_paper* execute(img_one_paper* img) override; img_one_paper* execute(img_one_paper* img) override;

View File

@ -1,12 +1,16 @@
#include "img_algorithm.h" #include "img_algorithm.h"
#include "dogear.h"
#include "common/json/gb_json.h" #include "common/json/gb_json.h"
#include "../capimage/hgutils.h" #include "../capimage/hgutils.h"
#include "dogear.h"
#include "remove_hole.h"
#include "discard_blank.h"
#include "auto_crop.h"
#ifdef TEMPORARY_API #ifdef TEMPORARY_API
extern int32_t (*set_dpi)(int*, int*); extern int32_t (*set_dpi)(int*, int*);
extern int32_t (*set_pixel_type)(int*);
#endif #endif
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -95,6 +99,15 @@ img_alg* img_alg::create_image_algorithm(img_alg_type type)
return dynamic_cast<img_alg*>(new img_resizer()); return dynamic_cast<img_alg*>(new img_resizer());
if(type == IMG_ALG_ADJUST_COLOR) if(type == IMG_ALG_ADJUST_COLOR)
return dynamic_cast<img_alg*>(new color_correct()); return dynamic_cast<img_alg*>(new color_correct());
if(type == IMG_ALG_REMOVE_HOLE)
return dynamic_cast<img_alg*>(new rm_hole());
if(type == IMG_ALG_DISCARD_BLANK)
return dynamic_cast<img_alg*>(new discard_blank());
if(type == IMG_ALG_COLOR_TRANSFER)
return dynamic_cast<img_alg*>(new img_color_transfer());
// if(type == IMG_ALG_AUTO_CROP)
// return dynamic_cast<img_alg*>(new auto_crop());
return nullptr; return nullptr;
} }
@ -117,7 +130,7 @@ const char* img_alg::option_name(void)
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// class img_resizer // class color_correct
// { // {
// "color-correct": { // "color-correct": {
// "category": "base", // "category": "base",
@ -125,7 +138,7 @@ const char* img_alg::option_name(void)
// "visible": true, // "visible": true,
// "field": "imgproc", // "field": "imgproc",
// "group": "imgproc", // "group": "imgproc",
// "pos": 100, // "pos": 400,
// "unit": "none", // "unit": "none",
// "ver": 1, // "ver": 1,
// "title": "颜色校正", // "title": "颜色校正",
@ -138,7 +151,7 @@ const char* img_alg::option_name(void)
// } // }
// } // }
static std::string color_correct_json = 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) 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) if(cfg_->get_value(cfg_name, child) && child)
{ {
sane_cfg_provider::sane_refine_range(child, data, len); sane_cfg_provider::sane_refine_range(child, data, len);
if(name_ == cfg_name) sane_cfg_provider::sane_option_value_set(child, data);
{ child->release();
std::string val((char*)data);
on_cur_val_changed(val);
child->set_value("cur", val.c_str());
child->release();
}
} }
return ret; return ret;
} }
void color_correct::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void color_correct::update_enabled(std::function<GET_SANE_OPT_PROTO> 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; gb_json *child = nullptr;
int32_t ret = ENOENT; int32_t ret = ENOENT;
if(cfg_->get_value(name, child) && child) 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(); child->release();
} }
@ -276,7 +283,7 @@ bool color_correct::is_enabled(std::function<int32_t(const char*, void*, size_t*
// } // }
// } // }
static std::string resize_json = static std::string resize_json =
"{\"resolution\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"CIS\",\"pos\":200,\"unit\":\"DPI\",\"ver\":1,\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":{\"min\":100,\"max\":600,\"step\":50}}}"; "{\"resolution\":{\"category\":\"base\",\"readonly\":false,\"visible\":true,\"field\":\"imgproc\",\"group\":\"base\",\"pos\":200,\"unit\":\"DPI\",\"ver\":1,\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"cur\":200,\"default\":200,\"size\":4,\"range\":{\"min\":100,\"max\":600,\"step\":50}}}";
img_resizer::img_resizer() : dpi_(200), enable_(false) img_resizer::img_resizer() : dpi_(200), enable_(false)
{ {
@ -334,27 +341,28 @@ int32_t img_resizer::set_config(const char* cfg_name, void* data, size_t* len, u
{ {
dpi_ = *(int*)data; dpi_ = *(int*)data;
child->set_value("cur", dpi_); child->set_value("cur", dpi_);
child->release();
int x = *(int*)data, int x = *(int*)data,
y = x; y = x;
set_dpi(&x, &y); set_dpi(&x, &y);
enable_ = x != dpi_ || y != dpi_; enable_ = x != dpi_ || y != dpi_;
} }
child->release();
} }
return ret; return ret;
} }
void img_resizer::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void img_resizer::update_enabled(std::function<GET_SANE_OPT_PROTO> 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; gb_json *child = nullptr;
int32_t ret = ENOENT; int32_t ret = ENOENT;
if(cfg_->get_value(name, child) && child) 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(); child->release();
} }
@ -384,13 +392,147 @@ bool img_resizer::is_enabled(std::function<int32_t(const char*, void*, size_t*)>
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> get_opt_value)
{
return enable_;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// class img_alg // class img_encoder
// { // {
// "img-format": { // "img-format": {
// "category": "base", // "category": "base",
// "readonly": true, // "readonly": false,
// "affect": 0, // "affect": 0,
// "group": "output", // "group": "output",
// "visible": true, // "visible": true,
@ -408,7 +550,7 @@ bool img_resizer::is_enabled(std::function<int32_t(const char*, void*, size_t*)>
// } // }
// } // }
static std::string fmt_json = 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") 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; return ret;
} }
void img_encoder::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void img_encoder::update_enabled(std::function<GET_SANE_OPT_PROTO> 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; gb_json* child = nullptr;
int32_t ret = ENOENT; int32_t ret = ENOENT;
if(cfg_->get_value(name, child) && child) 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(); child->release();
ret = val.empty() ? ENOENT : 0;
} }
return ret; return ret;

View File

@ -64,9 +64,10 @@ enum img_alg_type
IMG_ALG_NONE = 0, IMG_ALG_NONE = 0,
IMG_ALG_DOGEAR, IMG_ALG_DOGEAR,
IMG_ALG_SIZE_CHECK, IMG_ALG_SIZE_CHECK,
IMG_ALG_FILL_HOLE, IMG_ALG_REMOVE_HOLE,
IMG_ALG_DISCARD_BLANK,
IMG_ALG_AUTO_CROP, IMG_ALG_AUTO_CROP,
IMG_ALG_BLANK, IMG_ALG_COLOR_TRANSFER,
IMG_ALG_CUSTOM_AREA, IMG_ALG_CUSTOM_AREA,
IMG_ALG_FADE_BACK, IMG_ALG_FADE_BACK,
IMG_ALG_FILTER, IMG_ALG_FILTER,
@ -126,8 +127,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
virtual img_one_paper* execute(img_one_paper* img) override; virtual img_one_paper* execute(img_one_paper* img) override;
@ -149,8 +150,32 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) 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<int32_t(const char*, void*, size_t*)> 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_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
virtual img_one_paper* execute(img_one_paper* img) override; virtual img_one_paper* execute(img_one_paper* img) override;
@ -171,8 +196,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
MemoryPtr encode(PROCIMG* img); MemoryPtr encode(PROCIMG* img);

View File

@ -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_SANE_OPT_PROTO> 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<cv::Mat> 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<int32_t(const char*, void*, size_t*)> 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();
}

View File

@ -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_SANE_OPT_PROTO> 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<int32_t(const char*, void*, size_t*)> get_opt_value) override;
uint32_t position(void) override;
uint32_t version(void) override;
const char* option_name(void) override;
};

View File

@ -195,7 +195,7 @@ int32_t cis_pre_do::set_config(const char* cfg_name, void* data, size_t* len, ui
return ret; return ret;
} }
void cis_pre_do::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void cis_pre_do::update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt)
{ {
gb_json* root = new gb_json(); gb_json* root = new gb_json();
@ -207,7 +207,7 @@ void cis_pre_do::update_enabled(std::function<int32_t(const char* cfg_name, void
root->release(); root->release();
} }
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; gb_json* root = new gb_json(), *child = nullptr;
int32_t ret = ENOENT; 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(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; ret = 0;
child->release(); child->release();
} }

View File

@ -32,8 +32,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
img_one_paper* execute(img_one_paper* img); img_one_paper* execute(img_one_paper* img);

View File

@ -102,10 +102,11 @@ void img_processor::load_processors(void)
CREATE_ALG(IMG_ALG_DOGEAR); CREATE_ALG(IMG_ALG_DOGEAR);
CREATE_ALG(IMG_ALG_SIZE_CHECK); 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_AUTO_CROP);
CREATE_ALG(IMG_ALG_BLANK); CREATE_ALG(IMG_ALG_DISCARD_BLANK);
CREATE_ALG(IMG_ALG_CUSTOM_AREA); CREATE_ALG(IMG_ALG_CUSTOM_AREA);
CREATE_ALG(IMG_ALG_COLOR_TRANSFER);
CREATE_ALG(IMG_ALG_FADE_BACK); CREATE_ALG(IMG_ALG_FADE_BACK);
CREATE_ALG(IMG_ALG_FILTER); CREATE_ALG(IMG_ALG_FILTER);
CREATE_ALG(IMG_ALG_ADJUST_COLOR); 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; return ret;
} }
void img_processor::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void img_processor::update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt)
{ {
// sane_cfg_provider::update_option_enable_status(cfg_, get_opt); // sane_cfg_provider::update_option_enable_status(cfg_, get_opt);
cis_pre_->update_enabled(get_opt); cis_pre_->update_enabled(get_opt);
@ -325,18 +326,18 @@ void img_processor::update_enabled(std::function<int32_t(const char* cfg_name, v
reload_cur_processors(); reload_cur_processors();
encoder_->update_enabled(get_opt); encoder_->update_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) if(ret == ENOENT)
{ {
ret = encoder_->get_value(name, key, val); ret = encoder_->get_raw_value(name, key, val, type);
if(ret == ENOENT) if(ret == ENOENT)
{ {
for(auto& v: all_proc_) for(auto& v: all_proc_)
{ {
ret = v->get_value(name, key, val); ret = v->get_raw_value(name, key, val, type);
if(ret != ENOENT) if(ret != ENOENT)
break; break;
} }

View File

@ -62,8 +62,8 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name = nullptr, std::string* strval = nullptr) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
public: public:
int32_t push_image(img_one_paper* img/*scan status if 'over' was true*/, bool over = false); int32_t push_image(img_one_paper* img/*scan status if 'over' was true*/, bool over = false);

View File

@ -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); uint32_t err = cfg_mgr_->get_config(val, pack->payload, &str);
LPCFGVAL cfg = nullptr; 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); reply = dyn_mem::memory(base_head_size + sizeof(CFGVAL) + strlen(pack->payload) + 1 + val.length() + 1);
pk = (LPPACK_BASE)reply->ptr(); pk = (LPPACK_BASE)reply->ptr();
BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err); BASE_PACKET_REPLY(*pk, pack->cmd + 1, pack->pack_id, err);
@ -807,7 +807,7 @@ uint32_t async_scanner::stop(void)
// return ret; // return ret;
// } // }
// void async_scanner::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) // void async_scanner::update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt)
// { // {
// gb_json *jsn = new gb_json(); // gb_json *jsn = new gb_json();
// int32_t ret = EINVAL; // int32_t ret = EINVAL;

View File

@ -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 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
// virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; // virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
// virtual int32_t get_value(const char* name, const char* key, std::string& val) 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); 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);

View File

@ -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 !!! // read-only attributes not support this operation !!!
return EINVAL; return EINVAL;
} }
void readonly_cfg::update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) void readonly_cfg::update_enabled(std::function<GET_SANE_OPT_PROTO> 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; int32_t ret = ENOENT;
gb_json* child = nullptr; gb_json* child = nullptr;
if(jsn_->get_value(name, child) && child) 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; ret = 0;
child->release(); child->release();

View File

@ -26,6 +26,6 @@ protected:
public: public:
virtual int32_t get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval) override; 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 int32_t set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo) override;
virtual void update_enabled(std::function<int32_t(const char* cfg_name, void* buf, size_t* len, const char* key)> get_opt) override; virtual void update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt) override;
virtual int32_t get_value(const char* name, const char* key, std::string& val) override; virtual int32_t get_raw_value(const char* name, const char* key, std::string& val, uint32_t* type = nullptr) override;
}; };

View File

@ -22,6 +22,8 @@ int32_t (*scan_start)(void) = nullptr;
int32_t (*scan_stop)(void) = nullptr; int32_t (*scan_stop)(void) = nullptr;
int32_t (*set_dpi)(int*, int*) = nullptr; int32_t (*set_dpi)(int*, int*) = nullptr;
int32_t (*set_scan_num)(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; 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 #endif
@ -91,6 +93,14 @@ int32_t call_set_scan_num(int num)
{ {
return inst->set_scan_num(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) 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); return inst->set_img_receiver((void*)rcv, param);
@ -364,6 +374,8 @@ UsbDevice::UsbDevice(std::function<bool(int, struct usb_ctrlrequest *, unsigned
::set_dpi = call_set_dpi; ::set_dpi = call_set_dpi;
::set_scan_num = call_set_scan_num; ::set_scan_num = call_set_scan_num;
::set_image_receiver = call_set_image_receiver; ::set_image_receiver = call_set_image_receiver;
::set_paper_type = call_set_paper_type;
::set_pixel_type = call_set_pixel_type;
thread_pool<UsbDevice> *t = new thread_pool<UsbDevice>(this); thread_pool<UsbDevice> *t = new thread_pool<UsbDevice>(this);
t->thread_new(&UsbDevice::do_system_command, R"(echo linaro | sudo -S sh -c "echo fe900000.dwc3 > /opt/cfg/usb_gadget/g1/UDC")"); 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; 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 #endif

View File

@ -885,6 +885,12 @@ HWND dlg_page::create_control_bool(int sn, const SANE_Option_Descriptor* desc, v
if (now) if (now)
SendMessage(wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0); SendMessage(wnd, BM_SETCHECK, (WPARAM)BST_CHECKED, 0);
if (IS_CAP_READONLY(desc->cap))
{
if (IsWindow(wnd))
EnableWindow(wnd, FALSE);
}
return wnd; 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) 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); vals.push_back(text);
} }
swprintf_s(text, _countof(text) - 1, L"%d", now); 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; x += size.cx;
} }
else 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; 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; 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) 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) if (v[i + 1] == *(SANE_Word*)cur_val)
wcscpy_s(cur, _countof(cur) - 1, text); 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; x += size.cx;
} }
else 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; 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; 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 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; int x = pos_.x;
std::wstring now(local_trans::a2u((char*)cur_val, CP_UTF8)); 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; x += text_size->cx + dlg_page::gap_x;
if (desc->constraint_type == SANE_CONSTRAINT_STRING_LIST) 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)); std::wstring text(local_trans::a2u(str[i], CP_UTF8));
vals.push_back(text); 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; x += size.cx;
} }
else 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); wnd = create_edit(sn, x, pos_.y, text_size->cy, 200);
SetWindowTextW(wnd, now.c_str()); SetWindowTextW(wnd, now.c_str());
x += 200; 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; 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_RELEASEDCAPTURE)
{ {
if (pnmh->code == NM_CUSTOMDRAW && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) && GetFocus() == pnmh->hwndFrom) // drag track ... //if (pnmh->code == NM_CUSTOMDRAW && (GetAsyncKeyState(VK_LBUTTON) & 0x8000) && GetFocus() == pnmh->hwndFrom) // drag track ...
; // ;
else //else
return FALSE; 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) if (GetWindowLong(ctrls_[ind], GWL_ID) != sn)
break; 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); 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()); HWND host = (HWND)GetPropW(ctrls_[ind], dlg_page::property_host.c_str());
if (IsWindow(host)) if (IsWindow(host))
{ {
BOOL checked = SendMessage(host, BM_GETCHECK, 0, 0) == BST_CHECKED; 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_) if (sn - dlg_page::dyn_id_base == id_custom_area_)
{ {
EnableWindow(ctrls_[ind], checked); EnableWindow(ctrls_[ind], checked);