2499 lines
62 KiB
C++
2499 lines
62 KiB
C++
#include "hg_scanner.h"
|
||
#include "../../sdk/hginclude/hg_log.h"
|
||
#include "sane/sane_option_definitions.h"
|
||
|
||
#ifdef WIN32
|
||
#include "scanner_manager.h"
|
||
#include <direct.h>
|
||
#endif
|
||
|
||
|
||
|
||
static int ui_default_callback(scanner_handle, int, void*, unsigned int*, void*)
|
||
{
|
||
return 0;
|
||
}
|
||
|
||
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
// hg_scanner
|
||
hg_scanner::hg_scanner(ScannerSerial serial
|
||
, const char* dev_name, usb_io* io)
|
||
: name_(dev_name ? dev_name : ""), io_(io), status_(HG_ERR_NOT_START)
|
||
, scan_count_(-1), run_(true), paper_size_(TwSS::A4), erase_bkg_range_(10)
|
||
, noise_range_(30), omit_empty_level_(50), resolution_(200), rid_hole_range_(.1f)
|
||
, bright_(128), contrast_(4), gamma_(1.0f), threshold_(40), anti_noise_(8), margin_(5)
|
||
, fractate_level_(50), ui_ev_cb_(ui_default_callback), scan_life_(NULL)
|
||
, notify_setting_result_(false), user_cancel_(false), cb_mem_(true), test_1_paper_(false)
|
||
, setting_count_(0),img_type_(""), online_(false),is_quality_(-1)
|
||
{
|
||
custom_gamma_val_ = new SANE_Gamma;
|
||
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
|
||
#ifdef MAPPING_FUNCTION_IN_BASE
|
||
init_setting_map(setting_map_, ARRAY_SIZE(setting_map_));
|
||
#endif
|
||
|
||
paper_size_mm_.cx = 210;
|
||
paper_size_mm_.cy = 297;
|
||
custom_gamma_val_->pt_count_r = custom_gamma_val_->pt_count_g = custom_gamma_val_->pt_count_b = 0;
|
||
for (int i = 0; i < ARRAY_SIZE(custom_gamma_val_->table); ++i)
|
||
custom_gamma_val_->table[i] = i & 0x0ff;
|
||
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "%s(%s) constructed\n", name_.c_str(), hg_log::format_ptr(this).c_str());
|
||
image_prc_param_.value = 0;
|
||
|
||
if (io_)
|
||
{
|
||
io_->add_ref();
|
||
status_ = io_->last_error();
|
||
online_ = status_ == HG_ERR_OK;
|
||
}
|
||
|
||
wait_usb_.set_debug_info("USB");
|
||
wait_img_.set_debug_info("Image");
|
||
thread_usb_read_.reset(new std::thread(&hg_scanner::thread_handle_usb, this));
|
||
thread_img_handle_.reset(new std::thread(&hg_scanner::thread_image_handle, this));
|
||
}
|
||
hg_scanner::~hg_scanner()
|
||
{
|
||
close(true);
|
||
|
||
if (thread_usb_read_.get() && thread_usb_read_->joinable())
|
||
thread_usb_read_->join();
|
||
if (thread_img_handle_.get() && thread_img_handle_->joinable())
|
||
thread_img_handle_->join();
|
||
delete custom_gamma_val_;
|
||
|
||
name_.insert(0, "\350\256\276\345\244\207 “");
|
||
name_ += "”\345\267\262\347\273\217\345\205\263\351\227\255\343\200\202";
|
||
notify_ui_working_status(name_.c_str(), SANE_EVENT_SCANNER_CLOSED);
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "%s(%s) destroyed.\n", name_.c_str(), hg_log::format_ptr(this).c_str());
|
||
}
|
||
|
||
std::string hg_scanner::strerr(hg_err err)
|
||
{
|
||
RETURN_IF(err, HG_ERR_OK);
|
||
RETURN_IF(err, HG_ERR_INVALID_PARAMETER);
|
||
RETURN_IF(err, HG_ERR_INSUFFICIENT_MEMORY);
|
||
RETURN_IF(err, HG_ERR_ACCESS_DENIED);
|
||
RETURN_IF(err, HG_ERR_IO_PENDING);
|
||
RETURN_IF(err, HG_ERR_NOT_EXACT);
|
||
RETURN_IF(err, HG_ERR_CONFIGURATION_CHANGED);
|
||
RETURN_IF(err, HG_ERR_NOT_OPEN);
|
||
RETURN_IF(err, HG_ERR_NOT_START);
|
||
RETURN_IF(err, HG_ERR_NO_DATA);
|
||
RETURN_IF(err, HG_ERR_HAS_DATA_YET);
|
||
RETURN_IF(err, HG_ERR_OUT_OF_RANGE);
|
||
RETURN_IF(err, HG_ERR_IO);
|
||
RETURN_IF(err, HG_ERR_TIMEOUT);
|
||
RETURN_IF(err, HG_ERR_CREATE_FILE_FAILED);
|
||
RETURN_IF(err, HG_ERR_WRITE_FILE_FAILED);
|
||
RETURN_IF(err, HG_ERR_OPENED_BY_OTHER_PROCESS);
|
||
|
||
// 2:USB错误
|
||
RETURN_IF(err, HG_ERR_USB_INIT_FAILED);
|
||
RETURN_IF(err, HG_ERR_USB_REGISTER_PNP_FAILED);
|
||
RETURN_IF(err, HG_ERR_USB_CLAIM_INTERFACE_FAILED);
|
||
|
||
// 3:硬件错误
|
||
RETURN_IF(err, HG_ERR_DEVICE_NOT_FOUND);
|
||
RETURN_IF(err, HG_ERR_DEVICE_NOT_SUPPORT);
|
||
RETURN_IF(err, HG_ERR_DEVICE_BUSY);
|
||
RETURN_IF(err, HG_ERR_DEVICE_STOPPED);
|
||
RETURN_IF(err, HG_ERR_DEVICE_COVER_OPENNED);
|
||
RETURN_IF(err, HG_ERR_DEVICE_NO_PAPER);
|
||
RETURN_IF(err, HG_ERR_DEVICE_FEEDING_PAPER);
|
||
RETURN_IF(err, HG_ERR_DEVICE_DOUBLE_FEEDING);
|
||
RETURN_IF(err, HG_ERR_DEVICE_PAPER_JAMMED);
|
||
RETURN_IF(err, HG_ERR_DEVICE_STAPLE_ON);
|
||
RETURN_IF(err, HG_ERR_DEVICE_PAPER_SKEW);
|
||
RETURN_IF(err, HG_ERR_DEVICE_SIZE_CHECK);
|
||
RETURN_IF(err, HG_ERR_DEVICE_DOGEAR);
|
||
RETURN_IF(err, HG_ERR_DEVICE_NO_IMAGE);
|
||
RETURN_IF(err, HG_ERR_DEVICE_SCANN_ERROR);
|
||
|
||
char unk[80];
|
||
sprintf(unk, "\346\234\252\347\237\245\351\224\231\350\257\257\357\274\2320x%x", err);
|
||
|
||
return unk;
|
||
}
|
||
std::string hg_scanner::error_description(hg_err err)
|
||
{
|
||
RETURN_DESC_IF(err, HG_ERR_OK);
|
||
RETURN_DESC_IF(err, HG_ERR_INVALID_PARAMETER);
|
||
RETURN_DESC_IF(err, HG_ERR_INSUFFICIENT_MEMORY);
|
||
RETURN_DESC_IF(err, HG_ERR_ACCESS_DENIED);
|
||
RETURN_DESC_IF(err, HG_ERR_IO_PENDING);
|
||
RETURN_DESC_IF(err, HG_ERR_NOT_EXACT);
|
||
RETURN_DESC_IF(err, HG_ERR_CONFIGURATION_CHANGED);
|
||
RETURN_DESC_IF(err, HG_ERR_NOT_OPEN);
|
||
RETURN_DESC_IF(err, HG_ERR_NOT_START);
|
||
RETURN_DESC_IF(err, HG_ERR_NO_DATA);
|
||
RETURN_DESC_IF(err, HG_ERR_HAS_DATA_YET);
|
||
RETURN_DESC_IF(err, HG_ERR_OUT_OF_RANGE);
|
||
RETURN_DESC_IF(err, HG_ERR_IO);
|
||
RETURN_DESC_IF(err, HG_ERR_TIMEOUT);
|
||
RETURN_DESC_IF(err, HG_ERR_CREATE_FILE_FAILED);
|
||
RETURN_DESC_IF(err, HG_ERR_WRITE_FILE_FAILED);
|
||
RETURN_DESC_IF(err, HG_ERR_OPENED_BY_OTHER_PROCESS);
|
||
|
||
// 2:USB错误
|
||
RETURN_DESC_IF(err, HG_ERR_USB_INIT_FAILED);
|
||
RETURN_DESC_IF(err, HG_ERR_USB_REGISTER_PNP_FAILED);
|
||
RETURN_DESC_IF(err, HG_ERR_USB_CLAIM_INTERFACE_FAILED);
|
||
|
||
// 3:硬件错误
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_NOT_FOUND);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_NOT_SUPPORT);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_BUSY);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_STOPPED);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_COVER_OPENNED);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_NO_PAPER);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_FEEDING_PAPER);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_DOUBLE_FEEDING);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_PAPER_JAMMED);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_STAPLE_ON);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_PAPER_SKEW);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_SIZE_CHECK);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_DOGEAR);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_NO_IMAGE);
|
||
RETURN_DESC_IF(err, HG_ERR_DEVICE_SCANN_ERROR);
|
||
|
||
char unk[80];
|
||
sprintf(unk, "\346\234\252\347\237\245\351\224\231\350\257\257\357\274\2320x%x", err);
|
||
|
||
return unk;
|
||
}
|
||
std::string hg_scanner::temporary_file(char* tail, char* head)
|
||
{
|
||
std::string path("/tmp/");
|
||
char buf[128];
|
||
FILE* src = NULL;
|
||
unsigned int ind = 1;
|
||
|
||
if (!head || *head == 0)
|
||
head = (char*)"scan";
|
||
if (!tail)
|
||
tail = (char*)"";
|
||
|
||
#ifdef WIN32
|
||
char me[MAX_PATH] = { 0 }, * n = NULL;
|
||
|
||
GetModuleFileNameA(NULL, me, _countof(me) - 1);
|
||
n = strrchr(me, '\\');
|
||
if (n++ == NULL)
|
||
n = me;
|
||
*n = 0;
|
||
path = me;
|
||
path += "img_tmp\\";
|
||
mkdir(path.c_str());
|
||
#endif
|
||
|
||
srand(time(NULL));
|
||
sprintf(buf, "%s%s", head, tail);
|
||
while ((src = fopen((path + buf).c_str(), "rb")))
|
||
{
|
||
fclose(src);
|
||
sprintf(buf, "%s(%u)%s", head, ind++, tail);
|
||
}
|
||
|
||
return path + buf;
|
||
}
|
||
int hg_scanner::save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std::string* path_file, unsigned int index)
|
||
{
|
||
char head[40] = { 0 };
|
||
std::string file("");
|
||
FILE* dst = nullptr;
|
||
int ret = HG_ERR_OK;
|
||
|
||
sprintf(head, "scan_%06u", index);
|
||
file = hg_scanner::temporary_file((char*)".jpg", (char*)head);
|
||
dst = fopen(file.c_str(), "wb+");
|
||
if (dst)
|
||
{
|
||
ENOSPC; EROFS; strerror(errno);
|
||
size_t wrote = fwrite(data->data(), 1, data->size(), dst);
|
||
if (wrote == data->size())
|
||
{
|
||
if (path_file)
|
||
*path_file = file;
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "--->Wrote %u bytes to file '%s'\n", wrote, file.c_str());
|
||
}
|
||
else
|
||
{
|
||
ret = HG_ERR_WRITE_FILE_FAILED;
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_FATAL, "Failed in writting file(%u/%u) '%s'\n", wrote, data->size(), file.c_str());
|
||
}
|
||
fclose(dst);
|
||
}
|
||
else
|
||
{
|
||
ret = HG_ERR_CREATE_FILE_FAILED;
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_FATAL, "Failed in creating file '%s'\n", file.c_str());
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
void hg_scanner::init_setting_map(int* setting_map, int count)
|
||
{
|
||
for (int i = 0; i < count; ++i)
|
||
setting_map[i] = -1;
|
||
}
|
||
void hg_scanner::set_setting_map(int sn, const char* title)
|
||
{
|
||
std::string val(title);
|
||
int empty = 0;
|
||
|
||
while (empty < val.length() && val[empty] == ' ')
|
||
empty++;
|
||
val.erase(0, empty);
|
||
|
||
//HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "title: '%s', val: '%s'\n", title, val.c_str());
|
||
|
||
if (val == OPTION_TITLE_HFMRSZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_RESTORE_DEFAULT_SETTINGS] = sn;
|
||
else if (val == OPTION_TITLE_BZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_HELP] = sn;
|
||
else if (val == OPTION_TITLE_YSMS)
|
||
setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE] = sn;
|
||
else if (val == OPTION_TITLE_DLSC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_MULTI_OUT] = sn;
|
||
else if (val == OPTION_TITLE_HDHHBTX_CS)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_COLOR] = sn;
|
||
else if (val == OPTION_TITLE_24WCSTX_DLSCCH)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_MULTI_OUT_RED] = sn;
|
||
else if (val == OPTION_TITLE_24WCSTX_DTKCH)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_ANSWER_RED] = sn;
|
||
else if (val == OPTION_TITLE_BJYC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_BACKGROUND] = sn;
|
||
else if (val == OPTION_TITLE_BJSCFDFW)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_BACKGROUND_RANGE] = sn;
|
||
else if (val == OPTION_TITLE_HBTXZDYH)
|
||
setting_map_[HG_BASE_SETTING_INDEX_NOISE_OPTIMIZE] = sn;
|
||
else if (val == OPTION_TITLE_ZDYHCC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_NOISE_OPTIMIZE_SIZE] = sn;
|
||
else if (val == OPTION_TITLE_ZZCC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PAPER] = sn;
|
||
else if (val == OPTION_TITLE_CCJC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PAPER_SIZE_CHECK] = sn;
|
||
else if (val == OPTION_TITLE_ZDYSMQY)
|
||
setting_map_[HG_BASE_SETTING_INDEX_IS_CUSTOM_AREA] = sn;
|
||
else if (val == OPTION_TITLE_SMQYZCmm)
|
||
setting_map_[HG_BASE_SETTING_INDEX_CUSTOM_AREA_LEFT] = sn;
|
||
else if (val == OPTION_TITLE_SMQYYCmm)
|
||
setting_map_[HG_BASE_SETTING_INDEX_CUSTOM_AREA_RIGHT] = sn;
|
||
else if (val == OPTION_TITLE_SMQYSCmm)
|
||
setting_map_[HG_BASE_SETTING_INDEX_CUSTOM_AREA_TOP] = sn;
|
||
else if (val == OPTION_TITLE_SMQYXCmm)
|
||
setting_map_[HG_BASE_SETTING_INDEX_CUSTOM_AREA_BOTTOM] = sn;
|
||
else if (val == OPTION_TITLE_SMYM)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PAGE] = sn;
|
||
else if (val == OPTION_TITLE_TGKBYLMD)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PAGE_OMIT_EMPTY_LEVEL] = sn;
|
||
else if (val == OPTION_TITLE_FBL)
|
||
setting_map_[HG_BASE_SETTING_INDEX_RESOLUTION] = sn;
|
||
else if (val == OPTION_TITLE_TXZL)
|
||
setting_map_[HG_BASE_SETTING_INDEX_IMG_QUALITY] = sn;
|
||
else if (val == OPTION_TITLE_JHZFM)
|
||
setting_map_[HG_BASE_SETTING_INDEX_EXCHANGE] = sn;
|
||
else if (val == OPTION_TITLE_TXCF)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SPLIT] = sn;
|
||
else if (val == OPTION_TITLE_ZDJP)
|
||
setting_map_[HG_BASE_SETTING_INDEX_AUTO_CORRECT] = sn;
|
||
else if (val == OPTION_TITLE_CKYC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_RID_HOLE] = sn;
|
||
else if (val == OPTION_TITLE_CKSSFWZFMBL)
|
||
setting_map_[HG_BASE_SETTING_INDEX_RID_HOLE_RANGE] = sn;
|
||
else if (val == OPTION_TITLE_QYSDQX)
|
||
setting_map_[HG_BASE_SETTING_INDEX_IS_CUSTOM_GAMMA] = sn;
|
||
else if (val == OPTION_TITLE_LDZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_BRIGHT] = sn;
|
||
else if (val == OPTION_TITLE_DBD)
|
||
setting_map_[HG_BASE_SETTING_INDEX_CONTRAST] = sn;
|
||
else if (val == OPTION_TITLE_GMZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_GAMMA] = sn;
|
||
else if (val == OPTION_TITLE_RHYMH)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SHARPEN] = sn;
|
||
else if (val == OPTION_TITLE_SSYZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_DARK_SAMPLE] = sn;
|
||
else if (val == OPTION_TITLE_XCHK)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERASE_BLACK_FRAME] = sn;
|
||
else if (val == OPTION_TITLE_YZ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_THRESHOLD] = sn;
|
||
else if (val == OPTION_TITLE_BJKZDJ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ANTI_NOISE_LEVEL] = sn;
|
||
else if (val == OPTION_TITLE_BYSJ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_MARGIN] = sn;
|
||
else if (val == OPTION_TITLE_BJTCFS)
|
||
setting_map_[HG_BASE_SETTING_INDEX_FILL_BACKGROUND] = sn;
|
||
else if (val == OPTION_TITLE_FZST)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PERMEATE] = sn;
|
||
else if (val == OPTION_TITLE_FZSTDJ)
|
||
setting_map_[HG_BASE_SETTING_INDEX_PERMEATE_LV] = sn;
|
||
else if (val == OPTION_TITLE_QCMW)
|
||
setting_map_[HG_BASE_SETTING_INDEX_REMOVE_MORR] = sn;
|
||
else if (val == OPTION_TITLE_CWKS)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ERROR_EXTENTION] = sn;
|
||
else if (val == OPTION_TITLE_CWW)
|
||
setting_map_[HG_BASE_SETTING_INDEX_REMOVE_TXTTURE] = sn;
|
||
else if (val == OPTION_TITLE_CSBJC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ULTRASONIC_CHECK] = sn;
|
||
else if (val == OPTION_TITLE_ZDJC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_STAPLE_CHECK] = sn;
|
||
else if (val == OPTION_TITLE_SMZS)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SCAN_MODE] = sn;
|
||
else if (val == OPTION_TITLE_SMSL)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SCAN_COUNT] = sn;
|
||
else if (val == OPTION_TITLE_WGFX)
|
||
setting_map_[HG_BASE_SETTING_INDEX_TEXT_DIRECTION] = sn;
|
||
else if (val == OPTION_TITLE_BMXZ180)
|
||
setting_map_[HG_BASE_SETTING_INDEX_ROTATE_BKG_180] = sn;
|
||
else if (val == OPTION_TITLE_ZJJC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_FRACTATE_CHECK] = sn;
|
||
else if (val == OPTION_TITLE_ZJJCFZD)
|
||
setting_map_[HG_BASE_SETTING_INDEX_FRACTATE_CHECK_LEVEL] = sn;
|
||
else if (val == OPTION_TITLE_WXJC)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SKEW_CHECK] = sn;
|
||
else if (val == OPTION_TITLE_WXJCFZD)
|
||
setting_map_[HG_BASE_SETTING_INDEX_SKEW_CHECK_LEVEL] = sn;
|
||
}
|
||
void hg_scanner::thread_handle_usb(void)
|
||
{
|
||
while (run_)
|
||
{
|
||
wait_usb_.wait();
|
||
if (!run_)
|
||
break;
|
||
|
||
if (scan_life_)
|
||
{
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(3000));
|
||
if (scan_life_)
|
||
{
|
||
HG_LOG(HG_LOG_LEVEL_FATAL, "image process is still running!\n");
|
||
continue;
|
||
}
|
||
}
|
||
|
||
scan_life_ = new do_when_born_and_dead<hg_scanner>(this, &hg_scanner::working_begin, &hg_scanner::working_done, NULL);
|
||
usb_img_index_ = 0;
|
||
thread_handle_usb_read();
|
||
if (scan_life_->release() == 0)
|
||
scan_life_ = NULL;
|
||
}
|
||
}
|
||
void hg_scanner::thread_image_handle(void)
|
||
{
|
||
while (run_)
|
||
{
|
||
wait_img_.wait();
|
||
if (!run_)
|
||
break;
|
||
|
||
scan_life_->add_ref();
|
||
thread_handle_image_process();
|
||
if (scan_life_->release() == 0)
|
||
scan_life_ = NULL;
|
||
}
|
||
}
|
||
void hg_scanner::get_range(int setting_no, std::vector<std::string>& range, std::string& def_val, bool& is_range/*range or list*/)
|
||
{
|
||
char sn[20];
|
||
std::string type("");
|
||
|
||
sprintf(sn, "%d", setting_no);
|
||
range.clear();
|
||
if (setting_jsn_.at(sn).contains("range"))
|
||
{
|
||
setting_jsn_.at(sn).at("type").get_to(type);
|
||
is_range = !setting_jsn_.at(sn).at("range").is_array();
|
||
if (is_range)
|
||
{
|
||
if (type == "int")
|
||
{
|
||
int l = 0, u = 0;
|
||
setting_jsn_.at(sn).at("range").at("min").get_to(l);
|
||
setting_jsn_.at(sn).at("range").at("max").get_to(u);
|
||
|
||
char str[20];
|
||
sprintf(str, "%d", l);
|
||
range.push_back(str);
|
||
sprintf(str, "%d", u);
|
||
range.push_back(str);
|
||
}
|
||
else
|
||
{
|
||
double l = .0f, u = .0f;
|
||
setting_jsn_.at(sn).at("range").at("min").get_to(l);
|
||
setting_jsn_.at(sn).at("range").at("max").get_to(u);
|
||
|
||
char str[40];
|
||
sprintf(str, "%f", l);
|
||
range.push_back(str);
|
||
sprintf(str, "%f", u);
|
||
range.push_back(str);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
char str[40];
|
||
for (int i = 0; i < setting_jsn_.at(sn).at("range").size(); ++i)
|
||
{
|
||
if (type == "int")
|
||
{
|
||
int v = 0;
|
||
setting_jsn_.at(sn).at("range").at(i).get_to(v);
|
||
sprintf(str, "%d", v);
|
||
range.push_back(str);
|
||
}
|
||
else if(type == "float")
|
||
{
|
||
double v = 0;
|
||
setting_jsn_.at(sn).at("range").at(i).get_to(v);
|
||
sprintf(str, "%f", v);
|
||
range.push_back(str);
|
||
}
|
||
else
|
||
{
|
||
std::string v("");
|
||
setting_jsn_.at(sn).at("range").at(i).get_to(v);
|
||
range.push_back(v);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
if (type == "int")
|
||
{
|
||
int v = 0;
|
||
setting_jsn_.at(sn).at("default").get_to(v);
|
||
sprintf(sn, "%d", v);
|
||
def_val = sn;
|
||
}
|
||
else if (type == "float")
|
||
{
|
||
double v = 0;
|
||
setting_jsn_.at(sn).at("default").get_to(v);
|
||
sprintf(sn, "%f", v);
|
||
def_val = sn;
|
||
}
|
||
else if(type == "string")
|
||
setting_jsn_.at(sn).at("default").get_to(def_val);
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "setting %d has %d range(s) and default value is '%s'\n", setting_no, range.size(), def_val.c_str());
|
||
}
|
||
bool hg_scanner::check_range(int setting_no, bool& val)
|
||
{
|
||
std::vector<std::string> range;
|
||
std::string init(""), in(val ? "true" : "false");
|
||
bool is_range = false;;
|
||
|
||
get_range(setting_no, range, init, is_range);
|
||
if (range.size() == 0)
|
||
return true;
|
||
|
||
for (int i = 0; i < range.size(); ++i)
|
||
{
|
||
if (in == range[i])
|
||
return true;
|
||
}
|
||
|
||
val = init == "true" ? true : false;
|
||
|
||
return false;
|
||
}
|
||
bool hg_scanner::check_range(int setting_no, int& val)
|
||
{
|
||
std::vector<std::string> range;
|
||
std::string init("");
|
||
bool is_range = false;;
|
||
|
||
get_range(setting_no, range, init, is_range);
|
||
if (range.size() == 0)
|
||
return true;
|
||
|
||
if (is_range && range.size() == 2)
|
||
{
|
||
if (val >= atoi(range[0].c_str()) && val <= atoi(range[1].c_str()))
|
||
return true;
|
||
|
||
if(val < atoi(range[0].c_str()))
|
||
val = atoi(range[0].c_str());
|
||
else
|
||
val = atoi(range[1].c_str());
|
||
|
||
return false;
|
||
}
|
||
else if (!is_range)
|
||
{
|
||
for (int i = 0; i < range.size(); ++i)
|
||
{
|
||
if (atoi(range[i].c_str()) == val)
|
||
return true;
|
||
}
|
||
}
|
||
|
||
val = atoi(init.c_str());
|
||
|
||
return false;
|
||
}
|
||
bool hg_scanner::check_range(int setting_no, double& val)
|
||
{
|
||
std::vector<std::string> range;
|
||
std::string init("");
|
||
bool is_range = false;;
|
||
|
||
get_range(setting_no, range, init, is_range);
|
||
if (range.size() == 0)
|
||
return true;
|
||
|
||
if (is_range && range.size() == 2)
|
||
{
|
||
if (val >= atof(range[0].c_str()) && val <= atof(range[1].c_str()))
|
||
return true;
|
||
|
||
if (val < atof(range[0].c_str()))
|
||
val = atof(range[0].c_str());
|
||
else
|
||
val = atof(range[1].c_str());
|
||
|
||
return false;
|
||
}
|
||
else if (!is_range)
|
||
{
|
||
for (int i = 0; i < range.size(); ++i)
|
||
{
|
||
if (fabs(atof(range[i].c_str()) - val) < .000001)
|
||
return true;
|
||
}
|
||
}
|
||
|
||
val = atof(init.c_str());
|
||
|
||
return false;
|
||
}
|
||
bool hg_scanner::check_range(int setting_no, std::string& val)
|
||
{
|
||
std::vector<std::string> range;
|
||
std::string init(""), in(val);
|
||
bool is_range = false;;
|
||
|
||
get_range(setting_no, range, init, is_range);
|
||
if (range.size() == 0)
|
||
return true;
|
||
|
||
for (int i = 0; i < range.size(); ++i)
|
||
{
|
||
if (in == range[i])
|
||
return true;
|
||
}
|
||
|
||
val = init;
|
||
|
||
return false;
|
||
}
|
||
int hg_scanner::restore(int setting_no)
|
||
{
|
||
char key[20];
|
||
int sn = setting_no;
|
||
std::string val("");
|
||
|
||
sprintf(key, "%d", setting_no);
|
||
setting_jsn_.at(key).at("name").get_to(val);
|
||
if (val == KNOWN_OPT_NAME_CUSTOM_GAMMA)
|
||
{
|
||
custom_gamma_val_->pt_count_r = custom_gamma_val_->pt_count_g = custom_gamma_val_->pt_count_b = 0;
|
||
for (int i = 0; i < ARRAY_SIZE(custom_gamma_val_->table); ++i)
|
||
custom_gamma_val_->table[i] = i & 0x0ff;
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
setting_jsn_.at(key).at("type").get_to(val);
|
||
if (val == "string")
|
||
{
|
||
val = "";
|
||
setting_jsn_.at(key).at("default").get_to(val);
|
||
|
||
char* buf = NULL;
|
||
int size = 0;
|
||
|
||
setting_jsn_.at(key).at("size").get_to(size);
|
||
buf = (char*)malloc(size + 4);
|
||
bzero(buf, size + 4);
|
||
strcpy(buf, val.c_str());
|
||
sn = set_setting(sn, buf, val.length());
|
||
free(buf);
|
||
}
|
||
else if (val == "int")
|
||
{
|
||
int v = 0;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
sn = set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
else if (val == "float")
|
||
{
|
||
double v = .0f;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
sn = set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
else if (val == "bool")
|
||
{
|
||
bool v = false;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
sn = set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
else
|
||
sn = HG_ERR_OK;
|
||
|
||
return sn;
|
||
}
|
||
bool hg_scanner::get_default_value(void* buf, json* jsn)
|
||
{
|
||
std::string type("");
|
||
|
||
jsn->at("name").get_to(type);
|
||
if (type == KNOWN_OPT_NAME_CUSTOM_GAMMA)
|
||
{
|
||
SANE_Int* gma = (SANE_Int*)buf;
|
||
for (size_t i = 0; i < sizeof(custom_gamma_val_); ++i)
|
||
gma[i] = i & 0x0ff;
|
||
|
||
return true;
|
||
}
|
||
|
||
jsn->at("type").get_to(type);
|
||
if (type == "bool")
|
||
{
|
||
bool v = false;
|
||
jsn->at("default").get_to(v);
|
||
*((SANE_Bool*)buf) = v;
|
||
}
|
||
else if (type == "int")
|
||
{
|
||
int v = 0;
|
||
jsn->at("default").get_to(v);
|
||
*((SANE_Int*)buf) = v;
|
||
}
|
||
else if (type == "float")
|
||
{
|
||
double v = 0;
|
||
jsn->at("default").get_to(v);
|
||
*((SANE_Fixed*)buf) = SANE_FIX(v);
|
||
}
|
||
else if (type == "string")
|
||
{
|
||
type = "";
|
||
jsn->at("default").get_to(type);
|
||
strcpy((char*)buf, type.c_str());
|
||
}
|
||
else
|
||
return false;
|
||
|
||
return true;
|
||
}
|
||
bool hg_scanner::is_to_file(void)
|
||
{
|
||
return resolution_ > 200
|
||
|| paper_size_ == TwSS::USStatement
|
||
|| paper_size_ == TwSS::MaxSize
|
||
|| paper_size_ == TwSS::Trigeminy;
|
||
}
|
||
void hg_scanner::thread_handle_image_process(void)
|
||
{
|
||
while (run_ && !user_cancel_)
|
||
{
|
||
std::shared_ptr<std::vector<char>> buffer;
|
||
if (imgs_.Size() == 0 && paths_.Size() == 0)
|
||
{
|
||
if (wait_usb_.is_waiting())
|
||
break;
|
||
|
||
this_thread::sleep_for(chrono::milliseconds(30));
|
||
continue;
|
||
}
|
||
|
||
if (is_to_file())
|
||
{
|
||
std::string file(paths_.Take());
|
||
FILE* src = fopen(file.c_str(), "rb+");
|
||
if (src)
|
||
{
|
||
unsigned length = 0;
|
||
|
||
fseek(src, 0, SEEK_END);
|
||
length = ftell(src);
|
||
fseek(src, 0, SEEK_SET);
|
||
buffer.reset(new std::vector<char>);
|
||
buffer->resize(length);
|
||
fread(buffer->data(), 1, length, src);
|
||
fclose(src);
|
||
remove(file.c_str());
|
||
}
|
||
else
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_FATAL, "FATAL: open tempory image file '%s' failed.\n", file.c_str());
|
||
}
|
||
}
|
||
else
|
||
{
|
||
buffer = imgs_.Take();
|
||
}
|
||
|
||
image_process(buffer);
|
||
}
|
||
}
|
||
|
||
void hg_scanner::working_begin(void*)
|
||
{
|
||
final_img_index_ = 0;
|
||
notify_ui_working_status(STATU_DESC_SCAN_WORKING, SANE_EVENT_WORKING, HG_ERR_OK);
|
||
}
|
||
void hg_scanner::working_done(void*)
|
||
{
|
||
imgs_.Clear();
|
||
while (paths_.Size())
|
||
{
|
||
remove(paths_.Take().c_str());
|
||
}
|
||
|
||
switch (status_)
|
||
{
|
||
case HG_ERR_OK:
|
||
notify_ui_working_status(STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_BUSY:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_PC_BUSY, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_STOPPED:
|
||
notify_ui_working_status(STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_COVER_OPENNED:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_COVER_OPENNED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_NO_PAPER:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_NO_PAPER, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_FEEDING_PAPER:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_FEEDING_PAPER, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_NOT_FOUND:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_NOT_FOUND, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_SLEEPING:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_SLEEPING, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_COUNT_MODE:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_COUNT_MODE, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_DOUBLE_FEEDING:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_DOUBLE_FEEDING, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_PAPER_JAMMED:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_PAPER_JAMMED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_STAPLE_ON:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_STAPLE_ON, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_PAPER_SKEW:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_PAPER_SKEW, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_SIZE_CHECK:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_SIZE_CHECK, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_DOGEAR:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_DOGEAR, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_NO_IMAGE:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_NO_IMAGE, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_SCANN_ERROR:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_SCANN_ERROR, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
case HG_ERR_DEVICE_PC_BUSY:
|
||
notify_ui_working_status(STATU_DESC_HG_ERR_DEVICE_PC_BUSY, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
default:
|
||
notify_ui_working_status(user_cancel_ ? STATU_DESC_SCAN_CANCELED : STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
break;
|
||
}
|
||
|
||
//notify_ui_working_status(STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_);
|
||
|
||
if (test_1_paper_)
|
||
{
|
||
HG_LOG(HG_LOG_LEVEL_DEBUG_INFO, "scanning mode: finished testing ONE paper, restore to normal scanning.\n");
|
||
}
|
||
else
|
||
{
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "scanned %d picture(s) and finished with error %s.\n", final_img_index_, hg_scanner::strerr((hg_err)status_).c_str());
|
||
}
|
||
|
||
test_1_paper_ = false;
|
||
}
|
||
|
||
void hg_scanner::reset_custom_area_range(int paper)
|
||
{
|
||
if (paper == PAPER_A3)
|
||
{
|
||
paper_size_mm_.cx = 297;
|
||
paper_size_mm_.cy = 420;
|
||
}
|
||
else if (paper == PAPER_A4)
|
||
{
|
||
paper_size_mm_.cx = 210;
|
||
paper_size_mm_.cy = 297;
|
||
}
|
||
else if (paper == PAPER_A4_LATERAL)
|
||
{
|
||
paper_size_mm_.cx = 297;
|
||
paper_size_mm_.cy = 210;
|
||
}
|
||
else if (paper == PAPER_A5)
|
||
{
|
||
paper_size_mm_.cx = 148;
|
||
paper_size_mm_.cy = 210;
|
||
}
|
||
else if (paper == PAPER_A5_LATERAL)
|
||
{
|
||
paper_size_mm_.cx = 210;
|
||
paper_size_mm_.cy = 148;
|
||
}
|
||
else if (paper == PAPER_A6)
|
||
{
|
||
paper_size_mm_.cx = 105;
|
||
paper_size_mm_.cy = 148;
|
||
}
|
||
else if (paper == PAPER_A6_LATERAL)
|
||
{
|
||
paper_size_mm_.cx = 148;
|
||
paper_size_mm_.cy = 105;
|
||
}
|
||
else if (paper == PAPER_B4)
|
||
{
|
||
paper_size_mm_.cx = 250;
|
||
paper_size_mm_.cy = 353;
|
||
}
|
||
else if (paper == PAPER_B5)
|
||
{
|
||
paper_size_mm_.cx = 176;
|
||
paper_size_mm_.cy = 250;
|
||
}
|
||
else if (paper == PAPER_B6)
|
||
{
|
||
paper_size_mm_.cx = 125;
|
||
paper_size_mm_.cy = 176;
|
||
}
|
||
else if (paper == PAPER_B5_LATERAL)
|
||
{
|
||
paper_size_mm_.cx = 250;
|
||
paper_size_mm_.cy = 176;
|
||
}
|
||
else if (paper == PAPER_B6_LATERAL)
|
||
{
|
||
paper_size_mm_.cx = 176;
|
||
paper_size_mm_.cy = 125;
|
||
}
|
||
else
|
||
{
|
||
paper_size_mm_.cx = 210;
|
||
paper_size_mm_.cy = 297;
|
||
}
|
||
}
|
||
|
||
int hg_scanner::setting_restore(void* data)
|
||
{
|
||
// restore ...
|
||
int count = 0;
|
||
|
||
setting_jsn_.at("option_count").get_to(count);
|
||
notify_setting_result_ = false;
|
||
for (int i = 1; i < count; ++i)
|
||
restore(i);
|
||
notify_setting_result_ = true;
|
||
|
||
return HG_ERR_CONFIGURATION_CHANGED;
|
||
}
|
||
int hg_scanner::setting_help(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
if (name_ == "华高扫描仪—G100") //保留
|
||
{
|
||
/* code */
|
||
}
|
||
|
||
std::string helpfile = helpfile_;
|
||
std::string com = "xdg-open ";//注意空格保留
|
||
|
||
#ifdef WIN32
|
||
FILE* src = fopen(helpfile.c_str(), "rb");
|
||
if (src)
|
||
fclose(src);
|
||
else
|
||
#else
|
||
if (access(helpfile.c_str(),F_OK) == -1)
|
||
#endif
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO,"App_Help_pdf path is:%s\r\n",hg_scanner::strerr((hg_err)ret).c_str());
|
||
ret = HG_ERR_OPEN_FILE_FAILED;
|
||
return ret ;
|
||
}
|
||
|
||
com += helpfile;
|
||
system(com.c_str());
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO,"App_Help_pdf path is:%s system is:%d\r\n",helpfile.c_str());
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_color_mode(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
int old = image_prc_param_.bits.color_mode,
|
||
sub = HG_ERR_OK,
|
||
val = 0,
|
||
ret = HG_ERR_OK;
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_COLOR_MODE], str);
|
||
|
||
val = image_prc_param_.bits.color_mode = match_best_color_mode(str, NULL);
|
||
|
||
sub = on_color_mode_changed(val);
|
||
image_prc_param_.bits.color_mode = val;
|
||
|
||
if (sub == HG_ERR_NOT_EXACT)
|
||
{
|
||
image_prc_param_.bits.color_mode = old;
|
||
str = color_mode_string(image_prc_param_.bits.color_mode);
|
||
ret = HG_ERR_NOT_EXACT;
|
||
}
|
||
else if (sub)
|
||
{
|
||
ret = sub;
|
||
image_prc_param_.bits.color_mode = old;
|
||
}
|
||
else if (!exact)
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
}
|
||
|
||
is_auto_matic_color = image_prc_param_.bits.color_mode == COLOR_MODE_AUTO_MATCH ? true :false; // 等于COLOR_MODE_AUTO_MATCH 的时候颜色模式需要变为2 彩色模式图像参数和硬件参数都如此
|
||
|
||
|
||
HG_VLOG_MINI_4(HG_LOG_LEVEL_DEBUG_INFO, "Change color mode from %s to %s = %s color is =%s\n", color_mode_string(old).c_str(), (char*)data, hg_scanner::strerr((hg_err)ret).c_str(),str.c_str());
|
||
if(ret == HG_ERR_NOT_EXACT)
|
||
strcpy((char*)data, str.c_str());
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_multi_out(void *data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
if(image_prc_param_.bits.color_mode != 2)
|
||
{
|
||
ret = HG_ERR_INVALID_PARAMETER;
|
||
return ret;
|
||
}
|
||
std::string str((char*)data);
|
||
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_MULTI_OUT], str);
|
||
image_prc_param_.bits.multi_out = match_best_multi_out(str,NULL);
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "set multi_out type from %s to %s = %s\n", multi_out_string(image_prc_param_.bits.multi_out).c_str(), (char*)data, hg_scanner::strerr((hg_err)ret).c_str());
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_rid_color(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
int ret = HG_ERR_OK,
|
||
color = -1,
|
||
old = image_prc_param_.bits.rid_color;
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_ERASE_COLOR], str);
|
||
|
||
image_prc_param_.bits.rid_color = match_best_rid_color(str, NULL);
|
||
|
||
|
||
on_color_mode_changed(color);
|
||
|
||
if (!exact)
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
strcpy((char*)data, str.c_str());
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_rid_multi_red(void* data)
|
||
{
|
||
image_prc_param_.bits.rid_red = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_rid_answer_red(void* data)
|
||
{
|
||
image_prc_param_.bits.rid_answer_red = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_erase_background(void* data)
|
||
{
|
||
image_prc_param_.bits.erase_bakground = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_erase_background_range(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
erase_bkg_range_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_ERASE_BACKGROUND_RANGE], erase_bkg_range_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = erase_bkg_range_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_noise_optimize(void* data)
|
||
{
|
||
image_prc_param_.bits.noise_optimize = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_noise_optimize_range(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
noise_range_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_NOISE_OPTIMIZE_SIZE], noise_range_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = noise_range_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_paper(void* data)
|
||
{
|
||
std::string paper((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_PAPER], paper);
|
||
int ret = HG_ERR_OK, sub = HG_ERR_OK,
|
||
val = 0,
|
||
old = image_prc_param_.bits.paper;
|
||
|
||
val = image_prc_param_.bits.paper = match_best_paper(paper, NULL);
|
||
sub = on_paper_changed(val);
|
||
image_prc_param_.bits.paper = val;
|
||
if (sub == HG_ERR_NOT_EXACT)
|
||
{
|
||
ret = sub;
|
||
paper = paper_string(image_prc_param_.bits.paper);
|
||
}
|
||
else if (sub)
|
||
{
|
||
ret = sub;
|
||
image_prc_param_.bits.paper = old;
|
||
}
|
||
else if (!exact)
|
||
ret = HG_ERR_NOT_EXACT;
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "Change paper from %s to %s = %s\n", paper_string(old).c_str(), (char*)data, hg_scanner::strerr((hg_err)ret).c_str());
|
||
|
||
if(ret == HG_ERR_NOT_EXACT)
|
||
strcpy((char*)data, paper.c_str());
|
||
if(old != image_prc_param_.bits.paper)
|
||
reset_custom_area_range(image_prc_param_.bits.paper);
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_paper_check(void* data)
|
||
{
|
||
bool use = *((bool*)data);
|
||
int ret = on_paper_check_changed(use);
|
||
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "Change paper size-checking %s = %s\n", *((bool*)data) ? "enabled" : "disabled", hg_scanner::strerr((hg_err)ret).c_str());
|
||
*((bool*)data) = use;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_page(void* data)
|
||
{
|
||
std::string val((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_PAGE], val);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT;
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "Change page from %s to %s = %s\n", page_string(image_prc_param_.bits.page).c_str(), (char*)data, hg_scanner::strerr((hg_err)ret).c_str());
|
||
image_prc_param_.bits.page = match_best_page(val, NULL);
|
||
if (!exact)
|
||
strcpy((char*)data, val.c_str());
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_page_omit_empty(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
omit_empty_level_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_PAGE_OMIT_EMPTY_LEVEL], omit_empty_level_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = omit_empty_level_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_resolution(void* data)
|
||
{
|
||
int ret = HG_ERR_OK,
|
||
old = resolution_,
|
||
sub = HG_ERR_OK;
|
||
|
||
resolution_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_RESOLUTION], resolution_))
|
||
ret = HG_ERR_NOT_EXACT;
|
||
sub = on_resolution_changed(resolution_);
|
||
if (sub == HG_ERR_NOT_EXACT)
|
||
ret = sub;
|
||
else if (sub)
|
||
ret = sub;
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "Change resolution from %d to %d = %s\n", old, *((int*)data), hg_scanner::strerr((hg_err)ret).c_str());
|
||
*((int*)data) = resolution_;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_exchagnge(void* data)
|
||
{
|
||
image_prc_param_.bits.exchange = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_split_image(void* data)
|
||
{
|
||
image_prc_param_.bits.split = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_automatic_skew(void* data)
|
||
{
|
||
// automatic_skew_detection_ = *((bool*)data);
|
||
image_prc_param_.bits.automatic_skew = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_rid_hole(void* data)
|
||
{
|
||
image_prc_param_.bits.rid_hole = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_rid_hoe_range(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
rid_hole_range_ = *((double*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_RID_HOLE_RANGE], rid_hole_range_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = rid_hole_range_;
|
||
}
|
||
rid_hole_range_*=100;
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_WARNING, "rid_hole_range_ = %f\r\n", rid_hole_range_);
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_bright(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
bright_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_BRIGHT], bright_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = bright_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_contrast(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
contrast_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_CONTRAST], contrast_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = contrast_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_gamma(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
gamma_ = *((double*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_GAMMA], gamma_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((double*)data) = gamma_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_sharpen(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
int ret = HG_ERR_OK;
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_SHARPEN], str);
|
||
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "Change sharpen from %s to %s = ", sharpen_string(image_prc_param_.bits.sharpen).c_str(), (char*)data);
|
||
|
||
image_prc_param_.bits.sharpen = match_best_sharpen(str, NULL);
|
||
if (!exact)
|
||
{
|
||
strcpy((char*)data, str.c_str());
|
||
ret = HG_ERR_NOT_EXACT;
|
||
}
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "%d\n", ret);
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_dark_sample(void* data)
|
||
{
|
||
image_prc_param_.bits.dark_sample = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_erase_black_frame(void* data)
|
||
{
|
||
image_prc_param_.bits.erase_black_frame = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_threshold(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
threshold_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_THRESHOLD], threshold_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = threshold_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_anti_noise(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
anti_noise_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_ANTI_NOISE_LEVEL], anti_noise_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = anti_noise_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_margin(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
margin_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_MARGIN], margin_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = margin_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_filling_background(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_FILL_BACKGROUND], str);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT;
|
||
|
||
image_prc_param_.bits.fill_background = match_best_fill_background(str, NULL);
|
||
if (!exact)
|
||
{
|
||
strcpy((char*)data, str.c_str());
|
||
ret = HG_ERR_NOT_EXACT;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_is_permeate(void* data)
|
||
{
|
||
image_prc_param_.bits.is_permeate = *((bool*)data);
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_is_permeate_lv(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
std::string str((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_PERMEATE_LV], str);
|
||
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "Change is_permeate_lv from %s to %s = ", is_permaeate_string(image_prc_param_.bits.is_permeate_lv_).c_str(), (char*)data);
|
||
image_prc_param_.bits.is_permeate_lv_ = match_best_permaeate_lv(str, NULL);
|
||
|
||
if (!exact)
|
||
{
|
||
strcpy((char*)data, str.c_str());
|
||
ret = HG_ERR_NOT_EXACT;
|
||
}
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "%d\n", ret);
|
||
|
||
return ret;
|
||
|
||
}
|
||
int hg_scanner::setting_remove_morr(void* data)
|
||
{
|
||
image_prc_param_.bits.remove_morr = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_error_extention(void* data)
|
||
{
|
||
image_prc_param_.bits.error_extention = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_remove_texture(void* data)
|
||
{
|
||
image_prc_param_.bits.remove_txtture = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_ultrasonic_check(void* data)
|
||
{
|
||
bool use = *((bool*)data);
|
||
int ret = on_ultrasonic_check_changed(use);
|
||
|
||
if (ret)
|
||
*((bool*)data) = use;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_staple_check(void* data)
|
||
{
|
||
bool use = *((bool*)data);
|
||
int ret = on_staple_check_changed(use);
|
||
|
||
if (ret)
|
||
*((bool*)data) = use;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_scan_mode(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_SCAN_MODE], str);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT;
|
||
|
||
if (strcmp(str.c_str(), HUAGAO_SETTING_STR_SCAN_MODE_CONTINUOUS) == 0)
|
||
{
|
||
scan_count_ = -1;
|
||
}
|
||
else
|
||
{
|
||
char key[20];
|
||
sprintf(key, "%d", setting_map_[HG_BASE_SETTING_INDEX_SCAN_COUNT]);
|
||
setting_jsn_.at(key).at("cur").get_to(scan_count_);
|
||
}
|
||
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "set scanning pages to %d\n", scan_count_);
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_scan_count(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
char key[20];
|
||
std::string val("");
|
||
|
||
sprintf(key, "%d", setting_map_[HG_BASE_SETTING_INDEX_SCAN_MODE]);
|
||
setting_jsn_.at(key).at("cur").get_to(val);
|
||
if (val == HUAGAO_SETTING_STR_SCAN_MODE_CONTINUOUS)
|
||
{
|
||
scan_count_ = -1;
|
||
}
|
||
else
|
||
{
|
||
scan_count_ = *((int*)data);
|
||
}
|
||
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "set scanning pages to %d\n", scan_count_);
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_text_direction(void* data)
|
||
{
|
||
std::string str((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_TEXT_DIRECTION], str);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT;
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "Change text direction from '%s' to '%s' = %s\n", text_direction_string(image_prc_param_.bits.text_direction).c_str()
|
||
, (char*)data, hg_scanner::strerr((hg_err)ret).c_str());
|
||
image_prc_param_.bits.text_direction = match_best_text_direction(str, NULL);
|
||
if (!exact)
|
||
strcpy((char*)data, str.c_str());
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_rotate_bkg_180(void* data)
|
||
{
|
||
image_prc_param_.bits.rotate_back_180 = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_fractate_check(void* data)
|
||
{
|
||
image_prc_param_.bits.fractate_check = *((bool*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_fractate_check_level(void* data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
fractate_level_ = *((int*)data);
|
||
if (!check_range(setting_map_[HG_BASE_SETTING_INDEX_FRACTATE_CHECK_LEVEL], fractate_level_))
|
||
{
|
||
ret = HG_ERR_NOT_EXACT;
|
||
*((int*)data) = fractate_level_;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_skew_check(void* data)
|
||
{
|
||
bool use = *((bool*)data);
|
||
int ret = on_skew_check_changed(use);
|
||
|
||
if (ret)
|
||
*((bool*)data) = use;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_skew_check_level(void* data)
|
||
{
|
||
int level = *((int*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_SKEW_CHECK_LEVEL], level);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT,
|
||
sub = on_skew_check_level_changed(level);
|
||
|
||
if (sub)
|
||
{
|
||
ret = sub;
|
||
}
|
||
if (ret)
|
||
*((int*)data) = level;
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::setting_is_custom_gamma(void* data)
|
||
{
|
||
SANE_Bool* v = (SANE_Bool*)data;
|
||
|
||
custom_gamma_ = *v == SANE_TRUE;
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_custom_gamma_data(void* data)
|
||
{
|
||
SANE_Gamma* gamma = (SANE_Gamma*)data;
|
||
|
||
memcpy(custom_gamma_val_, gamma, sizeof(*custom_gamma_val_));
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_is_custom_area(void* data)
|
||
{
|
||
SANE_Bool* v = (SANE_Bool*)data;
|
||
|
||
custom_area_ = *v == SANE_TRUE;
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_custom_area_left(void* data)
|
||
{
|
||
SANE_Fixed* v = (SANE_Fixed*)data;
|
||
|
||
custom_area_lt_x_ = *((double*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_custom_area_top(void* data)
|
||
{
|
||
SANE_Fixed* v = (SANE_Fixed*)data;
|
||
|
||
custom_area_lt_y_ = *((double*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_custom_area_right(void* data)
|
||
{
|
||
SANE_Fixed* v = (SANE_Fixed*)data;
|
||
|
||
custom_area_br_x_ = *((double*)data);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::setting_custom_area_bottom(void* data)
|
||
{
|
||
SANE_Fixed* v = (SANE_Fixed*)data;
|
||
|
||
custom_area_br_y_ = *((double*)data);
|
||
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
int hg_scanner::setting_img_quality(void *data)
|
||
{
|
||
std::string str((char*)data);
|
||
bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_IMG_QUALITY], str);
|
||
int ret = exact ? HG_ERR_OK : HG_ERR_NOT_EXACT;
|
||
|
||
HG_VLOG_MINI_3(HG_LOG_LEVEL_DEBUG_INFO, "Change quality from '%s' to '%s' = %s\n", is_img_quality(is_quality_).c_str()
|
||
, (char*)data, hg_scanner::strerr((hg_err)ret).c_str());
|
||
|
||
is_quality_ = match_best_img_quality(str,NULL);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
int hg_scanner::on_color_mode_changed(int& color_mode)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_paper_changed(int& paper)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_paper_check_changed(bool& check)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_resolution_changed(int& dpi)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_ultrasonic_check_changed(bool& check)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_staple_check_changed(bool& check)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_skew_check_changed(bool& check)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_skew_check_level_changed(int& check)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
void hg_scanner::on_device_reconnected(void)
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_DEBUG_INFO, "%04x:%04x reconnected.\n", io_->get_vid(), io_->get_pid());
|
||
}
|
||
int hg_scanner::set_setting_value(int setting_no, void* data, int len)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::on_scanner_closing(bool force)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
void hg_scanner::thread_handle_usb_read(void)
|
||
{
|
||
}
|
||
|
||
void hg_scanner::init_settings(const char* json_setting_text)
|
||
{
|
||
setting_jsn_ = jsonconfig::load_json_from_text(json_setting_text);
|
||
|
||
int count = 0;
|
||
|
||
notify_setting_result_ = false;
|
||
setting_jsn_.at("option_count").get_to(count);
|
||
for (int sn = 1; sn < count; ++sn)
|
||
{
|
||
char key[20];
|
||
std::string val("");
|
||
|
||
sprintf(key, "%d", sn);
|
||
setting_jsn_.at(key).at("name").get_to(val);
|
||
if (val == KNOWN_OPT_NAME_CUSTOM_GAMMA)
|
||
continue;
|
||
|
||
#ifdef MAPPING_FUNCTION_IN_BASE
|
||
setting_jsn_.at(key).at("title").get_to(val);
|
||
set_setting_map(sn, val.c_str());
|
||
#endif
|
||
|
||
setting_jsn_.at(key).at("type").get_to(val);
|
||
if (val == "string")
|
||
{
|
||
val = "";
|
||
setting_jsn_.at(key).at("default").get_to(val);
|
||
|
||
char* buf = NULL;
|
||
int size = 0;
|
||
|
||
setting_jsn_.at(key).at("size").get_to(size);
|
||
buf = (char*)malloc(size + 4);
|
||
bzero(buf, size + 4);
|
||
strcpy(buf, val.c_str());
|
||
set_setting(sn, buf, val.length());
|
||
free(buf);
|
||
}
|
||
else if (val == "int")
|
||
{
|
||
int v = 0;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
else if (val == "float")
|
||
{
|
||
double v = .0f;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
else if (val == "bool")
|
||
{
|
||
bool v = false;
|
||
setting_jsn_.at(key).at("default").get_to(v);
|
||
set_setting(sn, (char*)&v, sizeof(v));
|
||
}
|
||
}
|
||
setting_count_ = count;
|
||
notify_setting_result_ = true;
|
||
}
|
||
int hg_scanner::on_scann_error(int err)
|
||
{
|
||
status_ = err;
|
||
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_FATAL, "[xxx]Device status: 0x%x\n", err);
|
||
|
||
unsigned int e = err;
|
||
|
||
return ui_ev_cb_((scanner_handle)this, SANE_EVENT_ERROR, (void*)hg_scanner::strerr((hg_err)err).c_str(), &e, NULL);
|
||
}
|
||
int hg_scanner::notify_ui_working_status(const char* msg, int ev, int status)
|
||
{
|
||
unsigned int s = status;
|
||
|
||
return ui_ev_cb_((scanner_handle)this, ev, (void*)msg, &s, NULL);
|
||
}
|
||
bool hg_scanner::waiting_for_memory_enough(unsigned need_bytes)
|
||
{
|
||
return true; // disable the memory control - added on 2022-03-22
|
||
|
||
bool ret = true;
|
||
|
||
if(cb_mem_)
|
||
{
|
||
int ret = ui_ev_cb_((scanner_handle)this, SANE_EVENT_IS_MEMORY_ENOUGH, NULL, &need_bytes, NULL);
|
||
|
||
if (ret == HG_ERR_INSUFFICIENT_MEMORY)
|
||
{
|
||
user_cancel_ = true;
|
||
status_ = HG_ERR_INSUFFICIENT_MEMORY;
|
||
ret = false;
|
||
}
|
||
else if (ret == HG_ERR_NOT_ANY_MORE)
|
||
cb_mem_ = false;
|
||
}
|
||
else
|
||
{
|
||
need_bytes *= 4;
|
||
|
||
void* buf = malloc(need_bytes);
|
||
bool first = true;
|
||
while (!buf && !user_cancel_)
|
||
{
|
||
if (first)
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "Memory is too small for aquiring image(%u bytes), wait for ENOUGH ...\n", need_bytes);
|
||
notify_ui_working_status(STATU_DESC_WAIT_FOR_MEM);
|
||
first = false;
|
||
}
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(30));
|
||
buf = malloc(need_bytes);
|
||
}
|
||
if (!first)
|
||
{
|
||
if (buf)
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "waited for memory need(%u)\n", need_bytes);
|
||
}
|
||
else
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "canceled by user while waiting for memory need(%u)\n", need_bytes);
|
||
}
|
||
}
|
||
ret = (!user_cancel_) && (buf != NULL);
|
||
if (buf)
|
||
free(buf);
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
|
||
void hg_scanner::copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels)
|
||
{
|
||
if (channels == 3)
|
||
header->format = SANE_FRAME_RGB;
|
||
else
|
||
header->format = SANE_FRAME_GRAY;
|
||
header->depth = 8; // 此处指每一个颜色分量的位深,我们的扫描仪固定为“8”
|
||
header->last_frame = true; // 一幅图片如果各个分量相互分离,则最后一个分量的时候设置为true。彩色图像RGB时也只有一“帧”,所以也为true
|
||
header->pixels_per_line = w;
|
||
header->lines = h;
|
||
header->bytes_per_line = line_bytes;
|
||
}
|
||
int hg_scanner::save_usb_data(std::shared_ptr<std::vector<char>> data)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
|
||
usb_img_index_++;
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_DEBUG_INFO, "USB read one picture with %u bytes\n", data->size());
|
||
if (is_to_file())
|
||
{
|
||
std::string file("");
|
||
|
||
ret = hg_scanner::save_2_tempory_file(data, &file, usb_img_index_);
|
||
if (ret == HG_ERR_OK)
|
||
paths_.Put(file);
|
||
}
|
||
else
|
||
{
|
||
imgs_.Put(data);
|
||
|
||
#ifdef SAVE_TO_FILE
|
||
hg_scanner::save_2_tempory_file(data, NULL, usb_img_index_);
|
||
#endif
|
||
}
|
||
if (wait_img_.is_waiting())
|
||
wait_img_.notify();
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf)
|
||
{
|
||
final_img_index_++;
|
||
if (async_io_)
|
||
{
|
||
SANE_Image img;
|
||
copy_to_sane_image_header(&img.header, head->width, head->height, head->line_bytes, head->channels);
|
||
img.data = (unsigned char*)buf;
|
||
img.bytes = head->total_bytes;
|
||
|
||
return ui_ev_cb_((scanner_handle)this, SANE_EVENT_IMAGE_OK, &img, &final_img_index_, NULL);
|
||
}
|
||
|
||
final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes);
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
int hg_scanner::reset_io(usb_io* io)
|
||
{
|
||
online_ = false;
|
||
if (!io)
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
usb_io* old = io_;
|
||
|
||
io->add_ref();
|
||
io_ = io;
|
||
status_ = io_->last_error();
|
||
online_ = status_ == HG_ERR_OK;
|
||
if (old)
|
||
old->release();
|
||
}
|
||
on_device_reconnected();
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
int hg_scanner::io_disconnected(void)
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
online_ = false;
|
||
io_->on_disconnected();
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
void hg_scanner::set_ui_callback(sane_callback cb, bool enable_async_io)
|
||
{
|
||
ui_ev_cb_ = cb ? cb : ui_default_callback;
|
||
async_io_ = enable_async_io;
|
||
}
|
||
int hg_scanner::get_pid(void)
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
return io_->get_pid();
|
||
}
|
||
int hg_scanner::get_vid(void)
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
return io_->get_vid();
|
||
}
|
||
int hg_scanner::close(bool force)
|
||
{
|
||
int ret = on_scanner_closing(force);
|
||
|
||
online_ = false;
|
||
if (ret == HG_ERR_OK)
|
||
{
|
||
run_ = false;
|
||
wait_usb_.notify();
|
||
wait_img_.notify();
|
||
if(!scan_life_)
|
||
{
|
||
std::lock_guard<std::mutex> lock(io_lock_);
|
||
|
||
if (io_)
|
||
{
|
||
io_->close();
|
||
io_->release();
|
||
io_ = NULL;
|
||
}
|
||
}
|
||
else if (io_)
|
||
{
|
||
HG_LOG(HG_LOG_LEVEL_WARNING, "close scanner: USB thread or Image thread is still running.\n");
|
||
io_->close();
|
||
io_->release();
|
||
io_ = NULL;
|
||
}
|
||
|
||
status_ = HG_ERR_NOT_OPEN;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::set_setting(int setting_no, void* data, int len)
|
||
{
|
||
// NOTE: the array of 'func' must be ONE to ONE of the HG_BASE_SETTING_INDEX_xxx
|
||
int(hg_scanner:: * func[])(void*) = { &hg_scanner::setting_restore
|
||
, &hg_scanner::setting_help
|
||
, &hg_scanner::setting_color_mode
|
||
, &hg_scanner::setting_multi_out
|
||
, &hg_scanner::setting_rid_color
|
||
, &hg_scanner::setting_rid_multi_red
|
||
, &hg_scanner::setting_rid_answer_red
|
||
, &hg_scanner::setting_erase_background
|
||
, &hg_scanner::setting_erase_background_range
|
||
, &hg_scanner::setting_noise_optimize
|
||
, &hg_scanner::setting_noise_optimize_range
|
||
, &hg_scanner::setting_paper
|
||
, &hg_scanner::setting_paper_check
|
||
, &hg_scanner::setting_is_custom_area
|
||
, &hg_scanner::setting_custom_area_left
|
||
, &hg_scanner::setting_custom_area_right
|
||
, &hg_scanner::setting_custom_area_top
|
||
, &hg_scanner::setting_custom_area_bottom
|
||
, &hg_scanner::setting_page
|
||
, &hg_scanner::setting_page_omit_empty
|
||
, &hg_scanner::setting_resolution
|
||
, &hg_scanner::setting_img_quality
|
||
, &hg_scanner::setting_exchagnge
|
||
, &hg_scanner::setting_split_image
|
||
, &hg_scanner::setting_automatic_skew
|
||
, &hg_scanner::setting_rid_hole
|
||
, &hg_scanner::setting_rid_hoe_range
|
||
, &hg_scanner::setting_is_custom_gamma // 2022-05-05
|
||
, &hg_scanner::setting_bright
|
||
, &hg_scanner::setting_contrast
|
||
, &hg_scanner::setting_gamma
|
||
, &hg_scanner::setting_custom_gamma_data
|
||
, &hg_scanner::setting_sharpen
|
||
, &hg_scanner::setting_dark_sample
|
||
, &hg_scanner::setting_erase_black_frame
|
||
, &hg_scanner::setting_threshold
|
||
, &hg_scanner::setting_anti_noise
|
||
, &hg_scanner::setting_margin
|
||
, &hg_scanner::setting_filling_background
|
||
, &hg_scanner::setting_is_permeate
|
||
, &hg_scanner::setting_is_permeate_lv
|
||
, &hg_scanner::setting_remove_morr
|
||
, &hg_scanner::setting_error_extention
|
||
, &hg_scanner::setting_remove_texture
|
||
, &hg_scanner::setting_ultrasonic_check
|
||
, &hg_scanner::setting_staple_check
|
||
, &hg_scanner::setting_scan_mode
|
||
, &hg_scanner::setting_scan_count
|
||
, &hg_scanner::setting_text_direction
|
||
, &hg_scanner::setting_rotate_bkg_180
|
||
, &hg_scanner::setting_fractate_check
|
||
, &hg_scanner::setting_fractate_check_level
|
||
, &hg_scanner::setting_skew_check
|
||
, &hg_scanner::setting_skew_check_level
|
||
};
|
||
|
||
bool hit = false;
|
||
int ret = HG_ERR_OUT_OF_RANGE;
|
||
char sn[20];
|
||
|
||
sprintf(sn, "%d", setting_no);
|
||
for (size_t i = 0; i < ARRAY_SIZE(func); ++i)
|
||
{
|
||
if (setting_map_[i] == setting_no)
|
||
{
|
||
ret = (this->*func[i])(data);
|
||
hit = true;
|
||
break;
|
||
}
|
||
}
|
||
if (!hit)
|
||
{
|
||
HG_VLOG_MINI_1(HG_LOG_LEVEL_WARNING, "Setting %d is not found in base setting functions.\n", setting_no);
|
||
ret = set_setting_value(setting_no, data, len);
|
||
}
|
||
|
||
if (ret == HG_ERR_OK || ret == HG_ERR_NOT_EXACT || ret == HG_ERR_CONFIGURATION_CHANGED)
|
||
{
|
||
std::string type(""), name("");
|
||
|
||
setting_jsn_.at(sn).at("type").get_to(type);
|
||
setting_jsn_.at(sn).at("title").get_to(name);
|
||
if (type == "string")
|
||
{
|
||
setting_jsn_.at(sn).at("cur") = (char*)data;
|
||
type = (char*)data;
|
||
}
|
||
else if (type == "int")
|
||
{
|
||
setting_jsn_.at(sn).at("cur") = *((int*)data);
|
||
sprintf(sn, "%d", *((int*)data));
|
||
type = sn;
|
||
}
|
||
else if (type == "float")
|
||
{
|
||
setting_jsn_.at(sn).at("cur") = *((double*)data);
|
||
sprintf(sn, "%f", *((double*)data));
|
||
type = sn;
|
||
}
|
||
else if (type == "bool")
|
||
{
|
||
setting_jsn_.at(sn).at("cur") = *((bool*)data);
|
||
type = *((bool*)data) ? "true" : "false";
|
||
}
|
||
|
||
if (notify_setting_result_)
|
||
{
|
||
name.insert(0, "设置 “");
|
||
name += "” 值为“";
|
||
name += type + "” 成功。";
|
||
notify_ui_working_status(name.c_str());
|
||
}
|
||
}
|
||
else if (notify_setting_result_)
|
||
{
|
||
std::string name("");
|
||
if (setting_jsn_.contains(sn))
|
||
{
|
||
setting_jsn_.at(sn).at("title").get_to(name);
|
||
}
|
||
else
|
||
name = std::string("设置项") + sn;
|
||
name.insert(0, "设置 “");
|
||
name += "” 值失败: " + hg_scanner::strerr((hg_err)ret);
|
||
notify_ui_working_status(name.c_str());
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::get_setting(int setting_no, char* json_txt_buf, int* len)
|
||
{
|
||
if (!len)
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
|
||
if (setting_no == 0)
|
||
{
|
||
int count = 0;
|
||
setting_jsn_.at("option_count").get_to(count);
|
||
*len = count;
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
if (setting_count_ <= setting_no || setting_no < 0)
|
||
return HG_ERR_OUT_OF_RANGE;
|
||
|
||
char sn[20];
|
||
std::string text(""), name(""), tag("");
|
||
int add = 0;
|
||
bool is_gamma = false, is_area_x = false, is_area_y = false;
|
||
|
||
sprintf(sn, "%d", setting_no);
|
||
if (!setting_jsn_.contains(sn))
|
||
HG_VLOG_MINI_2(HG_LOG_LEVEL_FATAL, "!!!option(%d - %s) is not found.\n", setting_no, sn);
|
||
text = setting_jsn_.at(sn).dump();
|
||
setting_jsn_.at(sn).at("name").get_to(name);
|
||
if (name == KNOWN_OPT_NAME_CUSTOM_GAMMA)
|
||
{
|
||
is_gamma = true;
|
||
add = 4 * sizeof(custom_gamma_val_);
|
||
}
|
||
else if (name == KNOWN_OPT_NAME_CUSTOM_AREA_LEFT || name == KNOWN_OPT_NAME_CUSTOM_AREA_RIGHT)
|
||
{
|
||
is_area_x = true;
|
||
add = 20;
|
||
}
|
||
else if (name == KNOWN_OPT_NAME_CUSTOM_AREA_TOP || name == KNOWN_OPT_NAME_CUSTOM_AREA_BOTTOM)
|
||
{
|
||
is_area_y = true;
|
||
add = 20;
|
||
}
|
||
if (*len <= text.length() + add)
|
||
{
|
||
*len = text.length() + 8 + add;
|
||
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
|
||
if (is_gamma)
|
||
{
|
||
name = "";
|
||
add = 3 * 256;
|
||
sprintf(sn, "[%u", custom_gamma_val_->table[0]);
|
||
name += sn;
|
||
for (int i = 1; i < add; ++i)
|
||
{
|
||
sprintf(sn, ",%u", custom_gamma_val_->table[i]);
|
||
name += sn;
|
||
}
|
||
name += "]";
|
||
tag = "\"cur\":";
|
||
}
|
||
else if (is_area_x)
|
||
{
|
||
sprintf(sn, "%u.0", paper_size_mm_.cx);
|
||
name = sn;
|
||
tag = "\"max\":";
|
||
}
|
||
else if (is_area_y)
|
||
{
|
||
sprintf(sn, "%u.0", paper_size_mm_.cy);
|
||
name = sn;
|
||
tag = "\"max\":";
|
||
}
|
||
if (!tag.empty())
|
||
{
|
||
size_t pos = text.find(tag), end = pos;
|
||
if (pos != std::string::npos)
|
||
{
|
||
pos += tag.length();
|
||
end = pos;
|
||
while (end < text.length())
|
||
{
|
||
if (text[end] == ',' || text[end] == '}' || text[end] == ']' || text[end] == '\r' || text[end] == '\n')
|
||
break;
|
||
end++;
|
||
}
|
||
if (end > pos)
|
||
text.replace(pos, end - pos, name);
|
||
else
|
||
text.insert(end, name);
|
||
}
|
||
}
|
||
|
||
strcpy(json_txt_buf, text.c_str());
|
||
*len = text.length();
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
std::string hg_scanner::name(void)
|
||
{
|
||
return name_;
|
||
}
|
||
int hg_scanner::status(void)
|
||
{
|
||
return status_;
|
||
}
|
||
bool hg_scanner::is_online(void)
|
||
{
|
||
return online_;
|
||
}
|
||
|
||
int hg_scanner::start(void)
|
||
{
|
||
user_cancel_ = false;
|
||
|
||
return status_;
|
||
}
|
||
int hg_scanner::get_image_info(SANE_Parameters* ii)
|
||
{
|
||
int ret = HG_ERR_OK;
|
||
IMH imh;
|
||
|
||
bzero(&imh, sizeof(imh));
|
||
while ((!wait_img_.is_waiting() || !wait_usb_.is_waiting()) && final_imgs_.Size() <= 0)
|
||
this_thread::sleep_for(chrono::milliseconds(10));
|
||
|
||
if (final_imgs_.Size() <= 0)
|
||
ret = HG_ERR_NO_DATA;
|
||
else
|
||
{
|
||
if (!final_imgs_.front(&imh))
|
||
ret = HG_ERR_NO_DATA;
|
||
else
|
||
copy_to_sane_image_header(ii, imh.width, imh.height, imh.line_bytes, imh.channels);
|
||
}
|
||
HG_VLOG_MINI_4(HG_LOG_LEVEL_DEBUG_INFO, "Get image info(%d * %d * %d) = %s\n", ii->pixels_per_line, ii->lines, imh.bits, hg_scanner::strerr((hg_err)ret).c_str());
|
||
|
||
return ret;
|
||
}
|
||
int hg_scanner::read_image_data(unsigned char* buf, int* len)
|
||
{
|
||
if (!len)
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
|
||
if (!buf)
|
||
{
|
||
IMH imh;
|
||
final_imgs_.front(&imh);
|
||
*len = imh.bytes;
|
||
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
|
||
if (final_imgs_.Size() > 0)
|
||
{
|
||
int fetch = *len;
|
||
bool over = false;
|
||
|
||
final_imgs_.fetch_front(buf, len, &over);
|
||
|
||
return over ? HG_ERR_NO_DATA : HG_ERR_OK;
|
||
}
|
||
else
|
||
return HG_ERR_NO_DATA;
|
||
}
|
||
int hg_scanner::stop(void)
|
||
{
|
||
user_cancel_ = true;
|
||
|
||
return status_;
|
||
}
|
||
int hg_scanner::reset(void)
|
||
{
|
||
return status_;
|
||
}
|
||
int hg_scanner::device_io_control(unsigned long code, void* data, unsigned* len)
|
||
{
|
||
if (code == IO_CTRL_CODE_RESTORE_SETTINGS)
|
||
{
|
||
setting_restore(data);
|
||
|
||
return HG_ERR_CONFIGURATION_CHANGED;
|
||
}
|
||
else if (code == IO_CTRL_CODE_GET_DEFAULT_VALUE)
|
||
{
|
||
char* jsn_txt = NULL;
|
||
int size = 0;
|
||
json jsn;
|
||
int ret = get_setting(*len, jsn_txt, &size);
|
||
|
||
if (ret == HG_ERR_INSUFFICIENT_MEMORY)
|
||
{
|
||
jsn_txt = (char*)malloc(size + 4);
|
||
bzero(jsn_txt, size + 4);
|
||
get_setting(*len, jsn_txt, &size);
|
||
jsn = jsonconfig::load_json_from_text(jsn_txt);
|
||
free(jsn_txt);
|
||
if (get_default_value(data, &jsn))
|
||
ret = HG_ERR_OK;
|
||
else
|
||
ret = HG_ERR_DATA_DAMAGED;
|
||
}
|
||
|
||
return ret;
|
||
}
|
||
else if (code == IO_CTRL_CODE_CLEAR_ROLLER_COUNT)
|
||
{
|
||
int count = get_roller_num();
|
||
|
||
if (len)
|
||
*len = count;
|
||
|
||
return clear_roller_num();
|
||
}
|
||
else if (code == IO_CTRL_CODE_SET_FINAL_IMAGE_FORMAT)
|
||
{
|
||
SANE_FinalImgFormat* fmt = (SANE_FinalImgFormat*)data;
|
||
|
||
return set_final_image_format(fmt);
|
||
}
|
||
else if(code == IO_CTRL_CODE_TEST_SINGLE)
|
||
{
|
||
return set_leaflet_scan();
|
||
}
|
||
else if (code == IO_CTRL_CODE_SET_AUTO_COLOR_TYPE)
|
||
{
|
||
return set_auto_color_type();
|
||
}
|
||
else if(code == IO_CTRL_CODE_GET_HARDWARE_VERSION)
|
||
{
|
||
|
||
std::string fw = get_firmware_version();
|
||
if (*len < fw.size())
|
||
{
|
||
*len = fw.size();
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
|
||
char* buf = strcpy((char*)data, fw.c_str());
|
||
|
||
if (buf)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
return HG_ERR_DATA_DAMAGED;
|
||
}
|
||
else if(code == IO_CTRL_CODE_GET_SERIAL)
|
||
{
|
||
std::string ser = get_serial_num();
|
||
if (*len < ser.size())
|
||
{
|
||
*len = ser.size();
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
char* buf = strcpy((char*)data, ser.c_str());
|
||
if (buf)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
return HG_ERR_DATA_DAMAGED;
|
||
}
|
||
else if (code == IO_CTRL_CODE_GET_HARDWARE_VERSION)
|
||
{
|
||
std::string ip = get_ip();
|
||
if (*len < ip.size())
|
||
{
|
||
*len = ip.size();
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
char* buf = strcpy((char*)data, ip.c_str());
|
||
|
||
if (buf)
|
||
{
|
||
return HG_ERR_OK;
|
||
}
|
||
return HG_ERR_DATA_DAMAGED;
|
||
}
|
||
else if (code == IO_CTRL_CODE_GET_PAPER_ON)
|
||
{
|
||
return get_scanner_paperon((SANE_Bool*)data);
|
||
}
|
||
else if(code == IO_CTRL_CODE_GET_POWER_LEVEL)
|
||
{
|
||
int val = 0,
|
||
ret = HG_ERR_OK;
|
||
|
||
if (*len < sizeof(int *))
|
||
{
|
||
*len = sizeof(int *);
|
||
return HG_ERR_INSUFFICIENT_MEMORY;
|
||
}
|
||
|
||
ret = get_sleep_time(val);
|
||
if (ret == HG_ERR_OK)
|
||
{
|
||
*((int *)data) = val;
|
||
}
|
||
return ret;
|
||
}
|
||
else if(code == IO_CTRL_CODE_SET_POWER_LEVEL)
|
||
{
|
||
int val = *((int*)data);
|
||
int sleeptime = 0;
|
||
|
||
switch (val)
|
||
{
|
||
case SANE_POWER_NONE:
|
||
sleeptime = 0;
|
||
break;
|
||
case SANE_POWER_MINUTES_5:
|
||
sleeptime = 300;
|
||
break;
|
||
case SANE_POWER_MINUTES_10:
|
||
sleeptime = 600;
|
||
break;
|
||
case SANE_POWER_MINUTES_20:
|
||
sleeptime = 1200;
|
||
break;
|
||
case SANE_POWER_MINUTES_30:
|
||
sleeptime = 1800;
|
||
break;
|
||
case SANE_POWER_MINUTES_60:
|
||
sleeptime = 3600;
|
||
break;
|
||
case SANE_POWER_MINUTES_120:
|
||
sleeptime = 7200;
|
||
break;
|
||
case SANE_POWER_MINUTES_240:
|
||
sleeptime = 14400;
|
||
break;
|
||
default:
|
||
sleeptime = 0;
|
||
break;
|
||
}
|
||
return set_sleep_time(sleeptime);
|
||
}
|
||
else if (code == IO_CTRL_CODE_GET_CUSTOM_GAMMA)
|
||
{
|
||
SANE_Gamma* v = (SANE_Gamma*)data;
|
||
|
||
memcpy(v, custom_gamma_val_, sizeof(*custom_gamma_val_));
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
else if (code == IO_CTRL_CODE_SET_CUSTOM_GAMMA)
|
||
{
|
||
SANE_Gamma* v = (SANE_Gamma*)data;
|
||
|
||
memcpy(custom_gamma_val_, v, sizeof(*custom_gamma_val_));
|
||
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
std::string hg_scanner::get_firmware_version(void)
|
||
{
|
||
return BRAND_DEVICE_NOT_SUPPORT;
|
||
}
|
||
std::string hg_scanner::get_serial_num(void)
|
||
{
|
||
return BRAND_DEVICE_NOT_SUPPORT;
|
||
}
|
||
std::string hg_scanner::get_ip(void)
|
||
{
|
||
return BRAND_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_roller_num(void)
|
||
{
|
||
return -1;
|
||
}
|
||
int hg_scanner::clear_roller_num(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
//////////////////////////////////////////////////////////////////////////////////////////////////////
|
||
int hg_scanner::set_leaflet_scan(void)
|
||
{
|
||
return HG_ERR_NO_DATA;
|
||
}
|
||
int hg_scanner::get_abuot_info(void)
|
||
{
|
||
|
||
return HG_ERR_NO_DATA;
|
||
}
|
||
int hg_scanner::restore_default_setting(void)
|
||
{
|
||
return HG_ERR_NO_DATA;
|
||
}
|
||
int hg_scanner::set_final_image_format(SANE_FinalImgFormat* fmt)
|
||
{
|
||
switch (fmt->img_format)
|
||
{
|
||
case SANE_IMAGE_TYPE_BMP:
|
||
img_type_ = ".bmp";
|
||
break;
|
||
case SANE_IMAGE_TYPE_PNG:
|
||
img_type_ = ".png";
|
||
break;
|
||
case SANE_IMAGE_TYPE_JPG:
|
||
img_type_ = ".jpg";
|
||
break;
|
||
case SANE_IMAGE_TYPE_TIFF:
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
case SANE_IMAGE_TYPE_WEBP:
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
case SANE_IMAGE_TYPE_PDF:
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
case SANE_IMAGE_TYPE_GIF:
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
case SANE_IMAGE_TYPE_SVG:
|
||
return HG_ERR_INVALID_PARAMETER;
|
||
default:
|
||
img_type_ = "";
|
||
break;
|
||
}
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
int hg_scanner::get_compression_format(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_compression_format(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_auto_color_type(void)
|
||
{
|
||
is_auto_matic_color = true;
|
||
return HG_ERR_OK;
|
||
}
|
||
|
||
int hg_scanner::get_device_code(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_sleep_time(int& getsleepime)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_sleep_time(int sleeptime)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
|
||
int hg_scanner::get_dogear_distance(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_dogear_distance(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_scanner_paperon(SANE_Bool* paperon)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_scan_when_paper_on(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_scan_when_paper_on(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_scan_with_hole(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::set_scan_with_hole(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
}
|
||
int hg_scanner::get_scan_is_sleep(void)
|
||
{
|
||
return HG_ERR_DEVICE_NOT_SUPPORT;
|
||
} |