code_twain/huagaotwain/huagaotwain.h

447 lines
14 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
#include "huagao/hgscanner_error.h"
#include <string>
#include <vector>
#include <algorithm>
#include <mutex>
#include "sane_option_trans.h"
class sane_invoker;
class scanner;
struct _dev;
class refer
{
volatile long ref_;
public:
refer() : ref_(1)
{}
protected:
virtual ~refer()
{}
public:
long add_ref(void)
{
return InterlockedIncrement(&ref_);
}
long release(void)
{
long ref = InterlockedDecrement(&ref_);
if (ref <= 0)
delete this;
return ref;
}
};
class scanned_img
{
SANE_Parameters param_;
std::vector<unsigned char> data_;
std::string file_header(SANE_FinalImgFormat* header, float resolution);
public:
scanned_img(SANE_Image* img, SANE_FinalImgFormat* header);
~scanned_img();
public:
int width(void);
int line_bytes(void);
int height(void);
int depth(void);
int channel(void);
SANE_Frame type(void);
unsigned int bytes(void);
unsigned char* bits(void);
void copy_header(SANE_Parameters* head);
};
extern HMODULE me_;
namespace local_utility
{
std::wstring reg_read(HKEY root, const wchar_t* path, const wchar_t* name);
std::wstring reg_get_app_installing_path(void);
}
class scanner : public refer
{
SANE_Handle hdev_;
sane_invoker* host_;
std::string name_;
std::string type_;
std::string vendor_;
std::string product_;
bool online_;
int option_count_;
std::mutex lock_img_;
std::vector<scanned_img*> img_;
SANE_FinalImgFormat *fmt_;
typedef struct _sane_option
{
int ind;
const SANE_Option_Descriptor* desc;
union
{
bool bv;
int iv;
double dv;
std::string* sv;
}val;
bool operator==(int id)
{
return ind == id;
}
}SANEOPTION;
std::vector<SANEOPTION> options_;
float dpi_;
HANDLE wait_img_;
volatile bool scanning_;
int err_;
std::string desc_;
void load_options(void);
void init_image_format(void);
std::string get_string(int opt, int bytes);
bool get_boolean(int opt);
int get_integer(int opt);
double get_double(int opt);
int set_string(int opt, std::string& val, int size, SANE_Int* afterdo = NULL);
enum twain_essential
{
TWAIN_RESOLUTION,
TWAIN_PAPER_SIZE,
};
int opt_ind_dpi_;
int opt_ind_color_mode_;
int opt_ind_paper_;
int opt_ind_scann_count_; // MAKELONG(count, scan_continue)
int opt_ind_text_direction_;
int opt_ind_page_;
int opt_ind_auto_descrew_;
int opt_ind_erase_black_frame_;
int opt_ind_filter_;
int opt_ind_bright_;
int opt_ind_contrast_;
int opt_ind_gamma_;
int opt_ind_ultrasonic_;
int opt_ind_flip_;
int opt_ind_rotate_bkg_;
int opt_ind_fill_blank_bkg_;
int opt_ind_edge_ident_;
int opt_ind_threshold_;
int opt_ind_bkg_filling_method_;
int opt_ind_fill_hole_;
int opt_ind_fill_hole_ratio_;
int opt_ind_noise_;
int opt_ind_noise_threshold_;
int opt_ind_rid_red_;
int opt_ind_rid_red_hsv_;
int opt_ind_sharpen_;
int opt_ind_screw_detect_;
int opt_ind_screw_detect_level_;
int opt_ind_staple_;
int opt_ind_dogear_;
int opt_ind_dark_sample_;
int opt_ind_split_;
int opt_ind_fade_bkg_;
int opt_ind_fade_bkg_val_;
int opt_ind_size_detect_;
int opt_ind_multi_out_;
SANE_ImageType img_fmt_;
int jpeg_quality_;
SANE_CompressionType compression_;
bool auto_crop_;
void(*event_cb_)(int, void*, unsigned int*, void*);
void* cb_param_;
public:
scanner(sane_invoker* host, struct _dev& dev);
static std::string type(SANE_Value_Type st);
static value_limit limit(SANE_Constraint_Type st);
protected:
~scanner();
public:
int close(void);
int start(void);
int stop(void);
void set_event_callback(void(*cb)(int, void*, unsigned int*, void*), void* param);
bool wait_image(DWORD milliseconds = -1);
int get_scanned_images(DWORD milliseconds = 0);
scanned_img* take_first_image(void); // delete returned value, plz
bool get_first_image_header(SANE_Parameters* header);
int last_error(void);
SANE_Handle handle(void);
bool is_online(void);
void set_online(bool online);
void put_image(SANE_Image* img, unsigned int* len);
void scan_finished(const char* desc, int err);
// up to sane, we set the CAP_xxx according to settings display in UI ...
bool get_value_info(int sn, std::string& type, value_limit& limit);
bool get_value(int sn, std::list<std::string>& values, std::string& now, std::string& init);
bool get_value(int sn, std::list<float>& values, float& now, float& init);
bool get_value(int sn, std::list<bool>& values, bool& now, bool& init);
bool get_value(int sn, int& now, int& init, int* lower = NULL, int* upper = NULL, int* step = NULL);
bool get_value(int sn, float& now, float& init, float* lower = NULL, float* upper = NULL, float* step = NULL);
int set_value(int sn, std::string val);
int set_value(int sn, bool val);
int set_value(int sn, int val);
int set_value(int sn, double val);
// attribute for twain ...
public:
int twain_set_resolution(float dpi);
float twain_get_resolution(float* init = NULL, std::vector<float>* values = NULL, value_limit* limit = NULL);
int twain_set_color_mode(int twain_pixel_type);
int twain_get_color_mode(int* init = NULL, std::vector<int>* values = NULL, value_limit* limit = NULL);
int twain_set_auto_color_type(int type);
int twain_get_paper_ind(void);
int twain_set_paper_lateral(bool lateral);
bool twain_is_paper_lateral(void);
int twain_set_paper_auto_match_size(bool match);
bool twain_is_paper_auto_match_size(void);
int twain_set_scan_count(int count);
int twain_get_scan_count(void);
int twain_set_final_format(SANE_ImageType type, void* param);
int twain_get_jpeg_quality(void);
SANE_ImageType get_final_format(void);
int twain_set_final_compression(int compression);
int twain_get_final_compression(int *init = NULL, std::vector<int>* values = NULL);
int twain_set_text_direction(double degree);
double twain_get_text_direction(double* init = NULL, std::list<double>* vals = NULL, value_limit* limit = NULL);
int twain_set_text_auto_matic(bool am);
bool twain_is_text_auto_matic(void);
int twain_set_page_duplex(bool dup);
bool twain_is_page_duplex(void);
int twain_set_page_discarding_blank_page(bool discard, bool receipt);
bool twain_is_page_discarding_blank_page(bool receipt);
int twain_set_page_fold(bool fold);
bool twain_is_page_fold(void);
int twain_set_auto_descrew(bool enable);
bool twain_is_auto_descrew(void);
int twain_set_erase_black_frame(bool erase);
bool twain_is_erase_black_frame(bool* init);
int twain_set_filter(int tw_filter, bool enhance);
int twain_get_filter(bool enhance);
int twain_set_bright(double bright);
double twain_get_bright(double* init = NULL, double* lower = NULL, double* upper = NULL, double* step = NULL);
int twain_set_contrast(double bright);
double twain_get_contrast(double* init = NULL, double* lower = NULL, double* upper = NULL, double* step = NULL);
int twain_set_gamma(double bright);
double twain_get_gamma(double* init = NULL, double* lower = NULL, double* upper = NULL, double* step = NULL);
int twain_set_ultrasonic_check(bool check);
bool twain_is_ultrasonic_check(bool* init = NULL);
bool twain_is_auto_crop(void);
bool twain_is_paper_on(void);
int twain_get_device_code(char* buf, unsigned int len);
int twain_set_sharpen(int sharpen);
int twain_get_sharpen(void);
int twain_get_serial_num(char buf[256]);
int twain_get_hareware_version(char buf[256]);
int twain_get_ip(char buf[256]);
int twain_get_dogear_distance(void);
int twain_set_dogear_distance(int dist);
int twain_set_power_level(int level);
int twain_get_power_level(void);
int twain_set_to_be_scan(bool yes);
bool twain_get_to_be_scan(void);
int twain_set_scan_with_hole(bool yes);
bool twain_get_scan_with_hole(void);
int twain_set_multioutput_type(int type);
int twain_get_multioutput_type(void);
int twain_get_flip_ind(void);
int twain_get_rotate_bkg_ind(void);
int twain_get_fill_black_bkg_ind(void);
int twain_get_edge_ident_ind(void);
int twain_get_threshold_ind(void);
int twain_bkg_filling_method_ind(void);
int twain_fill_hole_ind(void);
int twain_fill_hole_ratio_ind(void);
int twain_detach_noise_ind(void);
int twain_detach_noise_threshold_ind(void);
int twain_rid_red_ind(void);
int twain_rid_red_hsv_ind(void);
int twain_screw_detect_ind(void);
int twain_screw_detect_level_ind(void);
int twain_staple_detect_ind(void);
int twain_dogear_detect_ind(void);
int twain_dark_sample_ind(void);
int twain_image_split_ind(void);
int twain_fade_bkground_ind(void);
int twain_fade_bkground_val_ind(void);
int twain_size_detect_ind(void);
};
struct delete_scanner
{
void operator()(scanner* p)
{
p->release();
}
};
typedef struct _dev
{
scanner* scanner;
std::string name;
std::string type;
std::string vendor;
std::string product;
struct _dev()
{
scanner = NULL;
name = type = vendor = product = "";
}
bool operator==(const char* n)
{
return name == n;
}
bool operator==(SANE_Handle h)
{
return scanner && scanner->handle() == h;
}
}SANEDEV;
class sane_invoker
{
bool ok_;
std::wstring cfg_file_;
SANE_Int ver_;
HMODULE sane_;
HANDLE first_cb_;
SANEAPI sane_api_;
std::mutex lock_dev_;
std::vector<SANEDEV> devices_;
SANE_Status (*real_sane_init_)(SANE_Int* version_code, SANE_Auth_Callback authorize);
void (*real_sane_exit_)(void);
SANE_Status(*real_sane_get_devices_)(const SANE_Device*** device_list, SANE_Bool local_only);
SANE_Status(*real_sane_open_)(SANE_String_Const devicename, SANE_Handle* handle);
void (*real_sane_close_)(SANE_Handle handle);
const SANE_Option_Descriptor* (*real_sane_get_option_descriptor_)(SANE_Handle handle, SANE_Int option);
SANE_Status(*real_sane_control_option_)(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info);
SANE_Status(*real_sane_get_parameters_)(SANE_Handle handle, SANE_Parameters* params);
SANE_Status(*real_sane_start_)(SANE_Handle handle);
SANE_Status(*real_sane_read_)(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length);
void (*real_sane_cancel_)(SANE_Handle handle);
SANE_Status(*real_sane_set_io_mode_)(SANE_Handle handle, SANE_Bool non_blocking);
SANE_Status(*real_sane_get_select_fd_)(SANE_Handle handle, SANE_Int* fd);
SANE_String_Const(*real_sane_strstatus_)(SANE_Status status);
SANE_Status(*real_sane_init_ex_)(SANE_Int* version_code, sane_callback cb, void* param);
SANE_Status(*real_sane_io_control_)(SANE_Handle h, unsigned long code, void* data, unsigned* len);
void(*log_)(int, const char*);
bool load_sane(void);
int handle_sane_event(SANE_Handle hdev, int code, void* data, unsigned int* len);
void get_online_devices(std::vector<SANEDEV>& devs);
int get_online_device_count(void);
scanner* find_scanner(SANE_Handle hdev);
scanner* open(const char* name, int* err);
static void no_log(int, const char*);
static int sane_callback_handler( // 注册回调的对象,需要保证该回调是多线程安全的
SANE_Handle hdev // 产生事件的设备句柄
, int code // 回调事件代码
, void* data // 回调事件数据,根据事件代码有所不同,参照具体事件定义
, unsigned int* len // 数据长度字节或者event_data的缓冲区长度详细请看相应的事件代码
, void* param // 用户自定义数据与调用sane_init_ex传入时的保持一致
); // 返回值依不同的事件代码而定通常为“0”
static sane_invoker* inst_;
protected:
sane_invoker(const wchar_t* path);
~sane_invoker();
public:
static int load_dll(const wchar_t* path_dll, HMODULE* dll);
static bool initialize(HMODULE me);
static void uninitialize(void);
static std::string u2m(const wchar_t* u, int page = CP_ACP);
static std::wstring m2u(const char* m, int page = CP_ACP);
static std::string u2ansi(const wchar_t* u);
static std::string u2utf8(const wchar_t* u);
static std::string utf82ansi(const char* utf8);
static std::string ansi2utf8(const char* ansi);
static std::wstring utf82u(const char* utf8);
static std::wstring ansi2u(const char* ansi);
static void log_debug_info(const char* info);
#ifdef VLOG_OK
static void __cdecl log_debug_info(int bytes, const char* fmt, ...);
#endif
static SANE_Status invoke_sane_init(SANE_Int* version_code, SANE_Auth_Callback authorize);
static void invoke_sane_exit(void);
static SANE_Status invoke_sane_get_devices(const SANE_Device*** device_list, SANE_Bool local_only);
static SANE_Status invoke_sane_open(SANE_String_Const devicename, SANE_Handle* handle);
static void invoke_sane_close(SANE_Handle handle);
static const SANE_Option_Descriptor* invoke_sane_get_option_descriptor(SANE_Handle handle, SANE_Int option);
static SANE_Status invoke_sane_control_option(SANE_Handle handle, SANE_Int option, SANE_Action action, void* value, SANE_Int* info);
static SANE_Status invoke_sane_get_parameters(SANE_Handle handle, SANE_Parameters* params);
static SANE_Status invoke_sane_start(SANE_Handle handle);
static SANE_Status invoke_sane_read(SANE_Handle handle, SANE_Byte* data, SANE_Int max_length, SANE_Int* length);
static void invoke_sane_cancel(SANE_Handle handle);
static SANE_Status invoke_sane_set_io_mode(SANE_Handle handle, SANE_Bool non_blocking);
static SANE_Status invoke_sane_get_select_fd(SANE_Handle handle, SANE_Int* fd);
static SANE_String_Const invoke_sane_strstatus(SANE_Status status);
static SANE_Status invoke_sane_init_ex(SANE_Int* version_code, sane_callback cb, void* param);
static SANE_Status invoke_sane_io_control(SANE_Handle h, unsigned long code, void* data, unsigned* len);
static LPSANEAPI get_api(void);
public:
static bool is_ok(void);
static std::string version(LPDWORD v = NULL);
static void get_devices(std::vector<SANEDEV>& devs);
static scanner* open_scanner(const char* name, int* err);
static int online_devices(void);
};