code_device/twain/ds/s2t_api.h

401 lines
12 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 <sane/sane_ex.h>
#include <huagao/hgscanner_error.h>
#include <string>
#include <vector>
#include <list>
#include <math.h>
#define COM_API_DECLARE(ret, decl) virtual ret decl = 0
#define COM_API_DECLARE_NON_PURE(ret, decl) virtual ret decl
#define COM_API_OVERRIDE(ret, decl) virtual ret decl override
#define COM_API_IMPLEMENT(cls, ret, decl) ret 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 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 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, //
VAL_LIMIT_MASK = 0x0ff,
VAL_LIMIT_READONLY = 0x100,
};
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_STREAM, // uint8_t[], must give array length
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(*set_opt_value)(void* val, value_role role, value_limit limit, void* param);
class IRef
{
public:
COM_API_DECLARE(int32_t, add_ref(void));
COM_API_DECLARE(int32_t, release(void));
};
class IScanImg : public IRef // 为兼容TWAIN传输方式位图全部转换为完整的位图文件内容TWAIN协议层在获取数据时根据不同传输方式跳过对应的文件头即可 - 2023-07-03
{
public:
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));
COM_API_DECLARE(size_t, get_bits_offset(void));
};
class ISaneInvoker : public IRef
{
public:
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(* handle_ev)(int, void*) = nullptr, void* para = nullptr));
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 = nullptr, int *dpi = nullptr));
COM_API_DECLARE(bool, discard_first_image(void));
COM_API_DECLARE(int, convert_image(SANE_ImageFormatConvert* conv));
COM_API_DECLARE(bool, is_online(void));
COM_API_DECLARE(bool, is_paper_on(void));
COM_API_DECLARE(int, last_error(void));
COM_API_DECLARE(int, image_fetched(IScanImg* tx)); // notify the image 'tx' has fetched by APP
// ui ...
COM_API_DECLARE(bool, ui_is_ok(void));
COM_API_DECLARE(bool, ui_show_setting(HWND parent, bool with_scan, bool indicator = true));
COM_API_DECLARE(bool, ui_show_progress(HWND parent, bool bIndicator));
COM_API_DECLARE(void, ui_hide(void));
// twain
COM_API_DECLARE(void, twain_set_transfer(twain_xfer xfer));
COM_API_DECLARE(void, twain_set_compression(SANE_CompressionType compression, void* detail = nullptr));
COM_API_DECLARE(int, twain_get_config(char* buf, size_t* len));
COM_API_DECLARE(int, twain_set_config(char* buf, size_t len));
// Function: 获取配置项信息
//
// Parameter: sn - 配置项索引 - sane_option_id
//
// type - 配置项数据类型
//
// limit - 配置项限制类型
//
// bytes - *type 为 VAL_TYPE_STR时需要的最小空间字节数
COM_API_DECLARE(bool, get_option_info(int sn, value_type* type, value_limit* limit, int *bytes, bool* readonly));
COM_API_DECLARE(int, get_fixed_ids(SANE_Bool(* cb)(int id, void* param), void* param));
COM_API_DECLARE(bool, get_value(int sn, set_opt_value func, void* param));
COM_API_DECLARE(bool, get_value(int sn, void* data, int* len)); // get operation with in-parameter
COM_API_DECLARE(int, set_value(int sn, void* val));
};
struct delete_scanner
{
void operator()(ISaneInvoker* p)
{
p->release();
}
};
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 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) \
{ \
sane_opts::get_opts<type> op(limit, vct); \
object->get_value(SANE_OPT_ID_##id_name, sane_opts::set_opt_value<type>, &op); \
op.re_order(); \
}
#define SET_SANE_OPT(ret, object, id_name, val) \
{ \
ret = object->set_value(SANE_OPT_ID_##id_name, val); \
}
extern "C"
{
bool is_scanner_online(const char* model);
ISaneInvoker* open_scanner(const char* model, int* err);
int uninitialize_sane(void* reserve);
}
// 标准TWAIN属性值与SANE属性值之间的转换
namespace s2t
{
// 页面 与 双面转换
bool page_is_duplex(const char* sane_val);
std::string page_from_duplex(bool duplex);
// 页面 与 丢弃空白页
bool discard_blank_from_sane(const char* sane_val);
std::string discard_blank_to_sane(bool discard);
// 页面 与 丢弃空白发票
bool discard_blank_receipt_from_sane(const char* sane_val);
std::string discard_blank_receipt_to_sane(bool discard);
// 页面 与 对折
bool fold_from_sane(const char* sane_val);
std::string fold_to_sane(bool fold);
// 语言
int language_to_twain(const char* sane_val);
std::string language_from_twain(int twain);
// 位深 与 颜色模式
int bits_from_sane(const char* color_mode);
std::string bits_to_sane(int bits);
// PixelType 与 颜色模式
int pixel_type_from_sane(const char* color_mode);
std::string pixel_type_to_sane(int pixel);
// 自动颜色匹配 与 颜色模式
bool color_mode_is_auto(const char* color_mode);
std::string color_mode_from_auto(bool auto_mode);
// 支持的尺寸 与 纸张
int paper_size_from_sane(const char* sane_val);
std::string paper_size_to_sane(int paper);
// 横向 与 纸张
bool lateral_from_sane(const char* sane_val, bool* support_lateral);
std::string lateral_to_sane(const char* sane_val, bool lateral); // 如果sane_val不支持横向则返回sane_val确定是否支持横向请调用lateral_from_sane
// 自动尺寸 与 纸张
bool auto_size_from_sane(const char* sane_val);
std::string auto_size_to_sane(bool autos);
// 自动裁切 与 纸张
bool auto_crop_from_sane(const char* sane_val);
std::string auto_crop_to_sane(bool autos);
// 旋转角度 与 送纸方向
double rotation_from_sane(const char* sane_val);
std::string rotation_to_sane(double rot);
bool auto_rotation_from_sane(const char* sane_val);
std::string auto_rotation_to_sane(bool autor);
// 滤波 与 除色与增强
void filter_from_sane(const std::vector<std::string>& sane/*sane_opts::RANGE_POS*/, std::vector<int>& twain, bool filter/*true - filter; false - enhance*/);
std::string filter_to_sane(int filter);
std::string enhance_to_sane(int enhance);
// 多流输出
int multi_out_from_sane(const char* sane_val);
std::string multi_out_to_sane(int mo);
// 休眠时间兼容老版本协议
int power_from_sane(const char* sane_val);
std::string power_to_sane(int power);
// 背景填充方式 设置凸多边形
bool convex_from_sane(const char* sane_val);
std::string convex_to_sane(bool convex);
// 锐化
int sharpen_from_sane(const char* sane_val);
std::string sharpen_to_sane(int sharpen);
};