twain3/device/GScanO200.cpp

519 lines
11 KiB
C++
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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();//ֹͣɨÃè
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<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); //Êý¾Ý½ÓÊÕÁ¿±ØÐëСÓÚµÈÓڹܵÀÄÚÊý¾ÝÁ¿£¬·ñÔò»á½ÓÊÕʧ°Ü
}
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));
}