change image process thread pool

This commit is contained in:
gb 2023-05-11 17:19:00 +08:00
parent d56e482a7a
commit eec4604ee3
13 changed files with 341 additions and 420 deletions

View File

@ -17,7 +17,7 @@
static const std::string loggername = "imageusbhandler";
ImageUsbHandler::ImageUsbHandler(std::shared_ptr<UsbImageProcQueue> images)
: pool(1), encodepools(6),pushpool(1)
: pool(1), encodepools(/*6*/1),pushpool(1)
{
LOG_INIT();
this->images = images;
@ -37,13 +37,13 @@ static int num = 0;
void ImageUsbHandler::add_image(void *data, int width, int height, int type, int scannnum,unsigned int fpgaversion)
{
printf("ImageUsbHandler::add_image %d(%d * %d), fpgaversion = %d, HRatio = %f, VRatio = %f\n", scannnum, width, height, fpgaversion, H_ratio, V_ratio);
#ifdef ASYNC_EP
if(images->push_raw(data, width, height, type == CV_8UC1 ? COLOR_CHANNEL_GRAY : COLOR_CHANNEL_RGB, scannnum, fpgaversion, 0))
{
return;
}
images->push(nullptr, false); // notify ONE paper passed
#endif
std::string ext = ".jpg";
{
@ -129,6 +129,10 @@ void ImageUsbHandler::add_image(void *data, int width, int height, int type, int
// if((H_ratio != 1.0f) || (V_ratio != 1.0f))
// cv::resize(saveMat,saveMat,cv::Size(),H_ratio,V_ratio);
// test sequence ...
// if(scannnum % 1) std::this_thread::sleep_for(std::chrono::milliseconds(500));
encode_data.Put(saveMat);
encodeimgs.push(encodepools.enqueue([this,width,height,type]() -> std::vector<MemoryPtr>
@ -293,7 +297,9 @@ void ImageUsbHandler::Set_ratio(u32 h_ratio,u32 v_ratio)
bool ImageUsbHandler::done()
{
#ifdef ASYNC_EP
return images->is_image_processing_over();
#endif
std::lock_guard<std::mutex> guard(mtx);
if(results.size() >= 1){

View File

@ -90,7 +90,7 @@ Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard
LOG_TRACE("callback SIZE ERROR\n");
}
mb_error_code = code;
printf("---------------mb_error_code value = %d ---------------\n", error_code);
printf("---------------mb_error_code value = %d (%d)---------------\n", error_code, error_code);
if (code != 0)
{
HGIntInfo errType = {.From = MtBoard, .Code = code};
@ -117,12 +117,13 @@ Scanner::Scanner(std::shared_ptr<ICapturer> capturer, std::shared_ptr<MotorBoard
};
auto mb_coveropen_call = [&](bool isopen)
{
HGIntInfo errType = {.From = MtBoard, .Code = 5 - isopen};
if (imagehandler.get())
imagehandler->add_scanevent(errType);
if (isopen)
{
LOG_TRACE("cover opened \n");
HGIntInfo errType = {.From = MtBoard, .Code = 4};
if (imagehandler.get())
imagehandler->add_scanevent(errType);
done_scan = 1;
}
else
@ -574,9 +575,10 @@ void Scanner::runScan()
else
autosizescan();
savescannerinfo(scannerinfo);
imagehandler->add_scanevent({.From = STOPSCAN, mb_error_code});
imagehandler->add_scanevent({.From = STOPSCAN, .Code = mb_error_code});
while (!imagehandler->done())
this_thread::sleep_for(chrono::milliseconds(10));
printf("\nscan finished.\n");
done_scan = 0;
if (wake.get())
@ -699,20 +701,20 @@ bool Scanner::pickpaper()
while (imagehandler->is_limit())
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
// unsigned int reg2v;
// mb->read(0x02, reg2v);
// if (reg2v & 0x00010000)
// { //有纸
unsigned int reg2v;
mb->read(0x02, reg2v);
if (reg2v & 0x00010000)
{ //有纸
printf("\n+++++++++pick paper ");
mb->pick_paper();
startcapimage(true);
return true;
// }
// else
// {
// printf("\n+++++++++pick paper no paper");
// return false;
// }
}
else
{
printf("\n+++++++++pick paper no paper");
return false;
}
}
void Scanner::set_motorboardcallback(MotorBoardGlue glue)

View File

@ -7,7 +7,7 @@
// configuration text
//
static std::string g_cis_cfg("{\"montage\":{\"cat\":\"cis\",\"group\":\"CIS\",\"title\":\"\\u56fe\\u50cf\\u62fc\\u63a5\",\"desc\":\"\\u5c06CIS\\u91c7\\u96c6\\u7684\\u539f\\u59cb\\u6570\\u636e\\u6062\\u590d\\u4e3a\\u6b63\\u5e38\\u7684\\u56fe\\u50cf\",\"ver\":1,\"pos\":10,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"cis-color-correct\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u5149\\u5b66\\u989c\\u8272\\u6821\\u6b63\",\"desc\":\"\\u5bf9CIS\\u7684\\u539f\\u56fe\\u989c\\u8272\\u8fdb\\u884c\\u6821\\u6b63\",\"ver\":1,\"pos\":20,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"reinstate\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u786c\\u4ef6\\u590d\\u539f\",\"desc\":\"\\u6d88\\u9664CIS\\u786c\\u4ef6\\u62c9\\u4f38\\u56e0\\u7d20\\uff0c\\u6062\\u590d\\u56fe\\u7247\\u521d\\u59cb\\u72b6\\u6001\",\"ver\":1,\"pos\":30,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"fb-split\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u62c6\\u5206\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u5c06\\u6b63\\u53cd\\u9762\\u5408\\u6210\\u7684\\u4e00\\u5f20\\u56fe\\u7247\\u62c6\\u5206\\u6210\\u6b63\\u9762\\u548c\\u53cd\\u9762\\u56fe\\u7247\",\"ver\":1,\"pos\":40,\"type\":\"bool\",\"unit\":\"none\",\"affect\":2,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"page\":{\"cat\":\"CIS\",\"group\":\"base\",\"title\":\"\\u9875\\u9762\",\"desc\":\"\\u83b7\\u53d6\\u7eb8\\u5f20\\u6307\\u5b9a\\u9762\\u7684\\u56fe\\u7247\",\"ver\":1,\"pos\":50,\"type\":\"string\",\"unit\":\"none\",\"affect\":2,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":30,\"cur\":\"\\u53cc\\u9762\",\"default\":\"\\u53cc\\u9762\",\"range\":[\"\\u6b63\\u9762\",\"\\u80cc\\u9762\",\"\\u53cc\\u9762\"],\"depend_or\":[\"fb-split==true\"]},\"is-exchange\":{\"cat\":\"CIS\",\"group\":\"base\",\"title\":\"\\u4ea4\\u6362\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u4ea4\\u6362\\u6bcf\\u5f20\\u6587\\u7a3f\\u7684\\u6b63\\u53cd\\u9762\\u51fa\\u56fe\\u987a\\u5e8f\",\"ver\":1,\"pos\":60,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":4,\"cur\":false,\"default\":false,\"depend_and\":[\"fb-split==true\",\"page==\\u53cc\\u9762\"]}}");
static std::string g_cis_cfg("{\"montage\":{\"cat\":\"cis\",\"group\":\"CIS\",\"title\":\"\\u56fe\\u50cf\\u62fc\\u63a5\",\"desc\":\"\\u5c06CIS\\u91c7\\u96c6\\u7684\\u539f\\u59cb\\u6570\\u636e\\u6062\\u590d\\u4e3a\\u6b63\\u5e38\\u7684\\u56fe\\u50cf\",\"ver\":1,\"pos\":10,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"cis-color-correct\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u5149\\u5b66\\u989c\\u8272\\u6821\\u6b63\",\"desc\":\"\\u5bf9CIS\\u7684\\u539f\\u56fe\\u989c\\u8272\\u8fdb\\u884c\\u6821\\u6b63\",\"ver\":1,\"pos\":20,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"reinstate\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u786c\\u4ef6\\u590d\\u539f\",\"desc\":\"\\u6d88\\u9664CIS\\u786c\\u4ef6\\u62c9\\u4f38\\u56e0\\u7d20\\uff0c\\u6062\\u590d\\u56fe\\u7247\\u521d\\u59cb\\u72b6\\u6001\",\"ver\":1,\"pos\":30,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"fb-split\":{\"cat\":\"CIS\",\"group\":\"CIS\",\"title\":\"\\u62c6\\u5206\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u5c06\\u6b63\\u53cd\\u9762\\u5408\\u6210\\u7684\\u4e00\\u5f20\\u56fe\\u7247\\u62c6\\u5206\\u6210\\u6b63\\u9762\\u548c\\u53cd\\u9762\\u56fe\\u7247\",\"ver\":1,\"pos\":40,\"type\":\"bool\",\"unit\":\"none\",\"affect\":2,\"readonly\":false,\"visible\":false,\"enabled\":true,\"size\":4,\"cur\":true,\"default\":true},\"page\":{\"cat\":\"CIS\",\"group\":\"base\",\"title\":\"\\u9875\\u9762\",\"desc\":\"\\u83b7\\u53d6\\u7eb8\\u5f20\\u6307\\u5b9a\\u9762\\u7684\\u56fe\\u7247\",\"ver\":1,\"pos\":50,\"type\":\"string\",\"unit\":\"none\",\"affect\":2,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":30,\"cur\":\"\\u53cc\\u9762\",\"default\":\"\\u53cc\\u9762\",\"range\":[\"\\u6b63\\u9762\",\"\\u80cc\\u9762\",\"\\u53cc\\u9762\"],\"depend_or\":[\"fb-split==true\"]},\"is-exchange\":{\"cat\":\"CIS\",\"group\":\"base\",\"title\":\"\\u4ea4\\u6362\\u6b63\\u53cd\\u9762\",\"desc\":\"\\u4ea4\\u6362\\u6bcf\\u5f20\\u6587\\u7a3f\\u7684\\u6b63\\u53cd\\u9762\\u51fa\\u56fe\\u987a\\u5e8f\",\"ver\":1,\"pos\":60,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":4,\"cur\":false,\"default\":false,\"depend_and\":[\"fb-split==true\",\"page==\\u53cc\\u9762\"]},\"is-rotate-bkg-180\":{\"cat\":\"CIS\",\"group\":\"base\",\"title\":\"\\u80cc\\u9762\\u65cb\\u8f6c180\\u00b0\",\"desc\":\"\\u80cc\\u9762\\u626b\\u63cf\\u7684\\u56fe\\u50cf\\u65cb\\u8f6c180\\u00b0\",\"ver\":1,\"pos\":70,\"type\":\"bool\",\"unit\":\"none\",\"affect\":0,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":4,\"cur\":false,\"default\":false,\"depend_and\":[\"fb-split==true\",\"page!=\\u6b63\\u9762\"]}}");
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -106,7 +106,7 @@ cis_pre_do::cis_pre_do(std::function<img_one_paper* (img_one_paper*)> montage
, std::function<SPLIT_PROTO> split)
: montage_(montage), split_(split)
, cfg_(g_cis_cfg), is_montage_(true), is_split_(true), page_(PAGE_DUPLEX), cis_dpi_(200)
, reinstate_(true), photo_mode_(false), is_correct_(true), is_exchg_(false)
, reinstate_(true), photo_mode_(false), is_correct_(true), is_exchg_(false), is_bkg_rot_180_(false)
{
if (!montage_)
montage_ = cis_montager;
@ -186,6 +186,15 @@ void cis_pre_do::init_value(void)
is_exchg_ = false;
child->release();
}
if (jsn->get_value("is-rotate-bkg-180", child) && child)
{
bool enable = false;
child->get_value("enabled", enable);
if (!child->get_value("cur", is_bkg_rot_180_))
is_bkg_rot_180_ = false;
is_bkg_rot_180_ &= enable;
child->release();
}
jsn->release();
}
}
@ -313,7 +322,7 @@ img_one_paper* cis_pre_do::execute(img_one_paper* img)
{
for(auto& v: img->images_queue())
{
correctColor(v.img, v.head.resolution_x, v.img.channels() == 3 ? 1 : 0, !photo_mode_);
correctColor(v.img, v.head.resolution_x, v.img.channels() == 3 ? 1 : 0, !photo_mode_);
}
}
@ -345,6 +354,17 @@ img_one_paper* cis_pre_do::execute(img_one_paper* img)
}
}
}
if(!is_bkg_rot_180_)
{
for(auto& v: img->images_queue())
{
if(v.head.pos.paper_side == PAPER_SIDE_BACK)
{
cv::flip(v.img, v.img, 0);
cv::flip(v.img, v.img, 1);
}
}
}
}
return img;

View File

@ -14,8 +14,8 @@ class gb_json;
// "montage": {
// "cat": "cis",
// "group": "CIS",
// "title": "图像拼接",
// "desc": "将CIS采集的原始数据恢复为正常的图像",
// "title": "\u56fe\u50cf\u62fc\u63a5",
// "desc": "\u5c06CIS\u91c7\u96c6\u7684\u539f\u59cb\u6570\u636e\u6062\u590d\u4e3a\u6b63\u5e38\u7684\u56fe\u50cf",
// "ver": 1,
// "pos": 10,
// "type": "bool",
@ -31,8 +31,8 @@ class gb_json;
// "cis-color-correct": {
// "cat": "CIS",
// "group": "CIS",
// "title": "光学颜色校正",
// "desc": "对CIS的原图颜色进行校正",
// "title": "\u5149\u5b66\u989c\u8272\u6821\u6b63",
// "desc": "\u5bf9CIS\u7684\u539f\u56fe\u989c\u8272\u8fdb\u884c\u6821\u6b63",
// "ver": 1,
// "pos": 20,
// "type": "bool",
@ -48,8 +48,8 @@ class gb_json;
// "reinstate": {
// "cat": "CIS",
// "group": "CIS",
// "title": "硬件复原",
// "desc": "消除CIS硬件拉伸因素恢复图片初始状态",
// "title": "\u786c\u4ef6\u590d\u539f",
// "desc": "\u6d88\u9664CIS\u786c\u4ef6\u62c9\u4f38\u56e0\u7d20\uff0c\u6062\u590d\u56fe\u7247\u521d\u59cb\u72b6\u6001",
// "ver": 1,
// "pos": 30,
// "type": "bool",
@ -65,8 +65,8 @@ class gb_json;
// "fb-split": {
// "cat": "CIS",
// "group": "CIS",
// "title": "拆分正反面",
// "desc": "将正反面合成的一张图片拆分成正面和反面图片",
// "title": "\u62c6\u5206\u6b63\u53cd\u9762",
// "desc": "\u5c06\u6b63\u53cd\u9762\u5408\u6210\u7684\u4e00\u5f20\u56fe\u7247\u62c6\u5206\u6210\u6b63\u9762\u548c\u53cd\u9762\u56fe\u7247",
// "ver": 1,
// "pos": 40,
// "type": "bool",
@ -82,8 +82,8 @@ class gb_json;
// "page": {
// "cat": "CIS",
// "group": "base",
// "title": "页面",
// "desc": "获取纸张指定面的图片",
// "title": "\u9875\u9762",
// "desc": "\u83b7\u53d6\u7eb8\u5f20\u6307\u5b9a\u9762\u7684\u56fe\u7247",
// "ver": 1,
// "pos": 50,
// "type": "string",
@ -93,16 +93,16 @@ class gb_json;
// "visible": true,
// "enabled": true,
// "size": 30,
// "cur": "双面",
// "default": "双面",
// "range": ["正面", "背面", "双面"],
// "cur": "\u53cc\u9762",
// "default": "\u53cc\u9762",
// "range": ["\u6b63\u9762", "\u80cc\u9762", "\u53cc\u9762"],
// "depend_or": ["fb-split==true"]
// },
// "is-exchange": {
// "cat": "CIS",
// "group": "base",
// "title": "交换正反面",
// "desc": "交换每张文稿的正反面出图顺序",
// "title": "\u4ea4\u6362\u6b63\u53cd\u9762",
// "desc": "\u4ea4\u6362\u6bcf\u5f20\u6587\u7a3f\u7684\u6b63\u53cd\u9762\u51fa\u56fe\u987a\u5e8f",
// "ver": 1,
// "pos": 60,
// "type": "bool",
@ -114,7 +114,25 @@ class gb_json;
// "size": 4,
// "cur": false,
// "default": false,
// "depend_and": ["fb-split==true", "page==双面"]
// "depend_and": ["fb-split==true", "page==\u53cc\u9762"]
// },
// "is-rotate-bkg-180": {
// "cat": "CIS",
// "group": "base",
// "title": "\u80cc\u9762\u65cb\u8f6c180\u00b0",
// "desc": "\u80cc\u9762\u626b\u63cf\u7684\u56fe\u50cf\u65cb\u8f6c180\u00b0",
// "ver": 1,
// "pos": 70,
// "type": "bool",
// "unit": "none",
// "affect": 0,
// "readonly": false,
// "visible": true,
// "enabled": true,
// "size": 4,
// "cur": false,
// "default": false,
// "depend_and": ["fb-split==true", "page!=\u6b63\u9762"]
// }
// }
@ -129,6 +147,7 @@ class cis_pre_do : public sane_cfg_provider
bool photo_mode_;
bool is_correct_;
bool is_exchg_;
bool is_bkg_rot_180_;
enum
{

View File

@ -22,21 +22,24 @@ extern int32_t (*set_image_process_over)(bool);
img_processor::img_processor(std::function<IMG_SENDER_PROTO> img_sender
, std::function<int32_t(const char*, void*, size_t*)> get_opt)
: img_sender_(img_sender), get_opt_val_(get_opt), speed_first_(true), run_(true)
, scan_staus_(0), busy_cnt_(0)
: img_sender_(img_sender), get_opt_val_(get_opt), run_(true)
, scan_staus_(0), busy_cnt_(0), pool_(6)
{
cis_pre_ = new cis_pre_do();
encoder_ = new img_encoder();
load_processors();
worker_ = new thread_pool<img_processor>(this);
worker_->thread_new(&img_processor::worker_thread, true);
// worker_ = new thread_pool<img_processor>(this);
// worker_->thread_new(&img_processor::worker_thread, true);
// worker_->thread_new(&img_processor::worker_thread, false);
// worker_->thread_new(&img_processor::worker_thread, false);
// worker_->thread_new(&img_processor::worker_thread, false);
}
img_processor::~img_processor()
{
stop();
worker_->thread_stop();
worker_->release();
// worker_->thread_stop();
// worker_->release();
cis_pre_->release();
encoder_->release();
@ -185,52 +188,50 @@ uint32_t img_processor::add_busy_count(int adden)
}
void img_processor::worker_thread(bool first)
{
log_cls::log(LOG_LEVEL_ALL, "+img_processor::worker_thread(%p) entered ...\n", sys_util::thread_id(std::this_thread::get_id()));
while(run_)
{
// while(run_)
// {
img_one_paper* img = nullptr;
if(img_que_.take(img, true))
{
if(img)
{
int paper = img->images_queue()[0].head.pos.paper_ind;
add_busy_count();
handle_image(img);
add_busy_count(-1);
// if(img_que_.take(img, true))
// {
// if(img)
// {
// int paper = img->images_queue()[0].head.pos.paper_ind;
// handle_image(img);
// img->release(); // release in 'handle_image'
}
else
{
while(add_busy_count(0))
std::this_thread::sleep_for(std::chrono::milliseconds(50));
// // img->release(); // release in 'handle_image'
// }
// else
// {
// while(add_busy_count(0))
// std::this_thread::sleep_for(std::chrono::milliseconds(50));
img_sender_(nullptr, nullptr, nullptr, scan_staus_);
set_image_process_over(true);
// img_sender_(nullptr, nullptr, nullptr, scan_staus_);
// set_image_process_over(true);
for(auto& v: tids_)
img_que_.quit();
img_que_.quit();
}
}
else if(first)
{
for(auto& v: tids_)
worker_->thread_stop(v);
tids_.clear();
}
else
{
break;
}
}
// // for(auto& v: tids_)
// // img_que_.quit();
// // img_que_.quit();
// }
// }
// else if(first)
// {
// for(auto& v: tids_)
// worker_->thread_stop(v);
// tids_.clear();
// }
// else
// {
// break;
// }
// }
log_cls::log(LOG_LEVEL_ALL, "-img_processor::worker_thread(%p) exited.\n", sys_util::thread_id(std::this_thread::get_id()));
}
void img_processor::handle_image(img_one_paper* img)
{
img_one_paper* doing = nullptr;
add_busy_count();
// img->add_ref(); // release it right now
// CIS pre-do ...
@ -255,6 +256,7 @@ void img_processor::handle_image(img_one_paper* img)
img_sender_(&v.head, imgf, v.info.c_str(), v.info.length());
}
img->release();
add_busy_count(-1);
}
int32_t img_processor::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval)
@ -373,22 +375,43 @@ int32_t img_processor::push_image(img_one_paper* img, bool over)
{
if(run_)
{
if(over)
{
scan_staus_ = (uint32_t)(uint64_t)img;
img_que_.save(nullptr, true);
}
else
{
// if(over)
// {
// scan_staus_ = (uint32_t)(uint64_t)img;
// img_que_.save(nullptr, true);
// }
// else
// {
// img->add_ref();
// size_t cnt = img_que_.save(img, true);
// // if(speed_first_ && cnt >= 4 && worker_->count() < 4)
// // {
// // tids_.push_back(worker_->thread_new(&img_processor::worker_thread, false));
// // }
// }
if(!over)
img->add_ref();
size_t cnt = img_que_.save(img, true);
results_.emplace(
pool_.enqueue([this, img, over]
{
if(over)
{
scan_staus_ = (size_t)(uint64_t)img;
while(add_busy_count(0))
std::this_thread::sleep_for(std::chrono::milliseconds(50));
if(speed_first_ && cnt >= 4 && worker_->count() < 2)
{
tids_.push_back(worker_->thread_new(&img_processor::worker_thread, false));
}
}
img_sender_(nullptr, nullptr, nullptr, scan_staus_);
set_image_process_over(true);
}
else
{
handle_image(img);
}
}
));
}
return 0;
@ -396,18 +419,28 @@ int32_t img_processor::push_image(img_one_paper* img, bool over)
int32_t img_processor::stop(void)
{
run_ = false;
for(size_t i = 0; i < worker_->count(); ++i)
img_que_.quit();
// for(size_t i = 0; i < worker_->count(); ++i)
// img_que_.quit();
int wait = 0;
while(add_busy_count(0) && wait++ < 100)
std::this_thread::sleep_for(std::chrono::milliseconds(5));
clear();
return 0;
}
int32_t img_processor::set_speed_first(bool first)
{
speed_first_ = first;
// speed_first_ = first;
return 0;
}
int32_t img_processor::que_size(void)
{
return img_que_.size();
return add_busy_count(0);
}
void img_processor::clear(void)
{
while (results_.size() > 0)
results_.pop();
}

View File

@ -13,6 +13,7 @@
#include <functional>
#include <vector>
#include "imemory.h"
#include "ThreadPool.h"
#define IMG_SENDER_PROTO void(LPPACKIMAGE /*image head, nullptr for scan over*/, MemoryPtr /*image data, nullptr for scan over*/, const void* /*image info*/, size_t/*image info bytes, scanner status for scan over*/)
@ -32,10 +33,14 @@ class img_processor : public sane_cfg_provider
std::vector<img_alg*> cur_proc_;
img_encoder* encoder_;
safe_fifo<img_one_paper*> img_que_;
thread_pool<img_processor>* worker_;
std::vector<uint64_t> tids_;
volatile bool speed_first_;
// safe_fifo<img_one_paper*> img_que_;
// thread_pool<img_processor>* worker_;
// std::vector<uint64_t> tids_;
// volatile bool speed_first_;
ThreadPool pool_;
std::queue<std::future<void>> results_;
volatile bool run_;
uint32_t scan_staus_;
uint32_t busy_cnt_;
@ -71,5 +76,6 @@ public:
int32_t stop(void);
int32_t set_speed_first(bool first); // start as many threads as possible if 'first' was true, or down to ONE thread
int32_t que_size(void);
void clear(void);
};

View File

@ -7,8 +7,8 @@
//
image_packet::image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, uint32_t sn, const void* info, size_t info_size)
: img_(img), offset_(0), sn_(sn), info_over_(false)
image_packet::image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, const void* info, size_t info_size)
: img_(img), offset_(0), info_over_(false)
{
LPPACK_BASE pack = nullptr;
LPPACKIMAGE pimg = nullptr;
@ -31,7 +31,19 @@ image_packet::image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, uin
head_->set_len(sizeof(PACK_BASE) + sizeof(PACKIMAGE));
info_over_ = info_.empty();
// log_cls::log(LOG_LEVEL_ALL, "Image-%04u wait to be sent: size = %u\n", sn_, img->size() + info_.length());
char buf[128] = {0};
sprintf(buf, "Image-%04u", head->pos.paper_ind);
pos_str_ = buf;
if(head->pos.paper_side == PAPER_SIDE_FRONT)
pos_str_ += "F_";
else if(head->pos.paper_side == PAPER_SIDE_BACK)
pos_str_ += "B_";
else
pos_str_ += "C_";
pos_str_ += std::to_string(head->pos.split_ind);
log_cls::log(LOG_LEVEL_ALL, "%s wait to be sent: size = %u\n", pos_str_.c_str(), img->size() + info_.length());
}
image_packet::~image_packet()
{
@ -39,7 +51,7 @@ image_packet::~image_packet()
head_->release();
img_.reset();
// log_cls::log(LOG_LEVEL_ALL, "Image-%04u sending complete: %u/%u\n", sn_, offset_, size);
log_cls::log(LOG_LEVEL_ALL, "%s sending complete: %u/%u\n", pos_str_.c_str(), offset_, size);
}
bool image_packet::is_memory_block(void)

