970 lines
23 KiB
C++
970 lines
23 KiB
C++
#include "predefine.h"
|
||
#include "GScanO200.h"
|
||
#ifdef WIN32
|
||
#include "UsbScanEx.h"
|
||
#else
|
||
#include "libusbex.h"
|
||
#endif
|
||
#include "StopWatch.h"
|
||
#include "ImageMatQueue.h"
|
||
#include "filetools.h"
|
||
#include "IConfig.h"
|
||
#include "scn_config.h"
|
||
#include <iostream>
|
||
#include "sane_common.h"
|
||
|
||
using namespace std;
|
||
|
||
GScanO200::GScanO200() : m_usrdata(0), m_usbreport(0)
|
||
{
|
||
m_serial = ScannerSerial::G200Serial;
|
||
}
|
||
|
||
GScanO200::~GScanO200()
|
||
{
|
||
if (m_threadUsb && m_threadUsb->joinable())
|
||
{
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
m_threadUsb.reset();
|
||
}
|
||
|
||
if(m_aquirethread.get()&&m_aquirethread->joinable())
|
||
{
|
||
m_aquirethread->join();
|
||
m_aquirethread.reset();
|
||
}
|
||
|
||
if(m_usb.get())
|
||
m_usb.reset();
|
||
std::cout<<"1"<<std::endl;
|
||
|
||
}
|
||
|
||
void GScanO200::setserial(ScannerSerial serial)
|
||
{
|
||
m_serial = serial;
|
||
m_pImages->Setserial(serial);
|
||
}
|
||
|
||
void GScanO200::open(int vid, int pid)
|
||
{
|
||
#ifdef WIN32
|
||
auto usbold = UsbScan_List::find_vid_pid(0x064b, 0x7823);
|
||
|
||
if (usbold.empty()) {
|
||
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
|
||
if (!usbs.empty())
|
||
{
|
||
m_usb = *usbs.begin();
|
||
m_usb->set_usbcallback(&GScanO200::on_usbcallback, this);
|
||
auto ret = m_usb->open();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
m_usb = *usbold.begin();
|
||
m_usb->set_usbcallback(&GScanO200::on_usbcallback, this);
|
||
auto ret = m_usb->open();
|
||
}
|
||
|
||
#else // WIN32
|
||
auto usbs = Libusb_List::find_vid_pid(vid, pid);
|
||
if (!usbs.empty())
|
||
{
|
||
if(!m_usb.get())
|
||
{
|
||
m_usb = *usbs.begin();
|
||
auto ret=m_usb->open();
|
||
if(!ret)
|
||
LOG("GScanO200 open usb failed\n");
|
||
m_usb->set_usbcallback(&GScanO200::on_usbcallback, this);
|
||
}
|
||
}
|
||
#endif
|
||
}
|
||
|
||
bool GScanO200::close()
|
||
{
|
||
if(m_usb.get()&&m_usb->is_open())
|
||
return m_usb->close();
|
||
return false;
|
||
}
|
||
|
||
bool GScanO200::is_open()
|
||
{
|
||
if(m_usb.get())
|
||
return m_usb->is_open();
|
||
return false;
|
||
}
|
||
|
||
void GScanO200::setusbreport_callback(usbreport_callback callback, void *usrdata)
|
||
{
|
||
m_usbreport = callback;
|
||
m_usrdata = usrdata;
|
||
}
|
||
void GScanO200::setonimage_callback(onimagecallback aqrcallback)
|
||
{
|
||
if (aqrcallback)
|
||
m_imagecallback = aqrcallback;
|
||
else
|
||
LOG("error on setonimage_callback ptr=%p \n", aqrcallback);
|
||
}
|
||
#ifdef LOG_NORMAL
|
||
fstream fsaquire;
|
||
static int aquiretimes = 1;
|
||
#endif // LOG
|
||
|
||
#ifdef TWAIN
|
||
int GScanO200::aquire_bmpdata(std::vector<unsigned char> &bmpdata)
|
||
{
|
||
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())
|
||
{
|
||
bmpdata = m_pImages->popBmpdata();
|
||
#ifdef LOG_NORMAL
|
||
static int aquireindex = 0;
|
||
FileTools::write_log("out.txt", "aquire image index " + std::to_string(++aquireindex));
|
||
#endif // LOG
|
||
return 0;
|
||
}
|
||
DoEvents(); //<2F><>ֹUI<55><49><EFBFBD><EFBFBD>
|
||
this_thread::sleep_for(chrono::milliseconds(1));
|
||
}
|
||
}
|
||
}
|
||
#else // TWAIN
|
||
|
||
int GScanO200::get_image_front_info(ImageInfo *info)
|
||
{
|
||
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())
|
||
{
|
||
*info = {0};
|
||
if (devState == DEV_WRONG)
|
||
{
|
||
return get_ErrorCode();
|
||
}
|
||
return -1;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
if (m_pImages->valid())
|
||
{
|
||
m_pImages->get_image_front_info(info);
|
||
cout << "get real image info" << endl;
|
||
#ifdef LOG_NORMAL
|
||
static int aquireindex = 0;
|
||
FileTools::write_log("out.txt", "aquire image index " + std::to_string(++aquireindex));
|
||
#endif // LOG
|
||
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(std::vector<uchar> &imgdata, int &bppinfo, int &width, int &height)
|
||
{
|
||
cv::Mat tmp;
|
||
int ret= aquire_image(tmp,bppinfo);
|
||
if(tmp.empty())
|
||
return ret;
|
||
width = tmp.cols;
|
||
height = tmp.rows;
|
||
if(tmp.channels()==3)
|
||
cv::cvtColor(tmp,tmp,cv::COLOR_BGR2RGB);
|
||
imgdata = tmp.reshape(1,tmp.cols*tmp.rows*tmp.channels());
|
||
return ret;
|
||
}
|
||
int GScanO200::aquire_image(cv::Mat &mat, int &bppinfo)
|
||
{
|
||
StopWatch sw;
|
||
while (true)
|
||
{
|
||
if (m_pImages->empty())
|
||
{
|
||
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));
|
||
}
|
||
|
||
if (sw.elapsed_s() > 25.00)
|
||
{
|
||
if (m_threadUsb && m_threadUsb->joinable())
|
||
{
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
m_threadUsb.reset();
|
||
}
|
||
Stop_scan(); //ֹͣɨ<D6B9><C9A8>
|
||
ResetScanner();
|
||
return HARDWARE_ERROR;
|
||
}
|
||
}
|
||
}
|
||
#endif
|
||
|
||
BOOL GScanO200::IsConnected()
|
||
{
|
||
return m_usb && m_usb->is_connected();
|
||
}
|
||
|
||
std::string GScanO200::GetFWVersion()
|
||
{
|
||
if (m_usb.get()&& m_usb->is_connected())
|
||
{
|
||
lock_guard<mutex> lock(m_imgLocker);
|
||
if (fwVersion.empty())
|
||
{
|
||
uint length=8;
|
||
fwVersion.resize(length);
|
||
USBCB cmd = {
|
||
GET_FW_VERSION,
|
||
length,
|
||
0,
|
||
};
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
m_usb->read_bulk(&fwVersion[0], length);
|
||
}
|
||
return fwVersion;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
std::string GScanO200::GetSerialNum()
|
||
{
|
||
if (m_usb->is_connected())
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
if (SerialNum.empty())
|
||
{
|
||
uint length=12;
|
||
SerialNum.resize(length);
|
||
USBCB usbcb = {GET_SERIAL, length, 0};
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
m_usb->read_bulk(&SerialNum[0], length);
|
||
}
|
||
return SerialNum;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
bool GScanO200::is_scan()
|
||
{
|
||
//std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
return devState == DEV_RUNNING;
|
||
}
|
||
|
||
BOOL GScanO200::Get_Scanner_PaperOn()
|
||
{
|
||
if (!m_usb.get()&&!m_usb->is_open())
|
||
return false;
|
||
USBCB usbcb = {GET_PAPERFEEDER_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)
|
||
{
|
||
params.resolution_native = 200;
|
||
if (m_usb.get()&&m_usb->is_connected())
|
||
{
|
||
cap=params;
|
||
hgConfigClass cfg = hgConfigClass(params);
|
||
UINT32 cfgdata = cfg.GetData();
|
||
USBCB usbcb = {CONFIGURED_DATA, cfgdata, 0};
|
||
m_usb->write_bulk(&usbcb, sizeof(USBCB));
|
||
m_pImages->setparam(params);
|
||
std::cout << "Config Params" << std::endl;
|
||
}
|
||
}
|
||
|
||
void GScanO200::SetSerialNum(std::string serial)
|
||
{
|
||
if (m_usb.get()&&m_usb->is_connected())
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
USBCB sercmd = { SEND_SERIAL ,0,12};
|
||
m_usb->write_bulk(&sercmd, sizeof(sercmd));
|
||
m_usb->write_bulk(&serial, serial.length());
|
||
}
|
||
}
|
||
|
||
|
||
bool GScanO200::Updata(std::string filename, std::function<void (long, long)> func)
|
||
{
|
||
std::ifstream updatefile;
|
||
updatefile.open(filename, std::ios_base::in | std::ios_base::binary);
|
||
if (!updatefile.is_open())
|
||
{
|
||
return false;
|
||
}
|
||
updatefile.seekg(0, std::ios::end);
|
||
size_t length = updatefile.tellg();
|
||
func(0, length);
|
||
updatefile.seekg(0, std::ios::beg);
|
||
USBCB pre_update = { PRE_UPGRADE,0,(uint32_t)length };
|
||
m_usb->write_bulk(&pre_update, sizeof(pre_update));
|
||
this_thread::sleep_for(chrono::milliseconds(200));
|
||
char* uotstream = new char[length];
|
||
updatefile.read(uotstream, length);
|
||
m_usb->write_bulk(uotstream, length);
|
||
delete[] uotstream;
|
||
USBCB updatefinished = { START_UPGRADE,0,0 };
|
||
m_usb->write_bulk(&updatefinished, sizeof(updatefinished));
|
||
func(length,length);
|
||
this_thread::sleep_for(chrono::seconds(8));
|
||
return true;
|
||
}
|
||
|
||
std::string GScanO200::GetMbVersion()
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
USBCB usbcb = { GET_MOTORFPGA_VERSION,0,4 };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
m_usb->read_bulk(&usbcb, sizeof(usbcb));
|
||
return std::to_string(usbcb.u32_Data);
|
||
}
|
||
return "";
|
||
}
|
||
|
||
std::string GScanO200::GetIpAddr()
|
||
{
|
||
return "no support";
|
||
}
|
||
std::string GScanO200::GetKernelVersion()
|
||
{
|
||
return "no support";
|
||
}
|
||
|
||
void GScanO200::SetRatio(int tyepe, int ration)
|
||
{
|
||
UsbKeyWords keyword = tyepe == 0 ? SET_JUST_COF_H : SET_JUST_COF_V;
|
||
USBCB cmd = { keyword ,(uint)ration,0};
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
}
|
||
|
||
void GScanO200::GetRatio(int type, int& ratio)
|
||
{
|
||
UsbKeyWords keyword = type == 0 ? GET_JUST_COF_H : GET_JUST_COF_V;
|
||
USBCB cmd = { keyword ,0,0 };
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
m_usb->read_bulk(&cmd, sizeof(cmd));
|
||
ratio = cmd.u32_Data;
|
||
}
|
||
|
||
void GScanO200::Reboot(){}
|
||
void GScanO200::PowerOff(){}
|
||
|
||
void GScanO200::SendFlatData(CorrectParam param, int index)
|
||
{
|
||
auto capparams= GetFlatData();
|
||
if(index>1)
|
||
{
|
||
USBCB cmd = { SEND_COMPONENTS_GR ,param.Exposures[0]+capparams.colorExposure[0]*65536,4 };
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
this_thread::sleep_for(chrono::milliseconds(1000));
|
||
cmd = {ADI_PARA,param.Gain[0]+param.Gain[6]*256+param.Offset[0]*65536+param.Offset[6]*65536*256,4};
|
||
m_usb->write_bulk(&cmd,sizeof(USBCB));
|
||
}
|
||
else
|
||
{
|
||
USBCB cmd = { SEND_COMPONENTS_GR ,param.Exposures[0]*65536+capparams.grayExposure[0],4 };
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
this_thread::sleep_for(chrono::milliseconds(1000));
|
||
cmd = { SEND_COMPONENTS_GB ,param.Exposures[2]*65536+param.Exposures[1],4 };
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
this_thread::sleep_for(chrono::milliseconds(1000));
|
||
cmd = {RGB_ADI_PARA,param.Gain[0]+param.Gain[6]*256+param.Offset[0]*65536+param.Offset[6]*65536*256,4};
|
||
m_usb->write_bulk(&cmd,sizeof(USBCB));
|
||
}
|
||
|
||
}
|
||
|
||
CaptureParams GScanO200::GetFlatData()
|
||
{
|
||
CaptureParams tmp{0};
|
||
USBCB usbcb={GET_CIS_PARA,0,0x10};
|
||
uchar data[16]{0};
|
||
m_usb->write_bulk(&usbcb,sizeof(USBCB));
|
||
this_thread::sleep_for(chrono::milliseconds(1000));
|
||
m_usb->read_bulk(data,16);
|
||
for(int i=0;i<6;i++)
|
||
tmp.correctGrayExposure[i]=tmp.grayExposure[i] =data[0]+data[1]*256;
|
||
tmp.correctColorExposure[0]=tmp.correctColorExposure[3]=tmp.colorExposure[0]=tmp.colorExposure[3]=data[2]+data[3]*256;
|
||
tmp.correctColorExposure[1]=tmp.correctColorExposure[4]=tmp.colorExposure[1]=tmp.colorExposure[4]=data[4]+data[5]*256;
|
||
tmp.correctColorExposure[2]=tmp.correctColorExposure[5]=tmp.colorExposure[2]=tmp.colorExposure[5]=data[6]+data[7]*256;
|
||
for(int i=0;i<6;i++)
|
||
tmp.colorGain[i] =tmp.correctColorGain[i] =data[8];
|
||
for(int i=0;i<6;i++)
|
||
tmp.colorGain[6+i] =tmp.correctColorGain[i+6] =data[9];
|
||
for(int i=0;i<6;i++)
|
||
tmp.colorOffset[i] =tmp.correctColorOffset[i] =data[10];
|
||
for(int i=0;i<6;i++)
|
||
tmp.colorOffset[6+i] =tmp.correctColorOffset[i+6] =data[11];
|
||
for(int i=0;i<6;i++)
|
||
tmp.grayGain[i] =tmp.correctGrayGain[i] =data[12];
|
||
for(int i=0;i<6;i++)
|
||
tmp.grayGain[6+i] =tmp.correctGrayGain[i+6] =data[13];
|
||
for(int i=0;i<6;i++)
|
||
tmp.grayOffset[i] =tmp.correctGrayOffset[i] =data[14];
|
||
for(int i=0;i<6;i++)
|
||
tmp.grayOffset[6+i] =tmp.correctGrayOffset[i+6] =data[15];
|
||
return tmp;
|
||
}
|
||
|
||
void GScanO200::Scanner_StartScan(int count)
|
||
{
|
||
is_flat =false;
|
||
std::cout<<"Scanner_StartScan "<<count<<std::endl;
|
||
if (m_usb.get()&&m_usb->is_connected())
|
||
{
|
||
if (m_threadUsb && m_threadUsb->joinable())
|
||
{
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
}
|
||
if (m_aquirethread.get() && m_aquirethread->joinable())
|
||
{
|
||
m_aquirethread->join();
|
||
}
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
devState = DEV_RUNNING;
|
||
m_pImages->setscanflags(true);
|
||
USBCB usbcb = {START_COMMAND, (UINT32)count, 0};
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
std::this_thread::sleep_for(std::chrono::milliseconds(500));
|
||
std::cout << "usb send scanner start scan command\n" << std::endl;
|
||
m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this));
|
||
m_pImages->run();
|
||
//m_aquirethread.reset(new std::thread(&GScanO200::aquirethreadfunc,this));
|
||
|
||
std::cout<<"scanner start"<<std::endl;
|
||
}
|
||
}
|
||
|
||
void GScanO200::Stop_scan()
|
||
{
|
||
if (!m_usb.get()&&!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.get()&&!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::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.get()&&!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.get()&&!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.get()&&!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.get()&&!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.get()&&!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.get()&&!m_usb->is_connected())
|
||
return -1;
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
USBCB usbcb = {0x40, 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::StartFlat(bool iscolor)
|
||
{
|
||
if (!m_usb.get()&&!m_usb->is_connected())
|
||
return ;
|
||
is_flat=true;
|
||
std::lock_guard<std::mutex> lck(m_imgLocker);
|
||
uint data =iscolor?0x60:0x40;
|
||
USBCB usbcb = {START_FLAT,data,0};
|
||
m_usb->write_bulk(&usbcb,sizeof(USBCB));
|
||
if (m_threadUsb&&m_threadUsb->joinable()) {
|
||
devState = DEV_STOP;
|
||
m_threadUsb->join();
|
||
}
|
||
devState = DEV_RUNNING;
|
||
m_threadUsb.reset(new std::thread(&GScanO200::usbmain, this));
|
||
}
|
||
|
||
void GScanO200::on_usbcallback(int conditioncode, void *usrdata)
|
||
{
|
||
GScanO200 *This = (GScanO200 *)usrdata;
|
||
This->onusbcallback(conditioncode);
|
||
}
|
||
|
||
void GScanO200::onusbcallback(int conditioncode)
|
||
{
|
||
std::cout<<"GScanO200::onusbcallback "<<conditioncode<<std::endl;
|
||
if (conditioncode!=0)
|
||
{
|
||
Error_Code = DEVICE_OFF_LINE;
|
||
devState = DEV_WRONG;
|
||
}
|
||
if (m_usbreport && m_usrdata)
|
||
{
|
||
m_usbreport(conditioncode, m_usrdata);
|
||
m_usb.reset();
|
||
}
|
||
}
|
||
|
||
void GScanO200::usbmain()
|
||
{
|
||
std::cout<<"scanner main run"<<std::endl;
|
||
std::shared_ptr<std::vector<char>> imgData;
|
||
devState = DEV_RUNNING;
|
||
bool haveError = false;
|
||
StopWatch sw;
|
||
while (devState == DEV_RUNNING)
|
||
{
|
||
if (!m_usb->is_connected())
|
||
{
|
||
this_thread::sleep_for(chrono::milliseconds(200));
|
||
continue;
|
||
}
|
||
if (sw.elapsed_ms() > 30000)
|
||
{
|
||
m_pImages->setscanflags(false);
|
||
//devState = haveError ? DevState::DEV_WRONG : DevState::DEV_STOP;
|
||
devState = DEV_WRONG;
|
||
Set_ErrorCode(HARDWARE_ERROR);
|
||
std::cout << "usb commnication error\n" << std::endl;
|
||
return;
|
||
}
|
||
USBCB usbcb = Get_Scanner_Status();
|
||
switch (usbcb.u32_Data)
|
||
{
|
||
case HAVE_IMAGE:
|
||
{
|
||
//while (m_pImages->orginimgcount()>4) {
|
||
// this_thread::sleep_for(chrono::milliseconds(20));
|
||
//}
|
||
int totalNum = usbcb.u32_Count;
|
||
m_usb->set_timeout((cap.paperSize==TwSS::MaxSize||cap.paperSize==TwSS::USStatement)?3000:1500);
|
||
imgData = Get_Img_Data(totalNum);
|
||
m_usb->set_timeout(200);
|
||
if (!imgData->size())
|
||
{
|
||
Stop_scan();
|
||
}
|
||
|
||
m_pImages->pushMat(std::shared_ptr<IDecode>(new G200Decode(imgData)));
|
||
static int rawdataindex = 0;
|
||
LOG("Enquque rawbuffer index =%d \n",++rawdataindex);
|
||
Pop_Image();
|
||
if(is_flat)
|
||
{
|
||
USBCB cmd={STOP_FLAT,0,0};
|
||
m_usb->write_bulk(&cmd,sizeof(USBCB));
|
||
m_pImages->setscanflags(false);
|
||
devState =DEV_STOP;
|
||
this_thread::sleep_for(chrono::milliseconds(3000));
|
||
m_flatcallback("У<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>",true);
|
||
break;
|
||
}
|
||
if((cap.paperSize==TwSS::MaxSize||cap.paperSize==TwSS::USStatement))
|
||
this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||
sw.reset();
|
||
break;
|
||
}
|
||
case STOP_SCAN:
|
||
m_pImages->setscanflags(false);
|
||
LOG("Stop Scan\n");
|
||
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:
|
||
if(!haveError)
|
||
{
|
||
haveError=true;
|
||
Set_ErrorCode(usbcb.u32_Data);
|
||
m_pImages->setscanflags(false);
|
||
devState = DEV_WRONG;
|
||
LOG("have error\n");
|
||
}
|
||
break;
|
||
case NORMAL:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
this_thread::sleep_for(chrono::milliseconds(10));
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
USBCB GScanO200::Get_Scanner_Status()
|
||
{
|
||
if (!m_usb.get()&&!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;
|
||
}
|
||
|
||
void GScanO200::aquirethreadfunc()
|
||
{
|
||
StopWatch sw;
|
||
while (true)
|
||
{
|
||
if (m_pImages->empty())
|
||
{
|
||
if (!is_scan())
|
||
{
|
||
if (devState == DEV_WRONG)
|
||
{
|
||
if (m_imagecallback)
|
||
m_imagecallback(nullptr, 0, get_ErrorCode());
|
||
}
|
||
else
|
||
{
|
||
if (m_imagecallback)
|
||
m_imagecallback(nullptr, 0, -1);
|
||
}
|
||
}
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
if (m_pImages->valid())
|
||
{
|
||
auto ret = m_pImages->popimage();
|
||
cv::Mat mat = ret.mat.clone();
|
||
int bppinfo = ret.Bpp;
|
||
sw.reset();
|
||
if (m_imagecallback)
|
||
m_imagecallback(&mat, bppinfo, 0);
|
||
}
|
||
this_thread::sleep_for(chrono::milliseconds(1));
|
||
continue;
|
||
}
|
||
|
||
// if (sw.elapsed_s() > 25.00)
|
||
// {
|
||
// if (m_threadUsb && m_threadUsb->joinable())
|
||
// {
|
||
// devState = DEV_STOP;
|
||
// m_threadUsb->join();
|
||
// m_threadUsb.reset();
|
||
// }
|
||
// Stop_scan(); //ֹͣɨ<D6B9><C9A8>
|
||
// ResetScanner();
|
||
// if (m_imagecallback)
|
||
// m_imagecallback(nullptr, 0, HARDWARE_ERROR);
|
||
// break;
|
||
// }
|
||
}
|
||
}
|
||
|
||
std::shared_ptr<std::vector<char>> GScanO200::Get_Img_Data(int bufferSize)
|
||
{
|
||
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(bufferSize));
|
||
if (!m_usb.get()&&!m_usb->is_connected())
|
||
return imData;
|
||
StopWatch sw;
|
||
int readed = 0;
|
||
while (readed < bufferSize && sw.elapsed_ms() < 3000)
|
||
{
|
||
USBCB usbcb = {GET_IMAGE, 0, (UINT32)bufferSize};
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
readed = m_usb->read_bulk(imData->data(), bufferSize);
|
||
LOG("read_bulk nread data length = %d\n",readed);
|
||
}
|
||
|
||
if (sw.elapsed_ms() > 3000)
|
||
{
|
||
LOG("read usb image data timeout\n");
|
||
}
|
||
|
||
return imData;
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
void GScanO200::Pop_Image()
|
||
{
|
||
if (!m_usb.get()&&!m_usb->is_open())
|
||
return;
|
||
|
||
USBCB usbcb = {POP_IMAGE, 0, 0};
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
}
|
||
void GScanO200::GetExpose(int& Aside, int& Bside)
|
||
{
|
||
|
||
}
|
||
void GScanO200::SetExpose(int aside, int bside)
|
||
{
|
||
|
||
}
|
||
|
||
void GScanO200::GetSptime(int type, int& time)
|
||
{
|
||
|
||
}
|
||
void GScanO200::SetSptime(int type, int time)
|
||
{
|
||
|
||
}
|
||
|
||
void GScanO200::GetSleepTime(int& sleeptime)
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
USBCB usb = { GET_SLEEP_TIME,0,0 };
|
||
m_usb->write_bulk(&usb, sizeof(usb));
|
||
m_usb->read_bulk(&usb, sizeof(usb));
|
||
switch (usb.u32_Data) {
|
||
case 0:
|
||
sleeptime= -1;
|
||
break;
|
||
case 1:
|
||
sleeptime = 300;
|
||
break;
|
||
case 2:
|
||
sleeptime =600;
|
||
break;
|
||
case 3:
|
||
sleeptime=1200;
|
||
break;
|
||
case 4:
|
||
sleeptime = 1800;
|
||
break;
|
||
case 5:
|
||
sleeptime =3600;
|
||
break;
|
||
case 6:
|
||
sleeptime =7200;
|
||
break;
|
||
case 7:
|
||
sleeptime = 14400;
|
||
break;
|
||
default:
|
||
sleeptime=0;
|
||
break;
|
||
}
|
||
}
|
||
}
|
||
void GScanO200::SetSleepTime(int sleeptime)
|
||
{
|
||
uint data;
|
||
if(sleeptime<0)
|
||
data=0;
|
||
else if(sleeptime>=0 && sleeptime <=300)
|
||
data=1;
|
||
else if(sleeptime >300 && sleeptime <=600)
|
||
data=2;
|
||
else if(sleeptime >600 && sleeptime <=1200)
|
||
data =3;
|
||
else if(sleeptime >1200 && sleeptime <=1800)
|
||
data=4;
|
||
else if(sleeptime >1800 && sleeptime <=3600)
|
||
data =5;
|
||
else if(sleeptime >3600 && sleeptime <=7200)
|
||
data=6;
|
||
else
|
||
data=7;
|
||
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
USBCB usb = { SET_SLEEP_TIME,data,0 };
|
||
m_usb->write_bulk(&usb, sizeof(usb));
|
||
}
|
||
}
|
||
|
||
void GScanO200::GetSpeedMode(int& speedmode, bool get)
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
USBCB speed = { get ? GET_SPEED_MODE:SET_SPEED_MODE,(uint)speedmode,4 };
|
||
m_usb->write_bulk(&speed, sizeof(speed));
|
||
if (get)
|
||
{
|
||
m_usb->read_bulk(&speed, sizeof(speed));
|
||
speedmode = speed.u32_Data;
|
||
}
|
||
}
|
||
}
|
||
void GScanO200::GetOrSetVIDPID(int& value, bool get)
|
||
{
|
||
|
||
}
|
||
|
||
std::string GScanO200::GetSysInfo()
|
||
{
|
||
return "no support";
|
||
}
|
||
|
||
void GScanO200::GetFlatMaxBright(bool iscolor, unsigned int& val)
|
||
{
|
||
}
|
||
|
||
void GScanO200::SetFlatMaxBright(bool iscolor, unsigned int val)
|
||
{
|
||
}
|