synchronize from branch dev
This commit is contained in:
parent
ea2edfd30c
commit
a0123c49b9
|
@ -152,7 +152,6 @@ cv::Scalar CImageApplyAutoCrop::getBackGroudColor(const cv::Mat& image, int thre
|
|||
}
|
||||
}
|
||||
|
||||
CImageApplyDispersion m_dispersion_apply;
|
||||
void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst, bool isAutoCrop, bool isDesaskew, bool isFillBlank, int dWidth, int dHeight,
|
||||
bool isConvex, bool isColorBlank, double threshold, int noise, int indent, bool isNormalCrop, bool dispersion, double fx, double fy)
|
||||
{
|
||||
|
@ -217,6 +216,7 @@ void CImageApplyAutoCrop::autoCrop_desaskew_fillBlank(cv::Mat& src, cv::Mat& dst
|
|||
|
||||
if (dispersion)
|
||||
{
|
||||
CImageApplyDispersion m_dispersion_apply;
|
||||
cv::Mat mat_dispersion = src(cv::boundingRect(maxContour));
|
||||
m_dispersion_apply.apply(mat_dispersion, 0);
|
||||
}
|
||||
|
|
|
@ -1,21 +1,38 @@
|
|||
#include "ImageApplyChannel.h"
|
||||
#include "ImageApplyAdjustColors.h"
|
||||
|
||||
CImageApplyChannel::CImageApplyChannel()
|
||||
: m_channel(Invalid)
|
||||
, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
, m_scale(0)
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyChannel::CImageApplyChannel(Channel channel)
|
||||
: m_channel(channel)
|
||||
, colors(new CImageApplyAdjustColors(0, 30, 1.0))
|
||||
{
|
||||
switch (m_channel)
|
||||
{
|
||||
case Red_Plus:
|
||||
m_scale = 0.333333;
|
||||
break;
|
||||
case Green_Plus:
|
||||
m_scale = 1;
|
||||
break;
|
||||
case Blue_Plus:
|
||||
m_scale = 1;
|
||||
break;
|
||||
default:
|
||||
m_scale = 0;
|
||||
}
|
||||
}
|
||||
|
||||
CImageApplyChannel::CImageApplyChannel(Channel channel, double scale)
|
||||
: m_channel(channel)
|
||||
, m_scale(scale)
|
||||
{
|
||||
}
|
||||
|
||||
CImageApplyChannel::~CImageApplyChannel()
|
||||
{
|
||||
if (colors != nullptr) delete colors;
|
||||
}
|
||||
|
||||
void CImageApplyChannel::apply(cv::Mat& pDib, int side)
|
||||
|
@ -24,11 +41,13 @@ void CImageApplyChannel::apply(cv::Mat& pDib, int side)
|
|||
if (pDib.empty()) return;
|
||||
|
||||
cv::Mat dst(pDib.rows, pDib.cols, CV_8UC1);
|
||||
cv::Mat mv[3];
|
||||
cv::split(pDib, mv);
|
||||
cv::Mat mask, mask1, mask2;
|
||||
switch (m_channel)
|
||||
{
|
||||
case Red:
|
||||
cv::extractChannel(pDib, dst, 2);
|
||||
colors->apply(pDib, side);
|
||||
break;
|
||||
case Green:
|
||||
cv::extractChannel(pDib, dst, 1);
|
||||
|
@ -48,6 +67,15 @@ void CImageApplyChannel::apply(cv::Mat& pDib, int side)
|
|||
case Except_Blue:
|
||||
except_channel(pDib, dst, 0);
|
||||
break;
|
||||
case Red_Plus:
|
||||
channel_plus(pDib, dst, 2, m_scale);
|
||||
break;
|
||||
case Green_Plus:
|
||||
channel_plus(pDib, dst, 1, m_scale);
|
||||
break;
|
||||
case Blue_Plus:
|
||||
channel_plus(pDib, dst, 0, m_scale);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -125,3 +153,15 @@ void CImageApplyChannel::colourless(const cv::Mat& src, cv::Mat& dst, uchar thre
|
|||
cv::cvtColor(hsv, hsv, cv::COLOR_HSV2BGR_FULL);
|
||||
cv::cvtColor(hsv, dst, cv::COLOR_BGR2GRAY);
|
||||
}
|
||||
|
||||
void CImageApplyChannel::channel_plus(const cv::Mat& src, cv::Mat& dst, int channel, double scale)
|
||||
{
|
||||
cv::Mat mv[3];
|
||||
cv::split(src, mv);
|
||||
cv::Mat temp;
|
||||
|
||||
temp = mv[channel] * 2 - mv[(channel + 1) % 3] - mv[(channel + 2) % 3];
|
||||
|
||||
//cv::imwrite("111/temp.jpg", temp);
|
||||
dst = mv[channel] + temp * scale;
|
||||
}
|
||||
|
|
|
@ -3,12 +3,15 @@
|
|||
|
||||
* 功能:通道提取,又名除色。可提取BGR图像中的单个通道、两种通道的混合以及去除彩色像素的图像,目标图像均为灰度图
|
||||
* 作者:刘丁维
|
||||
* 生成时间:2020/4/21
|
||||
* 最近修改时间:v1.0 2020/4/21
|
||||
v1.1 2020/6/11 在除红时,增加对比度,提高除色效果。
|
||||
v1.2 2020/7/21 修正之前增强红绿蓝效果的色彩配比。
|
||||
v1.3 2021/5/24 替换红色增强算法方案。
|
||||
* 版本号:v1.3
|
||||
* 生成时间:2020/04/21
|
||||
* 最近修改时间:v1.0 2020/04/21
|
||||
v1.1 2020/06/11 在除红时,增加对比度,提高除色效果。
|
||||
v1.2 2020/07/21 修正之前增强红绿蓝效果的色彩配比。
|
||||
v1.3 2021/05/24 替换红色增强算法方案。
|
||||
v1.4 2023/03/01 增加Red_Plus、Green_Plus和Blue_Plus模式。取消使用CImageApplyAdjustColors增强通道。
|
||||
v1.5 2023/03/16 可自定义Red_Plus、Green_Plus和Blue_Plus除色增强比例。
|
||||
v1.5.1 2023/03/16 修复通道切换的BUG。
|
||||
* 版本号:v1.5.1
|
||||
|
||||
* ====================================================
|
||||
*/
|
||||
|
@ -18,48 +21,59 @@
|
|||
|
||||
#include "ImageApply.h"
|
||||
|
||||
class CImageApplyAdjustColors;
|
||||
class GIMGPROC_LIBRARY_API CImageApplyChannel : public CImageApply
|
||||
{
|
||||
public:
|
||||
|
||||
typedef enum channel
|
||||
{
|
||||
Red, //红色通道
|
||||
Green, //绿色通道
|
||||
Blue, //蓝色通道
|
||||
Red_Plus, //增强红色通道
|
||||
Green_Plus, //增强绿色通道
|
||||
Blue_Plus, //增强蓝色通道
|
||||
All, //去除所有HSV色彩结构中,S大于80的色彩
|
||||
Invalid, //无效
|
||||
Except_Red, //绿蓝色通道混合
|
||||
Except_Green, //红蓝色通道混合
|
||||
Except_Blue //红绿色通道混合
|
||||
Except_Blue, //红绿色通道混合
|
||||
Red, //红色通道
|
||||
Green, //绿色通道
|
||||
Blue, //蓝色通道
|
||||
}Channel;
|
||||
|
||||
public:
|
||||
|
||||
CImageApplyChannel();
|
||||
|
||||
/*
|
||||
* channel [in]:通道模式
|
||||
* */
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// 默认Red_Plus时,m_scale = 0.333333;Green_Plus时, m_scale = 1;Blue_Plus时 m_scale = 1
|
||||
/// </summary>
|
||||
/// <param name="channel">通道模式</param>
|
||||
CImageApplyChannel(Channel channel);
|
||||
|
||||
/// <summary>
|
||||
/// 构造函数
|
||||
/// </summary>
|
||||
/// <param name="channel">通道模式</param>
|
||||
/// <param name="scale">仅在Red_Plus、 Green_Plus、 Blue_Plus模式下生效。增强除色效果,取值范围[0, +∞),值越大增强效果越明显</param>
|
||||
CImageApplyChannel(Channel channel, double scale);
|
||||
|
||||
virtual ~CImageApplyChannel(void);
|
||||
|
||||
virtual void apply(cv::Mat& pDib, int side);
|
||||
|
||||
virtual void apply(std::vector<cv::Mat>& mats, bool isTwoSide);
|
||||
|
||||
private:
|
||||
|
||||
void except_channel(const cv::Mat& src, cv::Mat& dst, int channel);
|
||||
|
||||
void colourless(const cv::Mat& src, cv::Mat& dst, uchar threshold = 80);
|
||||
|
||||
private:
|
||||
void channel_plus(const cv::Mat& src, cv::Mat& dst, int channel, double scale);
|
||||
|
||||
private:
|
||||
Channel m_channel;
|
||||
CImageApplyAdjustColors* colors;
|
||||
double m_scale;
|
||||
};
|
||||
|
||||
#endif // !IMAGE_APPLY_CHANNEL_H
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
#include "ImageApplyColorRecognition.h"
|
||||
#include "ImageApplyHeaders.h"
|
||||
|
||||
static CImageApplyBWBinaray m_bw;
|
||||
static CImageApplyAdjustColors m_ac(0, 50, 1.0f);
|
||||
//static CImageApplyBWBinaray m_bw;
|
||||
//static CImageApplyAdjustColors m_ac(0, 50, 1.0f);
|
||||
|
||||
/// <summary>
|
||||
/// 检测图像是否是彩色。当前逻辑仅针对红色像素进行判断,即存在红色像素则为彩色,否则为非彩色
|
||||
|
|
|
@ -292,6 +292,7 @@ enum
|
|||
SLEEP_TIME_0MIN = 0,
|
||||
SLEEP_TIME_5MIN,
|
||||
SLEEP_TIME_10MIN,
|
||||
SLEEP_TIME_20MIN,
|
||||
SLEEP_TIME_30MIN,
|
||||
SLEEP_TIME_60MIN,
|
||||
SLEEP_TIME_120MIN,
|
||||
|
@ -570,7 +571,7 @@ typedef struct _scan_conf
|
|||
unsigned char is_autocontrast; /**< 自动对比度>*/
|
||||
unsigned char is_autocrop; /**< 自动裁切>*/
|
||||
unsigned char is_autodiscradblank_normal; /**< 自动丢弃空白页通用>*/
|
||||
int discardblank_percent; /**< 跳过空白页阀值*/
|
||||
int discardblank_percent; /**< 跳过空白页阈值*/
|
||||
unsigned char is_autodiscradblank_vince; /**< 自动丢弃空白页发票>*/
|
||||
unsigned char is_switchfrontback; /**< 交换正反面>*/
|
||||
unsigned char autodescrew; /**< 自动纠偏>*/
|
||||
|
@ -700,6 +701,17 @@ namespace setting_hardware
|
|||
//硬件协议定义 -OVER
|
||||
namespace setting3288dsp
|
||||
{
|
||||
struct HG_JpegCompressInfo
|
||||
{
|
||||
unsigned int data_type;
|
||||
unsigned int first_frame;
|
||||
unsigned int last_frame;
|
||||
unsigned int index_frame;
|
||||
unsigned int DataLength;
|
||||
unsigned int width;
|
||||
unsigned int height;
|
||||
unsigned char* pJpegData;
|
||||
};
|
||||
//100-200 dsp 300-400 3288设备状态
|
||||
typedef enum tagUsbSupported
|
||||
{
|
||||
|
@ -1297,10 +1309,24 @@ namespace setting3399
|
|||
#define HGBASE_LIBNAME "libNeuBase.so"
|
||||
|
||||
#ifdef UOS
|
||||
#define HELP_PATH "../../entries/help/HuaGoScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH "../../entries/help/NeuScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#elif KYLIN
|
||||
#define HELP_PATH "../doc/HuaGoScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH "../doc/NeuScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#endif
|
||||
|
||||
#elif defined(OEM_DELI)
|
||||
#define LIBNAME "libdldriver.so"
|
||||
#define HGVERSION_LIBNANE "libDlVersion.so"
|
||||
#define IMGPRC_LIBNANE "libDlImgProc.so"
|
||||
#define HGBASE_LIBNAME "libDlBase.so"
|
||||
|
||||
#ifdef UOS
|
||||
#define HELP_PATH "../../entries/help/DeliScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#elif KYLIN
|
||||
#define HELP_PATH "../doc/DeliScan_scanSettings_Help_manual.pdf";
|
||||
#define HELP_PATH_EN ""
|
||||
#endif
|
||||
|
||||
|
@ -1359,7 +1385,14 @@ namespace setting3399
|
|||
#define HGVERSION_LIBNANE "NEUVersion.dll"
|
||||
#define IMGPRC_LIBNANE "NEUImgProc.dll"
|
||||
#define HGBASE_LIBNAME "NEUBase.dll"
|
||||
#define HELP_PATH "HuaGoScan_scanSettings_Help_manual.pdf"
|
||||
#define HELP_PATH "NeuScan_scanSettings_Help_manual.pdf"
|
||||
#define HELP_PATH_EN ""
|
||||
|
||||
#elif defined(OEM_DELI)
|
||||
#define HGVERSION_LIBNANE "DLVersion.dll"
|
||||
#define IMGPRC_LIBNANE "DLImgProc.dll"
|
||||
#define HGBASE_LIBNAME "DLBase.dll"
|
||||
#define HELP_PATH "DeliScan_scanSettings_Help_manual.pdf"
|
||||
#define HELP_PATH_EN ""
|
||||
|
||||
#else
|
||||
|
|
|
@ -163,7 +163,7 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i
|
|||
, is_auto_paper_scan_exit_time(60), is_read_int(true), is_auto_feedmode_(false)
|
||||
, firmware_sup_wait_paper_(false),firmware_sup_pick_strength_(false),firmware_sup_log_export_(false),firmware_sup_color_corr_(false),firmware_sup_wake_device_(false)
|
||||
, firmware_sup_double_img(false),firmware_sup_devs_lock_(false),firmware_sup_dpi_300(false),firmware_sup_dpi_600(false),firmware_sup_auto_speed_(false),firmware_sup_morr_(false)
|
||||
, firmware_sup_color_fill_(false),firmware_sup_history_cnt(false), have_max_size(false)
|
||||
, firmware_sup_color_fill_(false),firmware_sup_history_cnt(false), have_max_size(false), is_discardblank(false)
|
||||
{
|
||||
#if !defined(_WIN32) && !defined(_WIN64) &&defined(x86_64)
|
||||
isx86_Advan_ = false;
|
||||
|
@ -219,12 +219,11 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i
|
|||
|
||||
custom_gamma_val_ = new SANE_Gamma;
|
||||
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
|
||||
for (int i = 0; i < ARRAY_SIZE(custom_gamma_val_->table); ++i)
|
||||
custom_gamma_val_->table[i] = i & 0x0ff;
|
||||
|
||||
paper_size_mm_.cx = 210;
|
||||
paper_size_mm_.cy = 297;
|
||||
custom_gamma_val_->pt_count_r = custom_gamma_val_->pt_count_g = custom_gamma_val_->pt_count_b = 0;
|
||||
for (int i = 0; i < ARRAY_SIZE(custom_gamma_val_->table); ++i)
|
||||
custom_gamma_val_->table[i] = i & 0x0ff;
|
||||
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "%s(%p) constructed\n", name_.c_str(), this);
|
||||
image_prc_param_.value = 0;
|
||||
|
@ -250,6 +249,7 @@ hg_scanner::hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io, i
|
|||
#endif
|
||||
|
||||
ImagePrc_pHandle_ = hg_imgproc::init(pid_, isx86_Advan_);;
|
||||
//ImagePrc_pHandle_ = nullptr;
|
||||
}
|
||||
hg_scanner::~hg_scanner()
|
||||
{
|
||||
|
@ -269,6 +269,7 @@ hg_scanner::~hg_scanner()
|
|||
#endif
|
||||
|
||||
delete custom_gamma_val_;
|
||||
if(ImagePrc_pHandle_)
|
||||
hg_imgproc::release(ImagePrc_pHandle_);
|
||||
|
||||
name_.insert(0, lang_load_string(ID_STATU_DESC_SCANNER_ERR_DEVICE_DEVS, nullptr));
|
||||
|
@ -491,6 +492,9 @@ int hg_scanner::hg_version_init_handle()
|
|||
HGVersion_Free_ = (SDKHGVersion_Free_)dlsym(Dynamicopen_HGVersion_pHandle_, "HGVersion_DestroyMgr");
|
||||
|
||||
#else
|
||||
//string scanner_path = utils::get_module_full_path(LIBNAME);
|
||||
//scanner_path = scanner_path.substr(0, scanner_path.size() - strlen(LIBNAME));
|
||||
|
||||
string HGVersionlib_path = scanner_path + HGVERSION_LIBNANE;
|
||||
wchar_t* Prclibbuffer = new wchar_t[HGVersionlib_path.length() + 1];
|
||||
|
||||
|
@ -675,6 +679,11 @@ void hg_scanner::init_setting_func_map(void)
|
|||
setting_map_[SANE_STD_OPT_NAME_FOLD_TYPE] = &hg_scanner::setting_fold_type;
|
||||
setting_map_[SANE_STD_OPT_NAME_COLOR_CORRECTION] = &hg_scanner::setting_color_correction;
|
||||
setting_map_[SANE_STD_OPT_NAME_WAIT_SCAN_EXIT] = &hg_scanner::setting_auto_paper_scan_exit_time;
|
||||
setting_map_[SANE_STD_OPT_NAME_DISCARDBLANK] = &hg_scanner::setting_set_discardblank;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
setting_map_[SANE_STD_OPT_NAME_DEVICE_VID] = &hg_scanner::setting_get_dev_vid;
|
||||
setting_map_[SANE_STD_OPT_NAME_DEVICE_PID] = &hg_scanner::setting_get_dev_pid;
|
||||
|
@ -688,6 +697,7 @@ void hg_scanner::init_setting_func_map(void)
|
|||
setting_map_[SANE_STD_OPT_NAME_GET_DEVS_L0G] = &hg_scanner::setting_get_devs_log;
|
||||
setting_map_[SANE_STD_OPT_NAME_LANGUAGE] = &hg_scanner::setting_set_language;
|
||||
setting_map_[SANE_STD_OPT_NAME_MOTOR_VER] = &hg_scanner::setting_get_motor_ver;
|
||||
setting_map_[SANE_STD_OPT_NAME_INITIAL_BOOT_TIME] = &hg_scanner::setting_get_initial_boot_time;
|
||||
}
|
||||
std::string hg_scanner::setting_name_from(const char* n_or_id, int* id)
|
||||
{
|
||||
|
@ -799,6 +809,8 @@ void hg_scanner::get_range(const char* name, std::vector<std::string>& range, st
|
|||
}
|
||||
}
|
||||
|
||||
if (setting_jsn_.at(name).contains("default"))
|
||||
{
|
||||
if (type == "int")
|
||||
{
|
||||
int v = 0;
|
||||
|
@ -819,6 +831,7 @@ void hg_scanner::get_range(const char* name, std::vector<std::string>& range, st
|
|||
{
|
||||
def_val = get_setting_item_string(name, "default");
|
||||
}
|
||||
}
|
||||
//utils::to_log(LOG_LEVEL_DEBUG, "setting %d has %d range(s) and default value is '%s'\n", setting_no, range.size(), def_val.c_str());
|
||||
}
|
||||
bool hg_scanner::check_range(const char* name, bool& val)
|
||||
|
@ -962,6 +975,9 @@ int hg_scanner::restore(const char* name)
|
|||
std::string val("");
|
||||
int ret = SCANNER_ERR_OK;
|
||||
|
||||
if (!setting_jsn_.at(name).contains("default"))
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
|
||||
setting_jsn_.at(name).at("type").get_to(val);
|
||||
if (val == "string")
|
||||
{
|
||||
|
@ -1010,6 +1026,9 @@ bool hg_scanner::get_default_value(void* buf, json* jsn)
|
|||
{
|
||||
std::string type("");
|
||||
|
||||
if (!jsn->contains("default"))
|
||||
return false;
|
||||
|
||||
jsn->at("type").get_to(type);
|
||||
if (type == "bool")
|
||||
{
|
||||
|
@ -1086,12 +1105,15 @@ void hg_scanner::thread_handle_image_process(void)
|
|||
{
|
||||
if (!ImagePrc_pHandle_)
|
||||
{
|
||||
|
||||
ImagePrc_pHandle_ = hg_imgproc::init(pid_, isx86_Advan_);
|
||||
if (!ImagePrc_pHandle_)
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_FATAL, "[thread_handle_image_process]:Get Image Process is NULL pid is %d.\n", pid_);
|
||||
stop_fatal_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
|
||||
stop();
|
||||
break;
|
||||
}
|
||||
}
|
||||
image_process(tiny_buffer, id);
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
|
@ -1133,9 +1155,9 @@ void hg_scanner::working_begin(void*)
|
|||
}
|
||||
void hg_scanner::working_done(void*)
|
||||
{
|
||||
imgs_.Clear();
|
||||
if(user_cancel_)
|
||||
final_imgs_.clear();
|
||||
// imgs_.Clear(); // do before start ...
|
||||
// if(user_cancel_)
|
||||
// final_imgs_.clear();
|
||||
|
||||
if (status_ == SCANNER_ERR_OK && stop_fatal_)
|
||||
status_ = stop_fatal_;
|
||||
|
@ -1401,10 +1423,12 @@ bool hg_scanner::jsn_reorganize()
|
|||
if (!firmware_sup_wait_paper_ && pid_ == 0x239)
|
||||
{
|
||||
erase_option(SANE_STD_OPT_NAME_WAIT_TO_SCAN);
|
||||
erase_option(SANE_STD_OPT_NAME_WAIT_SCAN_EXIT);
|
||||
}
|
||||
if (!firmware_sup_pick_strength_ && pid_ == 0x239)
|
||||
{
|
||||
erase_option(SANE_STD_OPT_NAME_IS_AUTO_FEED_STRENGTH);
|
||||
erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH_VALUE);
|
||||
erase_option(SANE_STD_OPT_NAME_FEED_STRENGTH);
|
||||
}
|
||||
if (!firmware_sup_color_fill_ && (pid_ == 0x239 || pid_ == 0x439))
|
||||
|
@ -1486,27 +1510,97 @@ int hg_scanner::setting_restore(void* data, long* len)
|
|||
|
||||
return SCANNER_ERR_CONFIGURATION_CHANGED;
|
||||
}
|
||||
|
||||
static int GetModuleName(void* addr, char* name, int maxLen)
|
||||
{
|
||||
if (NULL == name || 0 == maxLen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if !defined(_WIN32)
|
||||
if (NULL == addr)
|
||||
{
|
||||
char dir[PATH_MAX] = { 0 };
|
||||
if (0 == readlink("/proc/self/exe", dir, PATH_MAX))
|
||||
return -1;
|
||||
if (maxLen < strlen(dir) + 1)
|
||||
return -1;
|
||||
strcpy(name, dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
Dl_info dlinfo;
|
||||
if (0 == dladdr(addr, &dlinfo))
|
||||
return -1;
|
||||
if (maxLen < strlen(dlinfo.dli_fname) + 1)
|
||||
return -1;
|
||||
strcpy(name, dlinfo.dli_fname);
|
||||
}
|
||||
#else
|
||||
HMODULE hModule = NULL;
|
||||
GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
|
||||
| GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT, (LPCSTR)addr, &hModule);
|
||||
|
||||
CHAR moduleName[MAX_PATH] = { 0 };
|
||||
DWORD len = GetModuleFileNameA(hModule, moduleName, MAX_PATH);
|
||||
if (0 == len || maxLen < strlen(moduleName) + 1)
|
||||
return -1;
|
||||
strcpy(name, moduleName);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int GetFilePath(const char* fileName, char* path, int maxLen)
|
||||
{
|
||||
if (NULL == fileName || NULL == path || 0 == maxLen)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#if defined(_WIN32)
|
||||
const char* pcName = strrchr(fileName, '\\');
|
||||
if (NULL == pcName)
|
||||
{
|
||||
pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
const char* pcName = strrchr(fileName, '/');
|
||||
if (NULL == pcName)
|
||||
return -1;
|
||||
#endif
|
||||
|
||||
++pcName;
|
||||
if (maxLen < (int)(pcName - fileName + 1))
|
||||
return -1;
|
||||
memcpy(path, fileName, pcName - fileName);
|
||||
path[pcName - fileName] = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hg_scanner::setting_help(void* data, long* len)
|
||||
{
|
||||
std::string helpfile = HELP_PATH;
|
||||
char moduleName[256];
|
||||
GetModuleName(NULL, moduleName, 256);
|
||||
char exePath[256];
|
||||
GetFilePath(moduleName, exePath, 256);
|
||||
std:string exePath2 = exePath;
|
||||
|
||||
std::string helpfile = exePath2 + HELP_PATH;
|
||||
std::string com = "xdg-open ";//注意空格保留
|
||||
int code_page = lang_get_cur_code_page();
|
||||
int ret = SCANNER_ERR_OK;
|
||||
|
||||
if (code_page == 20127)
|
||||
{
|
||||
helpfile = HELP_PATH_EN;
|
||||
helpfile = exePath2 + HELP_PATH_EN;
|
||||
}
|
||||
|
||||
#if defined(WIN32) || defined(_WIN64)
|
||||
std::string root(utils::get_module_full_path(SCANNER_DRIVER_PART_NAME));
|
||||
size_t pos = root.rfind(PATH_SEPARATOR[0]);
|
||||
|
||||
if(pos++ == std::string::npos)
|
||||
pos = 0;
|
||||
root.erase(pos);
|
||||
com = "";
|
||||
helpfile.insert(0, root);
|
||||
//helpfile.insert(0, root);
|
||||
FILE* src = fopen(helpfile.c_str(), "rb");
|
||||
if (src)
|
||||
fclose(src);
|
||||
|
@ -1628,13 +1722,24 @@ int hg_scanner::setting_rid_color(void* data, long* len)
|
|||
}
|
||||
int hg_scanner::setting_rid_multi_red(void* data, long* len)
|
||||
{
|
||||
int val = 2;
|
||||
image_prc_param_.bits.rid_red = *((bool*)data);
|
||||
if (*((bool*)data))
|
||||
{
|
||||
on_color_mode_changed(val);
|
||||
}
|
||||
|
||||
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
int hg_scanner::setting_rid_answer_red(void* data, long* len)
|
||||
{
|
||||
int val = 2;
|
||||
image_prc_param_.bits.rid_answer_red = *((bool*)data);
|
||||
if (*((bool*)data))
|
||||
{
|
||||
on_color_mode_changed(val);
|
||||
}
|
||||
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
|
@ -2686,6 +2791,21 @@ int hg_scanner::setting_get_motor_ver(void* data, long* len)
|
|||
}
|
||||
return ret;
|
||||
}
|
||||
int hg_scanner::setting_get_initial_boot_time(void* data, long* len)
|
||||
{
|
||||
string str;
|
||||
int ret = get_devs_time(str);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
strcpy((char*)data, str.c_str());
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
int hg_scanner::setting_set_discardblank(void* data, long* len)
|
||||
{
|
||||
is_discardblank = *(bool*)data;
|
||||
return SCANNER_ERR_OK;
|
||||
}
|
||||
int hg_scanner::on_color_mode_changed(int& color_mode)
|
||||
{
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
|
@ -2777,17 +2897,22 @@ void hg_scanner::adjust_color(hg_imgproc::HIMGPRC handle)
|
|||
if (img_conf_.pixtype == COLOR_MODE_BLACK_WHITE || img_conf_.pixtype == COLOR_MODE_256_GRAY)
|
||||
{
|
||||
tableLength = 256;
|
||||
memcpy(buffer1, custom_gamma_val_->table, tableLength);
|
||||
memcpy(buffer1, custom_gamma_val_->table + 256 * GAMMA_INDEX_GRAY, tableLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
// convert R[256] + G[256] + B[256] to BGR[256] ...
|
||||
//
|
||||
// To be modified: here should be color[256] + R[256] + G[256] + B[256] to BGR[256], final pixel = color[R[x]] - commented on 2023-08-07
|
||||
tableLength = 256 * 3;
|
||||
for (int i = 0; i < 256; ++i)
|
||||
{
|
||||
buffer1[i * 3 + 0] = custom_gamma_val_->table[256 * 2 + i];
|
||||
buffer1[i * 3 + 1] = custom_gamma_val_->table[256 * 1 + i];
|
||||
buffer1[i * 3 + 2] = custom_gamma_val_->table[256 * 0 + i];
|
||||
//buffer1[i * 3 + 0] = custom_gamma_val_->table[256 * GAMMA_INDEX_BLUE + i];
|
||||
//buffer1[i * 3 + 1] = custom_gamma_val_->table[256 * GAMMA_INDEX_GREEN + i];
|
||||
//buffer1[i * 3 + 2] = custom_gamma_val_->table[256 * GAMMA_INDEX_RED + i];
|
||||
buffer1[i * 3 + 0] = custom_gamma_val_->table[256 * GAMMA_INDEX_COLOR + custom_gamma_val_->table[256 * GAMMA_INDEX_BLUE + i]];
|
||||
buffer1[i * 3 + 1] = custom_gamma_val_->table[256 * GAMMA_INDEX_COLOR + custom_gamma_val_->table[256 * GAMMA_INDEX_GREEN + i]];
|
||||
buffer1[i * 3 + 2] = custom_gamma_val_->table[256 * GAMMA_INDEX_COLOR + custom_gamma_val_->table[256 * GAMMA_INDEX_RED + i]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2853,6 +2978,66 @@ void hg_scanner::change_setting_language(bool init)
|
|||
change_string_2_lang_id(v.c_str(), "desc");
|
||||
|
||||
setting_jsn_.at(v.c_str()).at("type").get_to(val);
|
||||
string depend;
|
||||
string depend_temp;
|
||||
bool is_depend = false;
|
||||
|
||||
if (setting_jsn_.at(v.c_str()).contains("depend_or"))
|
||||
{
|
||||
int depend_size = setting_jsn_.at(v.c_str()).at("depend_or").size();
|
||||
int y = 0;
|
||||
while (y < depend_size)
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_or").at(y).get_to(depend);
|
||||
for (size_t k = 0; k < erase_depend_.size(); k++)
|
||||
{
|
||||
if (depend.find(erase_depend_[k]) != string::npos)
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_or").erase(y);
|
||||
depend_temp = depend;
|
||||
y--;
|
||||
break;
|
||||
}
|
||||
else if (!depend_temp.empty() && !(depend[0] <= 'z' && depend[0] >= 'a'))
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_or").erase(y);
|
||||
y--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
depend_size = setting_jsn_.at(v.c_str()).at("depend_or").size();
|
||||
y++;
|
||||
}
|
||||
}
|
||||
else if (setting_jsn_.at(v.c_str()).contains("depend_and"))
|
||||
{
|
||||
int depend_size = setting_jsn_.at(v.c_str()).at("depend_and").size();
|
||||
int y = 0;
|
||||
while (y < depend_size)
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_and").at(y).get_to(depend);
|
||||
for (size_t k = 0; k < erase_depend_.size(); k++)
|
||||
{
|
||||
if (depend.find(erase_depend_[k]) != string::npos)
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_and").erase(y);
|
||||
depend_temp = depend;
|
||||
y--;
|
||||
break;
|
||||
}
|
||||
else if (!depend_temp.empty() && !(depend[0] <= 'z' && depend[0] >= 'a'))
|
||||
{
|
||||
setting_jsn_.at(v.c_str()).at("depend_and").erase(y);
|
||||
y--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
depend_size = setting_jsn_.at(v.c_str()).at("depend_and").size();
|
||||
y++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//if (v.compare(from_default_language(SANE_STD_OPT_NAME_TIME_TO_SLEEP)) == 0)
|
||||
//{
|
||||
// int val = 0;
|
||||
|
@ -2914,7 +3099,7 @@ void hg_scanner::change_setting_language(bool init)
|
|||
if (v.compare(from_default_language(SANE_STD_OPT_NAME_LANGUAGE)) == 0)
|
||||
continue;
|
||||
|
||||
if (init)
|
||||
if (init && setting_jsn_.at(v.c_str()).contains("default"))
|
||||
{
|
||||
val = get_setting_item_string(v.c_str(), "default");
|
||||
|
||||
|
@ -2929,7 +3114,7 @@ void hg_scanner::change_setting_language(bool init)
|
|||
free(buf);
|
||||
}
|
||||
}
|
||||
else if (init)
|
||||
else if (init && setting_jsn_.at(v.c_str()).contains("default"))
|
||||
{
|
||||
if (val == "int")
|
||||
{
|
||||
|
@ -2957,6 +3142,7 @@ void hg_scanner::change_setting_language(bool init)
|
|||
}
|
||||
void hg_scanner::erase_option(const char* name)
|
||||
{
|
||||
erase_depend_.push_back(name);
|
||||
setting_jsn_.erase(name);
|
||||
|
||||
std::vector<std::string>::iterator it = std::find(jsn_children_.begin(), jsn_children_.end(), name);
|
||||
|
@ -3582,6 +3768,20 @@ int hg_scanner::get_setting(const char* name, char* json_txt_buf, int* len, int*
|
|||
}
|
||||
else
|
||||
{
|
||||
// language can be set outer:
|
||||
if (real_n == SANE_STD_OPT_NAME_LANGUAGE && setting_jsn_.contains(SANE_STD_OPT_NAME_LANGUAGE))
|
||||
{
|
||||
LANATTR** lang = lang_get_supported_languages();
|
||||
for (int i = 0; lang[i]; ++i)
|
||||
{
|
||||
if (lang[i]->cp == lang_get_cur_code_page())
|
||||
{
|
||||
setting_jsn_.at(SANE_STD_OPT_NAME_LANGUAGE).at("cur") = lang[i]->id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//json_name.find(real_n)
|
||||
//auto it = json_name.find(real_n);
|
||||
//if (it != json_name.end())
|
||||
|
@ -3973,6 +4173,9 @@ int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len)
|
|||
case SLEEP_TIME_10MIN:
|
||||
val = 10;
|
||||
break;
|
||||
case SLEEP_TIME_20MIN:
|
||||
val = 20;
|
||||
break;
|
||||
case SLEEP_TIME_30MIN:
|
||||
val = 30;
|
||||
break;
|
||||
|
@ -4407,6 +4610,14 @@ int hg_scanner::get_motor_board_ver(string& ver)
|
|||
{
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
int hg_scanner::set_devs_time(string times)
|
||||
{
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
int hg_scanner::get_devs_time(string& times)
|
||||
{
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
}
|
||||
int hg_scanner::set_device_model(string sts)
|
||||
{
|
||||
return SCANNER_ERR_DEVICE_NOT_SUPPORT;
|
||||
|
@ -4583,6 +4794,14 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
|
|||
(this->*dump_img_)(ImagePrc_pHandle_, "auto_crop");
|
||||
}
|
||||
|
||||
if (is_quality_ == IMG_SPEED && resolution_ >= 300)//239
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "set resolution_ is :%d\n", resolution_);
|
||||
err = hg_imgproc::quality(ImagePrc_pHandle_, resolution_);
|
||||
|
||||
(this->*dump_img_)(ImagePrc_pHandle_, "quality");
|
||||
}
|
||||
|
||||
if (img_conf_.is_colorcast && pid_ != 0x239 && pid_ != 0x439)
|
||||
{
|
||||
ret = hg_imgproc::color_cast_correction(ImagePrc_pHandle_);
|
||||
|
@ -4724,13 +4943,7 @@ void hg_scanner::image_process(std::shared_ptr<tiny_buffer>& buffer, uint32_t id
|
|||
(this->*dump_img_)(ImagePrc_pHandle_, "ocr_auto_txtdirect");
|
||||
}
|
||||
|
||||
if (is_quality_ == IMG_SPEED && resolution_ >= 300)//239
|
||||
{
|
||||
utils::to_log(LOG_LEVEL_DEBUG, "set resolution_ is :%d\n", resolution_);
|
||||
err = hg_imgproc::quality(ImagePrc_pHandle_, resolution_);
|
||||
|
||||
(this->*dump_img_)(ImagePrc_pHandle_, "quality");
|
||||
}
|
||||
|
||||
if (is_multiout)//239
|
||||
{
|
||||
|
@ -4827,7 +5040,7 @@ int hg_scanner::image_configuration(SCANCONF& ic)
|
|||
ic.threshold = threshold_;
|
||||
ic.is_autocontrast = 0; //无参数
|
||||
ic.is_autocrop = (ic.papertype == TwSS::None || ic.papertype == TwSS::USStatement);
|
||||
ic.is_autodiscradblank_normal = image_prc_param_.bits.page == PAGE_OMIT_EMPTY;
|
||||
ic.is_autodiscradblank_normal = image_prc_param_.bits.page == PAGE_OMIT_EMPTY || is_discardblank;
|
||||
ic.discardblank_percent = omit_empty_level_;
|
||||
ic.is_autodiscradblank_vince = image_prc_param_.bits.page == PAGE_OMIT_EMPTY_RECEIPT;
|
||||
ic.is_switchfrontback = image_prc_param_.bits.exchange;
|
||||
|
|
|
@ -239,7 +239,8 @@ protected:
|
|||
int setting_get_devs_log(void* data, long* len);
|
||||
int setting_set_language(void* data, long* len);
|
||||
int setting_get_motor_ver(void* data, long* len);
|
||||
|
||||
int setting_get_initial_boot_time(void* data, long* len);
|
||||
int setting_set_discardblank(void* data, long* len);
|
||||
|
||||
virtual void on_device_reconnected(void);
|
||||
virtual int on_scanner_closing(bool force);
|
||||
|
@ -293,6 +294,7 @@ protected:
|
|||
bool cb_mem_;
|
||||
bool test_1_paper_; // 是否为单张扫描模式
|
||||
std::vector<std::string> jsn_children_;
|
||||
std::vector<string> erase_depend_; //需要删除父依赖项
|
||||
json setting_jsn_;
|
||||
|
||||
IMGPRCFIXPARAM image_prc_param_;
|
||||
|
@ -340,6 +342,7 @@ protected:
|
|||
bool color_correction_; //是否色彩校正
|
||||
int is_auto_paper_scan_exit_time; //待纸扫描退出时间
|
||||
bool is_auto_feedmode_; //是否启用自动分纸强度
|
||||
bool is_discardblank; //是否启动跳过空白页
|
||||
|
||||
SANE_DISTORTION_VAL distortion_val; //畸变修正结构体保存
|
||||
|
||||
|
@ -541,7 +544,10 @@ public:
|
|||
virtual int set_auto_flat(int data) = 0; //设置自动平场校正
|
||||
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
|
||||
virtual int set_updata0303(void) ;
|
||||
virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号
|
||||
virtual int get_motor_board_ver(string &ver); //获取G239电机板的固件号 //3399设备支持
|
||||
|
||||
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
|
||||
virtual int get_devs_time(string ×); //获取设备时间 //3399设备支持
|
||||
};
|
||||
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -48,6 +48,9 @@ class hg_scanner_239 : public hg_scanner
|
|||
void init_version(void);
|
||||
void thread_get_dves_image(void);
|
||||
void thread_correction(void);
|
||||
|
||||
int write_control_device_files(std::string file_path,std::string file_str);
|
||||
int read_control_device_files(std::string file_path, std::string &file_str);
|
||||
protected:
|
||||
virtual void on_device_reconnected(void) override;
|
||||
virtual int on_scanner_closing(bool force) override;
|
||||
|
@ -136,5 +139,8 @@ public:
|
|||
// data:0(ALL) 1(200dpi、gray) 2(200dpi、color) 3(300dpi、gray) 4(300dpi、color) 5(600dpi、gray) 6(600dpi、color)
|
||||
|
||||
virtual int get_motor_board_ver(string &ver);
|
||||
|
||||
virtual int set_devs_time(string times); //设置设备时间 //3399设备支持
|
||||
virtual int get_devs_time(string& times); //获取设备时间 //3399设备支持
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -59,6 +59,7 @@ private:
|
|||
int pop_image(void);
|
||||
int get_scanner_status(USBCB &usb);
|
||||
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
|
||||
int get_img_data_7010(std::shared_ptr<tiny_buffer>& imagedata);
|
||||
int writedown_device_configuration(bool type =false,setting_hardware::HGSCANCONF_3288 *d = NULL);
|
||||
void writedown_image_configuration(void);
|
||||
void printf_devconfig(setting_hardware::HGSCANCONF_3288 *d = NULL);
|
||||
|
@ -67,6 +68,8 @@ private:
|
|||
setting_hardware::HGSCANCONF_3288 dsp_config;
|
||||
Device::PaperSize papersize;
|
||||
bool is_devs_sleep_;
|
||||
int index_;
|
||||
char* pdata;
|
||||
public:
|
||||
//////////////固定的硬件信息设置或获取//////////////
|
||||
virtual std::string get_firmware_version(void)override;
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -234,11 +234,14 @@ namespace hg_imgproc
|
|||
pos = 0;
|
||||
my_path_.erase(pos);
|
||||
|
||||
cv::setUseOptimized(isx86_Advan_); //开关cpu高级指令<EFBFBD>?
|
||||
cv::setUseOptimized(isx86_Advan_); //开关cpu高级指令�
|
||||
}
|
||||
~imgproc()
|
||||
{
|
||||
free_auto_txt_hanld();
|
||||
#ifdef FREE_GLOBAL_OBJECTS
|
||||
cv::unload();
|
||||
#endif
|
||||
}
|
||||
|
||||
// load data
|
||||
|
@ -324,7 +327,7 @@ namespace hg_imgproc
|
|||
{
|
||||
return SCANNER_ERR_OUT_OF_RANGE;
|
||||
}
|
||||
printf("HGBaselib_path<EFBFBD>?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
|
||||
printf("HGBaselib_pathï¿?s HGImagePrclib_path:%s\r\n",HGBaselib_path.c_str(),HGImagePrclib_path.c_str());
|
||||
|
||||
Dynamicopen_HGImageprc_pHandle_ = dlopen(HGImagePrclib_path.c_str(), RTLD_LAZY);
|
||||
Dynamicopen_HGBase_pHandle_ = dlopen(HGBaselib_path.c_str(), RTLD_LAZY);
|
||||
|
@ -343,6 +346,9 @@ namespace hg_imgproc
|
|||
HGBase_FreeImg = (SDKHGBase_FreeImage_)dlsym(Dynamicopen_HGBase_pHandle_,"HGBase_DestroyImage");
|
||||
|
||||
#else
|
||||
//string scanner_path = hg_log::get_module_full_path("scanner.dll");
|
||||
//scanner_path = scanner_path.substr(0, scanner_path.size() - strlen("scanner.dll"));
|
||||
|
||||
string HGImagePrclib_path = scanner_path + IMGPRC_LIBNANE;
|
||||
string HGBaselib_path = scanner_path + HGBASE_LIBNAME;
|
||||
|
||||
|
@ -506,7 +512,7 @@ namespace hg_imgproc
|
|||
catch (const std::exception& e)
|
||||
{
|
||||
utils::log_info(e.what(), LOG_LEVEL_FATAL);
|
||||
throw(e); // 继续抛到上层处理<EFBFBD>?
|
||||
throw(e); // 继ç»æŠ›åˆ°ä¸Šå±‚处ç<EFBFBD>†ï¿?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -518,7 +524,7 @@ namespace hg_imgproc
|
|||
|
||||
if (pid_ == 0x100 || pid_ == 0x200 || pid_ == 0x300 || pid_ == 0x400 || pid == 0x402 || pid == 0x302)
|
||||
{
|
||||
//////除穿孔算法移至解压图像之<EFBFBD>?
|
||||
//////除穿å”算法移至解压图åƒ<EFBFBD>之ï¿?
|
||||
double left = img_conf_.fillholeratio_left / 100.0;
|
||||
double right = img_conf_.fillholeratio_right / 100.0;
|
||||
double top = img_conf_.fillholeratio_up / 100.0;
|
||||
|
@ -604,7 +610,7 @@ namespace hg_imgproc
|
|||
{
|
||||
cv::flip(matex.mat, matex.mat, rotation01_);
|
||||
cv::flip(matex.mat,matex.mat,rotation02_);
|
||||
if (i > 1 && (pid_ == 0x402 || pid_ == 0x100 || pid_ == 0x400 || pid_== 0x302))
|
||||
if (i > 1 && (pid_ == 0x402 || pid_ == 0x100 || pid_ == 0x400 || pid_== 0x302 || pid_ == 0x300))
|
||||
{
|
||||
cv::flip(matex.mat,matex.mat,-1);
|
||||
}
|
||||
|
@ -614,7 +620,7 @@ namespace hg_imgproc
|
|||
}
|
||||
CImageApplyRotation::RotationType rotatetype = CImageApplyRotation::RotationType::Invalid;
|
||||
|
||||
if (pid_ == 0x402 || pid_ == 0x400 || pid_ == 0x239 || pid_ == 0x439 || pid_ == 0x302)
|
||||
if (pid_ == 0x402 || pid_ == 0x400 || pid_ == 0x239 || pid_ == 0x439 || pid_ == 0x302 || pid_ == 0x300)
|
||||
rotatetype = CImageApplyRotation::RotationType::Rotate_90_clockwise;
|
||||
else if(pid_ == 0x100)
|
||||
rotatetype = CImageApplyRotation::RotationType::Rotate_90_anti_clockwise;
|
||||
|
@ -850,7 +856,7 @@ namespace hg_imgproc
|
|||
|
||||
//utils::to_log(LOG_LEVEL_DEBUG, "adjust_color: table len = %d, brightness = %f, contrast = %f, gamma = %f\n", tableLength
|
||||
// , img_conf_.brightness, img_conf_.contrast, img_conf_.gamma);
|
||||
if (gamma_table && tableLength)
|
||||
if (gamma_table && tableLength && img_conf_.pixtype != COLOR_MODE_AUTO_MATCH)
|
||||
{
|
||||
CImageApplyCustomGamma gamme(gamma_table, tableLength);
|
||||
|
||||
|
@ -1062,9 +1068,10 @@ namespace hg_imgproc
|
|||
|
||||
double threshold = 40;
|
||||
int edge = 30;
|
||||
int dis = img_conf_.discardblank_percent;
|
||||
if (img_conf_.is_autodiscradblank_vince)
|
||||
img_conf_.discardblank_percent *= 1.5;
|
||||
CImageApplyDiscardBlank discardblank(threshold, edge, img_conf_.discardblank_percent);
|
||||
dis *= 1.5;
|
||||
CImageApplyDiscardBlank discardblank(threshold, edge, dis);
|
||||
|
||||
discardblank.apply(mats, mats.size());
|
||||
|
||||
|
@ -1341,7 +1348,7 @@ namespace hg_imgproc
|
|||
info.width = mats.cols;
|
||||
info.origin = HGBASE_IMGORIGIN_TOP;
|
||||
int bits = mats.channels() == 1 ? 8 : 24;
|
||||
info.widthStep = mats.step; //opencv原始<EFBFBD>?
|
||||
info.widthStep = mats.step; //opencv原始�
|
||||
info.type = mats.channels() == 1 ? HGBASE_IMGTYPE_GRAY : HGBASE_IMGTYPE_BGR;
|
||||
|
||||
int ret = HGBase_CreatImg(const_cast<uchar*>(mats.data), &info, &image);
|
||||
|
@ -1353,11 +1360,11 @@ namespace hg_imgproc
|
|||
|
||||
|
||||
/// <summary>
|
||||
/// 8位图<EFBFBD>?位图
|
||||
/// 8ä½<EFBFBD>图ï¿?ä½<C3A4>图
|
||||
/// </summary>
|
||||
/// <param name="image">8bit<EFBFBD>?/param>
|
||||
/// <param name="image">8bitï¿?/param>
|
||||
/// <param name="threshold">阈值,建议默认127</param>
|
||||
/// <param name="reverse">true为反色,即黑0<EFBFBD>?;反之亦<E4B98B>?/param>
|
||||
/// <param name="reverse">true为å<EFBFBD><EFBFBD>色,å<EFBFBD>³é»‘0ï¿?ï¼›å<E280BA><C3A5>之亦ï¿?/param>
|
||||
/// <param name="align">true为四字节对齐</param>
|
||||
/// <returns>1位图</returns>
|
||||
///
|
||||
|
|
|
@ -376,7 +376,7 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
|
|||
int index = -1;
|
||||
for (int i = 0; i < _countof(g_supporting_devices); ++i)
|
||||
{
|
||||
// 064B 澶氬彴璁惧浣跨敤杩欎釜vid锛屾墍浠ュ姞杞芥椂涓嶄細娓呮瑕佹墦寮€鍝竴鍙拌澶囷紝鍙湁閫氳繃澶栭儴杩涜鍔犺浇鏀瑰彉瀹炰緥
|
||||
// 064B 婢舵艾褰寸拋鎯ь槵娴h法鏁ゆ潻娆庨嚋vid閿涘本澧嶆禒銉ュ<EFBFBD>鏉炶姤妞傛稉宥勭窗濞撳懏顨熺憰浣瑰ⅵ瀵<EFBFBD>偓閸濐亙绔撮崣鎷岊啎婢跺浄绱濋崣顏呮箒闁<EFBFBD>俺绻冩径鏍<EFBFBD>劥鏉╂稖顢戦崝鐘烘祰閺€鐟板綁鐎圭偘绶?
|
||||
if (g_supporting_devices[i].vid == vid && g_supporting_devices[i].pid == pid)
|
||||
{
|
||||
index = i;
|
||||
|
@ -411,7 +411,7 @@ void hg_scanner_mgr::on_hgscanner_pnp(usb_event ev, libusb_device* device, int v
|
|||
break;
|
||||
}
|
||||
}
|
||||
if (add) // 澶勭悊瀵硅薄鈥渄evice鈥濇敼鍙樼殑鎯呮櫙
|
||||
if (add) // 婢跺嫮鎮婄€电<EFBFBD>钖勯垾娓別vice閳ユ繃鏁奸崣妯兼畱閹<EFBFBD>懏娅?
|
||||
{
|
||||
i = 0;
|
||||
for (auto& v : online_devices_)
|
||||
|
@ -576,6 +576,7 @@ scanner_err hg_scanner_mgr::get_about_info(scanner_handle h, void* data, unsigne
|
|||
bytes += sizeof(tmp.appendix[0]) + BRAND_INFO_MAX_LENGTH + 8 + strlen(GET_LANG(BRAND_TITLE_IP,&islang)) + 8; append_cnt++;
|
||||
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_ROLLER_COUNT,&islang)) + 8; append_cnt++;
|
||||
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_HISTORY_COUNT,&islang)) + 8; append_cnt++;
|
||||
bytes += sizeof(tmp.appendix[0]) + 28 + strlen(GET_LANG(BRAND_TITLE_DEVICE_INITIAL_POWER_ON_TIME, &islang)) + 8; append_cnt++;
|
||||
bytes += sizeof(tmp.appendix[0]); append_cnt++;
|
||||
}
|
||||
|
||||
|
@ -635,6 +636,11 @@ scanner_err hg_scanner_mgr::get_about_info(scanner_handle h, void* data, unsigne
|
|||
info = scanner->get_device_model();
|
||||
if (!info.empty())
|
||||
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_DEVICE_MODEL, &islang), info.c_str(), NULL);
|
||||
ret = scanner->get_devs_time(info);
|
||||
if (ret == SCANNER_ERR_OK && !info.empty())
|
||||
{
|
||||
set_appendix_info_for_about(about, ptr, count, GET_LANG(BRAND_TITLE_ROLLER_COUNT, &islang), info.c_str(), NULL);
|
||||
}
|
||||
ret = scanner->get_roller_num(rolls);
|
||||
if (ret == SCANNER_ERR_OK)
|
||||
{
|
||||
|
@ -869,7 +875,8 @@ scanner_err hg_scanner_mgr::hg_scanner_get_parameter(scanner_handle h, const cha
|
|||
strcmp(SANE_STD_OPT_NAME_DEVICE_IP_ADDR, name) == 0 ||
|
||||
strcmp(SANE_STD_OPT_NAME_ROLLER_COUNT, name) == 0 ||
|
||||
strcmp(SANE_STD_OPT_NAME_TOTAL_COUNT, name) == 0 ||
|
||||
strcmp(SANE_STD_OPT_NAME_MOTOR_VER, name) == 0)
|
||||
strcmp(SANE_STD_OPT_NAME_MOTOR_VER, name) == 0 ||
|
||||
strcmp(SANE_STD_OPT_NAME_INITIAL_BOOT_TIME, name) == 0)
|
||||
return (scanner_err)SCAN_PTR(h)->set_setting(name, data, len);
|
||||
}
|
||||
|
||||
|
|
|
@ -495,7 +495,7 @@ void usb_manager::enum_endpoints(libusb_device* device, USBTRANSENDP* endp)
|
|||
else
|
||||
s = &ep->out; // = (conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress & 3) | LIBUSB_ENDPOINT_OUT;
|
||||
|
||||
// NOTE: 这里应该尽量将输入输出端口统一到同一个接口上来,目前未做,只取第一<EFBFBD>?
|
||||
// NOTE: 这里应该尽é‡<EFBFBD>将输入输出端å<EFBFBD>£ç»Ÿä¸€åˆ°å<EFBFBD>Œä¸€ä¸ªæŽ¥å<EFBFBD>£ä¸Šæ<EFBFBD>¥ï¼Œç›®å‰<EFBFBD>未å<EFBFBD>šï¼Œå<EFBFBD>ªå<EFBFBD>–第一ï¿?
|
||||
if (s->port == usb_manager::uninit_uint8)
|
||||
{
|
||||
s->port = conf->interface[j].altsetting[k].endpoint[l].bEndpointAddress & (LIBUSB_ENDPOINT_IN | LIBUSB_ENDPOINT_OUT | 3);
|
||||
|
@ -629,8 +629,13 @@ bool usb_io::make_singleton(void)
|
|||
singleton_->release();
|
||||
singleton_ = nullptr;
|
||||
last_err_ = SCANNER_ERR_OPENED_BY_OTHER_PROCESS;
|
||||
str.insert(0, "\350\256\276\345\244\207\345\267\262\347\273\217\350\242\253\350\277\233\347\250\213 '");
|
||||
str += "' \345\215\240\347\224\250";
|
||||
|
||||
std::string tips(from_default_language("\350\256\276\345\244\207\345\267\262\347\273\217\350\242\253\350\277\233\347\250\213 '%s' \345\215\240\347\224\250"));
|
||||
size_t pos = tips.find("%s");
|
||||
|
||||
if (pos != std::string::npos)
|
||||
tips.replace(pos, 2, str);
|
||||
str = std::move(tips);
|
||||
init_err_msg_ = str;
|
||||
utils::to_log(LOG_LEVEL_FATAL, "Open failed: %s\n", str.c_str());
|
||||
|
||||
|
@ -795,7 +800,7 @@ bool usb_io::on_io_error(scanner_err err, usb_manager::USBSIMPLEX* endp)
|
|||
|
||||
if (err == SCANNER_ERR_TIMEOUT)
|
||||
{
|
||||
//因为在发送img参数出现timeout,暂时禁<EFBFBD>?
|
||||
//å› ä¸ºåœ¨å<EFBFBD>‘é€<EFBFBD>imgå<EFBFBD>‚数出现timeout,暂时ç¦<EFBFBD>ï¿?
|
||||
// //utils::log_info(LOG_LEVEL_DEBUG, "Operation timeout\n");
|
||||
// libusb_clear_halt(handle_, endp->port);
|
||||
|
||||
|
|
|
@ -178,7 +178,7 @@ namespace local_utility
|
|||
return str > bgn;
|
||||
}
|
||||
|
||||
// 暂不支持科学计数<EFBFBD>?1.2e+10
|
||||
// æš‚ä¸<EFBFBD>支æŒ<EFBFBD>科å¦è®¡æ•°ï¿?1.2e+10
|
||||
bool get_number(const char*& str, double& val)
|
||||
{
|
||||
const char* bgn = str;
|
||||
|
@ -362,6 +362,8 @@ namespace local_utility
|
|||
TRY_MATCH(FOLD_TYPE);
|
||||
TRY_MATCH(COLOR_CORRECTION);
|
||||
TRY_MATCH(LANGUAGE);
|
||||
TRY_MATCH(INITIAL_BOOT_TIME);
|
||||
TRY_MATCH(DISCARDBLANK);
|
||||
|
||||
//TRY_MATCH(HISTORY_COUNT);
|
||||
//TRY_MATCH(DRIVER_VERSION);
|
||||
|
@ -414,6 +416,7 @@ namespace local_utility
|
|||
FIX_ID_TO_NAME(DRIVER_LOG, 255);
|
||||
FIX_ID_TO_NAME(DEVICE_LOG, 255);
|
||||
FIX_ID_TO_NAME(MOTOR_VER, 255);
|
||||
FIX_ID_TO_NAME(INITIAL_BOOT_TIME, 255);
|
||||
|
||||
FIX_ID_TO_NAME(DEVICE_SERIAL_NO, 255);
|
||||
FIX_ID_TO_NAME(FIRMWARE_VERSION, 255);
|
||||
|
@ -548,9 +551,6 @@ hg_sane_middleware::hg_sane_middleware(void) : opt_0_(nullptr), init_ok_(false)
|
|||
signal(SIGUSR1, &hg_sane_middleware::device_pnp);
|
||||
hg_scanner_set_sane_info(g_sane_name.c_str(), sane_ver);
|
||||
hg_scanner_initialize(local_utility::ui_cb, NULL);
|
||||
|
||||
if (lang_get_cur_code_page() != DEFAULT_CODE_PAGE)
|
||||
lang_refresh_language();
|
||||
register_language_changed_notify(&hg_sane_middleware::language_changed, true);
|
||||
|
||||
#if !defined(WIN32) && !defined(_WIN64)
|
||||
|
@ -891,17 +891,26 @@ SANE_Option_Descriptor* hg_sane_middleware::number_option_to_SANE_descriptor(con
|
|||
|
||||
return sod;
|
||||
}
|
||||
std::string hg_sane_middleware::get_string_in_json(json* jsn, const char* key)
|
||||
std::string hg_sane_middleware::get_string_in_json(json* jsn, const char* key, bool* has)
|
||||
{
|
||||
std::string str("");
|
||||
int id = -1;
|
||||
|
||||
if (has)
|
||||
*has = false;
|
||||
|
||||
if (jsn->get_value(key, id) && id != -1)
|
||||
{
|
||||
str = lang_load_string(id, &id);
|
||||
if (has)
|
||||
*has = true;
|
||||
}
|
||||
else
|
||||
jsn->get_value(key, str);
|
||||
{
|
||||
bool ok = jsn->get_value(key, str);
|
||||
if (has)
|
||||
*has = ok;
|
||||
}
|
||||
|
||||
return std::move(str);
|
||||
}
|
||||
|
@ -1033,6 +1042,7 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
|
|||
std::vector<std::string> constraints;
|
||||
double lower = .0f, upper = .0f, step = .0f;
|
||||
bool db_val = false;
|
||||
int opt_val_size = 0;
|
||||
|
||||
if (!jsn->get_value("type", val))
|
||||
return NULL;
|
||||
|
@ -1048,27 +1058,15 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
|
|||
{
|
||||
if (range->first_child(val))
|
||||
{
|
||||
size_t pos = val.find(".");
|
||||
if (pos != std::string::npos)
|
||||
{
|
||||
for (size_t i = val.length() - 1; i > pos; --i)
|
||||
{
|
||||
if (val[i] != '0')
|
||||
{
|
||||
pos = i + 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
val.erase(pos);
|
||||
}
|
||||
if (std::to_string(atoi(val.c_str())) == val)
|
||||
constraints.push_back(lang_load_string(atoi(val.c_str()), (int*)&lower));
|
||||
else
|
||||
local_utility::trans_language_if_was_word_id(val);
|
||||
constraints.push_back(val);
|
||||
opt_val_size = val.length();
|
||||
while (range->next_child(val))
|
||||
{
|
||||
local_utility::trans_language_if_was_word_id(val);
|
||||
constraints.push_back(val);
|
||||
if (opt_val_size < val.length())
|
||||
opt_val_size = val.length();
|
||||
}
|
||||
}
|
||||
delete range;
|
||||
|
@ -1174,8 +1172,17 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
|
|||
bool bv = false;
|
||||
|
||||
jsn->get_value("size", bytes);
|
||||
if (bytes < opt_val_size)
|
||||
{
|
||||
opt_val_size = ALIGN_INT(opt_val_size + 4);
|
||||
local_utility::to_log(LOG_LEVEL_DEBUG, "Resize size of '%s' from %d to %d\n", name.c_str(), bytes, opt_val_size);
|
||||
bytes = opt_val_size;
|
||||
}
|
||||
ret->size = bytes;
|
||||
|
||||
if (jsn->get_value("auto", bv) && !bv)
|
||||
ret->cap &= ~SANE_CAP_AUTOMATIC;
|
||||
|
||||
if (jsn->get_value("readonly", bv) && bv)
|
||||
SET_CAP_READONLY(ret->cap)
|
||||
|
||||
|
@ -1200,7 +1207,7 @@ SANE_Option_Descriptor* hg_sane_middleware::from_json(scanner_handle h, const st
|
|||
//if (jsn->get_value("enable", enabled) && !enabled)
|
||||
// ret->cap |= SANE_CAP_INACTIVE;
|
||||
|
||||
// 关联<EFBFBD>?
|
||||
// å…³è<EFBFBD>”ï¿?
|
||||
json* depend = NULL;
|
||||
SLAVEOP so;
|
||||
if (jsn->get_value("depend_or", depend))
|
||||
|
@ -1505,7 +1512,7 @@ bool hg_sane_middleware::get_current_value(scanner_handle handle, const void* op
|
|||
|
||||
return ret;
|
||||
}
|
||||
void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* option, int* bytes, bool log)
|
||||
void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* option, int* bytes, bool log, bool* can_auto)
|
||||
{
|
||||
std::string val(get_option_json(handle, (void *)option));
|
||||
void* data = nullptr;
|
||||
|
@ -1514,6 +1521,15 @@ void* hg_sane_middleware::get_default_value(scanner_handle handle, const void* o
|
|||
if (jsn->attach_text(&val[0]) &&
|
||||
jsn->get_value("type", val))
|
||||
{
|
||||
if (can_auto)
|
||||
{
|
||||
bool yes = false;
|
||||
|
||||
*can_auto = true;
|
||||
if (jsn->get_value("auto", yes))
|
||||
*can_auto = yes;
|
||||
}
|
||||
|
||||
std::string title(hg_sane_middleware::get_string_in_json(jsn, "title"));
|
||||
if (val == "bool")
|
||||
{
|
||||
|
@ -1609,7 +1625,7 @@ SANE_Status hg_sane_middleware::get_devices(const SANE_Device*** device_list, SA
|
|||
|
||||
if (hgerr == SCANNER_ERR_INSUFFICIENT_MEMORY)
|
||||
{
|
||||
count += 4; // 为两次hg_scanner_enum间隙可能新增的设备预留空<EFBFBD>?
|
||||
count += 4; // 为两次hg_scanner_enumé—´éš™å<EFBFBD>¯èƒ½æ–°å¢žçš„设备预留空ï¿?
|
||||
dev = (ScannerInfo*)local_utility::acquire_memory(sizeof(ScannerInfo) * count, "hg_sane_middleware::get_devices");
|
||||
hgerr = hg_scanner_enum(dev, &count, local_only);
|
||||
if (hgerr != SCANNER_ERR_OK)
|
||||
|
@ -1895,10 +1911,16 @@ SANE_Status hg_sane_middleware::set_option(SANE_Handle h, const void* option, SA
|
|||
local_utility::to_log(LOG_LEVEL_WARNING, "Option %d(%s) call SANE_ACTION_SET_AUTO, we set default value.\n", option, desc->title);
|
||||
|
||||
int len = 0;
|
||||
void* val = get_default_value(handle, option, &len);
|
||||
bool can_auto = true;
|
||||
void* val = get_default_value(handle, option, &len, false, &can_auto);
|
||||
|
||||
if (!val || !can_auto)
|
||||
{
|
||||
if(val)
|
||||
local_utility::free_memory(val);
|
||||
|
||||
if (!val)
|
||||
return SANE_STATUS_UNSUPPORTED;
|
||||
}
|
||||
|
||||
if (value)
|
||||
{
|
||||
|
@ -2103,7 +2125,7 @@ bool hg_sane_middleware::is_ready(void)
|
|||
}
|
||||
|
||||
/// <summary>
|
||||
/// 关联项处<EFBFBD>?
|
||||
/// å…³è<EFBFBD>”项处ï¿?
|
||||
bool hg_sane_middleware::compare_val_equal(const char* cur_val, const char* limit_l, const char* limit_r)
|
||||
{
|
||||
return strcmp(cur_val, limit_l) == 0;
|
||||
|
@ -2454,7 +2476,7 @@ OPTEN* hg_sane_middleware::get_control_enalbe_data(LPDEVINST dev, const SLAVEOP&
|
|||
bzero(opt, size);
|
||||
|
||||
opt->enabled = slave.enable_now;
|
||||
opt->name = slave.name;
|
||||
strcpy(opt->name, slave.name.c_str());
|
||||
opt->master_count = 0;
|
||||
for (size_t i = 0; i < master.size(); ++i)
|
||||
{
|
||||
|
@ -2462,7 +2484,7 @@ OPTEN* hg_sane_middleware::get_control_enalbe_data(LPDEVINST dev, const SLAVEOP&
|
|||
if (m == dev->cur_vals.end())
|
||||
continue;
|
||||
|
||||
opt->master[opt->master_count].name = master[i];
|
||||
strcpy(opt->master[opt->master_count].name, master[i].c_str());
|
||||
if (m->type == "string")
|
||||
{
|
||||
opt->master[opt->master_count].data = malloc(m->val.length() + 4);
|
||||
|
@ -2477,8 +2499,8 @@ OPTEN* hg_sane_middleware::get_control_enalbe_data(LPDEVINST dev, const SLAVEOP&
|
|||
*((int*)opt->master[opt->master_count].data) = atoi(m->val.c_str());
|
||||
else
|
||||
*((double*)opt->master[opt->master_count].data) = atof(m->val.c_str());
|
||||
opt->master_count++;
|
||||
}
|
||||
opt->master_count++;
|
||||
}
|
||||
|
||||
return opt;
|
||||
|
|
|
@ -150,7 +150,7 @@ class hg_sane_middleware
|
|||
|
||||
void reload_current_value(scanner_handle handle, std::vector<std::string>* changed = NULL);
|
||||
bool get_current_value(scanner_handle handle, const void* option, void(*setv)(void*, size_t, void*), void* value, SANE_Value_Type* type = NULL);
|
||||
void* get_default_value(scanner_handle handle, const void* option, int* bytes = nullptr, bool log = false); // caller should call local_utility::free_memory to free the returned value
|
||||
void* get_default_value(scanner_handle handle, const void* option, int* bytes = nullptr, bool log = false, bool* can_auto = nullptr); // caller should call local_utility::free_memory to free the returned value
|
||||
|
||||
/// <summary>
|
||||
/// 关联项处理
|
||||
|
@ -215,7 +215,7 @@ public:
|
|||
, const std::vector<int>& values); // NO constraint if values was empty
|
||||
static SANE_Option_Descriptor* number_option_to_SANE_descriptor(const char* name, const char* title, const char* desc
|
||||
, const std::vector<double>& values); // NO constraint if values was empty
|
||||
static std::string get_string_in_json(json* jsn, const char* key);
|
||||
static std::string get_string_in_json(json* jsn, const char* key, bool* has = nullptr);
|
||||
|
||||
// methods ...
|
||||
public:
|
||||
|
|
|
@ -178,12 +178,12 @@ enum hg_control_code
|
|||
};
|
||||
typedef struct _opt_val
|
||||
{
|
||||
std::string name; // 配置项名称
|
||||
char name[MAX_OPT_NAME_LEN]; // 配置项名称
|
||||
void* data; // 配置项数据
|
||||
}OPTVAL;
|
||||
typedef struct _opt_enabled // 配置项使能状态改变
|
||||
{
|
||||
std::string name; // 配置项名称
|
||||
char name[MAX_OPT_NAME_LEN]; // 配置项名称
|
||||
int enabled; // 0 - 禁止;1 - 可用
|
||||
int master_count; // 该配置项的依赖项数目
|
||||
OPTVAL master[1]; // 该配置项的依赖项当前值
|
||||
|
|
Loading…
Reference in New Issue