code_device/hgdriver/hgdev/hg_scanner.cpp

2334 lines
55 KiB
C++
Raw Normal View History

2022-05-03 03:56:07 +00:00
#include "hg_scanner.h"
#include "../../sdk/hginclude/hg_log.h"
#ifdef WIN32
#include "scanner_manager.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)
{
2022-05-06 08:39:00 +00:00
custom_gamma_val_ = new SANE_Gamma;
memset(custom_gamma_val_, 0, sizeof(SANE_Gamma));
2022-05-06 05:37:14 +00:00
paper_size_mm_.cx = 210;
paper_size_mm_.cy = 297;
2022-05-06 08:39:00 +00:00
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;
2022-05-06 05:37:14 +00:00
2022-05-03 03:56:07 +00:00
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();
2022-05-06 08:39:00 +00:00
delete custom_gamma_val_;
2022-05-03 03:56:07 +00:00
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);
// 2USB错误
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);
// 2USB错误
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)
{
char buf[128];
FILE* src = NULL;
if (!head || *head == 0)
head = (char*)"scan";
if (!tail)
tail = (char*)"";
srand(time(NULL));
sprintf(buf, "/tmp/%s_%04x%s", head, rand(), tail);
while ((src = fopen(buf, "rb")))
{
fclose(src);
sprintf(buf, "/tmp/%s_%04x%s", head, rand(), tail);
}
return buf;
}
int hg_scanner::save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std::string* path_file)
{
std::string file(hg_scanner::temporary_file((char*)".jpg"));
FILE* dst = fopen(file.c_str(), "wb+");
int ret = HG_ERR_OK;
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::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);
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);
2022-05-06 05:37:14 +00:00
setting_jsn_.at(key).at("name").get_to(val);
if (val == KNOWN_OPT_NAME_CUSTOM_GAMMA)
{
2022-05-06 08:39:00 +00:00
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;
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
2022-05-03 03:56:07 +00:00
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("");
2022-05-06 05:37:14 +00:00
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;
}
2022-05-03 03:56:07 +00:00
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;
}
2022-05-06 05:37:14 +00:00
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 = 2338;
paper_size_mm_.cy = 3307;
}
}
2022-05-03 03:56:07 +00:00
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_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)
2022-05-06 05:37:14 +00:00
strcpy((char*)data, paper.c_str());
if(old != image_prc_param_.bits.paper)
reset_custom_area_range(image_prc_param_.bits.paper);
2022-05-03 03:56:07 +00:00
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;
}
2022-05-06 05:37:14 +00:00
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)
{
2022-05-06 06:37:52 +00:00
SANE_Gamma* gamma = (SANE_Gamma*)data;
2022-05-06 05:37:14 +00:00
2022-05-06 08:39:00 +00:00
memcpy(custom_gamma_val_, gamma, sizeof(*custom_gamma_val_));
2022-05-06 05:37:14 +00:00
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;
2022-05-06 09:34:17 +00:00
custom_area_lt_x_ = *((double*)data);
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
int hg_scanner::setting_custom_area_top(void* data)
{
SANE_Fixed* v = (SANE_Fixed*)data;
2022-05-06 09:34:17 +00:00
custom_area_lt_y_ = *((double*)data);
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
int hg_scanner::setting_custom_area_right(void* data)
{
SANE_Fixed* v = (SANE_Fixed*)data;
2022-05-06 09:34:17 +00:00
custom_area_br_x_ = *((double*)data);
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
int hg_scanner::setting_custom_area_bottom(void* data)
{
SANE_Fixed* v = (SANE_Fixed*)data;
2022-05-06 09:34:17 +00:00
custom_area_br_y_ = *((double*)data);
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
2022-05-03 03:56:07 +00:00
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);
2022-05-06 05:37:14 +00:00
setting_jsn_.at(key).at("name").get_to(val);
if (val == KNOWN_OPT_NAME_CUSTOM_GAMMA)
continue;
2022-05-03 03:56:07 +00:00
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;
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);
if (ret == HG_ERR_OK)
paths_.Put(file);
}
else
{
imgs_.Put(data);
#ifdef SAVE_TO_FILE
hg_scanner::save_2_tempory_file(data, NULL);
#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
2022-05-06 05:37:14 +00:00
, &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
2022-05-03 03:56:07 +00:00
, &hg_scanner::setting_page
, &hg_scanner::setting_page_omit_empty
, &hg_scanner::setting_resolution
, &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
2022-05-06 05:37:14 +00:00
, &hg_scanner::setting_is_custom_gamma // 2022-05-05
2022-05-03 03:56:07 +00:00
, &hg_scanner::setting_bright
, &hg_scanner::setting_contrast
, &hg_scanner::setting_gamma
2022-05-06 05:37:14 +00:00
, &hg_scanner::setting_custom_gamma_data
2022-05-03 03:56:07 +00:00
, &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
2022-05-06 05:37:14 +00:00
, &hg_scanner::setting_skew_check_level
2022-05-03 03:56:07 +00:00
};
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];
2022-05-06 05:37:14 +00:00
std::string text(""), name(""), tag("");
int add = 0;
bool is_gamma = false, is_area_x = false, is_area_y = false;
2022-05-03 03:56:07 +00:00
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();
2022-05-06 05:37:14 +00:00
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)
2022-05-03 03:56:07 +00:00
{
2022-05-06 05:37:14 +00:00
*len = text.length() + 8 + add;
2022-05-03 03:56:07 +00:00
return HG_ERR_INSUFFICIENT_MEMORY;
}
2022-05-06 05:37:14 +00:00
if (is_gamma)
{
name = "";
2022-05-06 06:37:52 +00:00
add = 3 * 256;
2022-05-06 08:39:00 +00:00
sprintf(sn, "[%u", custom_gamma_val_->table[0]);
2022-05-06 05:37:14 +00:00
name += sn;
for (int i = 1; i < add; ++i)
{
2022-05-06 08:39:00 +00:00
sprintf(sn, ",%u", custom_gamma_val_->table[i]);
2022-05-06 05:37:14 +00:00
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);
}
}
2022-05-03 03:56:07 +00:00
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);
}
2022-05-06 05:37:14 +00:00
else if (code == IO_CTRL_CODE_GET_CUSTOM_GAMMA)
{
2022-05-06 06:37:52 +00:00
SANE_Gamma* v = (SANE_Gamma*)data;
2022-05-06 08:39:00 +00:00
memcpy(v, custom_gamma_val_, sizeof(*custom_gamma_val_));
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
2022-05-06 06:37:52 +00:00
else if (code == IO_CTRL_CODE_SET_CUSTOM_GAMMA)
2022-05-06 05:37:14 +00:00
{
2022-05-06 06:37:52 +00:00
SANE_Gamma* v = (SANE_Gamma*)data;
2022-05-06 08:39:00 +00:00
memcpy(custom_gamma_val_, v, sizeof(*custom_gamma_val_));
2022-05-06 05:37:14 +00:00
return HG_ERR_OK;
}
2022-05-03 03:56:07 +00:00
return HG_ERR_DEVICE_NOT_SUPPORT;
}
std::string hg_scanner::get_firmware_version(void)
{
return "";
}
std::string hg_scanner::get_serial_num(void)
{
return "";
}
std::string hg_scanner::get_ip(void)
{
return "";
}
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;
}