401 lines
11 KiB
C++
401 lines
11 KiB
C++
#include "sane_option.h"
|
|
#include <sane/sane_option_definitions.h>
|
|
#include "../sdk/hginclude/huagaoxxx_warraper_ex.h"
|
|
|
|
#include "../../sdk/include/lang/app_language.h"
|
|
|
|
#define ARRAY_SIZE(a) (sizeof(a) / sizeof(a[0]))
|
|
|
|
static struct _paper_size
|
|
{
|
|
const char* title;
|
|
int width;
|
|
int height;
|
|
}g_paper[] =
|
|
{
|
|
{OPTION_VALUE_ZZCC_A3, 297, 420},
|
|
{OPTION_VALUE_ZZCC_8K, 297, 420},
|
|
{OPTION_VALUE_ZZCC_A4HX,297, 210},
|
|
{OPTION_VALUE_ZZCC_B4, 257, 364},
|
|
{OPTION_VALUE_ZZCC_B5HX,250, 176}, // {PAPER_B5, {182, 257}},
|
|
{OPTION_VALUE_ZZCC_A4, 210, 297},
|
|
{OPTION_VALUE_ZZCC_16K, 210, 285}, // {PAPER_16K, {185, 260}}
|
|
{OPTION_VALUE_ZZCC_A5HX,210, 148},
|
|
{OPTION_VALUE_ZZCC_B5, 176, 250}, // {PAPER_B5, {182, 257}},
|
|
{OPTION_VALUE_ZZCC_B6HX,176, 125},
|
|
{OPTION_VALUE_ZZCC_A5, 148, 210},
|
|
{OPTION_VALUE_ZZCC_A6HX,148, 105},
|
|
{OPTION_VALUE_ZZCC_B6, 125, 176},
|
|
{OPTION_VALUE_ZZCC_A6, 105, 148}
|
|
};
|
|
static void match_paper(char* buf, int cx, int cy)
|
|
{
|
|
unsigned long fc0 = -1, fc1 = 0;
|
|
int index = -1;
|
|
|
|
fc0 = 1600 + 40000;
|
|
for (size_t i = 0; i < ARRAY_SIZE(g_paper); ++i)
|
|
{
|
|
fc1 = (cx - g_paper[i].width) * (cx - g_paper[i].width);
|
|
fc1 += (cy - g_paper[i].height) * (cy - g_paper[i].height);
|
|
if (fc1 < fc0)
|
|
{
|
|
fc0 = fc1;
|
|
index = i;
|
|
}
|
|
}
|
|
|
|
if (index == -1)
|
|
strcpy(buf, from_default_language(OPTION_VALUE_ZZCC_PPYSCC, NULL));
|
|
else
|
|
strcpy(buf, from_default_language(g_paper[index].title, NULL));
|
|
|
|
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "match paper(%u * %u) to '%s'\n", cx, cy, (char*)buf);
|
|
}
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// sane_std_opts
|
|
sane_std_opts::sane_std_opts(int opt_base) : opt_num_base_(opt_base), page_height_(0), page_width_(0)
|
|
{}
|
|
sane_std_opts::~sane_std_opts()
|
|
{
|
|
for (size_t i = 0; i < known_opts_.size(); ++i)
|
|
{
|
|
char* buf = (char*)known_opts_[i].known.desc;
|
|
|
|
delete[] buf;
|
|
}
|
|
known_opts_.clear();
|
|
}
|
|
|
|
SANE_Option_Descriptor* sane_std_opts::get_known_option(int opt, int* ind)
|
|
{
|
|
if (ind)
|
|
*ind = -1;
|
|
|
|
for (size_t i = 0; i < known_opts_.size(); ++i)
|
|
{
|
|
if (known_opts_[i].known.opt == opt)
|
|
{
|
|
if (ind)
|
|
*ind = i;
|
|
|
|
return known_opts_[i].known.desc;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
SANE_Option_Descriptor* sane_std_opts::get_known_option(const char* name, int* ind)
|
|
{
|
|
if (ind)
|
|
*ind = -1;
|
|
|
|
for (size_t i = 0; i < known_opts_.size(); ++i)
|
|
{
|
|
if (strcmp(known_opts_[i].known.desc->name, name) == 0)
|
|
{
|
|
if (ind)
|
|
*ind = i;
|
|
|
|
return known_opts_[i].known.desc;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
void sane_std_opts::to_known_opt_value(OPTMAP* opmap, const void* data, void* known_data)
|
|
{
|
|
if (strcmp(opmap->known.desc->name, SANE_STD_OPT_NAME_DUPLEX) == 0)
|
|
{
|
|
*((SANE_Bool*)known_data) = strcmp((char*)data, from_default_language(OPTION_VALUE_SMYM_DM, NULL)) == 0 ? SANE_FALSE : SANE_TRUE;
|
|
}
|
|
else if (strcmp(opmap->user.desc->name, SANE_STD_OPT_NAME_PAGE) == 0)
|
|
{
|
|
bool ok = false;
|
|
for (size_t i = 0; i < ARRAY_SIZE(g_paper); ++i)
|
|
{
|
|
if (strcmp((char*)data, g_paper[i].title) == 0)
|
|
{
|
|
page_width_ = g_paper[i].width;
|
|
page_height_ = g_paper[i].height;
|
|
ok = true;
|
|
break;
|
|
}
|
|
}
|
|
if (!ok)
|
|
{
|
|
page_width_ = 2338;
|
|
page_height_ = 3307;
|
|
}
|
|
if (strcmp(opmap->known.desc->name, SANE_STD_OPT_NAME_PAPER_W) == 0)
|
|
*((SANE_Int*)known_data) = page_width_;
|
|
else if (strcmp(opmap->known.desc->name, SANE_STD_OPT_NAME_PAPER_H) == 0)
|
|
*((SANE_Int*)known_data) = page_height_;
|
|
}
|
|
}
|
|
void* sane_std_opts::from_known_opt_value(OPTMAP* opmap, const void* known_data, long* len)
|
|
{
|
|
void* buf = nullptr;
|
|
int size = opmap->user.desc->size;
|
|
|
|
if (strcmp(opmap->known.desc->name, SANE_STD_OPT_NAME_DUPLEX) == 0)
|
|
{
|
|
buf = local_utility::acquire_memory(size + 4, "");
|
|
memset(buf, 0, size + 4);
|
|
if (len)
|
|
*len = size;
|
|
if (*((const SANE_Bool*)known_data) == SANE_TRUE)
|
|
strcpy((char*)buf, from_default_language(OPTION_VALUE_SMYM_SM, NULL));
|
|
else
|
|
strcpy((char*)buf, from_default_language(OPTION_VALUE_SMYM_DM, NULL));
|
|
}
|
|
else if (strcmp(opmap->user.desc->name, SANE_STD_OPT_NAME_PAPER) == 0)
|
|
{
|
|
int cx = page_width_,
|
|
cy = page_height_;
|
|
|
|
buf = local_utility::acquire_memory(size + 4, "");
|
|
memset(buf, 0, size + 4);
|
|
if (len)
|
|
*len = size;
|
|
if (strcmp(opmap->known.desc->name, SANE_STD_OPT_NAME_PAPER_W) == 0)
|
|
page_width_ = cx = *((SANE_Int*)known_data);
|
|
else
|
|
page_height_ = cy = *((SANE_Int*)known_data);
|
|
|
|
match_paper((char*)buf, cx, cy);
|
|
}
|
|
|
|
return buf;
|
|
}
|
|
|
|
json* sane_std_opts::get_opt_json(scanner_handle h, int opt)
|
|
{
|
|
char* buf = nullptr;
|
|
long len = 0;
|
|
json* jsn = nullptr;
|
|
|
|
if (hg_scanner_get_parameter(h, (const char*)opt, buf, &len) == SCANNER_ERR_INSUFFICIENT_MEMORY)
|
|
{
|
|
buf = new char[len + 8];
|
|
memset(buf, 0, len + 8);
|
|
if (hg_scanner_get_parameter(h, (const char*)opt, buf, &len) == SCANNER_ERR_OK)
|
|
{
|
|
jsn = new json();
|
|
if (!jsn->attach_text(buf))
|
|
{
|
|
delete jsn;
|
|
jsn = nullptr;
|
|
}
|
|
}
|
|
delete[] buf;
|
|
}
|
|
|
|
return jsn;
|
|
}
|
|
void* sane_std_opts::get_current_value(scanner_handle h, int opt)
|
|
{
|
|
json* jsn = sane_std_opts::get_opt_json(h, opt);
|
|
void* ret = nullptr;
|
|
|
|
if (jsn)
|
|
{
|
|
std::string val("");
|
|
int size = 0;
|
|
jsn->get_value("type", val);
|
|
jsn->get_value("size", size);
|
|
if (val == "string")
|
|
{
|
|
jsn->get_value("cur", val);
|
|
if (size < (int)val.length())
|
|
size = val.length() + 4;
|
|
ret = local_utility::acquire_memory(size, "");
|
|
strcpy((char*)ret, val.c_str());
|
|
}
|
|
else if (val == "bool")
|
|
{
|
|
bool v = false;
|
|
jsn->get_value("cur", v);
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Bool), "");
|
|
*((SANE_Bool*)ret) = v ? SANE_TRUE : SANE_FALSE;
|
|
}
|
|
else if (val == "int")
|
|
{
|
|
int v = 0;
|
|
jsn->get_value("cur", v);
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Int), "");
|
|
*((SANE_Int*)ret) = v;
|
|
}
|
|
else if (val == "float")
|
|
{
|
|
double v = .0f;
|
|
jsn->get_value("cur", v);
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Fixed), "");
|
|
*((SANE_Fixed*)ret) = SANE_FIX(v);
|
|
}
|
|
delete jsn;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
void sane_std_opts::init_known_opt(int option, SANE_Option_Descriptor* desc)
|
|
{
|
|
if (strcmp(desc->name, SANE_STD_OPT_NAME_PAGE) == 0)
|
|
{
|
|
// duplex
|
|
if (!get_known_option(SANE_STD_OPT_NAME_DUPLEX))
|
|
{
|
|
OPTMAP om;
|
|
int size = sizeof(SANE_Option_Descriptor);
|
|
|
|
om.user.opt = option;
|
|
om.user.desc = desc;
|
|
om.known.opt = opt_num_base_ + known_opts_.size();
|
|
om.known.desc = (SANE_Option_Descriptor*)new char[size];
|
|
memset(om.known.desc, 0, size);
|
|
om.known.desc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC;
|
|
om.known.desc->constraint_type = SANE_CONSTRAINT_NONE;
|
|
om.known.desc->desc = "set page to be simplex or duplex";
|
|
om.known.desc->name = SANE_STD_OPT_NAME_DUPLEX;
|
|
om.known.desc->size = sizeof(SANE_Bool);
|
|
om.known.desc->title = "Duplex";
|
|
om.known.desc->type = SANE_TYPE_BOOL;
|
|
om.known.desc->unit = SANE_UNIT_NONE;
|
|
om.init = "true";
|
|
known_opts_.push_back(om);
|
|
}
|
|
}
|
|
else if (strcmp(desc->name, SANE_STD_OPT_NAME_PAPER) == 0)
|
|
{
|
|
// page-width && page-height
|
|
if (!get_known_option(SANE_STD_OPT_NAME_PAPER_W))
|
|
{
|
|
OPTMAP om;
|
|
int size = sizeof(SANE_Option_Descriptor);
|
|
|
|
om.user.opt = option;
|
|
om.user.desc = desc;
|
|
om.known.opt = opt_num_base_ + known_opts_.size();
|
|
om.known.desc = (SANE_Option_Descriptor*)new char[size];
|
|
memset(om.known.desc, 0, size);
|
|
om.known.desc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC;
|
|
om.known.desc->constraint_type = SANE_CONSTRAINT_NONE;
|
|
om.known.desc->desc = "set page width";
|
|
om.known.desc->name = SANE_STD_OPT_NAME_PAPER_W;
|
|
om.known.desc->size = sizeof(SANE_Int);
|
|
om.known.desc->title = "Page Width";
|
|
om.known.desc->type = SANE_TYPE_INT;
|
|
om.known.desc->unit = SANE_UNIT_MM;
|
|
om.init = "210";
|
|
known_opts_.push_back(om);
|
|
|
|
om.known.opt = opt_num_base_ + known_opts_.size();
|
|
om.known.desc = (SANE_Option_Descriptor*)new char[size];
|
|
memset(om.known.desc, 0, size);
|
|
om.known.desc->cap = SANE_CAP_SOFT_SELECT | SANE_CAP_SOFT_DETECT | SANE_CAP_AUTOMATIC;
|
|
om.known.desc->constraint_type = SANE_CONSTRAINT_NONE;
|
|
om.known.desc->desc = "set page height";
|
|
om.known.desc->name = SANE_STD_OPT_NAME_PAPER_H;
|
|
om.known.desc->size = sizeof(SANE_Int);
|
|
om.known.desc->title = "Page Height";
|
|
om.known.desc->type = SANE_TYPE_INT;
|
|
om.known.desc->unit = SANE_UNIT_MM;
|
|
om.init = "297";
|
|
known_opts_.push_back(om);
|
|
}
|
|
}
|
|
}
|
|
SANE_Option_Descriptor* sane_std_opts::get_option(int option)
|
|
{
|
|
return get_known_option(option);
|
|
}
|
|
|
|
bool sane_std_opts::is_known_option(int opt, SANE_Option_Descriptor** user)
|
|
{
|
|
int ind = -1;
|
|
SANE_Option_Descriptor* sod = get_known_option(opt, &ind);
|
|
|
|
if (user && ind != -1)
|
|
*user = known_opts_[ind].user.desc;
|
|
|
|
return sod != nullptr;
|
|
}
|
|
void* sane_std_opts::get_default_value(scanner_handle h, int opt)
|
|
{
|
|
int ind = -1;
|
|
void* ret = nullptr;
|
|
|
|
if (get_known_option(opt, &ind))
|
|
{
|
|
OPTMAP* op = &known_opts_[ind];
|
|
if (op->known.desc->type == SANE_TYPE_BOOL)
|
|
{
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Bool), nullptr);
|
|
*(SANE_Bool*)ret = op->init == "true" ? SANE_TRUE : SANE_FALSE;
|
|
}
|
|
else if (op->known.desc->type == SANE_TYPE_INT)
|
|
{
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Int), nullptr);
|
|
*(SANE_Int*)ret = atoi(op->init.c_str());
|
|
}
|
|
else if(op->known.desc->type == SANE_TYPE_FIXED)
|
|
{
|
|
ret = local_utility::acquire_memory(sizeof(SANE_Fixed), nullptr);
|
|
*(SANE_Fixed*)ret = SANE_FIX(atof(op->init.c_str()));
|
|
}
|
|
else if (op->known.desc->type == SANE_TYPE_STRING)
|
|
{
|
|
ret = local_utility::acquire_memory(op->known.desc->size + 4, nullptr);
|
|
memset(ret, 0, op->known.desc->size + 4);
|
|
strcpy((char*)ret, op->init.c_str());
|
|
}
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
scanner_err sane_std_opts::get_value(scanner_handle h, int opt, void* buf)
|
|
{
|
|
int ind = -1;
|
|
scanner_err statu = SCANNER_ERR_INVALID_PARAMETER;
|
|
|
|
if (get_known_option(opt, &ind))
|
|
{
|
|
OPTMAP* op = &known_opts_[ind];
|
|
void* data = sane_std_opts::get_current_value(h, op->user.opt);
|
|
|
|
if (data)
|
|
{
|
|
to_known_opt_value(op, data, buf);
|
|
local_utility::free_memory(data);
|
|
}
|
|
}
|
|
|
|
return statu;
|
|
}
|
|
scanner_err sane_std_opts::set_value(scanner_handle h, int opt, void* buf)
|
|
{
|
|
int ind = -1;
|
|
scanner_err statu = SCANNER_ERR_INVALID_PARAMETER;
|
|
|
|
if (get_known_option(opt, &ind))
|
|
{
|
|
OPTMAP* op = &known_opts_[ind];
|
|
long len = 0;
|
|
void* data = from_known_opt_value(op, buf, &len);
|
|
|
|
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "%d->%d: %s\n", opt, op->user.opt, (char*)data);
|
|
|
|
statu = hg_scanner_set_parameter(h, (const char*)op->user.opt, data, len);
|
|
if (statu == SCANNER_ERR_NOT_EXACT)
|
|
to_known_opt_value(op, data, buf);
|
|
if (data)
|
|
local_utility::free_memory(data);
|
|
}
|
|
|
|
return statu;
|
|
}
|