diff --git a/device/gxx-linux/scanner/imageusbhandler.cpp b/device/gxx-linux/scanner/imageusbhandler.cpp index d403423..42cf968 100644 --- a/device/gxx-linux/scanner/imageusbhandler.cpp +++ b/device/gxx-linux/scanner/imageusbhandler.cpp @@ -17,7 +17,7 @@ static const std::string loggername = "imageusbhandler"; ImageUsbHandler::ImageUsbHandler(std::shared_ptr 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 @@ -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 guard(mtx); if(results.size() >= 1){ diff --git a/device/gxx-linux/scanner/scanner.cpp b/device/gxx-linux/scanner/scanner.cpp index 4ef7136..8036a1d 100644 --- a/device/gxx-linux/scanner/scanner.cpp +++ b/device/gxx-linux/scanner/scanner.cpp @@ -90,7 +90,7 @@ Scanner::Scanner(std::shared_ptr capturer, std::shared_ptr capturer, std::shared_ptradd_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) diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp index 90e0ef4..0f73f03 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.cpp @@ -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 montage , std::function 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; diff --git a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h index 0892fa1..8c2c9af 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h +++ b/device/gxx-linux/usb/src/async_model/img_process/cis_preproc.h @@ -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 { diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp index 9485dfa..a93bea3 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.cpp @@ -22,21 +22,24 @@ extern int32_t (*set_image_process_over)(bool); img_processor::img_processor(std::function img_sender , std::function 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(this); - worker_->thread_new(&img_processor::worker_thread, true); + // worker_ = new thread_pool(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(); +} \ No newline at end of file diff --git a/device/gxx-linux/usb/src/async_model/img_process/img_process.h b/device/gxx-linux/usb/src/async_model/img_process/img_process.h index e135a6c..3c24845 100644 --- a/device/gxx-linux/usb/src/async_model/img_process/img_process.h +++ b/device/gxx-linux/usb/src/async_model/img_process/img_process.h @@ -13,6 +13,7 @@ #include #include #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 cur_proc_; img_encoder* encoder_; - safe_fifo img_que_; - thread_pool* worker_; - std::vector tids_; - volatile bool speed_first_; + // safe_fifo img_que_; + // thread_pool* worker_; + // std::vector tids_; + // volatile bool speed_first_; + + ThreadPool pool_; + std::queue> 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); }; diff --git a/device/gxx-linux/usb/src/async_model/io/sent_img.cpp b/device/gxx-linux/usb/src/async_model/io/sent_img.cpp index bb2076f..4eaac62 100644 --- a/device/gxx-linux/usb/src/async_model/io/sent_img.cpp +++ b/device/gxx-linux/usb/src/async_model/io/sent_img.cpp @@ -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) diff --git a/device/gxx-linux/usb/src/async_model/io/sent_img.h b/device/gxx-linux/usb/src/async_model/io/sent_img.h index c59856b..cfd1c6c 100644 --- a/device/gxx-linux/usb/src/async_model/io/sent_img.h +++ b/device/gxx-linux/usb/src/async_model/io/sent_img.h @@ -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(); diff --git a/device/gxx-linux/usb/src/async_model/io/usb_io.cpp b/device/gxx-linux/usb/src/async_model/io/usb_io.cpp index 6702a95..dc657ff 100644 --- a/device/gxx-linux/usb/src/async_model/io/usb_io.cpp +++ b/device/gxx-linux/usb/src/async_model/io/usb_io.cpp @@ -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; diff --git a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp index cb4f7aa..f048e92 100644 --- a/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp +++ b/device/gxx-linux/usb/src/async_model/scanner/async_scanner.cpp @@ -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_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; -// } - diff --git a/device/gxx-linux/usb/usbimageprocqueue.h b/device/gxx-linux/usb/usbimageprocqueue.h index 1811de8..1f01038 100644 --- a/device/gxx-linux/usb/usbimageprocqueue.h +++ b/device/gxx-linux/usb/usbimageprocqueue.h @@ -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) { diff --git a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe index 56a911d..836207b 100644 Binary files a/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe and b/pc/code_twain/sln/usb_tools/Debug/usb_tools.exe differ diff --git a/pc/code_twain/sln/usb_tools/DlgScanner.cpp b/pc/code_twain/sln/usb_tools/DlgScanner.cpp index ee6fcb2..82642a7 100644 --- a/pc/code_twain/sln/usb_tools/DlgScanner.cpp +++ b/pc/code_twain/sln/usb_tools/DlgScanner.cpp @@ -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 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(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(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); }