mirror of http://192.168.1.51:8099/lmh188/twain3.0
396 lines
8.5 KiB
C++
396 lines
8.5 KiB
C++
#include "stdafx.h"
|
||
#include "GScanO200.h"
|
||
#include "UsbScanEx.h"
|
||
#include "UsbScanEx.h"
|
||
#include "StopWatch.h"
|
||
#include "scn_config.h"
|
||
#include "ImageMatQueue.h"
|
||
#include "filetools.h"
|
||
|
||
//u32_CMD
|
||
typedef enum tagUsbKeyWords : UINT32
|
||
{
|
||
//无命令
|
||
NO_COMMAND = 0,
|
||
//获取dsp 状态
|
||
GET_DSP_STATUS = 1,
|
||
//取图
|
||
GET_IMAGE = 2,
|
||
//销毁DSP中驻存的图
|
||
POP_IMAGE = 3,
|
||
//开始扫描命令
|
||
START_COMMAND = 4,
|
||
//停止扫描命令
|
||
STOP = 5,
|
||
//获取扫描仪扫描模式
|
||
GET_SCAN_MODE = 6,
|
||
//获取固件版本号
|
||
GET_FW_VERSION = 7,
|
||
//返回PC端的状态
|
||
SEND_STATUS_PC = 8,
|
||
//下发扫描配置参数
|
||
CONFIGURED_DATA = 9,
|
||
//下发固件信息
|
||
SEND_FW = 10,
|
||
//获取扫描参数
|
||
GET_CONFIG_DATA = 11,
|
||
//获取扫描总张数
|
||
GET_SCANN_NUM = 12,
|
||
//获取有无纸的状态
|
||
GET_PAPERFEEDER_STATUS = 13,
|
||
//DSP初始化
|
||
INIT_HARDWARE_SYS = 14,
|
||
//获取有无纸的状态
|
||
GET_PAPER_STATUS = 0x0d,
|
||
//下发元器件配置参数(灰度,LED R曝光时间)
|
||
SEND_COMPONENTS_GR = 15,
|
||
//下发元器件配置参数(LED G/B曝光时间)
|
||
SEND_COMPONENTS_GB = 16,
|
||
//下发扫描模式
|
||
SEND_SCAN_MODE = 17,
|
||
//开始进行平场矫正
|
||
START_FLAT = 18,
|
||
//停止平场矫正
|
||
STOP_FLAT = 19,
|
||
//下发200dpi彩色平场矫正参数
|
||
SEND_200_COLOR_FLAT_DATA = 20,
|
||
//下发300dpi彩色平场矫正参数
|
||
SEND_300_COLOR_FLAT_DATA = 21,
|
||
//获取200dpi彩色平场矫正参数
|
||
GET_200_COLOR_FLAT_DATA = 22,
|
||
//获取300dpi彩色平场矫正参数
|
||
GET_300_COLOR_FLAT_DATA = 23,
|
||
//下发200dpi灰度平场校正参数
|
||
SEND_200_GRAY_FLAT_DATA = 24,
|
||
//下发300dpi灰度平场校正参数
|
||
SEND_300_GRAY_FLAT_DATA = 25,
|
||
//获取200DPI灰度平场校正参数
|
||
GET_200_GRAY_FLAT_DATA = 26,
|
||
//获取300DPI灰度平场校正参数
|
||
GET_300_GRAY_FLAT_DATA = 27,
|
||
//下发序列号命令
|
||
SEND_SERIAL = 28,
|
||
//获取序列号命令
|
||
GET_SERIAL = 29
|
||
} UsbKeyWords, * PUsbKeyWords;
|
||
|
||
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();
|
||
bool ret= m_usb->open();
|
||
if (ret) {
|
||
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
|
||
}
|
||
}
|
||
}
|
||
#ifdef LOG_NORMAL
|
||
fstream fsaquire;
|
||
static int aquiretimes = 1;
|
||
#endif // LOG
|
||
int GScanO200::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
|
||
{
|
||
StopWatch sw;
|
||
while (true)
|
||
{
|
||
if (m_pImages->empty()) {
|
||
DoEvents();
|
||
this_thread::sleep_for(chrono::milliseconds(1));
|
||
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()) {
|
||
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();
|
||
this_thread::sleep_for(chrono::milliseconds(2));
|
||
}
|
||
}
|
||
}
|
||
|
||
BOOL GScanO200::IsConnected()
|
||
{
|
||
return m_usb.get() && 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()) {
|
||
fwVersion = " ";
|
||
USBCB cmd= { GET_FW_VERSION,8,0,};
|
||
m_usb->write_bulk(&cmd, sizeof(cmd));
|
||
m_usb->read_bulk(&fwVersion[0], 8);
|
||
}
|
||
return fwVersion;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
std::string GScanO200::GetSerialNum()
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected())
|
||
{
|
||
std::lock_guard<mutex> 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<mutex> lck(m_imgLocker);
|
||
return devState == DEV_ISRUNNING;
|
||
}
|
||
|
||
BOOL GScanO200::Get_Scanner_PaperOn()
|
||
{
|
||
if (m_usb.get()&&!m_usb->is_open())
|
||
return false;
|
||
|
||
USBCB usbcb = { GET_PAPER_STATUS ,0,0 };
|
||
std::lock_guard<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)
|
||
{
|
||
if (m_usb.get()&&m_usb->is_connected()) {
|
||
IConfig cfg;
|
||
cfg = hgConfigClass(params);
|
||
UINT32 cfgdata = cfg.GetData();
|
||
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
|
||
m_usb->write_bulk(&usbcb, sizeof(USBCB));
|
||
m_pImages->setparam(params);
|
||
}
|
||
}
|
||
|
||
void GScanO200::Scanner_StartScan(UINT16 count)
|
||
{
|
||
if (m_usb.get() && m_usb->is_connected()) {
|
||
std::lock_guard<mutex> 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 thread(&GScanO200::usbmain, this));
|
||
m_pImages->run();
|
||
m_pImages->setscanflags(true);
|
||
}
|
||
}
|
||
|
||
void GScanO200::Stop_scan()
|
||
{
|
||
if (m_usb.get() && !m_usb->is_connected()) {
|
||
return;
|
||
}
|
||
std::lock_guard<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<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<mutex> lck(m_imgLocker);
|
||
USBCB usbcb = { GET_SCANN_NUM ,0,0 };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
return usbcb.u32_Count;
|
||
}
|
||
|
||
void GScanO200::usbhotplug_callback(bool isconnect, void* userdata)
|
||
{
|
||
GScanO200* This = (GScanO200*)userdata;
|
||
This->usbhotplug(isconnect);
|
||
}
|
||
|
||
void GScanO200::usbhotplug(bool isleft)
|
||
{
|
||
if (isleft) {
|
||
//devState = DEV_WRONG;
|
||
//Error_Code = USB_DISCONNECTED;
|
||
//m_pImages->setscanflags(false);
|
||
}
|
||
}
|
||
|
||
void GScanO200::usbmain()
|
||
{
|
||
std::shared_ptr<std::vector<char>> imgData;
|
||
devState = DEV_ISRUNNING;
|
||
while (devState == DEV_ISRUNNING) {
|
||
if (m_usb.get() && !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);
|
||
if (!imgData->size()) {
|
||
Stop_scan();
|
||
}
|
||
|
||
|
||
m_pImages->pushMat(std::shared_ptr<IDecode>(new G200Decode(imgData)));
|
||
#ifdef LOG_NORMAL
|
||
static int rawdataindex = 0;
|
||
FileTools::write_log("out.txt", "Enquque rawbuffer index " + std::to_string(++rawdataindex));
|
||
#endif // LOG
|
||
m_usb->set_timeout(200);
|
||
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.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;
|
||
}
|
||
|
||
std::shared_ptr<std::vector<char>> GScanO200::Get_Img_Data(int bufferSize)
|
||
{
|
||
std::shared_ptr<std::vector<char>> imData(new std::vector<char>(bufferSize));
|
||
StopWatch sw;
|
||
int readed = 0;
|
||
while (readed < bufferSize && sw.elapsed_ms() < 5000){
|
||
USBCB usbcb = { GET_IMAGE,0,(UINT32)bufferSize };
|
||
m_usb->write_bulk(&usbcb, sizeof(usbcb));
|
||
readed = m_usb->read_bulk(imData->data(), bufferSize);
|
||
}
|
||
|
||
if (sw.elapsed_ms() > 3000) {
|
||
writelog("Usb read data error\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));
|
||
}
|