code_twain/sane/s2t_api.h

458 lines
15 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
//
// For: interface definition for SANE to TWAIN
//
// Date: 2022-06-08
//
#include <Windows.h>
#include <sane/sane_ex.h>
#include <huagao/hgscanner_error.h>
#include <string>
#define COM_API_DECLARE(ret, decl) virtual ret __stdcall decl = 0
#define COM_API_DECLARE_NON_PURE(ret, decl) virtual ret __stdcall decl
#define COM_API_OVERRIDE(ret, decl) virtual ret __stdcall decl override
#define COM_API_IMPLEMENT(cls, ret, decl) ret __stdcall cls##::decl
#define SANE_OPTION_ID_API(opt) COM_API_DECLARE(int, sane_opt_id_##opt(void)) // -1 is none
#define SANE_OPTION_ID_OVERRIDE(opt) COM_API_OVERRIDE(int, sane_opt_id_##opt(void))
#define SANE_OPTION_IMPLEMENT(cls, opt) int __stdcall cls##::sane_opt_id_##opt(void)
#define SANE_OPTION_ID_API_EX(opt) COM_API_DECLARE(int, sane_opt_id_ex_##opt(void)) // -1 is none
#define SANE_OPTION_ID_OVERRIDE_EX(opt) COM_API_OVERRIDE(int, sane_opt_id_ex_##opt(void))
#define SANE_OPTION_IMPLEMENT_EX(cls, opt) int __stdcall cls##::sane_opt_id_ex_##opt(void)
#define ALIGN_MEMORY(n, align) ((n + align - 1) / (align) * (align))
#define _TO_UNICODE_(str) L##str
#define UNICODE_STR(str) _TO_UNICODE_(str)
#define TWPT_AUTOMATIC_COLOR 0x0a0c
#define AUTO_MATIC_ROTATE 123.456f
#define IS_DOUBLE_EQUAL(a, b) fabs((a) - (b)) < .000001
enum value_limit
{
VAL_LIMIT_NONE = 0, //
VAL_LIMIT_ENUM, //
VAL_LIMIT_RANGE, //
};
enum value_role
{
VAL_ROLE_NONE = 0, // this value is no role but an item of the option only
VAL_ROLE_DEFAULT = 0x01, // this value is the default value of the option
VAL_ROLE_CURRENT = 0x02, // this value is the current value of the option
VAL_ROLE_LOWER = 0x04, // the lower value of a VAL_LIMIT_RANGE
VAL_ROLE_UPPER = 0x08, // the upper value of a VAL_LIMIT_RANGE
VAL_ROLE_STEP = 0x10, // the step value of a VAL_LIMIT_RANGE
};
enum value_type
{
VAL_TYPE_NONE = 0,
VAL_TYPE_BOOL, // bool
VAL_TYPE_INT, // int
VAL_TYPE_FLOAT, // float
VAL_TYPE_STR, // char*
VAL_TYPE_BUTTON, // a button
};
enum color_value // 除最后一项外其余与Twpp::PixelType值保持一致
{
COLOR_BW = 0,
COLOR_GRAY,
COLOR_RGB,
COLOR_AUTO_MATCH = TWPT_AUTOMATIC_COLOR,
};
enum paper_value // 与Twpp::PaperSize保持一致
{
PAPER_A4 = 1,
PAPER_16K = 1,
PAPER_LETTER = 3,
PAPER_LEGAL = 4,
PAPER_A5 = 5,
PAPER_B4 = 6,
PAPER_B6 = 7,
PAPER_A3 = 11,
PAPER_8K = 11,
PAPER_A6 = 13,
PAPER_B5 = 29,
PAPER_STATEMENT = 52, // 匹配原始尺寸
PAPER_MAXSIZE = 54, // 最大扫描尺寸
// 以下为未匹配选项
PAPER_DOUBLE_LETTER = 103,
PAPER_MAXSIZE_CROP = 154, // 最大扫描尺寸自动裁切
PAPER_TRIPPLE = 111, // 三联试卷
};
enum filter_value // 除色选项
{
FILTER_NONE = 0,
FILTER_RED,
FILTER_GREEN,
FILTER_BLUE,
};
enum enhance_value // 颜色增强选项
{
ENHANCE_NONE = 0,
ENHANCE_RED,
ENHANCE_GREEN,
ENHANCE_BLUE,
};
enum sharpen_value
{
SHARPEN_NONE = 0,
SHARPEN_SHARPEN,
SHARPEN_SHARPEN_MORE,
SHARPEN_BLUR,
SHARPEN_BLUR_MORE,
};
enum multiout_value
{
MULTI_OUT_NONE = -1,
MULTI_OUT_ALL,
MULTI_OUT_COLOR_GRAY,
MULTI_OUT_COLOR_BW,
MULTI_OUT_GRAY_BW,
};
enum twain_xfer
{
TWAIN_XFER_Native = 0, // BITMAPINFOHEADER + bits
TWAIN_XFER_File = 1, // BITMAPFILEHEADER + TWAIN_XFER_Native
TWAIN_XFER_Memory = 2, // to be implementing ...
};
typedef bool(__stdcall* set_opt_value)(void* val, value_role role, value_limit limit, void* param); // return false to stop the callback
struct __declspec(novtable) IRef
{
COM_API_DECLARE(long, add_ref(void));
COM_API_DECLARE(long, release(void));
};
struct __declspec(novtable) IScanImg : public IRef
{
COM_API_DECLARE(int, width(void));
COM_API_DECLARE(int, line_bytes(void));
COM_API_DECLARE(int, height(void));
COM_API_DECLARE(int, depth(void));
COM_API_DECLARE(int, channel(void));
COM_API_DECLARE(int, dpi(void));
COM_API_DECLARE(SANE_Frame, type(void));
COM_API_DECLARE(unsigned int, bytes(void));
COM_API_DECLARE(unsigned int, header_size(void));
COM_API_DECLARE(unsigned char*, data(unsigned long long off, unsigned int *bytes));
COM_API_DECLARE(int, read(void* buf, size_t* bytes, unsigned long long off = 0));
COM_API_DECLARE(const char*, file(void));
COM_API_DECLARE(void, keep_file(bool keep));
COM_API_DECLARE(void, copy_header(SANE_Parameters* head));
COM_API_DECLARE(int, image_status(void));
};
struct __declspec(novtable) ISaneInvoker : public IRef
{
COM_API_DECLARE(int, start(void));
COM_API_DECLARE(int, stop(void));
COM_API_DECLARE(int, get_event(void));
COM_API_DECLARE(void, set_event_callback(int(__stdcall* handle_ev)(int, void*) = NULL, void* para = NULL));
COM_API_DECLARE(bool, wait_image(DWORD milliseconds = -1));
COM_API_DECLARE(int, get_scanned_images(DWORD milliseconds = 0));
COM_API_DECLARE(IScanImg*, take_first_image(twain_xfer xfer = TWAIN_XFER_Native)); // call 'release' on returned value, plz
COM_API_DECLARE(bool, get_first_image_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL));
COM_API_DECLARE(bool, is_online(void));
COM_API_DECLARE(bool, is_paper_on(void));
COM_API_DECLARE(int, last_error(void));
// Function: 获取配置项信息
//
// Parameter: sn - 配置项索引
//
// type - 配置项数据类型
//
// limit - 配置项限制类型
//
// bytes - *type 为 VAL_TYPE_STR时需要的最小空间字节数
COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes));
COM_API_DECLARE(bool, get_value(int sn, set_opt_value, void* param));
COM_API_DECLARE(int, set_value(int sn, void* val));
COM_API_DECLARE(int, convert_image(SANE_ImageFormatConvert* conv));
COM_API_DECLARE(void, free_buffer(void* buf, int len));
// SANE options ID ...
SANE_OPTION_ID_API(color_correction); // 2023-02-24 15:31:19 色偏校正
SANE_OPTION_ID_API(fold_type); // 2023-02-24 15:28:47 对折模式
SANE_OPTION_ID_API(is_multiout); // 多流输出
SANE_OPTION_ID_API(multiout_type); // 多流输出类型
SANE_OPTION_ID_API(color_mode); // 颜色模式
SANE_OPTION_ID_API(erase_color); // 除色或增强
SANE_OPTION_ID_API(erase_multiout_red); // 多流输出除红
SANE_OPTION_ID_API(erase_paper_red); // 试卷除红
SANE_OPTION_ID_API(is_erase_background); // 背景移除
SANE_OPTION_ID_API(background_color_range); // 背景色彩范围
SANE_OPTION_ID_API(sharpen); // 锐化与模糊
SANE_OPTION_ID_API(erase_morr); // 除摩尔纹
SANE_OPTION_ID_API(erase_grids); // 除网纹
SANE_OPTION_ID_API(error_extend); // 错误扩散
SANE_OPTION_ID_API(is_noise_modify); // 噪点优化
SANE_OPTION_ID_API(noise_threshold); // 噪点优化尺寸
SANE_OPTION_ID_API(paper); // 纸张尺寸
SANE_OPTION_ID_API(is_custom_area); // 自定义扫描区域
SANE_OPTION_ID_API(curstom_area_l); // 自定义扫描区域 左
SANE_OPTION_ID_API(curstom_area_r); // 自定义扫描区域 右
SANE_OPTION_ID_API(curstom_area_t); // 自定义扫描区域 上
SANE_OPTION_ID_API(curstom_area_b); // 自定义扫描区域 下
SANE_OPTION_ID_API(is_size_check); // 尺寸检测
SANE_OPTION_ID_API(page); // 扫描页面
SANE_OPTION_ID_API(blank_page_threshold); // 跳过空白页灵敏度
SANE_OPTION_ID_API(resolution); // 分辨率
SANE_OPTION_ID_API(image_quality); // 图像质量
SANE_OPTION_ID_API(is_swap); // 交换正反面
SANE_OPTION_ID_API(is_split); // 图像拆分
SANE_OPTION_ID_API(is_auto_deskew); // 自动纠偏
SANE_OPTION_ID_API(is_custom_gamma); // 自定义gamma
SANE_OPTION_ID_API(bright); // 亮度
SANE_OPTION_ID_API(contrast); // 对比度
SANE_OPTION_ID_API(gamma); // gamma
SANE_OPTION_ID_API(is_erase_black_frame); // 消除黑框
SANE_OPTION_ID_API(deep_sample); // 深色样张
SANE_OPTION_ID_API(threshold); // 阈值
SANE_OPTION_ID_API(anti_noise); // 背景抗噪等级
SANE_OPTION_ID_API(margin); // 边缘缩进
SANE_OPTION_ID_API(fill_background); // 背景填充方式
SANE_OPTION_ID_API(is_anti_permeate); // 防止渗透
SANE_OPTION_ID_API(anti_permeate_level); // 防止渗透等级
SANE_OPTION_ID_API(is_erase_hole); // 穿孔移除
SANE_OPTION_ID_API(search_hole_range); // 穿孔搜索范围
SANE_OPTION_ID_API(is_filling_color); // 色彩填充
SANE_OPTION_ID_API(is_ultrasonic_check); // 超声波检测
SANE_OPTION_ID_API(is_check_staple); // 装订检测
SANE_OPTION_ID_API(scan_mode); // 扫描张数
SANE_OPTION_ID_API(scan_count); // 扫描数量
SANE_OPTION_ID_API(text_direction); // 文稿方向
SANE_OPTION_ID_API(is_rotate_bkg180); // 背面旋转180度
SANE_OPTION_ID_API(is_check_dogear); // 折角检测
SANE_OPTION_ID_API(dogear_size); // 折角检测大小
SANE_OPTION_ID_API(is_check_skew); // 歪斜检测
SANE_OPTION_ID_API(skew_range); // 歪斜容忍度
SANE_OPTION_ID_API(black_white_threshold); // 二值化图像阈值
SANE_OPTION_ID_API(is_photo_mode); // 照片模式
SANE_OPTION_ID_API(double_feed_handle); // 双张图片处理
SANE_OPTION_ID_API(scan_when_paper_on); // 待纸扫描
SANE_OPTION_ID_API(feed_strength); // 分纸强度
SANE_OPTION_ID_API(power_scheme); // 休眠时间
SANE_OPTION_ID_API(is_auto_strength); // 自动搓纸强度
SANE_OPTION_ID_API(feed_strength_value); // 自动搓纸强度设定值
SANE_OPTION_ID_API(is_reverse_bw); // 黑白图像反色输出
SANE_OPTION_ID_API(is_erase_hole_l); // 穿孔移除 - 左
SANE_OPTION_ID_API(search_hole_range_l); // 穿孔搜索范围 - 左
SANE_OPTION_ID_API(is_erase_hole_r); // 穿孔移除 - 右
SANE_OPTION_ID_API(search_hole_range_r); // 穿孔搜索范围 - 右
SANE_OPTION_ID_API(is_erase_hole_t); // 穿孔移除 - 上
SANE_OPTION_ID_API(search_hole_range_t); // 穿孔搜索范围 - 上
SANE_OPTION_ID_API(is_erase_hole_b); // 穿孔移除 - 下
SANE_OPTION_ID_API(search_hole_range_b); // 穿孔搜索范围 - 下
SANE_OPTION_ID_API(fold_direction); // 对折模式
// SANE-ex option ID:
SANE_OPTION_ID_API_EX(multiout_type); // int
SANE_OPTION_ID_API_EX(auto_color_type); // int
SANE_OPTION_ID_API_EX(color_mode); // int
SANE_OPTION_ID_API_EX(sharpen); // int
SANE_OPTION_ID_API_EX(paper); // paper_value
SANE_OPTION_ID_API_EX(paper_lateral); // bool
SANE_OPTION_ID_API_EX(auto_paper_size); // bool
SANE_OPTION_ID_API_EX(is_paper_auto_crop); // bool
SANE_OPTION_ID_API_EX(text_direction); // float 90, 180, ..., -1 is auto-text-direction
SANE_OPTION_ID_API_EX(duplex); // bool
SANE_OPTION_ID_API_EX(fill_background); // bool true - 凸多边形
SANE_OPTION_ID_API_EX(discard_blank_page); // bool
SANE_OPTION_ID_API_EX(discard_blank_receipt); // bool
SANE_OPTION_ID_API_EX(is_page_fold); // bool
SANE_OPTION_ID_API_EX(color_filter); // int (filter_value)
SANE_OPTION_ID_API_EX(color_enhance); // int (enhance_value)
SANE_OPTION_ID_API_EX(final_compression); // int
SANE_OPTION_ID_API_EX(final_format); // SANE_FinalImgFormat
SANE_OPTION_ID_API_EX(serial); // std::string
SANE_OPTION_ID_API_EX(to_be_scan); // bool
SANE_OPTION_ID_API_EX(scan_with_hole); // bool
SANE_OPTION_ID_API_EX(device_code); // std::string
SANE_OPTION_ID_API_EX(power); // int
SANE_OPTION_ID_API_EX(hardware_version); // std::string
SANE_OPTION_ID_API_EX(ip); // std::string
// ui ...
COM_API_DECLARE(bool, ui_show_main(HWND parent));
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
COM_API_DECLARE(bool, ui_show_progress(HWND parent));
COM_API_DECLARE(void, ui_hide(void));
COM_API_DECLARE(bool, ui_is_ok(void));
// twain
COM_API_DECLARE(void, twain_set_transfer(twain_xfer xfer));
COM_API_DECLARE(void, twain_set_compression(SANE_CompressionType compression, void* detail = NULL));
COM_API_DECLARE(int, twain_get_config(char* buf, size_t* len));
COM_API_DECLARE(int, twain_set_config(char* buf, size_t len));
};
struct delete_scanner
{
void operator()(ISaneInvoker* p)
{
p->release();
}
};
#include <vector>
#include <list>
namespace sane_opts
{
enum
{
RANGE_POS_CURRENT = 0,
RANGE_POS_DEFAULT,
RANGE_POS_ENUM_BEGIN,
RANGE_POS_LOWER = RANGE_POS_ENUM_BEGIN,
RANGE_POS_UPPER,
RANGE_POS_STEP,
};
template<class T>
class get_opts
{
public:
// 0 - cur val; 1 - def val;
//
// LIST: 2 - elements ...
//
// RANGE: 2 - lower; 3 - upper; 4 - step
T range[5];
value_limit lmt_;
std::vector<T>* lvs_;
value_limit* limit_;
public:
get_opts(value_limit* limit, std::vector<T>* ls) : limit_(limit), lvs_(ls)
{}
~get_opts()
{}
void re_order(void)
{
if (limit_)
*limit_ = lmt_;
if (lmt_ == VAL_LIMIT_RANGE || lmt_ == VAL_LIMIT_NONE)
{
if (lvs_)
{
lvs_->clear();
for (size_t i = 0; i < _countof(range); ++i)
lvs_->push_back(range[i]);
}
}
else if(lvs_)
{
lvs_->insert(lvs_->begin(), range[RANGE_POS_DEFAULT]);
lvs_->insert(lvs_->begin(), range[RANGE_POS_CURRENT]);
}
}
};
template<class T>
bool __stdcall set_opt_value(void* val, value_role role, value_limit limit, void* param)
{
get_opts<T>* v = (get_opts<T>*)param;
bool go = true;
v->lmt_ = limit;
if (role & VAL_ROLE_CURRENT)
{
v->range[RANGE_POS_CURRENT] = *(T*)val;
}
if (role & VAL_ROLE_DEFAULT)
{
v->range[RANGE_POS_DEFAULT] = *(T*)val;
}
if (role & VAL_ROLE_LOWER)
{
v->range[RANGE_POS_LOWER] = *(T*)val;
}
if (role & VAL_ROLE_UPPER)
{
v->range[RANGE_POS_UPPER] = *(T*)val;
}
if (role & VAL_ROLE_STEP)
{
v->range[RANGE_POS_STEP] = *(T*)val;
}
else if (v->lvs_)
v->lvs_->push_back(*(T*)val);
return go;
}
}
#define GET_SANE_OPT(type, object, id_name, limit, vct) \
{ \
int ind = object->sane_opt_id_##id_name##(); \
sane_opts::get_opts<type> op(limit, vct); \
if(ind > 0) \
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
else \
return capUnsupported(); \
op.re_order(); \
}
#define SET_SANE_OPT(ret, object, id_name, val) \
{ \
int ind = object->sane_opt_id_##id_name##(); \
if(ind > 0) \
ret = object->set_value(ind, val); \
else \
{ \
ret = SCANNER_ERR_INVALID_PARAMETER; \
load_sane_util::log_info((std::wstring(L"Fatal: property '") + L###id_name + L"' not found !!!\r\n").c_str(), 0); \
} \
}
typedef unsigned int SCANNERID;
#define MAKE_SCANNER_ID(pid, vid) MAKELONG(pid, vid)
#define GET_SCANNER_PID(sid) LOWORD(sid)
#define GET_SCANNER_VID(sid) HIWORD(sid)
extern "C"
{
#ifdef EXPORT_SANE_API
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
int __stdcall initialize(void* reserve);
#ifdef EXPORT_SANE_API
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
int __stdcall open_scanner(SCANNERID scanner_id, ISaneInvoker** invoker);
#ifdef EXPORT_SANE_API
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
bool __stdcall is_scanner_online(SCANNERID scanner_id);
#ifdef EXPORT_SANE_API
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
int __stdcall uninitialize(void* reserve);
#ifdef EXPORT_SANE_API
__declspec(dllexport)
#else
__declspec(dllimport)
#endif
void __stdcall log_info(const wchar_t* info, int level);
}