diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index c7b6aa9..cf2d910 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -3459,9 +3459,22 @@ int hg_scanner::try_third_app_handle_start(bool& handled) { int ret = SCANNER_ERR_OK; + handled = false; + return ret; + handled = !async_io_; if (handled) { + if (user_cancel_) + { + if (status_ != SCANNER_ERR_OK && status_ != SCANNER_ERR_USER_CANCELED) // call stop after exception occurs, start a new scanning ... + { + handled = false; + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "call start after user cancelled while status is %s, we start a new scanning\n", hg_scanner_err_description(status_)); + + return ret; + } + } while (wait_usb_result_.try_wait()) std::this_thread::sleep_for(std::chrono::milliseconds(3)); @@ -3505,13 +3518,14 @@ int hg_scanner::try_third_app_handle_start(bool& handled) } int hg_scanner::try_third_app_after_start(int err) { - if (!async_io_) - { - while (wait_img_.is_waiting() && !wait_usb_.is_waiting()) - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - if (wait_img_.is_waiting() && wait_usb_.is_waiting()) - err = status_; - } + //if (!async_io_) + //{ + // while (wait_img_.is_waiting() && !wait_usb_.is_waiting()) + // std::this_thread::sleep_for(std::chrono::milliseconds(10)); + // if (wait_img_.is_waiting() && wait_usb_.is_waiting()) + // err = status_; + // + //} return err; } @@ -3607,9 +3621,9 @@ int hg_scanner::save_usb_data(std::shared_ptr data) { int ret = SCANNER_ERR_OK; unsigned int bytes = data->size(); - + usb_img_index_++; - VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "USB read one picture with %u bytes\n", data->size()); + VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "USB packet(%04d) of picture with %u bytes(status: %d)\n", usb_img_index_, data->size(), data->get_image_statu()); if (dump_usb_path_.length()) //这两台设备不是jpg的图 所以不能直接处理 { char name[80] = { 0 }; @@ -4081,11 +4095,98 @@ void hg_scanner::on_language_changed(void) } } } +int hg_scanner::wait_one_image_from_start(bool& handled) +{ + int ret = SCANNER_ERR_OK; + + handled = false; + if (!async_io_) // non-callback + { + while (is_running() != THREAD_RUNNING_IDLE) + { + handled = true; + if (final_imgs_.size()) + { + break; + } + } + + if (final_imgs_.size()) + { + IMH head = { 0 }; + + handled = true; + if (final_imgs_.front(&head)) + { + if (head.statu & IMG_STATUS_DOUBLE) + ret = SCANNER_ERR_DEVICE_DOUBLE_FEEDING; + else if (head.statu & IMG_STATUS_JAM) + ret = SCANNER_ERR_DEVICE_PAPER_JAMMED; + else if (head.statu & IMG_STATUS_STAPLE) + ret = SCANNER_ERR_DEVICE_STAPLE_ON; + else if (head.statu & IMG_STATUS_SIZE_ERR) + ret = SCANNER_ERR_DEVICE_SIZE_CHECK; + else if (head.statu & IMG_STATUS_DOGEAR) + ret = SCANNER_ERR_DEVICE_DOGEAR; + } + } + else if (handled) // overed normal or exception + { + if (status_ == SCANNER_ERR_OK + || status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) // 双张特殊处理,视为成功 + { + SANE_Bool has_paper = SANE_FALSE; + + get_scanner_paperon(has_paper); + if (has_paper == SANE_TRUE) + handled = false; + else + ret = SCANNER_ERR_DEVICE_NO_PAPER; + } + else + ret = status_; + } + } + + return ret; +} int hg_scanner::start(void) { - user_cancel_ = false; + int ret = SCANNER_ERR_OK; + bool handled = false; - return status_; + if (user_cancel_) + { + user_cancel_ = false; // stopped by user, reset flag and starting a new scanning ... + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "start after user stopped just now while with %d image(s) in queue, a new scanning will to be started ...\n", final_imgs_.size()); + } + else + { + ret = wait_one_image_from_start(handled); + if (handled) + { + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "start in previous scanning and result is %s, image count %d\n", hg_scanner_err_description(ret), final_imgs_.size()); + return ret; + } + } + + // clear ... + imgs_.Clear(); + final_imgs_.clear(); + usb_img_index_ = final_img_index_ = 0; + status_ = SCANNER_ERR_OK; + + // start ... + ret = do_start(); + + if (ret == SCANNER_ERR_OK) + { + // wait ONE picture or stopped + ret = wait_one_image_from_start(handled); + } + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "start scanning result = %s\n", hg_scanner_err_description(ret)); + + return ret; } int hg_scanner::get_image_info(SANE_Parameters* ii, int len) { @@ -4197,9 +4298,21 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len) } int hg_scanner::stop(void) { - user_cancel_ = true; + int ret = SCANNER_ERR_OK; - return status_; + user_cancel_ = true; + ret = do_stop(); + + // wait until really stopped ... + if (ret == SCANNER_ERR_OK) + { + while (is_running() != THREAD_RUNNING_IDLE) + std::this_thread::sleep_for(std::chrono::milliseconds(3)); + ret = status_; + } + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "user stopped result = %s\n", hg_scanner_err_description(ret)); + + return ret; } int hg_scanner::reset(void) { diff --git a/hgdriver/hgdev/hg_scanner.h b/hgdriver/hgdev/hg_scanner.h index 98bcc4b..f2fe824 100644 --- a/hgdriver/hgdev/hg_scanner.h +++ b/hgdriver/hgdev/hg_scanner.h @@ -439,6 +439,7 @@ protected: int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf, uint32_t id = -1); void adjust_filling_hole(LPSCANCONF conf); + int wait_one_image_from_start(bool& handled); //////////////////////////////////////////////////////////////// // 新增自定义伽玛曲线及扫描区域属性 - 2022-05-05 @@ -461,6 +462,9 @@ protected: bool is_white_0_; // 是否‘0’代表白色 public: + int start(void); + int stop(void); + void set_ui_callback(sane_callback cb, bool enable_async_io); void set_dev_family(const char* family); void set_read_over_with_no_data(bool no_data); @@ -487,10 +491,10 @@ public: int is_running(void); // return thread_running public: - virtual int start(void); + virtual int do_start(void) = 0; + virtual int do_stop(void) = 0; virtual int get_image_info(SANE_Parameters* ii, int len); virtual int read_image_data(unsigned char* buf, int* len); - virtual int stop(void); virtual int reset(void); virtual int device_io_control(unsigned long code, void* data, unsigned* len); virtual int discard_all_images(void) = 0; diff --git a/hgdriver/hgdev/hg_scanner_200.cpp b/hgdriver/hgdev/hg_scanner_200.cpp index 558a08f..e3c08ef 100644 --- a/hgdriver/hgdev/hg_scanner_200.cpp +++ b/hgdriver/hgdev/hg_scanner_200.cpp @@ -265,7 +265,7 @@ void hg_scanner_200::thread_handle_usb_read(void) } VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_description(status_)); } -int hg_scanner_200::start(void) +int hg_scanner_200::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), @@ -318,7 +318,7 @@ int hg_scanner_200::start(void) return ret; } -int hg_scanner_200::stop(void) +int hg_scanner_200::do_stop(void) { int ret = SCANNER_ERR_OK; @@ -337,7 +337,8 @@ int hg_scanner_200::stop(void) { status_ = SCANNER_ERR_DEVICE_STOPPED; } - return status_; + + return ret; } int hg_scanner_200::writeusb(USBCB &usb) { diff --git a/hgdriver/hgdev/hg_scanner_200.h b/hgdriver/hgdev/hg_scanner_200.h index 5779b02..4785dfa 100644 --- a/hgdriver/hgdev/hg_scanner_200.h +++ b/hgdriver/hgdev/hg_scanner_200.h @@ -50,8 +50,8 @@ public: ~hg_scanner_200(); public: - virtual int start(void)override; - virtual int stop(void)override; + virtual int do_start(void) override; + virtual int do_stop(void) override; private: int initdevice(); diff --git a/hgdriver/hgdev/hg_scanner_239.cpp b/hgdriver/hgdev/hg_scanner_239.cpp index 9e2c1bf..80ec946 100644 --- a/hgdriver/hgdev/hg_scanner_239.cpp +++ b/hgdriver/hgdev/hg_scanner_239.cpp @@ -1337,6 +1337,7 @@ void hg_scanner_239::thread_get_dves_image(void) { std::lock_guard lock(io_lock_); + memset(buf, 0, size); ret = io_->read_interrupt(buf, &size); io_->set_timeout(1000); } @@ -1354,7 +1355,7 @@ void hg_scanner_239::thread_get_dves_image(void) if (is_auto_paper_scan && sw.elapsed_s() >= is_auto_paper_scan_exit_time && is_auto_paper_scan_exit_time != 0) { - stop(); + do_stop(); notify_ui_working_status(from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN), SANE_EVENT_ERROR, status_); VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "auto paper scan exit :%s\n", from_default_language(STATU_DESC_SCANNER_ERR_DEVICE_EXIT_WAIT_SCAN)); } @@ -1397,7 +1398,7 @@ void hg_scanner_239::thread_get_dves_image(void) && status_ != SCANNER_ERR_DEVICE_AUTO_FAIL_INFO ) { - if (info->From != setting3399::IMG && status_ != SCANNER_ERR_DEVICE_DOUBLE_FEEDING) + if (info->From != setting3399::IMG /*&& status_ != SCANNER_ERR_DEVICE_DOUBLE_FEEDING*/) svdevs_err_.push_back(status_); } @@ -1413,13 +1414,13 @@ void hg_scanner_239::thread_get_dves_image(void) while (get_image_count() > 0) { - ret = read_one_image_from_usb((status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING && dev_conf_.params_3399.double_out_en) ? IMG_STATUS_DOUBLE : IMG_STATUS_OK); + ret = read_one_image_from_usb((status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING /*&& dev_conf_.params_3399.double_out_en*/) ? IMG_STATUS_DOUBLE : IMG_STATUS_OK); //if (status_ == SCANNER_ERR_DEVICE_DOUBLE_FEEDING) // svdevs_err_.push_back(IMG_STATUS_DOUBLE); count++; - if (ret != SCANNER_ERR_OK - && ret != SCANNER_ERR_CREATE_FILE_FAILED - && ret != SCANNER_ERR_WRITE_FILE_FAILED) + //if (ret != SCANNER_ERR_OK + // && ret != SCANNER_ERR_CREATE_FILE_FAILED + // && ret != SCANNER_ERR_WRITE_FILE_FAILED) break; } } @@ -1441,15 +1442,22 @@ void hg_scanner_239::thread_get_dves_image(void) else std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + int rest = 0; while (get_image_count() > 0) { ret = read_one_image_from_usb(); - count++; + rest++; if (ret != SCANNER_ERR_OK && ret != SCANNER_ERR_CREATE_FILE_FAILED && ret != SCANNER_ERR_WRITE_FILE_FAILED) break; } + count += rest; + if (rest) + { + VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "STOPSCAN message is ahead of %d image(s)!\n", rest); + } + if (user_cancel_ && !is_auto_paper_scan) { if (status_ && status_ != SCANNER_ERR_DEVICE_STOPPED) // thread_handle_image_process maybe call stop() when insufficient memory occurs . @@ -1492,7 +1500,7 @@ void hg_scanner_239::thread_get_dves_image(void) else if (info->From == setting3399::V4L2) { VLOG_MINI_2(LOG_LEVEL_WARNING, "V4L2 message received, code = %d, index = %d\n", info->Code, info->Img_Index); - // stop(); + // do_stop(); break; } else if (info->From == setting3399::AutoCorrect) @@ -1526,7 +1534,7 @@ void hg_scanner_239::thread_handle_usb_read(void) thread_get_dves_image(); } -int hg_scanner_239::start(void) +int hg_scanner_239::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), @@ -1536,8 +1544,6 @@ int hg_scanner_239::start(void) return ret; - user_cancel_ = false; - split3399_ = 0; cb_mem_ = true; @@ -1614,15 +1620,14 @@ int hg_scanner_239::start(void) return ret; } -int hg_scanner_239::stop(void) +int hg_scanner_239::do_stop(void) { int ret = SCANNER_ERR_OK; - user_cancel_ = true; - ret = write_command(setting3399::SC_STOP); io_->set_timeout(500); - return status_; + + return ret; } int hg_scanner_239::reset(void) { @@ -1824,9 +1829,9 @@ int hg_scanner_239::get_scanner_paperon(SANE_Bool& type) int ret = read_register(setting3399::SR_GET_PAPERON, &val); //0无纸 1有纸 if (ret == SCANNER_ERR_OK) { - type = val == 0 ? false : true; + type = val == 0 ? SANE_FALSE : SANE_TRUE; } - VLOG_MINI_1(LOG_LEVEL_WARNING, "get_scanner_paperon is(%s)\n", !type ? hg_scanner_err_description(SCANNER_ERR_DEVICE_NO_PAPER) : hg_scanner_err_description(SCANNER_ERR_OK)); + VLOG_MINI_1(LOG_LEVEL_WARNING, "get_scanner_paperon is(%s)\n", val == 0 ? hg_scanner_err_description(SCANNER_ERR_DEVICE_NO_PAPER) : "paper on"); return ret; } diff --git a/hgdriver/hgdev/hg_scanner_239.h b/hgdriver/hgdev/hg_scanner_239.h index e35a103..940abea 100644 --- a/hgdriver/hgdev/hg_scanner_239.h +++ b/hgdriver/hgdev/hg_scanner_239.h @@ -86,8 +86,8 @@ public: public: //virtual int get_image_info(IMG_PARAM* ii) override; //virtual int read_image_data(unsigned char* buf, int* len) override; - virtual int start(void) override; - virtual int stop(void) override; + virtual int do_start(void) override; + virtual int do_stop(void) override; virtual int reset(void) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; virtual int get_roller_life(void) override; diff --git a/hgdriver/hgdev/hg_scanner_300.cpp b/hgdriver/hgdev/hg_scanner_300.cpp index d420326..188d119 100644 --- a/hgdriver/hgdev/hg_scanner_300.cpp +++ b/hgdriver/hgdev/hg_scanner_300.cpp @@ -334,7 +334,7 @@ int hg_scanner_300::get_roller_life(void) { return pid_ == 300 ? 150000 : 200000; } -int hg_scanner_300::start(void) +int hg_scanner_300::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop @@ -408,7 +408,7 @@ int hg_scanner_300::start(void) VLOG_MINI_1(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret)); return ret; } -int hg_scanner_300::stop(void) +int hg_scanner_300::do_stop(void) { int ret = SCANNER_ERR_OK; @@ -431,7 +431,7 @@ int hg_scanner_300::stop(void) } //final_imgs_.clear(); - return status_; + return ret; } int hg_scanner_300::writeusb(USBCB &usb) { @@ -554,7 +554,7 @@ int hg_scanner_300::get_img_data(std::shared_ptr& imagedata) else { VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Read image data from USB err: %s\n", hg_scanner_err_name(ret)); - stop(); + do_stop(); string str = STATU_DESC_SCANNER_ERR_DEVICE_GET_IMAGE_ERR; str = str + '-' + STATU_DESC_SCANNER_ERR_DEVICE_STOPPED; notify_ui_working_status(str.c_str(), SANE_EVENT_ERROR, ret); diff --git a/hgdriver/hgdev/hg_scanner_300.h b/hgdriver/hgdev/hg_scanner_300.h index d3aa3ec..e971dbe 100644 --- a/hgdriver/hgdev/hg_scanner_300.h +++ b/hgdriver/hgdev/hg_scanner_300.h @@ -51,8 +51,9 @@ public: hg_scanner_300(const char* dev_name,int pid, usb_io* io); ~hg_scanner_300(); public: - virtual int start(void)override; - virtual int stop(void)override; + virtual int do_start(void) override; + virtual int do_stop(void) override; + private: int set_kernelsnap_ver(); int agreement(TwSS tw,int align); diff --git a/hgdriver/hgdev/hg_scanner_302.cpp b/hgdriver/hgdev/hg_scanner_302.cpp index 9a9cbc5..df67ac0 100644 --- a/hgdriver/hgdev/hg_scanner_302.cpp +++ b/hgdriver/hgdev/hg_scanner_302.cpp @@ -1020,7 +1020,7 @@ void hg_scanner_302::thread_handle_usb_read(void) VLOG_MINI_1(LOG_LEVEL_FATAL, "V4L2 error: %d\n", info->Code); { bool cancel = user_cancel_; - stop(); + do_stop(); user_cancel_ = cancel; go = false; } @@ -1052,7 +1052,7 @@ void hg_scanner_302::thread_handle_usb_read(void) } VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "USB thread exit with code: %s, status = %s\n", hg_scanner_err_name(ret), hg_scanner_err_name(status_)); } -int hg_scanner_302::start(void) +int hg_scanner_302::do_start(void) { bool handled = false; @@ -1129,7 +1129,7 @@ int hg_scanner_302::start(void) return ret; } -int hg_scanner_302::stop(void) +int hg_scanner_302::do_stop(void) { std::lock_guard lock(io_lock_); int ret = SCANNER_ERR_OK; @@ -1139,7 +1139,7 @@ int hg_scanner_302::stop(void) // io_->set_timeout(500); //final_imgs_.clear(); - return status_; + return ret; } int hg_scanner_302::reset(void) { diff --git a/hgdriver/hgdev/hg_scanner_302.h b/hgdriver/hgdev/hg_scanner_302.h index 9cd5af8..37864fb 100644 --- a/hgdriver/hgdev/hg_scanner_302.h +++ b/hgdriver/hgdev/hg_scanner_302.h @@ -83,10 +83,9 @@ public: ~hg_scanner_302(); public: - virtual int start(void) override; - //virtual int get_image_info(IMG_PARAM* ii) override; - //virtual int read_image_data(unsigned char* buf, int* len) override; - virtual int stop(void) override; + virtual int do_start(void) override; + virtual int do_stop(void) override; + virtual int reset(void) override; virtual int device_io_control(unsigned long code, void* data, unsigned* len) override; diff --git a/hgdriver/hgdev/hg_scanner_306.cpp b/hgdriver/hgdev/hg_scanner_306.cpp index 8eb1a5b..e733ba0 100644 --- a/hgdriver/hgdev/hg_scanner_306.cpp +++ b/hgdriver/hgdev/hg_scanner_306.cpp @@ -294,7 +294,7 @@ int hg_scanner_306::get_roller_life(void) { return pid_ == 300 ? 150000 : 200000; } -int hg_scanner_306::start(void) +int hg_scanner_306::do_start(void) { bool handled = false; int ret = try_third_app_handle_start(handled), //sane调用是每次都会调用一次start和stop @@ -368,7 +368,7 @@ int hg_scanner_306::start(void) VLOG_MINI_1(LOG_LEVEL_WARNING, "----------Main start scan status : %s----------\n", hg_scanner_err_description(ret)); return ret; } -int hg_scanner_306::stop(void) +int hg_scanner_306::do_stop(void) { int ret = SCANNER_ERR_OK; @@ -391,7 +391,7 @@ int hg_scanner_306::stop(void) } //final_imgs_.clear(); - return status_; + return ret; } int hg_scanner_306::writeusb(USBCB &usb) { diff --git a/hgdriver/hgdev/hg_scanner_306.h b/hgdriver/hgdev/hg_scanner_306.h index 6f290f2..47c91bf 100644 --- a/hgdriver/hgdev/hg_scanner_306.h +++ b/hgdriver/hgdev/hg_scanner_306.h @@ -52,8 +52,9 @@ public: hg_scanner_306(const char* dev_name,int pid, usb_io* io); ~hg_scanner_306(); public: - virtual int start(void)override; - virtual int stop(void)override; + virtual int do_start(void) override; + virtual int do_stop(void) override; + private: int set_kernelsnap_ver(); int agreement(TwSS tw,int align);