#include "GScanO200.h" #ifdef WIN32 #include "UsbScanEx.h" #else #include "libusbex.h" #endif #include "G400ScanConfig.h" #include "StopWatch.h" #include "ImageMatQueue.h" #include "filetools.h" #include "IConfig.h" #include "scn_config.h" #include using namespace std; GScanO200::GScanO200() : m_usrdata(0) , m_usbreport(0) { } GScanO200::~GScanO200() { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } } void GScanO200::open(int vid, int pid) { #ifdef WIN32 auto usbs = UsbScan_List::find_vid_pid(vid, pid); #else // WIN32 auto usbs = Libusb_List::find_vid_pid(0x064b, 0x7823); #endif if (!usbs.empty()) { m_usb = *usbs.begin(); m_usb->set_usbcallback(&GScanO200::on_usbcallback, this); m_usb->open(); } } int GScanO200::open(int vid) { #ifdef WIN32 auto usbs = UsbScan_List::find_pid(vid); #else // WIN32 auto usbs = Libusb_List::find_vid_pid(0x064b, 0x7823); #endif if (!usbs.empty()) { m_usb = usbs.begin()->first; m_usb->set_usbcallback(&GScanO200::on_usbcallback, this); m_usb->open(); return usbs.cbegin()->second; } return 0; } bool GScanO200::close() { return m_usb->close(); } bool GScanO200::is_open() { return m_usb->is_open(); } void GScanO200::setusbreport_callback(usbreport_callback callback, void *usrdata) { m_usbreport=callback; m_usrdata = usrdata; } int GScanO200::get_image_front_info(ImageInfo *info) { StopWatch sw; while (true) { if (m_pImages->empty()) { if (sw.elapsed_s() > 30.00) { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } Stop_scan();//停止扫描 ResetScanner(); return HARDWARE_ERROR; } if (!is_scan()) { *info = { 0 }; if (devState == DEV_WRONG) { return get_ErrorCode(); } return -1; } } else { if (m_pImages->valid()) { m_pImages->get_image_front_info(info); return 0; } #ifdef WIN32 DoEvents();//防止UI阻塞 #endif // WIN32 this_thread::sleep_for(chrono::milliseconds(1)); } } //m_pImages->get_image_front_info(info); } int GScanO200::aquire_image(cv::Mat &mat,int& bppinfo) { StopWatch sw; while (true) { if (m_pImages->empty()) { if (sw.elapsed_s() > 20.00) { if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); m_threadUsb.reset(); } Stop_scan();//停止扫描 ResetScanner(); return HARDWARE_ERROR; } if (!is_scan()) { if (devState == DEV_WRONG) { return get_ErrorCode(); } return -1; } } else { if (m_pImages->valid()) { auto ret = m_pImages->popimage(); mat = ret.mat.clone(); bppinfo = ret.Bpp; return 0; } #ifdef WIN32 DoEvents();//防止UI阻塞 #endif // WIN32 this_thread::sleep_for(chrono::milliseconds(1)); } } } bool GScanO200::IsConnected() { return m_usb && m_usb->is_connected(); } std::string GScanO200::GetFWVersion(int mode) { if (m_usb&&m_usb->is_connected()) { lock_guard< mutex> lock(m_imgLocker); if (fwVersion.empty()) { if (mode == 1) fwVersion.resize(10); else fwVersion.resize(8); USBCB cmd= { GET_FW_VERSION,fwVersion.size(),0,}; m_usb->write_bulk(&cmd, sizeof(cmd)); m_usb->read_bulk(&fwVersion[0], fwVersion.size()); } return fwVersion; } return ""; } std::string GScanO200::GetSerialNum(int mode) { if (m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); if (SerialNum.empty()) { if (mode == 1) SerialNum.resize(14); else SerialNum.resize(12); USBCB usbcb = { GET_SERIAL,SerialNum.size(),0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&SerialNum[0], SerialNum.size()); } return SerialNum; } return ""; } bool GScanO200::is_scan() { return devState == DEV_RUNNING; } bool GScanO200::Get_Scanner_PaperOn() { if (!m_usb->is_open()) return false; USBCB usbcb = { GET_PAPER_STATUS ,0,0 }; std::lock_guard lck(m_imgLocker); m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Data != 0; } void GScanO200::config_params(GScanCap ¶ms,int mode) { if (m_usb->is_connected()) { UINT32 cfgdata=0; if (mode == 0){ hgConfigClass cfg = hgConfigClass(params); cfgdata = cfg.GetData(); } else{ G400ScanConfig cfg = G400ScanConfig(params); cfgdata = cfg.GetData(); } USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; m_usb->write_bulk(&usbcb, sizeof(USBCB)); m_pImages->setparam(params); } } void GScanO200::Scanner_StartScan(UINT32 count,int mode) { this->mode = mode; if (m_usb->is_connected()) { std::lock_guard lck(m_imgLocker); USBCB status = { GET_DSP_STATUS ,0,0 }; m_usb->write_bulk(&status, sizeof(status)); m_usb->read_bulk(&status, sizeof(status)); switch (status.u32_Data) { case COUNT_MODE: case NO_FEED: case OPEN_COVER: case FEED_IN_ERROR: case PAPER_JAM: case DETECT_DOUBLE_FEED: case DETECT_STAPLE: case PAPER_SKEW: case HARDWARE_ERROR: case PC_SCAN_BUSY_or_ERROR: m_pImages->setscanflags(false); devState = DEV_WRONG; Set_ErrorCode(status.u32_Data); return; default: break; } if (mode == 1) { USBCB paperstatus = { GET_PAPER_STATUS ,0,0 }; m_usb->write_bulk(&paperstatus, sizeof(paperstatus)); m_usb->read_bulk(&paperstatus, sizeof(paperstatus)); if (paperstatus.u32_Data == 0) { m_pImages->setscanflags(false); devState = DEV_WRONG; Set_ErrorCode(NO_FEED); return; } } USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); this_thread::sleep_for(std::chrono::milliseconds(200)); if (m_threadUsb && m_threadUsb->joinable()) { devState = DEV_STOP; m_threadUsb->join(); } m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this)); m_pImages->run(); m_pImages->setscanflags(true); } } void GScanO200::Stop_scan() { if (!m_usb->is_connected()) { return; } std::lock_guard lck(m_imgLocker); USBCB usbcb = { STOP ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } void GScanO200::ResetScanner() { if (!m_usb->is_connected()) return; std::lock_guard lck(m_imgLocker); USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } bool GScanO200::Get_IsImageQueueEmpty() { return m_pImages->empty(); } void GScanO200::clear_hwerror() { std::lock_guard lck(m_imgLocker); USBCB usbcb = { 0x40 ,0,0 }; if (m_usb.get() && m_usb->is_connected()) m_usb->write_bulk(&usbcb, sizeof(usbcb)); } void GScanO200::reset() { while (!m_pImages->empty()) m_pImages->clear(); } void GScanO200::setdecodepixtype(int twpixtype) { } UINT32 GScanO200::get_ErrorCode() { return Error_Code; } void GScanO200::Set_ErrorCode(UINT32 value) { Error_Code = value; } int GScanO200::get_scanned_num() { if (!m_usb->is_connected()) return -1; std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SCANN_NUM ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Data; } int GScanO200::get_roller_num() { if (!m_usb->is_connected()) return -1; std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_ROLLER_NUM ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Data; } void GScanO200::clr_roller_num() { if (!m_usb->is_connected()) return; std::lock_guard lck(m_imgLocker); USBCB usbcb = { CLR_ROLLER_NUM ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); } int GScanO200::get_sleep_time() { if (!m_usb->is_connected()) return -1; std::lock_guard lck(m_imgLocker); USBCB usbcb = { GET_SLEEP_TIME ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb.u32_Data; } void GScanO200::set_sleep_time(int time) { if (!m_usb->is_connected()) return; std::lock_guard lck(m_imgLocker); USBCB usbcb = { SET_SLEEP_TIME ,(unsigned int)time,0 }; } bool GScanO200::clr_hardware_cache() { if (!m_usb->is_connected()) return -1; std::lock_guard lck(m_imgLocker); USBCB usbcb = { CLR_HARDWARE_CACHE ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); uchar ret[4] = { 0,0,0,0 }; m_usb->read_bulk(ret, 4); return ret[0]; } void GScanO200::on_usbcallback(bool isleft, void * usrdata) { GScanO200* This = (GScanO200*)usrdata; This->onusbcallback(isleft); } void GScanO200::onusbcallback(bool isleft) { if (isleft) { Error_Code = DEVICE_OFF_LINE; devState = DEV_WRONG; } if(m_usbreport&&m_usrdata){ m_usbreport(isleft,m_usrdata); } } void GScanO200::usbmain() { std::shared_ptr> imgData; devState = DEV_RUNNING; while (devState == DEV_RUNNING) { if (!m_usb->is_connected()) { this_thread::sleep_for(chrono::milliseconds(200)); continue; } USBCB usbcb = Get_Scanner_Status(); switch (usbcb.u32_Data) { case HAVE_IMAGE: { int totalNum = usbcb.u32_Count; m_usb->set_timeout(1500); imgData = Get_Img_Data(totalNum); m_usb->set_timeout(200); if (!imgData->size()) { Stop_scan(); } if(mode==0) m_pImages->pushMat(std::shared_ptr(new G200Decode(imgData))); else m_pImages->pushMat(std::shared_ptr(new GRawDecode(imgData))); Pop_Image(); break; } case STOP_SCAN: m_pImages->setscanflags(false); devState = DEV_STOP; break; case COUNT_MODE: case NO_FEED: case OPEN_COVER: case FEED_IN_ERROR: case PAPER_JAM: case DETECT_DOUBLE_FEED: case DETECT_STAPLE: case PAPER_SKEW: case HARDWARE_ERROR: case PC_SCAN_BUSY_or_ERROR: Set_ErrorCode(usbcb.u32_Data); m_pImages->setscanflags(false); devState = DEV_WRONG; break; case NORMAL: break; default: break; } this_thread::sleep_for(chrono::milliseconds(20)); } } /////////////////////////////////////////////////////////////////////////// USBCB GScanO200::Get_Scanner_Status() { if (!m_usb->is_connected()) { return { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 }; } USBCB usbcb = { GET_DSP_STATUS ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); m_usb->read_bulk(&usbcb, sizeof(usbcb)); return usbcb; } std::shared_ptr> GScanO200::Get_Img_Data(int bufferSize) { if (!(m_usb.get() && m_usb->is_connected())) return std::shared_ptr>(new std::vector()); std::shared_ptr> imData(new std::vector(bufferSize)); StopWatch sw; int readed = 0; USBCB usbcb = { GET_IMAGE,0,bufferSize }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); int totalength = 1024*1024; int startindex = 0; while (startindex < bufferSize) { startindex += m_usb->read_bulk(imData->data() + startindex, (bufferSize - startindex) < totalength?(bufferSize - startindex):totalength); //数据接收量必须小于等于管道内数据量,否则会接收失败 } return imData; } /////////////////////////////////////////////////////////////////////////// void GScanO200::Pop_Image() { if (!(m_usb.get() && m_usb->is_connected())) return; USBCB usbcb = { POP_IMAGE ,0,0 }; m_usb->write_bulk(&usbcb, sizeof(usbcb)); }