#pragma once // hg_scanner is the base class of kinds of scanners // // created on 2022-01-30 // #include #include #include #include #include #include #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" #if defined(WIN32) || defined(_WIN64) #include //暂时linux 屏蔽 #include #include #include #include #else #include #endif #define MAPPING_FUNCTION_IN_BASE // 定义该标志,各子类不必再初始化setting_map_数组 // 删除指针 #define SAFE_DELETE(p){ \ if (NULL != (p)) {delete((p)); \ (p) = NULL; \ }\ } #ifdef OEM_HANWANG #define hg_scanner hw_scanner #elif defined(OEM_LISICHENG) #define hg_scanner lsc_scanner #elif defined(OEM_CANGTIAN) #define hg_scanner cts_scanner #endif class hg_scanner { bool notify_setting_result_; std::string name_; std::string save_multiout; //保存多留输出类型 bool save_sizecheck; bool read_over_with_no_data_; // 针对第三方调用,在最后一段数据时是否返回“SCANNER_ERR_NO_DATA” int is_color_type_;//保存最后下发到设备的颜色类型 sane_callback ui_ev_cb_; do_when_born_and_dead* scan_life_; std::unique_ptr thread_usb_read_; void thread_handle_usb(void); std::unique_ptr thread_img_handle_; void thread_image_handle(void); void(hg_scanner::* dump_img_)(hg_imgproc::HIMGPRC himg, const char* desc); void dump_image_empty(hg_imgproc::HIMGPRC himg, const char* desc); void dump_image_real(hg_imgproc::HIMGPRC himg, const char* desc); void init_setting_func_map(void); std::string setting_name_from(const char* n_or_id); void get_range(const char* name, std::vector& range, std::string& def_val, bool& is_range/*range or list*/); bool check_range(const char* name, bool& val); bool check_range(const char* name, int& val); bool check_range(const char* name, double& val); bool check_range(const char* name, std::string& val); bool check_paper_and_resolution(int res, int paper); bool check_resolution_and_quality(int res, const char* quality); int restore(const char* name); 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 image_process(std::shared_ptr& buff); void reset_custom_area_range(int paper); float reset_custom_area_jsn_value(const char* name, double& var, float range_l, float range_u, float value_l, float value_u); // return cur value int set_color_change(void); // 设置接口 protected: // 配置序号映射数组,各子类必须重载“init_setting_map”方法以初始化该数组 --> 2022-05-09:基类中以title自动匹配功能序号,子类不必再处理并屏蔽此项工作 // 比如: 某型设备的“颜色模式”功能号为1,则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = 1 // 如果设备的“颜色模式”配置逻辑与基类预定义的不同, // 则 setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = -1,在子类重载的set_setting_value方法中处理 // // 2022-06-28: 属性处理函数改用map结构存储,只须处理set_setting_map函数即可 // int setting_map_[HG_BASE_SETTING_INDEX_MAX]; //virtual void init_setting_map(int* setting_map, int count); std::map setting_map_; int invoke_setting_xxx(int(hg_scanner::* func)(void*), void* data); int setting_restore(void* data); int setting_help(void* data); int setting_color_mode(void* data); int setting_multi_out(void* data); int setting_multi_out_type(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_go_on_when_double_checked(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); int setting_img_quality(void* data); int setting_color_fill(void* data); int setting_keep_watermark(void* data); int setting_black_white_threshold(void* data); int setting_white_pixel_0(void* data); int setting_setfeedmode(void* data); int setting_setsleeptime(void* data); int setting_set_auto_pick_paper(void* data); int setting_set_auto_pick_paper_threshold(void* data); int setting_set_auto_paper_scan(void* data); int setting_set_isremove_left_hole(void* data); int setting_set_isremove_right_hole(void* data); int setting_set_isremove_top_hole(void* data); int setting_set_isremove_low_hole(void* data); int setting_set_isremove_left_hole_threshold(void* data); int setting_set_isremove_right_hole_threshold(void* data); int setting_set_isremove_top_hole_threshold(void* data); int setting_set_isremove_low_hole_threshold(void* data); int setting_set_fold_type(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); virtual int on_get_feedmode(int& feedmode);//获取分纸强度 virtual int on_set_feedmode(int feedmode);//设置分纸强度 virtual int on_pic_type(bool& pic);//照片模式或者文本模式 virtual int on_pick_paper(bool autostrength);//设置搓纸使能 virtual int on_pick_paper_threshold(double threshold);//设置搓纸阈值 virtual int on_is_auto_paper(bool isautopaper);//待纸扫描 protected: virtual void on_device_reconnected(void); virtual int set_setting_value(const char* name, void* data, int len); virtual int on_scanner_closing(bool force); virtual void thread_handle_usb_read(void) = 0; // adjust color or apply custom gamma void adjust_color(hg_imgproc::HIMGPRC handle); hg_imgproc::IMGPRCPARAM get_image_process_object(int model); SANE_Image_Statu last_usb_image_statu(int err); hg_imgproc::HIMGPRC ImagePrc_pHandle_; protected: ScannerSerial serial_; volatile bool run_; volatile bool user_cancel_; platform_event wait_usb_; platform_event wait_img_; platform_event wait_usb_result_; usb_io* io_; std::mutex io_lock_; std::string firmware_ver_; bool online_; int status_; bool async_io_; bool cb_mem_; bool test_1_paper_; // 是否为单张扫描模式 std::vector jsn_children_; json setting_jsn_; 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;// 自动颜色识别 int is_quality_; // 画质设置 0 - 速度优先;1 - 画质优先 bool is_color_fill; // 色彩填充 bool is_multiout; // 多流输出 int bw_threshold_; // 黑白图像阈值 (added on 2022-06-28) int feedmode_; // 分纸强度 int sleeptime_; // 睡眠时间 bool is_auto_paper_scan; // 待纸扫描 bool size_check; // 尺寸检测 bool save_feedmode_type_; //保存分支强度狀態 bool save_sleeptime_type_; //保存休眠時間 bool isremove_left_hole; //设置左边除穿孔 bool isremove_right_hole; //设置右边除穿孔 bool isremove_top_hole; //设置上边除穿孔 bool isremove_low_hole; //设置下边除穿孔 double isremove_left_hole_threshold; //设置左边除穿孔阈值 double isremove_right_hole_threshold; //设置右边除穿孔阈值 double isremove_top_hole_threshold; //设置上边除穿孔阈值 double isremove_low_hole_threshold; //设置下边除穿孔阈值 int fold_type_; //对折类型 int split3399_; //3399设备正面和反面图像是相对的,所以对折时反面需要进行特殊处理 int pid_; bool is_kernelsnap_220830_; //此版本支持待纸扫描,手动睡眠唤醒,分纸强度 bool is_kernelsnap_211209_; //获取固件版本号是否是新旧版本 SCANCONF img_conf_; //此参数外部不做任何改变,请在writedown_image_configuration做修改 std::string img_type_; std::string dump_usb_path_; // 诊断模式,输出USB原始图像 final_img_queue final_imgs_; // JPG ... unsigned int usb_img_index_; unsigned int final_img_index_; std::string final_path_; BlockingQueue> imgs_; void init_settings(const char* json_setting_text); int init_settings(int pid); int on_scann_error(int err); // 返回“0”忽略错误继续执行,其它值则停止后续工作 int try_third_app_handle_start(bool& handled); int try_third_app_after_start(int err); std::shared_ptr aquire_memory(int size, bool from_usb = true); // callback to ui ... int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = SCANNER_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 bits); int save_usb_data(std::shared_ptr data); int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf); void adjust_filling_hole(LPSCANCONF conf); enum thread_running { THREAD_RUNNING_IDLE = 0, THREAD_RUNNING_USB = 1 << 0, THREAD_RUNNING_IMAGE = 1 << 1, }; int is_running(void); // return thread_running //////////////////////////////////////////////////////////////// // 新增自定义伽玛曲线及扫描区域属性 - 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 //////////////////////////////////////////////////////////////// // 2022-07-23 新增双张之后留图继续扫描 int double_paper_handle_; // 汉王要求出现双张的时候可保留 bool keep_watermark_; // 汉王要求图像处理过程中保留水印 - 是否与背景移除、背景填充相关??? // 2022-08-31 新增黑白图像是否反色输出(PNM黑白像素与BMP黑白像素相反) bool is_white_0_; // 是否‘0’代表白色 public: void set_ui_callback(sane_callback cb, bool enable_async_io); void set_read_over_with_no_data(bool no_data); 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(const char* name, void* data, int len); int get_setting(const char* name, char* json_txt_buf, int* len); int hgpaper_to_devspaper(Paper_Map papermap[], int len, int& paper, bool* exact, TwSS* type); int image_configuration(LPSCANCONF ic); 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 temporary_file(char* tail = NULL, char* head = NULL); static int save_2_tempory_file(std::shared_ptr> data, std::string* path_file, unsigned int index = 0); public: 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 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_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);//获取设备是否休眠当中 virtual int get_sleep_time(int& getsleepime);//获取功耗模式(休眠) virtual int set_sleep_time(int sleeptime);//设置功耗模式(休眠) virtual int get_history_count(void);//获取历史扫描张数 -2:设备不支持该功能;-1:与设备通信失败;其它大于等于0的为正常 virtual int get_roller_num(void); //获取滚轮张数 -2:设备不支持该功能;-1:与设备通信失败;其它大于等于0的为正常 virtual int notify_sleep(void);//唤醒设备 virtual int get_device_log(string &log);//获取设备日志 virtual int set_devreboot();//设置设备重启 virtual int set_devshtudown();//设置设备关机 virtual int set_scan_islock(SANE_Bool set_islock); virtual int get_scan_islock(SANE_Bool* islock);//获取设备是否锁定 -2:设备不支持该功能;它大于等于0的为正常 virtual int set_scan_lock_check_val(string check_str);//获取设备是否锁定 -2:设备不支持该功能;它大于等于0的为正常 virtual int firmware_upgrade(std::string filename); //固件升级 -2:设备不支持该功能;它大于等于0的为正常 }; #ifdef UOS #ifdef OEM_HANWANG static const std::string helpfile_ ="/opt/apps/com.hanvonchina.hanvonscan/entries/help/HanvonScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_LISICHENG) static const std::string helpfile_ ="/opt/apps/com.lanxumchina.lanxumscan/entries/help/LanxumScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_CANGTIAN) static const std::string helpfile_ = "/opt/apps/com.cumtennchina.cumtennscan/entries/help/CumTennScan_scanSettings_Help_manual.pdf";//帮助文档路径 #else static const std::string helpfile_ ="/opt/apps/com.huagaochina.huagoscan/entries/help/HuaGoScan_scanSettings_Help_manual.pdf";//帮助文档路径 #endif #elif KYLIN #ifdef OEM_HANWANG static const std::string helpfile_ ="/opt/apps/scanner-driver-hanvon/doc/HanvonScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_LISICHENG) static const std::string helpfile_ ="/opt/apps/scanner-driver-lanxum/doc/LanxumScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_CANGTIAN) static const std::string helpfile_ = "/opt/apps/scanner-driver-cumtenn/doc/CumTennScan_scanSettings_Help_manual.pdf";//帮助文档路径 #else static const std::string helpfile_ ="/opt/apps/scanner-driver-huagao/doc/HuaGoScan_scanSettings_Help_manual.pdf";//帮助文档路径 #endif #elif defined(WIN32) || defined(_WIN64) #ifdef OEM_HANWANG static const std::string helpfile_ = "HanvonScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_LISICHENG) static const std::string helpfile_ = "LanxumScan_scanSettings_Help_manual.pdf";//帮助文档路径 #elif defined(OEM_CANGTIAN) static const std::string helpfile_ = "CumTennScan_scanSettings_Help_manual.pdf";//帮助文档路径 #else static const std::string helpfile_ = "HuaGoScan_scanSettings_Help_manual.pdf";//帮助文档路径 #endif #endif //TEST 测试GIT切换