增加图像扩展信息接口;增加SANE接口;调整语言包转换方式;TWAIN属性区间步长与SANE保持一致

This commit is contained in:
gb 2023-01-28 15:20:51 +08:00
parent 7994a9b07c
commit 6e15875952
9 changed files with 1011 additions and 726 deletions

View File

@ -122,7 +122,7 @@ enum twain_xfer
TWAIN_XFER_Memory = 2, // to be implementing ...
};
typedef bool(__stdcall* set_opt_value)(void* val, value_role role, void* param); // return false to stop the callback
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));
@ -302,67 +302,87 @@ struct delete_scanner
#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:
T* init_;
T* cur_;
T* lower_;
T* upper_;
T* step_;
std::vector<T>* vvs_;
std::list<T>* lvs_;
// 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(T* cur = NULL, T* init = NULL, std::vector<T>* vs = NULL, std::list<T>* ls = NULL, T* lower = NULL, T* upper = NULL, T* step = NULL)
: init_(init), cur_(cur), vvs_(vs), lvs_(ls)
, lower_(lower), upper_(upper), step_(step)
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, void* param)
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)
{
if (v->cur_)
{
*v->cur_ = *(T*)val;
}
v->range[RANGE_POS_CURRENT] = *(T*)val;
}
if (role & VAL_ROLE_DEFAULT)
{
if (v->init_)
{
*v->init_ = *(T*)val;
}
v->range[RANGE_POS_DEFAULT] = *(T*)val;
}
if (role & VAL_ROLE_LOWER)
{
if (v->lower_)
*v->lower_ = *(T*)val;
v->range[RANGE_POS_LOWER] = *(T*)val;
}
if (role & VAL_ROLE_UPPER)
{
if (v->upper_)
*v->upper_ = *(T*)val;
v->range[RANGE_POS_UPPER] = *(T*)val;
}
if (role & VAL_ROLE_STEP)
{
if (v->step_)
*v->step_ = *(T*)val;
return go;
v->range[RANGE_POS_STEP] = *(T*)val;
}
if (v->vvs_)
v->vvs_->push_back(*(T*)val);
else if (v->lvs_)
v->lvs_->push_back(*(T*)val);
@ -370,25 +390,17 @@ namespace sane_opts
}
}
#define GET_SANE_OPT(type, object, id_name, cur, init, vec, lst) \
#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) \
{ \
sane_opts::get_opts<type> op(cur, init, vec, lst); \
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
} \
}
#define GET_SANE_OPT_RANGE(type, object, id_name, cur, init, low, up, step) \
{ \
int ind = object->sane_opt_id_##id_name##(); \
if(ind > 0) \
{ \
sane_opts::get_opts<type> op(cur, init, NULL, NULL, low, up, step); \
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
if(step && fabs(*step) < .000001) *step = 1; \
} \
else \
return capUnsupported(); \
op.re_order(); \
}
#define SET_SANE_OPT(ret, object, id_name, val) \
{ \
int ind = object->sane_opt_id_##id_name##(); \

View File

@ -22,3 +22,6 @@ EXPORTS
sane_hgsane_init_ex
sane_hgsane_io_control
sane_hgsane_err_desc
sane_hgsane_get_option_descriptor_ex
sane_hgsane_control_option_ex
sane_hgsane_read_ext_info

File diff suppressed because it is too large Load Diff

View File

@ -84,6 +84,7 @@ class scanner : public ISaneInvoker, virtual public refer
bool get_option_value_with_parent(int sn, set_opt_value setv, void* param); // return true if handled
bool set_option_value_with_parent(int sn, void* data, int* err); // return true if handled sn
int set_option_value(int sn, SANE_Value_Type type, int size, void* data);
int set_is_multiout(bool enable);
typedef struct _ex_api
{
@ -133,52 +134,31 @@ class scanner : public ISaneInvoker, virtual public refer
bool set_cur_and_def_value(T cur, T def, set_opt_value setv, void* param)
{
if (cur == def)
return setv(&cur, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), param);
else if (setv(&cur, VAL_ROLE_CURRENT, param))
return setv(&def, VAL_ROLE_DEFAULT, param);
else
return setv(&cur, (value_role)(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param);
else if (setv(&cur, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param))
return setv(&def, VAL_ROLE_DEFAULT, VAL_LIMIT_NONE, param);
return false;
}
template<class S, class T>
void set_value_range(S cur, S def, S l, S u, S s, set_opt_value setv, void* param, T(__stdcall* to_t)(S))
{
struct
T v = to_t(cur);
while (setv(&v, VAL_ROLE_CURRENT, VAL_LIMIT_RANGE, param))
{
int role;
S val;
}vals[5];
int count = 0;
std::vector<S> sv;
v = to_t(def);
if (!setv(&v, VAL_ROLE_DEFAULT, VAL_LIMIT_RANGE, param))
break;
sv.push_back(cur);
sv.push_back(def);
sv.push_back(l);
sv.push_back(u);
std::sort(sv.begin(), sv.end());
for (int i = 0; i < (int)sv.size(); ++i)
{
if (i && sv[i] == sv[i - 1])
continue;
v = to_t(l);
if (!setv(&v, VAL_ROLE_LOWER, VAL_LIMIT_RANGE, param))
break;
v = to_t(u);
if (!setv(&v, VAL_ROLE_UPPER, VAL_LIMIT_RANGE, param))
break;
v = to_t(s);
setv(&v, VAL_ROLE_STEP, VAL_LIMIT_RANGE, param);
vals[count].val = sv[i];
vals[count].role = 0;
if (sv[i] == cur)
vals[count].role |= VAL_ROLE_CURRENT;
if (sv[i] == def)
vals[count].role |= VAL_ROLE_DEFAULT;
if (sv[i] == l)
vals[count].role |= VAL_ROLE_LOWER;
if (sv[i] == u)
vals[count].role |= VAL_ROLE_UPPER;
count++;
}
vals[count].val = s;
vals[count++].role = VAL_ROLE_STEP;
for (int i = 0; i < count; ++i)
{
T v = to_t(vals[i].val);
if (!setv(&v, (value_role)vals[i].role, param))
break;
}
}

View File

@ -95,7 +95,7 @@ namespace load_sane_util
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());
if (!h && ret == ERROR_MOD_NOT_FOUND)
if (!h && (ret == ERROR_MOD_NOT_FOUND || ret == ERROR_BAD_EXE_FORMAT))
{
std::wstring dir(path_dll);
size_t pos = dir.rfind(L'\\');
@ -107,6 +107,7 @@ namespace load_sane_util
OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str());
SetDllDirectoryW(dir.c_str());
h = LoadLibraryW(path_dll);
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
ret = GetLastError();
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str());

