twain3/device/GScanO200.cpp

519 lines
11 KiB
C++
Raw Permalink Normal View History

#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 &params,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));
}