mirror of http://192.168.1.51:8099/lmh188/twain3
519 lines
11 KiB
C++
519 lines
11 KiB
C++
|
#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 <iostream>
|
|||
|
|
|||
|
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();//ֹͣɨ<D6B9><C9A8>
|
|||
|
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();//<2F><>ֹUI<55><49><EFBFBD><EFBFBD>
|
|||
|
#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();//ֹͣɨ<D6B9><C9A8>
|
|||
|
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();//<2F><>ֹUI<55><49><EFBFBD><EFBFBD>
|
|||
|
#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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::mutex> 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<std::vector<char>> 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<IDecode>(new G200Decode(imgData)));
|
|||
|
else
|
|||
|
m_pImages->pushMat(std::shared_ptr<IDecode>(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<std::vector<char>> GScanO200::Get_Img_Data(int bufferSize)
|
|||
|
{
|
|||
|
if (!(m_usb.get() && m_usb->is_connected()))
|
|||
|
return std::shared_ptr<std::vector<char>>(new std::vector<char>());
|
|||
|
|
|||
|
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(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); //<2F><><EFBFBD>ݽ<EFBFBD><DDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ڵ<EFBFBD><DAB5>ڹܵ<DAB9><DCB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʧ<EFBFBD><CAA7>
|
|||
|
}
|
|||
|
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));
|
|||
|
}
|