312 lines
5.7 KiB
C++
312 lines
5.7 KiB
C++
#include "hg_scanner.h"
|
|
|
|
|
|
#include "scanner_manager.h"
|
|
#include <sane_opt_json/device_opt.h>
|
|
#include <imgprc/imgprc_mgr.h>
|
|
#include <lang/app_language.h>
|
|
#include "./scanner/scanner_handler.h"
|
|
#include "user-opt/user.h"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// img_receiver
|
|
img_receiver::img_receiver(LPPACKIMAGE head, size_t info_size, size_t size, std::function<void(img_receiver*)> complete_routine, uint32_t id)
|
|
: id_(id), head_(*head), info_size_(info_size)
|
|
, size_(size), finish_(complete_routine)
|
|
{
|
|
buf_ = (uint8_t*)malloc(size);
|
|
if (buf_)
|
|
memset(buf_, 0, size);
|
|
}
|
|
img_receiver::~img_receiver()
|
|
{
|
|
if (buf_)
|
|
free(buf_);
|
|
buf_ = nullptr;
|
|
}
|
|
|
|
int img_receiver::put_data(const void* data, uint32_t* size)
|
|
{
|
|
size_t info = 0;
|
|
|
|
if (info_.length() < info_size_)
|
|
{
|
|
size_t need = info_size_ - info_.length();
|
|
if (need > *size)
|
|
{
|
|
info = *size;
|
|
info_ += std::string((const char*)data, *size);
|
|
*size = 0;
|
|
}
|
|
else
|
|
{
|
|
info_ += std::string((const char*)data, need);
|
|
*size -= need;
|
|
info = need;
|
|
}
|
|
}
|
|
|
|
if (*size)
|
|
{
|
|
if (*size > size_ - wpos_)
|
|
*size = size_ - wpos_;
|
|
|
|
memcpy(buf_ + wpos_, data, *size);
|
|
wpos_ += *size;
|
|
if (wpos_ >= size_ && finish_)
|
|
finish_(this);
|
|
}
|
|
*size += info;
|
|
|
|
return 0;
|
|
}
|
|
bool img_receiver::is_complete(void)
|
|
{
|
|
return wpos_ >= size_;
|
|
}
|
|
uint32_t img_receiver::get_required(void)
|
|
{
|
|
if (wpos_ >= size_)
|
|
return 0;
|
|
else
|
|
return size_ - wpos_ + (info_size_ - info_.length());
|
|
}
|
|
|
|
uint32_t img_receiver::id(void)
|
|
{
|
|
return id_;
|
|
}
|
|
size_t img_receiver::size(void)
|
|
{
|
|
return wpos_;
|
|
}
|
|
uint8_t* img_receiver::data(void)
|
|
{
|
|
return buf_;
|
|
}
|
|
std::string img_receiver::information(void)
|
|
{
|
|
return info_;
|
|
}
|
|
PACKIMAGE img_receiver::head(void)
|
|
{
|
|
return head_;
|
|
}
|
|
|
|
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// hg_scanner
|
|
hg_scanner::hg_scanner(ONLNSCANNER* dev, imgproc_mgr* imgproc, hguser* user, std::vector<sane_opt_provider*>* constopts)
|
|
: dev_(*dev), status_(SCANNER_ERR_OPENED_BY_OTHER_PROCESS)
|
|
, msg_(from_default_language("\350\256\276\345\244\207\345\267\262\347\273\217\350\242\253\350\277\233\347\250\213 '%s' \345\215\240\347\224\250"))
|
|
{
|
|
singleton_ = hg_scanner::create_device_singleton(dev_.vid, dev_.pid, dev_.addr);
|
|
if (!singleton_->is_first())
|
|
{
|
|
std::string pre(singleton_->read());
|
|
size_t pos = msg_.find("%s");
|
|
|
|
if (pos == std::string::npos)
|
|
msg_ += ": " + pre;
|
|
else
|
|
msg_.replace(pos, 2, pre);
|
|
singleton_->release();
|
|
}
|
|
else
|
|
{
|
|
set_where(dev->display_name.c_str());
|
|
user_ = user;
|
|
init();
|
|
if (status() == SCANNER_ERR_OK)
|
|
{
|
|
imgproc_ = imgproc;
|
|
imgproc_->add_ref();
|
|
|
|
dev_opts_->add(imgproc_);
|
|
if (constopts)
|
|
{
|
|
for(auto& v: *constopts)
|
|
dev_opts_->add(v);
|
|
}
|
|
imgpr_thread_.reset(new std::thread(&hg_scanner::thread_image_processor, this));
|
|
}
|
|
}
|
|
}
|
|
hg_scanner::~hg_scanner()
|
|
{
|
|
close();
|
|
}
|
|
|
|
shared_memory* hg_scanner::create_device_singleton(int vid, int pid, int addr)
|
|
{
|
|
unsigned long long key = vid;
|
|
key <<= 16;
|
|
key |= pid;
|
|
key <<= 16;
|
|
key |= addr;
|
|
|
|
return new shared_memory(key);
|
|
}
|
|
|
|
void hg_scanner::init(void)
|
|
{
|
|
auto on_status = [this](uint32_t statu) ->void
|
|
{
|
|
//status_ = statu;
|
|
};
|
|
auto on_image_received = [this](LPPACKIMAGE pimg, uint64_t size) ->data_holder_ptr
|
|
{
|
|
data_holder_ptr pdh = nullptr;
|
|
|
|
return pdh;
|
|
};
|
|
|
|
auto privilege = [this](int priv) -> bool
|
|
{
|
|
return user_->has_privilege(priv);
|
|
};
|
|
auto privilege_empty = [this](int priv) -> bool
|
|
{
|
|
return true;
|
|
};
|
|
auto logmsg = [&](const char* msg) -> void
|
|
{
|
|
utils::to_log(LOG_LEVEL_DEBUG, msg);
|
|
};
|
|
|
|
scanner_ = new scanner_handler();
|
|
scanner_->set_image_receiver(on_image_received);
|
|
scanner_->set_status_notifyer(on_status);
|
|
|
|
std::string opts("");
|
|
int ret = scanner_->option_get_all(opts);
|
|
|
|
if (ret == SCANNER_ERR_OK)
|
|
{
|
|
set_opt_json_text(&opts[0]);
|
|
if(user_)
|
|
dev_opts_ = new device_option(privilege, logmsg);
|
|
else
|
|
dev_opts_ = new device_option(privilege_empty, logmsg);
|
|
dev_opts_->add(this);
|
|
}
|
|
else
|
|
{
|
|
status_ = ret;
|
|
}
|
|
}
|
|
void hg_scanner::thread_image_processor(void)
|
|
{
|
|
imgproc_mgr * processor = imgproc_;
|
|
img_receiver* raw = nullptr;
|
|
|
|
processor->add_ref();
|
|
while (raw_imgs_.take(raw, true))
|
|
{
|
|
}
|
|
processor->release();
|
|
}
|
|
|
|
int hg_scanner::start(void)
|
|
{
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
cancelled_ = false;
|
|
if (scanner_)
|
|
ret = scanner_->scan_start();
|
|
|
|
return ret;
|
|
}
|
|
int hg_scanner::stop(void)
|
|
{
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
cancelled_ = true;
|
|
if (scanner_)
|
|
ret = scanner_->scan_stop();
|
|
|
|
return ret;
|
|
}
|
|
int hg_scanner::close(void)
|
|
{
|
|
int ret = SCANNER_ERR_OK;
|
|
|
|
if (scanner_)
|
|
{
|
|
ret = scanner_->close();
|
|
if (ret)
|
|
return ret;
|
|
scanner_->release();
|
|
scanner_ = nullptr;
|
|
}
|
|
|
|
if (dev_opts_)
|
|
{
|
|
dev_opts_->clear();
|
|
dev_opts_->release();
|
|
dev_opts_ = nullptr;
|
|
}
|
|
|
|
if (singleton_)
|
|
{
|
|
singleton_->release();
|
|
singleton_ = nullptr;
|
|
}
|
|
|
|
// wait image thread ...
|
|
if (imgpr_thread_.get() && imgpr_thread_->joinable())
|
|
imgpr_thread_->join();
|
|
|
|
if (imgproc_)
|
|
{
|
|
imgproc_->release();
|
|
imgproc_ = nullptr;
|
|
}
|
|
user_ = nullptr;
|
|
|
|
return ret;
|
|
}
|
|
int hg_scanner::re_connect(void)
|
|
{
|
|
return SCANNER_ERR_OK;
|
|
}
|
|
int hg_scanner::get_image_info(SANE_Parameters* pii)
|
|
{
|
|
return SCANNER_ERR_OK;
|
|
}
|
|
int hg_scanner::read_image_data(uint8_t* buf, size_t* len)
|
|
{
|
|
return SCANNER_ERR_OK;
|
|
}
|
|
int hg_scanner::status(void)
|
|
{
|
|
return status_;
|
|
}
|
|
std::string hg_scanner::status_message(void)
|
|
{
|
|
return msg_;
|
|
}
|
|
bool hg_scanner::is_online(void)
|
|
{
|
|
return online_;
|
|
}
|
|
device_option* hg_scanner::get_device_opt(void)
|
|
{
|
|
dev_opts_->add_ref();
|
|
|
|
return dev_opts_;
|
|
}
|
|
|