File diff suppressed because it is too large Load Diff

View File

@ -104,6 +104,7 @@ protected:
virtual Twpp::Result userInterfaceDisable(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
virtual Twpp::Result userInterfaceEnable(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
virtual Twpp::Result userInterfaceEnableUiOnly(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
virtual Twpp::Result extImageInfoGet(const Twpp::Identity& origin, Twpp::ExtImageInfo& data) override;
virtual Twpp::Result imageInfoGet(const Twpp::Identity& origin, Twpp::ImageInfo& data) override;
virtual Twpp::Result imageLayoutGet(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;
virtual Twpp::Result imageLayoutGetDefault(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;

View File

@ -1638,6 +1638,11 @@ public:
return m_cap;
}
/// dangerous set CapType
void dangerous_set_cap(CapType cap) {
m_cap = cap;
}
/// Container type.
ConType container() const noexcept{
return m_conType;

View File

@ -433,6 +433,21 @@ public:
info.m_itemType = Type::DontCare;
}
}
void set_data(const std::list<InfoId>& ids) noexcept {
m_data.reset(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]);
d()->m_numInfos = static_cast<UInt32>(ids.size());
Info* infos = d()->m_infos;
UInt32 i = 0;
for (const auto id : ids) {
auto& info = infos[i];
i++;
info.m_infoId = id;
info.m_itemType = Type::DontCare;
}
}
ExtImageInfo(ExtImageInfo&&) = default;
ExtImageInfo& operator=(ExtImageInfo&&) = default;