View File

@ -12,12 +12,12 @@ class image_packet : public data_source
MemoryPtr img_;
dyn_mem_ptr head_;
uint32_t offset_;
uint32_t sn_;
std::string info_;
bool info_over_;
std::string pos_str_;
public:
image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, uint32_t sn, const void* info = nullptr, size_t info_size = 0);
image_packet(LPPACKIMAGE head, MemoryPtr img, uint32_t scanid, const void* info = nullptr, size_t info_size = 0);
protected:
virtual ~image_packet();

View File

@ -410,7 +410,7 @@ int async_usb_gadget::inner_write_bulk(data_source_ptr data, int* err)
}
buf->release();
off = total;
log_cls::log(LOG_LEVEL_ALL, "Finished in sending large content with %u bytes.\n", total);
// log_cls::log(LOG_LEVEL_ALL, "Finished in sending large content with %u bytes.\n", total);
}
return off;

View File

@ -154,7 +154,7 @@ void async_scanner::push_image(int data_type, void* data, size_t w, size_t h, in
{
img_one_paper *paper = new img_one_paper();
paper->init_from(data, w, h, dpi_x, dpi_y, paper_ind, side, clr, status, img_new, img_over);
paper->init_from(data, w, h, dpi_x, dpi_y, paper_ind, side, clr, status, img_new, img_over, ratio_h, ratio_v);
img_prc_->push_image(paper);
paper->release();
@ -256,13 +256,7 @@ void async_scanner::init(void)
if(head)
{
{
LOCKER lock(locker_);
ind = ++img_cnt_;
}
imgp = new image_packet(head, img, scan_id_, ind, info, info_size);
imgp = new image_packet(head, img, scan_id_, info, info_size);
usb_->write_bulk(imgp);
imgp->release();
}
@ -354,6 +348,13 @@ dyn_mem_ptr async_scanner::handle_get_opt_all(LPPACK_BASE pack, uint32_t* used,
dyn_mem_ptr reply = nullptr;
LPPACK_BASE pk = nullptr;
#ifdef TEMPORARY_API
if(reg_img_cb)
{
reg_img_cb = set_image_receiver(::push_image, this);
}
#endif
*used = base_head_size;
{
std::string val("");
@ -548,281 +549,3 @@ uint32_t async_scanner::stop(void)
}
}
// void async_scanner::save_image(MemoryPtr data, bool img)
// {
// static uint64_t max_mem = 0;
// if(img)
// {
// uint64_t n = sys_util::get_memory_usage("scan");
// uint32_t que = 0;
// image_packet *ip = new image_packet(data, ++img_cnt_, scan_id_, n);
// if(max_mem < n)
// max_mem = n;
// que = usb_->write_bulk(ip);
// ip->release();
// // check has completed ?
// if(scan_over_pack_)
// {
// ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&n);
// if(n)
// {
// usb_->write_bulk(scan_over_pack_);
// scan_over_pack_->release();
// scan_over_pack_ = nullptr;
// }
// }
// }
// else if(data)
// {
// HGIntInfo* info = (HGIntInfo*)data->data();
// dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE));
// int cmd = /*PACK_CMD_SCAN_FINISHED_ROGER*/0,
// err = 0;
// if(info->From != HGType::MBEvent || scan_id_ == 0)
// log_cls::log(LOG_LEVEL_ALL, "Scanner event: From = %d, Code = %d, Img_Index = %d\n", info->From, info->Code, info->Img_Index);
// if(info->From == HGType::MtBoard)
// {
// cmd = PACK_CMD_SCAN_FINISHED_ROGER;
// switch(info->Code)
// {
// case 2:
// err = SCANNER_STATUS_NO_PAPER;
// break;
// case 4:
// err = SCANNER_STATUS_COVER_OPENNED;
// break;
// case 8:
// err = SCANNER_STATUS_FEED_FAILED;
// break;
// case 0x10:
// err = SCANNER_STATUS_PAPER_JAMMED;
// break;
// case 0x20:
// err = SCANNER_STATUS_DOUBLE_FEEDED;
// break;
// case 0x40:
// err = SCANNER_STATUS_STAPLE_ON;
// break;
// case 0x80:
// err = SCANNER_STATUS_PAPER_ASKEW;
// break;
// case 0x20000:
// break;
// }
// }
// else if(info->From == HGType::IMG)
// {
// if(info->Code == 1)
// {
// err = SCANNER_STATUS_DOGEAR;
// cmd = PACK_CMD_SCAN_FINISHED_ROGER;
// }
// else if(info->Code == 2)
// {
// err = SCANNER_STATUS_SIZE_ERR;
// cmd = PACK_CMD_SCAN_FINISHED_ROGER;
// }
// }
// else if(info->From == HGType::V4L2 || info->From == HGType::STOPSCAN)
// {
// cmd = PACK_CMD_SCAN_FINISHED_ROGER;
// }
// if(scan_id_ == 0 && info->From == HGType::MBEvent)
// {
// BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_STATUS_ROGER, 0, info->Code);
// reply->set_len(sizeof(PACK_BASE));
// usb_->write_bulk(reply);
// }
// else
// {
// if(err && scan_err_ == 0)
// scan_err_ = err;
// if(scan_id_ && /*cmd == PACK_CMD_SCAN_FINISHED_ROGER*/info->From == HGType::STOPSCAN && scan_over_pack_ == nullptr)
// {
// char ebuf[20] = {0};
// err = scan_err_;
// log_cls::log(LOG_LEVEL_ALL, "Scan over with error: %s; Max memory usage: %s\n", log_cls::str_scanner_status((scanner_status)scan_err_, ebuf), sys_util::format_readable_bytes(max_mem).c_str());
// max_mem = 0;
// BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), cmd, scan_id_, err);
// reply->set_len(sizeof(PACK_BASE));
// scan_id_ = 0;
// // check if the image-proc-queue has completed ...
// // ctrl_handler(-2, (usb_ctrlrequest*)SR_GET_IMAGEPROCESSDONE, (unsigned char*)&err);
// err = 1;
// if(err)
// usb_->write_bulk(reply);
// else
// {
// scan_over_pack_ = reply;
// scan_over_pack_->add_ref();
// }
// }
// }
// reply->release();
// }
// else
// {
// // paper count ...
// dyn_mem_ptr reply = dyn_mem::memory(sizeof(PACK_BASE));
// BASE_PACKET_REPLY(*((LPPACK_BASE)reply->ptr()), PACK_CMD_SCAN_PAPER_ROGER, 0, 0);
// reply->set_len(sizeof(PACK_BASE));
// usb_->write_bulk(reply);
// reply->release();
// }
// }
// int32_t async_scanner::get_config(void* buf, size_t* len, const char* cfg_name, std::string* strval)
// {
// int32_t ret = EINVAL;
// if(!len)
// return ret;
// if(cfg_name)
// {
// gb_json *jsn = new gb_json();
// if(jsn->attach_text(&cfg_text_[0]))
// {
// ret = inner_get_config(jsn, buf, len, cfg_name, strval);
// // gb_json* child = nullptr;
// // ret = ENOENT;
// // if(jsn->get_value(cfg_name, child) && child)
// // {
// // std::string val(sane_cfg_provider::sane_option_value_get(child, "cur", strval));
// // child->release();
// // if(*len < val.length())
// // {
// // *len = val.length();
// // ret = ENOMEM;
// // }
// // else
// // {
// // memcpy(buf, val.c_str(), val.length());
// // *len = val.length();
// // }
// // }
// jsn->release();
// }
// }
// else
// {
// if(*len < cfg_text_.length() + 1)
// {
// *len = cfg_text_.length() + 4;
// ret = ENOMEM;
// }
// else
// {
// strcpy((char*)buf, cfg_text_.c_str());
// *len = cfg_text_.length();
// ret = 0;
// }
// }
// return ret;
// }
// int32_t async_scanner::set_config(const char* cfg_name, void* data, size_t* len, uint32_t* afterdo)
// {
// gb_json *jsn = new gb_json();
// int32_t ret = EINVAL;
// if(jsn->attach_text(&cfg_text_[0]))
// {
// gb_json* child = nullptr;
// ret = ENOENT;
// if(jsn->get_value(cfg_name, child) && child)
// {
// int val = 0;
// child->get_value("affect", val);
// if(afterdo)
// *afterdo = val;
// if(strcmp(cfg_name, "resolution") == 0)
// {
// child->get_value("cur", val);
// ret = EUCLEAN;
// val = *(int*)data;
// if(val == 100 || val == 150 || val == 200 || val == 300 || val == 600)
// ret = 0;
// else if(val < 125)
// val = 100;
// else if(val < 175)
// val = 150;
// else if(val < 250)
// val = 200;
// else if(val < 450)
// val = 300;
// else
// val = 600;
// *(int*)data = val;
// child->set_value("cur", val);
// dpi_ = val;
// log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, dpi_);
// cfg_text_ = jsn->to_string();
// }
// else if(strcmp(cfg_name, "count") == 0)
// {
// child->get_value("cur", val);
// ret = EUCLEAN;
// val = *(int*)data;
// if(val == -1 || val == 1)
// ret = 0;
// else
// val = -1;
// *(int*)data = val;
// child->set_value("cur", val);
// scan_cnt_ = val;
// log_cls::log(LOG_LEVEL_ALL, "Set %s to %d\n", cfg_name, scan_cnt_);
// cfg_text_ = jsn->to_string();
// }
// child->release();
// }
// jsn->release();
// }
// return ret;
// }
// void async_scanner::update_enabled(std::function<GET_SANE_OPT_PROTO> get_opt)
// {
// gb_json *jsn = new gb_json();
// int32_t ret = EINVAL;
// if(jsn->attach_text(&cfg_text_[0]))
// {
// sane_cfg_provider::update_option_enable_status(jsn, get_opt);
// cfg_text_ = std::move(jsn->to_string());
// }
// jsn->release();
// }
// int32_t async_scanner::get_value(const char* name, const char* key, std::string& val)
// {
// gb_json* root = new gb_json(), *child = nullptr;
// int32_t ret = ENOENT;
// if(root->attach_text(&cfg_text_[0]))
// {
// if(root->get_value(name, child) && child)
// {
// if(sane_cfg_provider::raw_value_in_json(child, key, val))
// ret = 0;
// child->release();
// }
// }
// root->release();
// return ret;
// }

View File

@ -13,6 +13,7 @@
class UsbImageProcQueue
{
void (*push_image_)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, float ratio_h, float ratio_v, void* param) = nullptr;
void(*img_keeper_)(MemoryPtr, bool, void*);
void* kp_param_;
int scan_status_;
@ -32,6 +33,9 @@ class UsbImageProcQueue
case 4:
ss = SCANNER_STATUS_COVER_OPENNED;
break;
case 5:
ss = SCANNER_STATUS_COVER_CLOSED;
break;
case 8:
ss = SCANNER_STATUS_FEED_FAILED;
break;
@ -62,25 +66,25 @@ public:
void push(MemoryPtr image,bool containsimg)
{
#ifdef ASYNC_EP
if(!containsimg)
{
void (*push_image)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, float ratio_h, float ratio_v, void* param) = nullptr;
HGIntInfo* info = (HGIntInfo*)image->data();
HGIntInfo* info = (HGIntInfo*)image->data();
*(uint64_t*)&push_image = (uint64_t)img_keeper_;
if(info->From == HGType::STOPSCAN)
if(info->From == HGType::STOPSCAN)
{
if(push_image)
push_image(IMG_CB_STOPPED, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, ratio_h_, ratio_v_, kp_param_);
if(push_image_)
push_image_(IMG_CB_STOPPED, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, ratio_h_, ratio_v_, kp_param_);
}
else
{
scan_status_ = sensor_status_2_scanner_status(info->Code);
if(push_image)
push_image(IMG_CB_STATUS, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, ratio_h_, ratio_v_, kp_param_);
if(push_image_)
push_image_(IMG_CB_STATUS, nullptr, sensor_status_2_scanner_status(info->Code), 0, dpi_x_, dpi_y_, 0, PAPER_SIDE_LEFT, (clr_channel)0, (img_status)0, true, true, ratio_h_, ratio_v_, kp_param_);
}
}
return;
#endif
if(img_keeper_)
img_keeper_(image, containsimg, kp_param_);
@ -113,12 +117,9 @@ public:
imgp_over_ = false;
}
void (*push_image)(int data_type, void* data, size_t w, size_t h, int dpi_x, int dpi_y, size_t paper_ind, paper_side side, clr_channel clr, img_status status, bool img_new, bool img_over, float ratio_h, float ratio_v, void* param) = nullptr;
*(uint64_t*)&push_image = (uint64_t)img_keeper_;
if(push_image)
if(push_image_)
{
push_image(IMG_CB_IMAGE, data, width, height, dpi_x_, dpi_y_, scannnum, PAPER_SIDE_LEFT, (clr_channel)type, (img_status)status, true, true, ratio_h_, ratio_v_, kp_param_);
push_image_(IMG_CB_IMAGE, data, width, height, dpi_x_, dpi_y_, scannnum, PAPER_SIDE_LEFT, (clr_channel)type, (img_status)status, true, true, ratio_h_, ratio_v_, kp_param_);
return true;
}
@ -131,6 +132,7 @@ public:
img_keeper_ = img_keeper;
kp_param_ = param;
*(uint64_t*)&push_image_ = (uint64_t)img_keeper_;
}
void set_dpi(int x, int y)
{

View File

@ -654,6 +654,49 @@ const wchar_t* scanner_status(int s, wchar_t unk[20])
return unk;
}
static DWORD thread_open_id_ = 0;
static safe_fifo<std::string> images_;
static DWORD WINAPI thread_open_image(void* lp)
{
while (1)
{
std::string file("");
if (images_.take(file, true))
{
if (file.empty())
break;
ShellExecuteA(NULL, "Open", file.c_str(), NULL, NULL, SW_SHOWNORMAL);
}
}
return 0;
MSG msg = { 0 };
BOOL ret = TRUE;
while ((ret = GetMessage(&msg, NULL, 0, 0)))
{
if ((DWORD)ret == -1)
break;
if (msg.message == WM_USER + 1001)
break;
if (msg.message == WM_USER + 1)
{
std::string* file = (std::string*)msg.lParam;
ShellExecuteA(NULL, "Open", file->c_str(), NULL, NULL, SW_SHOWNORMAL);
delete file;
}
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
// CDlgScanner 对话框
IMPLEMENT_DYNAMIC(CDlgScanner, CDialogEx)
@ -668,13 +711,37 @@ CDlgScanner::CDlgScanner(CWnd* pParent /*=nullptr*/)
threads_ = new thread_pool<CDlgScanner>(this);
parent_ = pParent ? pParent->m_hWnd : NULL;
auto_wait_ = CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE h = CreateThread(NULL, 0, thread_open_image, NULL, 0, &thread_open_id_);
CloseHandle(h);
char buf[40] = { 0 };
sscanf(" ether fe:26:f4:f3:29:07 txqueuelen 1000 (Ethernet)", " ether %s", buf);
std::string tj("{\"resolution\":{\"cat\":\"imgp\",\"group\":\"base\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"ver\":1,\"pos\":200,\"type\":\"int\",\"unit\":\"dpi\",\"affect\":6,\"readonly\":false,\"visible\":true,\"enabled\":true,\"size\":4,\"cur\":400,\"default\":200,\"range\":{\"min\":100,\"max\":600,\"step\":50}}}");
gb_json* jsn = new gb_json();
if (jsn->attach_text(&tj[0]))
{
gb_json* child = jsn->first_child();
if (child)
{
bool bv = false, r = false;
int nv = 0;
double dv = .0f;
std::string sv("");
r = child->get_value("cur", bv);
r = child->get_value("cur", nv);
r = child->get_value("cur", dv);
r = child->get_value("cur", sv);
child->release();
}
}
jsn->release();
}
CDlgScanner::~CDlgScanner()
{
::PostThreadMessage(thread_open_id_, WM_USER + 1001, 0, 0);
images_.save("", true);
if (scanner_)
{
scanner_->close();
@ -689,6 +756,11 @@ void CDlgScanner::DoDataExchange(CDataExchange* pDX)
DDX_Control(pDX, IDC_TAB_OPER, tab_oper_);
}
typedef struct _prog_data
{
CDlgScanner* obj;
std::string file;
}PROGD, *LPPROGD;
void CDlgScanner::set_device(usb::LPUSBPNP pnp)
{
if (!pnp)
@ -715,11 +787,10 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
setting_ui_ = NULL;
}
static std::string cur_img_file("");
auto progresser = [&](uint64_t total, uint64_t cur, uint32_t err, void* user_data) -> int
{
CDlgScanner* dlg = (CDlgScanner*)user_data;
LPPROGD param = (LPPROGD)user_data;
CDlgScanner* dlg = param->obj;
if (cur >= total)
log_cls::log(LOG_LEVEL_DEBUG, "Finished in receiving new image = %d\r\n", err);
@ -732,7 +803,16 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
dlg->set_text(IDC_EDIT_COUNT, (std::to_wstring(dlg->img_cnt_) + L"/" + std::to_wstring(dlg->paper_cnt_)).c_str());
if (dlg->is_checked(IDC_CHECK_AUTO_OPEN_IMG))
ShellExecuteA(dlg->m_hWnd, "Open", cur_img_file.c_str(), NULL, NULL, SW_SHOWNORMAL);
{
images_.save(param->file, true);
//std::string* file(new std::string(param->file));
//if (!PostThreadMessage(thread_open_id_, WM_USER + 1, NULL, (LPARAM)file))
//{
// delete file;
// ShellExecuteA(dlg->m_hWnd, "Open", param->file.c_str(), NULL, NULL, SW_SHOWNORMAL);
//}
}
delete param;
}
return 0;
@ -781,9 +861,22 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
ext = "png";
else if (img->format == IMG_FMT_TIFF)
ext = "tiff";
sprintf_s(name, _countof(name) - 1, "scan_%04d.%s", ++img_cnt_, ext.c_str());
err = saver->open((root + name).c_str(), size);
log_cls::log(LOG_LEVEL_DEBUG, "Begin receiving new image (%s + %llu) = %d\r\n", (root + name).c_str(), size, err);
if (paper_cnt_ < img->pos.paper_ind)
paper_cnt_ = img->pos.paper_ind;
++img_cnt_;
sprintf_s(name, _countof(name) - 1, "scan_%04d", (int)img->pos.paper_ind);
root += name;
if (img->pos.paper_side == PAPER_SIDE_FRONT)
root += "F";
else if (img->pos.paper_side == PAPER_SIDE_BACK)
root += "B";
else
root += "C";
sprintf_s(name, _countof(name) - 1, "_%d.%s", (int)img->pos.split_ind, ext.c_str());
root += name;
err = saver->open(root.c_str(), size);
log_cls::log(LOG_LEVEL_DEBUG, "Begin receiving new image (%s + %llu) = %d\r\n", root.c_str(), size, err);
if (err)
{
saver->release();
@ -791,8 +884,10 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
}
else
{
saver->set_progress_notify(progresser, this);
cur_img_file = root + name;
LPPROGD param = new PROGD;
param->file = root;
param->obj = this;
saver->set_progress_notify(progresser, param);
}
return dynamic_cast<data_holder_ptr>(saver);
@ -834,8 +929,11 @@ void CDlgScanner::set_device(usb::LPUSBPNP pnp)
msg_box(m_hWnd, MB_OK, L"Unsupported Scanner", L"Failed to get protocol version with error %d.", err);
else
msg_box(m_hWnd, MB_OK, L"Unsupported Scanner", L"Protocol version is mismatch: expect %u.%u but return %u.%u", HIBYTE(PROTOCOL_VER), LOBYTE(PROTOCOL_VER), HIBYTE(ver), LOBYTE(ver));
scanner_->release();
scanner_ = NULL;
if (scanner_)
{
scanner_->release();
scanner_ = NULL;
}
enable_buttons(false);
OnDeviceStatus(0, (LPARAM)SCANNER_STATUS_NOT_OPEN);
}