code_device/hgdriver/hgdev/hg_scanner.h

331 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
// hg_scanner is the base class of kinds of scanners
//
// created on 2022-01-30
//
#include <memory>
#include <string>
#include <vector>
#include <algorithm>
#include <mutex>
#include <thread>
#include "usb_manager.h"
#include "../../sdk/hginclude/huagaoxxx_warraper_ex.h"
#include "jsonconfig.h"
#include "../3rdparty/nick/StopWatch.h"
#include "hg_ipc.h"
#include "common_setting.h"
#include "image_process.h"
#include "StopWatch.h"
#include "PaperSize.h"
#ifdef WIN32
#else
#include <unistd.h>
#endif
enum
{
HG_BASE_SETTING_INDEX_RESTORE_DEFAULT_SETTINGS = 0, // 恢复默认设置
HG_BASE_SETTING_INDEX_HELP, // 帮助
HG_BASE_SETTING_INDEX_COLOR_MODE, // 颜色模式
HG_BASE_SETTING_MULTI_OUT, // 多流输出
HG_BASE_SETTING_INDEX_ERASE_COLOR, // 除色
HG_BASE_SETTING_INDEX_ERASE_MULTI_OUT_RED, // 多流输出除红
HG_BASE_SETTING_INDEX_ERASE_ANSWER_RED, // 答题卡除红
HG_BASE_SETTING_INDEX_ERASE_BACKGROUND, // 移除背景
HG_BASE_SETTING_INDEX_ERASE_BACKGROUND_RANGE, // 移除背景范围
HG_BASE_SETTING_INDEX_NOISE_OPTIMIZE, // 黑白图像噪点优化
HG_BASE_SETTING_INDEX_NOISE_OPTIMIZE_SIZE, // 噪点优化尺寸
HG_BASE_SETTING_INDEX_PAPER, // 纸张尺寸
HG_BASE_SETTING_INDEX_PAPER_SIZE_CHECK, // 尺寸检测
HG_BASE_SETTING_INDEX_IS_CUSTOM_AREA, // 是否启用自定义区域
HG_BASE_SETTING_INDEX_CUSTOM_AREA_LEFT, // 自定义区域左侧mm
HG_BASE_SETTING_INDEX_CUSTOM_AREA_RIGHT, // 自定义区域右侧mm
HG_BASE_SETTING_INDEX_CUSTOM_AREA_TOP, // 自定义区域上侧mm
HG_BASE_SETTING_INDEX_CUSTOM_AREA_BOTTOM, // 自定义区域下侧mm
HG_BASE_SETTING_INDEX_PAGE, // 扫描页面
HG_BASE_SETTING_INDEX_PAGE_OMIT_EMPTY_LEVEL, // 跳过空白页灵敏度
HG_BASE_SETTING_INDEX_RESOLUTION, // 分辨率
HG_BASE_SETTING_INDEX_EXCHANGE, // 交换正反面
HG_BASE_SETTING_INDEX_SPLIT, // 图像拆分
HG_BASE_SETTING_INDEX_AUTO_CORRECT, // 自动纠偏
HG_BASE_SETTING_INDEX_RID_HOLE, // 穿孔移除
HG_BASE_SETTING_INDEX_RID_HOLE_RANGE, // 穿孔搜索范围
HG_BASE_SETTING_INDEX_IS_CUSTOM_GAMMA, // 是否启用自定义伽玛
HG_BASE_SETTING_INDEX_BRIGHT, // 亮度
HG_BASE_SETTING_INDEX_CONTRAST, // 对比度
HG_BASE_SETTING_INDEX_GAMMA, // 伽玛
HG_BASE_SETTING_INDEX_CUSTOM_GAMMA_DATA, // 自定义伽玛数据
HG_BASE_SETTING_INDEX_SHARPEN, // 锐化与模糊
HG_BASE_SETTING_INDEX_DARK_SAMPLE, // 深色样张
HG_BASE_SETTING_INDEX_ERASE_BLACK_FRAME, // 消除黑框
HG_BASE_SETTING_INDEX_THRESHOLD, // 阈值
HG_BASE_SETTING_INDEX_ANTI_NOISE_LEVEL, // 背景抗噪等级
HG_BASE_SETTING_INDEX_MARGIN, // 边缘缩进
HG_BASE_SETTING_INDEX_FILL_BACKGROUND, // 背景填充方式
HG_BASE_SETTING_INDEX_PERMEATE, // 防止渗透
HG_BASE_SETTING_INDEX_PERMEATE_LV, // 防止渗透等级
HG_BASE_SETTING_REMOVE_MORR, // 去除摩尔纹
HG_BASE_SETTING_ERROR_EXTENTION, // 错误扩散
HG_BASE_SETTING_REMOVE_TXTTURE, // 除网纹
HG_BASE_SETTING_INDEX_ULTRASONIC_CHECK, // 超声波检测
HG_BASE_SETTING_INDEX_STAPLE_CHECK, // 装订检测
HG_BASE_SETTING_INDEX_SCAN_MODE, // 连续扫描或扫描指定张数
HG_BASE_SETTING_INDEX_SCAN_COUNT, // 扫描指定数量
HG_BASE_SETTING_INDEX_TEXT_DIRECTION, // 文稿方向
HG_BASE_SETTING_INDEX_ROTATE_BKG_180, // 背面旋转180°
HG_BASE_SETTING_INDEX_FRACTATE_CHECK, // 折角检测
HG_BASE_SETTING_INDEX_FRACTATE_CHECK_LEVEL, // 折角检测复杂度
HG_BASE_SETTING_INDEX_SKEW_CHECK, // 歪斜检测
HG_BASE_SETTING_INDEX_SKEW_CHECK_LEVEL, // 歪斜检测复杂度
// 常规的功能索引声明必须在此之前
HG_BASE_SETTING_INDEX_MAX,
};
class hg_scanner
{
bool notify_setting_result_;
std::string name_;
sane_callback ui_ev_cb_;
do_when_born_and_dead<hg_scanner>* scan_life_;
std::unique_ptr<std::thread> thread_usb_read_;
void thread_handle_usb(void);
std::unique_ptr<std::thread> thread_img_handle_;
void thread_image_handle(void);
void get_range(int setting_no, std::vector<std::string>& range, std::string& def_val, bool& is_range/*range or list*/);
bool check_range(int setting_no, bool& val);
bool check_range(int setting_no, int& val);
bool check_range(int setting_no, double& val);
bool check_range(int setting_no, std::string& val);
int restore(int setting_no);
bool get_default_value(void* buf, json* jsn);
bool is_to_file(void);
void thread_handle_image_process(void);
void working_begin(void*);
void working_done(void*);
void reset_custom_area_range(int paper);
// 设置接口
protected:
// 配置序号映射数组各子类必须重载“init_setting_map”方法以初始化该数组
// 比如: 某型设备的“颜色模式”功能号为1则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = 1
// 如果设备的“颜色模式”配置逻辑与基类预定义的不同,
// 则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = -1在子类重载的set_setting_value方法中处理
int setting_map_[HG_BASE_SETTING_INDEX_MAX];
virtual void init_setting_map(int* setting_map, int count);
int setting_restore(void* data);
int setting_help(void* data);
int setting_color_mode(void* data);
int setting_multi_out(void *data);
int setting_rid_color(void* data);
int setting_rid_multi_red(void* data);
int setting_rid_answer_red(void* data);
int setting_erase_background(void* data);
int setting_erase_background_range(void* data);
int setting_noise_optimize(void* data);
int setting_noise_optimize_range(void* data);
int setting_paper(void* data);
int setting_paper_check(void* data);
int setting_page(void* data);
int setting_page_omit_empty(void* data);
int setting_resolution(void* data);
int setting_exchagnge(void* data);
int setting_split_image(void* data);
int setting_automatic_skew(void* data);
int setting_rid_hole(void* data);
int setting_rid_hoe_range(void* data);
int setting_bright(void* data);
int setting_contrast(void* data);
int setting_gamma(void* data);
int setting_sharpen(void* data);
int setting_dark_sample(void* data);
int setting_erase_black_frame(void* data);
int setting_threshold(void* data);
int setting_anti_noise(void* data);
int setting_margin(void* data);
int setting_filling_background(void* data);
int setting_is_permeate(void *data);
int setting_is_permeate_lv(void *data);
int setting_remove_morr(void* data);
int setting_error_extention(void* data);
int setting_remove_texture(void* data);
int setting_ultrasonic_check(void* data);
int setting_staple_check(void* data);
int setting_scan_mode(void* data);
int setting_scan_count(void* data);
int setting_text_direction(void* data);
int setting_rotate_bkg_180(void* data);
int setting_fractate_check(void* data);
int setting_fractate_check_level(void* data);
int setting_skew_check(void* data);
int setting_skew_check_level(void* data);
int setting_is_custom_gamma(void* data);
int setting_custom_gamma_data(void* data);
int setting_is_custom_area(void* data);
int setting_custom_area_left(void* data);
int setting_custom_area_top(void* data);
int setting_custom_area_right(void* data);
int setting_custom_area_bottom(void* data);
virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx
virtual int on_paper_changed(int& paper); // PAPER_xxx
virtual int on_paper_check_changed(bool& check);
virtual int on_resolution_changed(int& dpi);
virtual int on_ultrasonic_check_changed(bool& check);
virtual int on_staple_check_changed(bool& check);
virtual int on_skew_check_changed(bool& check);
virtual int on_skew_check_level_changed(int& check);
protected:
virtual void on_device_reconnected(void);
virtual int set_setting_value(int setting_no, void* data, int len);
virtual int on_scanner_closing(bool force);
virtual void thread_handle_usb_read(void) = 0;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) = 0;
protected:
volatile bool run_;
volatile bool user_cancel_;
platform_event wait_usb_;
platform_event wait_img_;
usb_io* io_;
std::mutex io_lock_;
bool online_;
int status_;
bool async_io_;
bool cb_mem_;
bool test_1_paper_; // 是否为单张扫描模式
json setting_jsn_;
int setting_count_;
IMGPRCFIXPARAM image_prc_param_;
int erase_bkg_range_; // 背景移除像素范围
int noise_range_; // 噪点优化尺寸
TwSS paper_size_;
int omit_empty_level_; // 跳过空白页灵敏度
int resolution_; // 分辨率
double rid_hole_range_; // 穿孔移除范围
int bright_; // 亮度
int contrast_; // 对比度
double gamma_; // 伽玛
int threshold_; // 阈值
int anti_noise_; // 背景搞噪等级
int margin_; // 边缘缩进
int fractate_level_; // 折角检测复杂度
int scan_count_; // 扫描张数各实例化类在重载set_setting_value中如果发现该设置项对该参数有影响时需要对此值作更改
bool is_auto_matic_color;// 自动颜色识别
SCANCONF img_conf_; //此参数外部不做任何改变请在writedown_image_configuration做修改
std::string img_type_;
image_data final_imgs_; // JPG ...
unsigned int final_img_index_;
BlockingQueue<std::shared_ptr<std::vector<char>>> imgs_;
BlockingQueue<std::string> paths_;
void init_settings(const char* json_setting_text);
int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作
// callback to ui ...
int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = HG_ERR_OK);
bool waiting_for_memory_enough(unsigned need_bytes);
void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels);
int save_usb_data(std::shared_ptr<std::vector<char>> data);
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf);
////////////////////////////////////////////////////////////////
// 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05
bool custom_gamma_; // 为true时应用custom_gamma_val_阵列调整图像色彩为false时保持原来的处理方式
SANE_Gamma *custom_gamma_val_; // 当为RGB或者彩色时为三组256字节的数据当为黑白或灰度时只有一组256字节
bool custom_area_; // 是否启用自定义区域为true时才使用下列4个数据为false时保持原来的处理方式
double custom_area_lt_x_; // 自定义区域左上角x坐标
double custom_area_lt_y_; // 自定义区域左上角y坐标
double custom_area_br_x_; // 自定义区域右下角x坐标
double custom_area_br_y_; // 自定义区域右下角y坐标
SIZE paper_size_mm_; // 当前纸张尺寸mm
// 新增自定义伽玛曲线及扫描区域属性 - END
////////////////////////////////////////////////////////////////
public:
void set_ui_callback(sane_callback cb, bool enable_async_io);
int reset_io(usb_io* io);
int io_disconnected(void);
int get_pid(void);
int get_vid(void);
int close(bool force);
int set_setting(int setting_no, void* data, int len);
int get_setting(int setting_no, char* json_txt_buf, int* len);
std::string name(void);
int status(void);
bool is_online(void);
public:
virtual int start(void);
virtual int get_image_info(SANE_Parameters* ii);
virtual int read_image_data(unsigned char* buf, int* len);
virtual int stop(void);
virtual int reset(void);
virtual int device_io_control(unsigned long code, void* data, unsigned* len);
public:
hg_scanner(ScannerSerial serial, const char* dev_name, usb_io* io);
virtual ~hg_scanner();
static std::string strerr(hg_err err);
static std::string error_description(hg_err err);
static std::string temporary_file(char* tail = NULL, char* head = NULL);
static int save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std::string* path_file);
public:
///////////////////////////////新增 20220425//////////////////////////
virtual int set_leaflet_scan(void);//单张扫描
virtual int get_abuot_info(void);//获取软件关于信息 (基类实现)
virtual int restore_default_setting(void);//恢复默认设置 (基类实现)
virtual int set_final_image_format(SANE_FinalImgFormat* fmt); // 设置图像处理最终输出final())的图像数据格式 (基类实现) ***
virtual int get_compression_format(void);//获取支持的压缩格式 功能不支持
virtual int get_roller_num(void); //获取滚轮张数
virtual int clear_roller_num(void); // 清除滚轴计数
virtual int set_compression_format(void);//设置图像数据最终输出的压缩格式
virtual int set_auto_color_type(void);// 设置自动匹配颜色模式 (基类实现) ***
virtual std::string get_firmware_version(void);
virtual std::string get_serial_num(void);
virtual std::string get_ip(void);
virtual int get_device_code(void);//获取设备编码
virtual int get_sleep_time(int& getsleepime);//获取功耗模式(休眠)//获取功耗模式(休眠)
virtual int set_sleep_time(int sleeptime);//设置功耗模式(休眠)
virtual int get_dogear_distance(void);//获取折角检测最小距离阈值
virtual int set_dogear_distance(void);// 设置折角检测最小距离阈值
virtual int get_scanner_paperon(SANE_Bool* paperon = NULL);//获取设备有无纸张
virtual int set_scan_when_paper_on(void);//获取是否为检测到进纸盘上有纸即开始扫描
virtual int get_scan_when_paper_on(void);//设置是否为检测到进纸盘上有纸即开始扫描
virtual int get_scan_with_hole(void);// 获取是否为带孔扫描
virtual int set_scan_with_hole(void);// 设置是否为带孔扫描
virtual int get_scan_is_sleep(void);//获取设备是否休眠当中
};
static const std::string helpfile_ ="/opt/apps/com.huagaochina.huagoscan/entries/help/HuaGoScan_App_Help_manual.pdf";//帮助文档路径