diff --git a/GScan200.cpp b/GScan200.cpp new file mode 100644 index 0000000..5a0d991 --- /dev/null +++ b/GScan200.cpp @@ -0,0 +1,74 @@ +#include "stdafx.h" +#include "GScan200.h" + +void GScan200::open(int vid, int pid) +{ +} + +int GScan200::aquire_image(cv::Mat& image) +{ + return 0; +} + +BOOL GScan200::IsConnected() +{ + return 0; +} + +std::string GScan200::GetFWVersion() +{ + return std::string(); +} + +std::string GScan200::GetSerialNum() +{ + return std::string(); +} + +bool GScan200::is_scan() +{ + return false; +} + +BOOL GScan200::Get_Scanner_PaperOn() +{ + return 0; +} + +void GScan200::config_params(SFreeImage& params) +{ +} + +void GScan200::Scanner_StartScan(UINT16 count) +{ +} + +void GScan200::Stop_scan() +{ +} + +void GScan200::ResetScanner() +{ +} + +bool GScan200::Get_IsImageQueueEmpty() +{ + return false; +} + +void GScan200::reset() +{ +} + +void GScan200::setdecodepixtype(int twpixtype) +{ +} + +UINT32 GScan200::get_ErrorCode() +{ + return UINT32(); +} + +void GScan200::Set_ErrorCode(UINT32 value) +{ +} diff --git a/GScan200.h b/GScan200.h new file mode 100644 index 0000000..8c6cc79 --- /dev/null +++ b/GScan200.h @@ -0,0 +1,24 @@ +#pragma once +#include "gscn_drv.h" +class GScan200 : + public IGScan +{ + // 通过 IGScan 继承 + virtual void open(int vid, int pid) override; + virtual int aquire_image(cv::Mat& image) override; + virtual BOOL IsConnected() override; + virtual std::string GetFWVersion() override; + virtual std::string GetSerialNum() override; + virtual bool is_scan() override; + virtual BOOL Get_Scanner_PaperOn() override; + virtual void config_params(SFreeImage& params) override; + virtual void Scanner_StartScan(UINT16 count) override; + virtual void Stop_scan() override; + virtual void ResetScanner() override; + virtual bool Get_IsImageQueueEmpty() override; + virtual void reset() override; + virtual void setdecodepixtype(int twpixtype) override; + virtual UINT32 get_ErrorCode() override; + virtual void Set_ErrorCode(UINT32 value) override; +}; + diff --git a/GScanO200.cpp b/GScanO200.cpp new file mode 100644 index 0000000..7b7db32 --- /dev/null +++ b/GScanO200.cpp @@ -0,0 +1,331 @@ +#include "stdafx.h" +#include "GScanO200.h" +#include "UsbScanEx.h" +#include "opencv2/opencv.hpp" +#include "twain.h" +#include "UsbScanEx.h" + +GScanO200::GScanO200() +{ +} + +GScanO200::~GScanO200() +{ + if (m_threadUsb && m_threadUsb->joinable()) { + devState = DEV_STOP; + m_threadUsb->join(); + m_threadUsb.reset(); + } +} + +void GScanO200::open(int vid, int pid) +{ + auto usbs = UsbScan_List::find_vid_pid(vid, pid); + + if (!usbs.empty()) { + m_usb = *usbs.begin(); + m_usb->open(); + } +} + +int GScanO200::aquire_image(cv::Mat& image) +{ + StopWatch sw; + sw.start(); + double timeout; + while (true) + { + if (Get_IsImageQueueEmpty()) + { + DoEvents(); + sw.stop(); + timeout = sw.time_run(); + if (timeout > 15.00) + { + if (m_threadUsb && m_threadUsb->joinable()) { + devState = DEV_STOP; + m_threadUsb->join(); + m_threadUsb.reset(); + } + m_pImages.release_img_prc_thread();//释放图像处理线程 + Stop_scan();//停止扫描 + ResetScanner(); + return HARDWARE_ERROR; + } + + if (!is_scan()) + { + if (devState == DEV_WRONG) + { + return get_ErrorCode(); + } + return 0; + } + } + else + { + + if (m_pImages.valid()) + { + image = popMat(); + return 0; + } + } + } +} + +BOOL GScanO200::IsConnected() +{ + return m_usb && m_usb->is_connected(); +} + +std::string GScanO200::GetFWVersion() +{ + return std::string(); +} + +std::string GScanO200::GetSerialNum() +{ + if (m_usb->is_connected()) + { + std::lock_guard lck(m_imgLocker); + if (SerialNum.empty()) + { + SerialNum = " "; + USBCB usbcb = { GET_SERIAL,12,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&SerialNum[0], 12); + } + return SerialNum; + } + return ""; +} + +bool GScanO200::is_scan() +{ + std::lock_guard lck(m_imgLocker); + return devState == DEV_ISRUNNING; +} + +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(SFreeImage& params) +{ + if (m_usb->is_connected()) + { + hgConfigClass cfg(params); + UINT32 cfgdata = cfg.GetData(); + USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 }; + m_usb->write_bulk(&usbcb, sizeof(USBCB)); + setdecodepixtype(params.m_HardWareParams.PixType); + m_pImages.setparam(params); + } +} + +void GScanO200::Scanner_StartScan(UINT16 count) +{ + if (m_usb->is_connected()) + { + std::lock_guard lck(m_imgLocker); + USBCB usbcb = { START_COMMAND,(UINT32)count ,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + if (m_threadUsb && m_threadUsb->joinable()) { + m_threadUsb->join(); + } + m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this)); + m_pImages.SetScanningStatus(true); + m_pImages.run(); + } +} + +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() +{ + std::lock_guard lck(m_imgLocker); + return m_pImages.empty(); +} + +void GScanO200::reset() +{ + std::lock_guard lck(m_imgLocker); + while (!m_pImages.empty()) + { + m_pImages.clear(); + } +} + +void GScanO200::setdecodepixtype(int twpixtype) +{ + if (twpixtype == TWPT_RGB) + pixType = TJPF_BGR; + else + pixType = TJPF_GRAY; +} + +UINT32 GScanO200::get_ErrorCode() +{ + std::lock_guard lck(m_imgLocker); + return Error_Code; +} + +void GScanO200::Set_ErrorCode(UINT32 value) +{ + std::lock_guard lck(m_imgLocker); + Error_Code = value; +} + +DWORD GScanO200::usbmain() +{ + cv::Mat imgData; + cv::Mat bufferF; + cv::Mat bufferB; + devState = DEV_ISRUNNING; + while (devState == DEV_ISRUNNING) + { + 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; + DWORD transferCount = 0; + imgData = Get_Img_Data(totalNum); + if (imgData.empty()) { //!< transfer data error + Stop_scan(); + } + + bufferF = cv::Mat(imgData.rows, imgData.cols, CV_8UC1); + bufferB = cv::Mat(imgData.rows, imgData.cols, CV_8UC1); + int j = 0; + int k = 0; + for (int i = 0; i < totalNum / 1024; i++) + { + if (imgData.data[1023 + i * 1024] == 0) + { + j++; + memcpy(&(bufferB.data[(j - 1) * 1023]), &(imgData.data[(j + k - 1) * 1024]), 1023); + } + else if (imgData.data[1023 + i * 1024] == 255) + { + k++; + memcpy(&(bufferF.data[(k - 1) * 1023]), &(imgData.data[(j + k - 1) * 1024]), 1023); + } + } + vector mats; + mats.push_back(bufferB); + mats.push_back(bufferF); + pushMat(JpegBuffer(mats, pixType, 0)); + imgData.release(); + bufferB.release(); + bufferF.release(); + Pop_Image(); + break; + } + case STOP_SCAN: + { + m_pImages.SetScanningStatus(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: + m_pImages.SetScanningStatus(false); + Set_ErrorCode(usbcb.u32_Data); + devState = DEV_WRONG; + break; + case NORMAL: + break; + default: + break; + } + this_thread::sleep_for(chrono::milliseconds(20)); + } + return 0; +} + +/////////////////////////////////////////////////////////////////////////// +USBCB GScanO200::Get_Scanner_Status() +{ + if (!m_usb->is_connected()) + { + USBCB errorType = { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 }; + return errorType; + } + USBCB usbcb = { GET_DSP_STATUS ,0,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + m_usb->read_bulk(&usbcb, sizeof(usbcb)); + return usbcb; +} + +cv::Mat GScanO200::Get_Img_Data(int bufferSize) +{ + cv::Mat iData(1, bufferSize, CV_8UC1); + StopWatch sw; + sw.start(); + int readed = 0; + while (readed < bufferSize && sw.time_run() < 3000){ + USBCB usbcb = { GET_IMAGE,0,(UINT32)bufferSize }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); + readed = m_usb->read_bulk(iData.data, bufferSize); + } + + if (sw.time_run() > 3000) + return cv::Mat(); + + return iData; +} + +/////////////////////////////////////////////////////////////////////////// +void GScanO200::Pop_Image() +{ + if (!m_usb->is_open()) + { + return; + } + USBCB usbcb = { POP_IMAGE ,0,0 }; + m_usb->write_bulk(&usbcb, sizeof(usbcb)); +} diff --git a/GScanO200.h b/GScanO200.h new file mode 100644 index 0000000..a0a28a9 --- /dev/null +++ b/GScanO200.h @@ -0,0 +1,37 @@ +#pragma once +#include "gscn_drv.h" +#include + + +class GScanO200 : public IGScan, GScn_Drv +{ +public: + GScanO200(); + virtual ~GScanO200(); + // 通过 IGScan 继承 + virtual void open(int vid, int pid) override; + virtual int aquire_image(cv::Mat& image) override; + virtual BOOL IsConnected() override; + virtual std::string GetFWVersion() override; + virtual std::string GetSerialNum() override; + virtual bool is_scan() override; + virtual BOOL Get_Scanner_PaperOn() override; + virtual void config_params(SFreeImage& params) override; + virtual void Scanner_StartScan(UINT16 count) override; + virtual void Stop_scan() override; + virtual void ResetScanner() override; + virtual bool Get_IsImageQueueEmpty() override; + virtual void reset() override; + virtual void setdecodepixtype(int twpixtype) override; + virtual UINT32 get_ErrorCode() override; + virtual void Set_ErrorCode(UINT32 value) override; +private: + DWORD usbmain(); + USBCB Get_Scanner_Status(); + cv::Mat Get_Img_Data(int buffersize); + void Pop_Image(); + + std::shared_ptr m_usb; + std::unique_ptr m_threadUsb; +}; +