增加图像扩展信息接口;增加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 ... 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 struct __declspec(novtable) IRef
{ {
COM_API_DECLARE(long, add_ref(void)); COM_API_DECLARE(long, add_ref(void));
@ -302,67 +302,87 @@ struct delete_scanner
#include <list> #include <list>
namespace sane_opts 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> template<class T>
class get_opts class get_opts
{ {
public: public:
T* init_; // 0 - cur val; 1 - def val;
T* cur_; //
T* lower_; // LIST: 2 - elements ...
T* upper_; //
T* step_; // RANGE: 2 - lower; 3 - upper; 4 - step
std::vector<T>* vvs_; T range[5];
std::list<T>* lvs_; value_limit lmt_;
std::vector<T>* lvs_;
value_limit* limit_;
public: 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) get_opts(value_limit* limit, std::vector<T>* ls) : limit_(limit), lvs_(ls)
: init_(init), cur_(cur), vvs_(vs), lvs_(ls)
, lower_(lower), upper_(upper), step_(step)
{} {}
~get_opts() ~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> 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; get_opts<T>* v = (get_opts<T>*)param;
bool go = true; bool go = true;
v->lmt_ = limit;
if (role & VAL_ROLE_CURRENT) if (role & VAL_ROLE_CURRENT)
{ {
if (v->cur_) v->range[RANGE_POS_CURRENT] = *(T*)val;
{
*v->cur_ = *(T*)val;
}
} }
if (role & VAL_ROLE_DEFAULT) if (role & VAL_ROLE_DEFAULT)
{ {
if (v->init_) v->range[RANGE_POS_DEFAULT] = *(T*)val;
{
*v->init_ = *(T*)val;
}
} }
if (role & VAL_ROLE_LOWER) if (role & VAL_ROLE_LOWER)
{ {
if (v->lower_) v->range[RANGE_POS_LOWER] = *(T*)val;
*v->lower_ = *(T*)val;
} }
if (role & VAL_ROLE_UPPER) if (role & VAL_ROLE_UPPER)
{ {
if (v->upper_) v->range[RANGE_POS_UPPER] = *(T*)val;
*v->upper_ = *(T*)val;
} }
if (role & VAL_ROLE_STEP) if (role & VAL_ROLE_STEP)
{ {
if (v->step_) v->range[RANGE_POS_STEP] = *(T*)val;
*v->step_ = *(T*)val;
return go;
} }
if (v->vvs_)
v->vvs_->push_back(*(T*)val);
else if (v->lvs_) else if (v->lvs_)
v->lvs_->push_back(*(T*)val); 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##(); \ int ind = object->sane_opt_id_##id_name##(); \
sane_opts::get_opts<type> op(limit, vct); \
if(ind > 0) \ if(ind > 0) \
{ \
sane_opts::get_opts<type> op(cur, init, vec, lst); \
object->get_value(ind, sane_opts::set_opt_value<type>, &op);\ object->get_value(ind, sane_opts::set_opt_value<type>, &op);\
} \ else \
} return capUnsupported(); \
#define GET_SANE_OPT_RANGE(type, object, id_name, cur, init, low, up, step) \ op.re_order(); \
{ \
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; \
} \
} }
#define SET_SANE_OPT(ret, object, id_name, val) \ #define SET_SANE_OPT(ret, object, id_name, val) \
{ \ { \
int ind = object->sane_opt_id_##id_name##(); \ int ind = object->sane_opt_id_##id_name##(); \

View File

@ -22,3 +22,6 @@ EXPORTS
sane_hgsane_init_ex sane_hgsane_init_ex
sane_hgsane_io_control sane_hgsane_io_control
sane_hgsane_err_desc 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 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 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_option_value(int sn, SANE_Value_Type type, int size, void* data);
int set_is_multiout(bool enable);
typedef struct _ex_api 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) bool set_cur_and_def_value(T cur, T def, set_opt_value setv, void* param)
{ {
if (cur == def) if (cur == def)
return setv(&cur, value_role(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), param); return setv(&cur, (value_role)(VAL_ROLE_CURRENT | VAL_ROLE_DEFAULT), VAL_LIMIT_NONE, param);
else if (setv(&cur, VAL_ROLE_CURRENT, param)) else if (setv(&cur, VAL_ROLE_CURRENT, VAL_LIMIT_NONE, param))
return setv(&def, VAL_ROLE_DEFAULT, param); return setv(&def, VAL_ROLE_DEFAULT, VAL_LIMIT_NONE, param);
else
return false; return false;
} }
template<class S, class T> 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)) 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; v = to_t(def);
S val; if (!setv(&v, VAL_ROLE_DEFAULT, VAL_LIMIT_RANGE, param))
}vals[5]; break;
int count = 0;
std::vector<S> sv;
sv.push_back(cur); v = to_t(l);
sv.push_back(def); if (!setv(&v, VAL_ROLE_LOWER, VAL_LIMIT_RANGE, param))
sv.push_back(l); break;
sv.push_back(u); v = to_t(u);
std::sort(sv.begin(), sv.end()); if (!setv(&v, VAL_ROLE_UPPER, VAL_LIMIT_RANGE, param))
for (int i = 0; i < (int)sv.size(); ++i) break;
{ v = to_t(s);
if (i && sv[i] == sv[i - 1]) setv(&v, VAL_ROLE_STEP, VAL_LIMIT_RANGE, param);
continue;
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; break;
} }
} }

View File

@ -95,7 +95,7 @@ namespace load_sane_util
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); 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); std::wstring dir(path_dll);
size_t pos = dir.rfind(L'\\'); 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()); OutputDebugStringW((L"[TWAIN]Load: try change directory to " + dir + L"\r\n").c_str());
SetDllDirectoryW(dir.c_str()); SetDllDirectoryW(dir.c_str());
h = LoadLibraryW(path_dll); h = LoadLibraryW(path_dll);
// h = LoadLibraryExW(path_dll, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
ret = GetLastError(); ret = GetLastError();
swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret); swprintf_s(info, _countof(info) - 1, L" = %d\r\n", ret);
OutputDebugStringW((L"[TWAIN]Load: " + std::wstring(path_dll) + info).c_str()); 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 userInterfaceDisable(const Twpp::Identity& origin, Twpp::UserInterface& data) override;
virtual Twpp::Result userInterfaceEnable(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 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 imageInfoGet(const Twpp::Identity& origin, Twpp::ImageInfo& data) override;
virtual Twpp::Result imageLayoutGet(const Twpp::Identity& origin, Twpp::ImageLayout& 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; virtual Twpp::Result imageLayoutGetDefault(const Twpp::Identity& origin, Twpp::ImageLayout& data) override;

View File

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

View File

@ -418,14 +418,29 @@ public:
/// are required to fill data in existing instance. /// are required to fill data in existing instance.
/// \param ids List of requested info IDs to be filled in by the source. /// \param ids List of requested info IDs to be filled in by the source.
ExtImageInfo(std::initializer_list<InfoId> ids) : ExtImageInfo(std::initializer_list<InfoId> ids) :
m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()){ m_data(new char[sizeof(Detail::ExtImageInfoData) - sizeof(Info) + ids.size() * sizeof(Info)]()) {
d()->m_numInfos = static_cast<UInt32>(ids.size()); d()->m_numInfos = static_cast<UInt32>(ids.size());
Info* infos = d()->m_infos; Info* infos = d()->m_infos;
UInt32 i = 0; UInt32 i = 0;
for (auto id : ids){ for (auto id : ids) {
auto& info = infos[i];
i++;
info.m_infoId = id;
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]; auto& info = infos[i];
i++; i++;