mirror of http://192.168.1.51:8099/lmh188/twain3.0
添加RK3399扫描流程
This commit is contained in:
parent
cfe838b394
commit
7d0e35e591
|
@ -0,0 +1,462 @@
|
|||
//______________________________________________________________________________
|
||||
//
|
||||
// Copyright (c) Cypress Semiconductor, 2003
|
||||
// All rights reserved.
|
||||
//
|
||||
//______________________________________________________________________________
|
||||
|
||||
#ifndef CyUSBH
|
||||
#define CyUSBH
|
||||
|
||||
#ifndef __USB200_H__
|
||||
#define __USB200_H__
|
||||
#include <Windows.h>
|
||||
|
||||
#pragma pack(push,1) ///
|
||||
|
||||
typedef struct _USB_DEVICE_DESCRIPTOR { //设备描述符
|
||||
UCHAR bLength; //长度
|
||||
UCHAR bDescriptorType; //描述符类型
|
||||
USHORT bcdUSB; //USB
|
||||
UCHAR bDeviceClass; //设备类
|
||||
UCHAR bDeviceSubClass; //设备派生类
|
||||
UCHAR bDeviceProtocol; //设备协议
|
||||
UCHAR bMaxPacketSize0; //最大数据包尺寸
|
||||
USHORT idVendor; //厂商ID
|
||||
USHORT idProduct; //产品ID
|
||||
USHORT bcdDevice; //设备
|
||||
UCHAR iManufacturer; //制造商
|
||||
UCHAR iProduct; //产品
|
||||
UCHAR iSerialNumber; //序列号
|
||||
UCHAR bNumConfigurations;//配置
|
||||
} USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR;
|
||||
|
||||
typedef struct _USB_ENDPOINT_DESCRIPTOR { //端点描述符
|
||||
UCHAR bLength; //长度
|
||||
UCHAR bDescriptorType; //描述符类型
|
||||
UCHAR bEndpointAddress; //端点地址
|
||||
UCHAR bmAttributes; //端点属性
|
||||
USHORT wMaxPacketSize; //最大数据包尺寸
|
||||
UCHAR bInterval; //间隔
|
||||
} USB_ENDPOINT_DESCRIPTOR, *PUSB_ENDPOINT_DESCRIPTOR;
|
||||
|
||||
typedef struct _USB_CONFIGURATION_DESCRIPTOR { //配置描述符
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT wTotalLength;
|
||||
UCHAR bNumInterfaces;
|
||||
UCHAR bConfigurationValue;
|
||||
UCHAR iConfiguration;
|
||||
UCHAR bmAttributes;
|
||||
UCHAR MaxPower;
|
||||
} USB_CONFIGURATION_DESCRIPTOR, *PUSB_CONFIGURATION_DESCRIPTOR;
|
||||
|
||||
typedef struct _USB_INTERFACE_DESCRIPTOR { //接口描述符
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
UCHAR bInterfaceNumber;
|
||||
UCHAR bAlternateSetting;
|
||||
UCHAR bNumEndpoints;
|
||||
UCHAR bInterfaceClass;
|
||||
UCHAR bInterfaceSubClass;
|
||||
UCHAR bInterfaceProtocol;
|
||||
UCHAR iInterface;
|
||||
} USB_INTERFACE_DESCRIPTOR, *PUSB_INTERFACE_DESCRIPTOR;
|
||||
|
||||
typedef struct _USB_STRING_DESCRIPTOR { //字符串描述符
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
WCHAR bString[1];
|
||||
} USB_STRING_DESCRIPTOR, *PUSB_STRING_DESCRIPTOR;
|
||||
|
||||
typedef struct _USB_COMMON_DESCRIPTOR { //USB串口描述符
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
} USB_COMMON_DESCRIPTOR, *PUSB_COMMON_DESCRIPTOR;
|
||||
#pragma pack(pop)
|
||||
#endif
|
||||
//______________________________________________________________________________
|
||||
|
||||
class CCyIsoPktInfo { //包信息
|
||||
public:
|
||||
LONG Status; //包状态
|
||||
LONG Length; //包长度
|
||||
};
|
||||
|
||||
//______________________________________________________________________________
|
||||
|
||||
|
||||
// {AE18AA60-7F6A-11d4-97DD-00010229B959}
|
||||
static GUID CYUSBDRV_GUID = {0xae18aa60, 0x7f6a, 0x11d4, 0x97, 0xdd, 0x0, 0x1, 0x2, 0x29, 0xb9, 0x59};
|
||||
|
||||
typedef enum {TGT_DEVICE, TGT_INTFC, TGT_ENDPT, TGT_OTHER } CTL_XFER_TGT_TYPE;
|
||||
typedef enum {REQ_STD, REQ_CLASS, REQ_VENDOR } CTL_XFER_REQ_TYPE;
|
||||
typedef enum {DIR_TO_DEVICE, DIR_FROM_DEVICE } CTL_XFER_DIR_TYPE;
|
||||
typedef enum {XMODE_BUFFERED, XMODE_DIRECT } XFER_MODE_TYPE;
|
||||
|
||||
const int MAX_ENDPTS = 16;
|
||||
const int MAX_INTERFACES = 8;
|
||||
const int USB_STRING_MAXLEN = 256;
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The CCyEndPoint ABSTRACT Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CCyUSBEndPoint
|
||||
{
|
||||
protected:
|
||||
bool WaitForIO(OVERLAPPED *ovLapStatus);
|
||||
|
||||
virtual PUCHAR BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); //直接传输模式
|
||||
virtual PUCHAR BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov); //缓冲传输模式
|
||||
|
||||
|
||||
public:
|
||||
|
||||
CCyUSBEndPoint(void);
|
||||
CCyUSBEndPoint(CCyUSBEndPoint& ept);
|
||||
CCyUSBEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor);
|
||||
|
||||
HANDLE hDevice;
|
||||
|
||||
// The fields of an EndPoint Descriptor
|
||||
UCHAR DscLen;
|
||||
UCHAR DscType;
|
||||
UCHAR Address;
|
||||
UCHAR Attributes;
|
||||
USHORT MaxPktSize;
|
||||
USHORT PktsPerFrame;
|
||||
UCHAR Interval;
|
||||
|
||||
// Other fields
|
||||
ULONG TimeOut;
|
||||
ULONG UsbdStatus;
|
||||
ULONG NtStatus;
|
||||
|
||||
DWORD bytesWritten;
|
||||
DWORD LastError;
|
||||
bool bIn;
|
||||
|
||||
XFER_MODE_TYPE XferMode;
|
||||
|
||||
bool XferData(PUCHAR buf, LONG &len, CCyIsoPktInfo* pktInfos = NULL);
|
||||
bool XferData(PUCHAR buf, LONG &bufLen, CCyIsoPktInfo* pktInfos, bool pktMode);
|
||||
virtual PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov) = 0;
|
||||
virtual bool FinishDataXfer(PUCHAR buf, LONG &len, OVERLAPPED *ov, PUCHAR pXmitBuf, CCyIsoPktInfo* pktInfos = NULL);
|
||||
bool WaitForXfer(OVERLAPPED *ov, ULONG tOut);
|
||||
ULONG GetXferSize(void);
|
||||
void SetXferSize(ULONG xfer);
|
||||
|
||||
bool Reset(void);
|
||||
bool Abort(void);
|
||||
|
||||
private:
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Control Endpoint Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CCyControlEndPoint : public CCyUSBEndPoint
|
||||
{
|
||||
private:
|
||||
|
||||
public:
|
||||
CCyControlEndPoint(void);
|
||||
CCyControlEndPoint(CCyControlEndPoint& ept);
|
||||
CCyControlEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor);
|
||||
|
||||
CTL_XFER_TGT_TYPE Target;
|
||||
CTL_XFER_REQ_TYPE ReqType;
|
||||
CTL_XFER_DIR_TYPE Direction;
|
||||
|
||||
UCHAR ReqCode;
|
||||
WORD Value;
|
||||
WORD Index;
|
||||
|
||||
bool Read(PUCHAR buf, LONG &len);
|
||||
bool Write(PUCHAR buf, LONG &len);
|
||||
PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Isoc Endpoint Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CCyIsocEndPoint : public CCyUSBEndPoint
|
||||
{
|
||||
|
||||
protected:
|
||||
virtual PUCHAR BeginDirectXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov);
|
||||
virtual PUCHAR BeginBufferedXfer(PUCHAR buf, LONG bufLen, OVERLAPPED *ov);
|
||||
|
||||
public:
|
||||
CCyIsocEndPoint(void);
|
||||
CCyIsocEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor);
|
||||
|
||||
PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);
|
||||
CCyIsoPktInfo* CreatePktInfos(LONG bufLen, int &packets);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Bulk Endpoint Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CCyBulkEndPoint : public CCyUSBEndPoint
|
||||
{
|
||||
public:
|
||||
CCyBulkEndPoint(void);
|
||||
CCyBulkEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor);
|
||||
|
||||
PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Interrupt Endpoint Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
class CCyInterruptEndPoint : public CCyUSBEndPoint
|
||||
{
|
||||
public:
|
||||
CCyInterruptEndPoint(void);
|
||||
CCyInterruptEndPoint(HANDLE h, PUSB_ENDPOINT_DESCRIPTOR pEndPtDescriptor);
|
||||
|
||||
PUCHAR BeginDataXfer(PUCHAR buf, LONG len, OVERLAPPED *ov);
|
||||
};
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Interface Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CCyUSBInterface
|
||||
{
|
||||
private:
|
||||
protected:
|
||||
public:
|
||||
CCyUSBEndPoint *EndPoints[MAX_ENDPTS]; // Holds pointers to all the interface's endpoints, plus a pointer to the Control endpoint zero
|
||||
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
UCHAR bInterfaceNumber;
|
||||
UCHAR bAlternateSetting;
|
||||
UCHAR bNumEndpoints; // Not counting the control endpoint
|
||||
UCHAR bInterfaceClass;
|
||||
UCHAR bInterfaceSubClass;
|
||||
UCHAR bInterfaceProtocol;
|
||||
UCHAR iInterface;
|
||||
|
||||
UCHAR bAltSettings;
|
||||
USHORT wTotalLength; // Needed in case Intfc has additional (non-endpt) descriptors
|
||||
|
||||
|
||||
CCyUSBInterface(HANDLE h, PUSB_INTERFACE_DESCRIPTOR pIntfcDescriptor);
|
||||
CCyUSBInterface(CCyUSBInterface& ifc); // Copy Constructor
|
||||
~CCyUSBInterface(void);
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The Config Class
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CCyUSBConfig
|
||||
{
|
||||
private:
|
||||
|
||||
protected:
|
||||
public:
|
||||
CCyUSBInterface *Interfaces[MAX_INTERFACES];
|
||||
|
||||
UCHAR bLength;
|
||||
UCHAR bDescriptorType;
|
||||
USHORT wTotalLength;
|
||||
UCHAR bNumInterfaces;
|
||||
UCHAR bConfigurationValue;
|
||||
UCHAR iConfiguration;
|
||||
UCHAR bmAttributes;
|
||||
UCHAR MaxPower;
|
||||
|
||||
UCHAR AltInterfaces;
|
||||
|
||||
|
||||
CCyUSBConfig(void);
|
||||
CCyUSBConfig(CCyUSBConfig& cfg); // Copy Constructor
|
||||
CCyUSBConfig(HANDLE h, PUSB_CONFIGURATION_DESCRIPTOR pConfigDescr);
|
||||
~CCyUSBConfig(void);
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// The USB Device Class - This is the main class that contains members of all the
|
||||
// other classes.
|
||||
//
|
||||
// To use the library, create an instance of this Class and call it's Open method
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class CCyUSBDevice
|
||||
{
|
||||
// The public members are accessible (i.e. corruptible) by the user of the library
|
||||
// Algorithms of the class don't rely on any public members. Instead, they use the
|
||||
// private members of the class for their calculations.
|
||||
|
||||
public:
|
||||
|
||||
CCyUSBDevice(HANDLE hnd = NULL, GUID guid = CYUSBDRV_GUID, BOOL bOpen = true);
|
||||
~CCyUSBDevice(void);
|
||||
|
||||
CCyUSBEndPoint **EndPoints; // Shortcut to USBCfgs[CfgNum]->Interfaces[IntfcIndex]->Endpoints
|
||||
CCyUSBEndPoint *EndPointOf(UCHAR addr);
|
||||
|
||||
CCyControlEndPoint *ControlEndPt;
|
||||
CCyIsocEndPoint *IsocInEndPt;
|
||||
CCyIsocEndPoint *IsocOutEndPt;
|
||||
CCyBulkEndPoint *BulkInEndPt;
|
||||
CCyBulkEndPoint *BulkOutEndPt;
|
||||
CCyInterruptEndPoint *InterruptInEndPt;
|
||||
CCyInterruptEndPoint *InterruptOutEndPt;
|
||||
|
||||
USHORT StrLangID;
|
||||
ULONG UsbdStatus;
|
||||
ULONG NtStatus;
|
||||
ULONG DriverVersion;
|
||||
ULONG USBDIVersion;
|
||||
char DeviceName[USB_STRING_MAXLEN];
|
||||
char FriendlyName[USB_STRING_MAXLEN];
|
||||
wchar_t Manufacturer[USB_STRING_MAXLEN];
|
||||
wchar_t Product[USB_STRING_MAXLEN];
|
||||
wchar_t SerialNumber[USB_STRING_MAXLEN];
|
||||
|
||||
CHAR DevPath[USB_STRING_MAXLEN];
|
||||
|
||||
USHORT BcdUSB;
|
||||
USHORT VendorID;
|
||||
USHORT ProductID;
|
||||
UCHAR USBAddress;
|
||||
UCHAR DevClass;
|
||||
UCHAR DevSubClass;
|
||||
UCHAR DevProtocol;
|
||||
UCHAR MaxPacketSize;
|
||||
USHORT BcdDevice;
|
||||
|
||||
UCHAR ConfigValue;
|
||||
UCHAR ConfigAttrib;
|
||||
UCHAR MaxPower;
|
||||
|
||||
UCHAR IntfcClass;
|
||||
UCHAR IntfcSubClass;
|
||||
UCHAR IntfcProtocol;
|
||||
bool bHighSpeed;
|
||||
|
||||
DWORD BytesXfered;
|
||||
|
||||
|
||||
UCHAR DeviceCount(void);
|
||||
UCHAR ConfigCount(void);
|
||||
UCHAR IntfcCount(void);
|
||||
UCHAR AltIntfcCount(void);
|
||||
UCHAR EndPointCount(void);
|
||||
|
||||
UCHAR Config(void) { return CfgNum; } // Normally 0
|
||||
void SetConfig(UCHAR cfg);
|
||||
|
||||
UCHAR Interface(void) { return IntfcNum; } // Usually 0
|
||||
// No SetInterface method since only 1 intfc per device (per Windows)
|
||||
|
||||
UCHAR AltIntfc(void);
|
||||
bool SetAltIntfc(UCHAR alt);
|
||||
|
||||
GUID DriverGUID(void) { return DrvGuid; }
|
||||
HANDLE DeviceHandle(void) { return hDevice; }
|
||||
void UsbdStatusString(ULONG stat, PCHAR s);
|
||||
bool CreateHandle(UCHAR dev);
|
||||
void DestroyHandle();
|
||||
|
||||
bool Open(UCHAR dev);
|
||||
void Close(void);
|
||||
bool Reset(void);
|
||||
bool ReConnect(void);
|
||||
bool Suspend(void);
|
||||
bool Resume(void);
|
||||
bool IsOpen(void) { return (hDevice != INVALID_HANDLE_VALUE); }
|
||||
|
||||
UCHAR PowerState(void);
|
||||
|
||||
|
||||
void GetDeviceDescriptor(PUSB_DEVICE_DESCRIPTOR descr);
|
||||
void GetConfigDescriptor(PUSB_CONFIGURATION_DESCRIPTOR descr);
|
||||
void GetIntfcDescriptor(PUSB_INTERFACE_DESCRIPTOR descr);
|
||||
CCyUSBConfig GetUSBConfig(int index);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
USB_DEVICE_DESCRIPTOR USBDeviceDescriptor;
|
||||
PUSB_CONFIGURATION_DESCRIPTOR USBConfigDescriptors[2];
|
||||
|
||||
CCyUSBConfig *USBCfgs[2];
|
||||
|
||||
HANDLE hWnd;
|
||||
HANDLE hDevice;
|
||||
HANDLE hDevNotification;
|
||||
HANDLE hHndNotification;
|
||||
|
||||
GUID DrvGuid;
|
||||
|
||||
UCHAR Devices;
|
||||
UCHAR Interfaces;
|
||||
UCHAR AltInterfaces;
|
||||
UCHAR Configs;
|
||||
|
||||
UCHAR DevNum;
|
||||
UCHAR CfgNum;
|
||||
UCHAR IntfcNum; // The current selected interface's bInterfaceNumber
|
||||
UCHAR IntfcIndex; // The entry in the Config's interfaces table matching to IntfcNum and AltSetting
|
||||
|
||||
void GetDevDescriptor(void);
|
||||
void GetCfgDescriptor(int descIndex);
|
||||
void GetString(wchar_t *s, UCHAR sIndex);
|
||||
void SetStringDescrLanguage(void);
|
||||
void SetAltIntfcParams(UCHAR alt);
|
||||
bool IoControl(ULONG cmd, PUCHAR buf, ULONG len);
|
||||
|
||||
void SetEndPointPtrs(void);
|
||||
void GetDeviceName(void);
|
||||
void GetFriendlyName(void);
|
||||
void GetDriverVer(void);
|
||||
void GetUSBDIVer(void);
|
||||
void GetSpeed(void);
|
||||
void GetUSBAddress(void);
|
||||
//void CloseEndPtHandles(void);
|
||||
|
||||
bool RegisterForPnpEvents(HANDLE h);
|
||||
};
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
#endif
|
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,128 @@
|
|||
#include "CyUsbEx.h"
|
||||
#include "CyAPI.h"
|
||||
|
||||
CyUsbEx::CyUsbEx(int index)
|
||||
{
|
||||
m_index = index;
|
||||
m_timeout = 100;
|
||||
}
|
||||
|
||||
bool CyUsbEx::open()
|
||||
{
|
||||
if (is_open())
|
||||
return true;
|
||||
|
||||
m_usb.reset(new CCyUSBDevice());
|
||||
m_usb->Open(m_index);
|
||||
m_usb->Reset();
|
||||
if (m_usb->IsOpen())
|
||||
{
|
||||
if (m_usb->BulkOutEndPt)
|
||||
m_usb->BulkOutEndPt->TimeOut = m_timeout;
|
||||
|
||||
if (m_usb->BulkInEndPt)
|
||||
m_usb->BulkInEndPt->TimeOut = m_timeout;
|
||||
|
||||
if (m_usb->InterruptInEndPt)
|
||||
m_usb->InterruptInEndPt->TimeOut = 400;
|
||||
}
|
||||
|
||||
return is_open();
|
||||
}
|
||||
|
||||
bool CyUsbEx::close()
|
||||
{
|
||||
if (is_open())
|
||||
{
|
||||
m_usb->Close();
|
||||
m_usb.reset();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool CyUsbEx::is_open()
|
||||
{
|
||||
if (m_usb.get() != NULL)
|
||||
return m_usb->IsOpen();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CyUsbEx::is_connected()
|
||||
{
|
||||
return is_open();
|
||||
}
|
||||
|
||||
void CyUsbEx::set_timeout(int timeout)
|
||||
{
|
||||
m_timeout = timeout;
|
||||
}
|
||||
|
||||
int CyUsbEx::read_bulk(void* data, int len)
|
||||
{
|
||||
LONG llen = len;
|
||||
m_usb->BulkInEndPt->XferData((UCHAR*)data, llen);
|
||||
return llen;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int CyUsbEx::write_bulk(void* data, int len)
|
||||
{
|
||||
LONG llen = len;
|
||||
m_usb->BulkOutEndPt->XferData((UCHAR*)data, llen);
|
||||
return llen;
|
||||
}
|
||||
|
||||
int CyUsbEx::read_int(void* data, int len)
|
||||
{
|
||||
LONG llen = len;
|
||||
m_usb->InterruptInEndPt->XferData((UCHAR*)data, llen);
|
||||
return llen;
|
||||
}
|
||||
|
||||
int CyUsbEx::control_msg(int rtype, int req, int value, int index, int len, void* data)
|
||||
{
|
||||
if (!m_usb.get() || !m_usb->ControlEndPt)
|
||||
return -1;
|
||||
|
||||
m_usb->ControlEndPt->Index = index;
|
||||
m_usb->ControlEndPt->Value = value;
|
||||
m_usb->ControlEndPt->ReqType = (CTL_XFER_REQ_TYPE)((rtype >> 5) & 0x03);
|
||||
m_usb->ControlEndPt->Direction = (CTL_XFER_DIR_TYPE)(rtype >> 7);//
|
||||
m_usb->ControlEndPt->Target = (CTL_XFER_TGT_TYPE)(rtype & 0x3);
|
||||
m_usb->ControlEndPt->ReqCode = req;
|
||||
LONG llen = len;
|
||||
m_usb->ControlEndPt->XferData((UCHAR*)data, llen);
|
||||
return llen;
|
||||
}
|
||||
|
||||
void CyUsbEx::set_usbhotplug_callback(usbhotplug_callback callback, void* userdata)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<IUsb>> CyUsbList::find_all()
|
||||
{
|
||||
std::list<std::shared_ptr<IUsb>> usblists;
|
||||
CCyUSBDevice usbDevice;
|
||||
for (int i = 0; i < usbDevice.DeviceCount(); i++)
|
||||
usblists.push_back(std::shared_ptr<IUsb>(new CyUsbEx(i)));
|
||||
return usblists;
|
||||
}
|
||||
|
||||
std::list<std::shared_ptr<IUsb>> CyUsbList::find_vid_pid(int vid, int pid)
|
||||
{
|
||||
std::list<std::shared_ptr<IUsb>> usblists;
|
||||
CCyUSBDevice usbDevice;
|
||||
for (int i = 0; i < usbDevice.DeviceCount(); i++) {
|
||||
usbDevice.Open(i);
|
||||
if (usbDevice.IsOpen() && (usbDevice.VendorID == vid) && (usbDevice.ProductID == pid)) {
|
||||
usblists.push_back(std::shared_ptr<IUsb>(new CyUsbEx(i)));
|
||||
usbDevice.Close();
|
||||
}
|
||||
}
|
||||
return usblists;
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
#pragma once
|
||||
#include "IUsb.h"
|
||||
#include <memory>
|
||||
#include <list>
|
||||
|
||||
|
||||
|
||||
class CCyUSBDevice;
|
||||
|
||||
class CyUsbList {
|
||||
public:
|
||||
static std::list<std::shared_ptr<IUsb>> find_all();
|
||||
static std::list<std::shared_ptr<IUsb>> find_vid_pid(int vid, int pid);
|
||||
};
|
||||
|
||||
class CyUsbEx :
|
||||
public IUsb
|
||||
{
|
||||
public:
|
||||
CyUsbEx(int index);
|
||||
// ͨ¹ý IUsb ¼Ì³Ð
|
||||
virtual bool open() override;
|
||||
virtual bool close() override;
|
||||
virtual bool is_open() override;
|
||||
virtual bool is_connected() override;
|
||||
virtual void set_timeout(int timeout) override;
|
||||
virtual int read_bulk(void* data, int len) override;
|
||||
virtual int write_bulk(void* data, int len) override;
|
||||
virtual int read_int(void* data, int len) override;
|
||||
virtual int control_msg(int rtype, int req, int value, int index, int len, void* data) override;
|
||||
virtual void set_usbhotplug_callback(usbhotplug_callback callback = NULL, void* userdata = NULL) override;
|
||||
|
||||
private:
|
||||
std::shared_ptr<CCyUSBDevice> m_usb;
|
||||
int m_index;
|
||||
int m_timeout;
|
||||
};
|
|
@ -72,15 +72,19 @@ typedef enum tagUsbSupported {
|
|||
// PC繁忙或出错
|
||||
PC_SCAN_BUSY_or_ERROR = 73,
|
||||
//摺角
|
||||
DOG_EAR=74,
|
||||
DOG_EAR = 74,
|
||||
//幅面检测错误
|
||||
SIZE_ERROR=75,
|
||||
SIZE_ERROR = 75,
|
||||
//取图超时
|
||||
AQUIRE_IMAGE_TIMEOUT=76,
|
||||
AQUIRE_IMAGE_TIMEOUT = 76,
|
||||
//获取图片与扫描张数不匹配
|
||||
LOSE_IMAGE=77,
|
||||
LOSE_IMAGE = 77,
|
||||
//usb读取数据错误
|
||||
USB_BULK_ERROR=78,
|
||||
USB_BULK_ERROR = 78,
|
||||
//v4l2取图失败
|
||||
V4L2_AQULRE_ERROR = 79,
|
||||
//扫描仪内部图片丢失
|
||||
V4L2_IMAGE_EMPTY = 80,
|
||||
//USB 未连接
|
||||
USB_DISCONNECTED = 200,
|
||||
//用户点击停止
|
||||
|
@ -109,7 +113,9 @@ static map<UsbSupported, string> msgs = {
|
|||
{UsbSupported::SIZE_ERROR,"幅面检测异常!"},
|
||||
{UsbSupported::AQUIRE_IMAGE_TIMEOUT,"取图超时!"},
|
||||
{UsbSupported::LOSE_IMAGE,"上传图片与扫描张数不匹配!"},
|
||||
{UsbSupported::USB_BULK_ERROR,"USB数据读取错误!"}
|
||||
{UsbSupported::USB_BULK_ERROR,"USB数据读取错误!"},
|
||||
{UsbSupported::V4L2_AQULRE_ERROR,"扫描仪取图失败!"},
|
||||
{UsbSupported::V4L2_IMAGE_EMPTY,"扫描仪图像处理异常!"},
|
||||
};
|
||||
|
||||
enum tagEventIndex
|
||||
|
|
|
@ -0,0 +1,652 @@
|
|||
#include "GScanO1003399.h"
|
||||
#include "ImageProcess/ImageApplyHeaders.h"
|
||||
#include "ImageMultiOutput.h"
|
||||
#include "scn_config.h"
|
||||
#include "PaperSize.h"
|
||||
#include "GScan.h"
|
||||
|
||||
static std::mutex mx_ctrl;
|
||||
|
||||
static int scanner_read_reg(std::shared_ptr<IUsb>& usb, int addr)
|
||||
{
|
||||
int val = 0;
|
||||
std::lock_guard<std::mutex> lck(mx_ctrl);
|
||||
usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static void scanner_write_reg(std::shared_ptr<IUsb>& usb, int addr, int val)
|
||||
{
|
||||
std::lock_guard<std::mutex> lck(mx_ctrl);
|
||||
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val);
|
||||
}
|
||||
|
||||
static void scanner_cmd(std::shared_ptr<IUsb>& usb, int cmd)
|
||||
{
|
||||
scanner_write_reg(usb, 0, cmd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
GScanO1003399::GScanO1003399():
|
||||
m_imgthread(1)
|
||||
{
|
||||
im_data.reset(new std::vector<char>());
|
||||
open(0, 0);
|
||||
|
||||
devState = DEV_STOP;
|
||||
}
|
||||
|
||||
GScanO1003399::~GScanO1003399()
|
||||
{
|
||||
if (m_usbthread.get() && m_usbthread->joinable())
|
||||
{
|
||||
b_usbthread = false;
|
||||
m_usbthread->join();
|
||||
m_usbthread.reset();
|
||||
}
|
||||
if (fu_rx.valid())
|
||||
fu_rx.wait();
|
||||
}
|
||||
|
||||
void GScanO1003399::open(int vid, int pid)
|
||||
{
|
||||
//auto lsusb=CyUsbList::find_vid_pid(vid, pid);
|
||||
//if (!lsusb.empty())
|
||||
//{
|
||||
// m_usb = *lsusb.begin();
|
||||
// m_usb->open();
|
||||
//}
|
||||
if (m_usb.get()&&m_usb->is_connected())
|
||||
return;
|
||||
auto lsusb = CyUsbList::find_all();
|
||||
if (!lsusb.empty())
|
||||
{
|
||||
m_usb = *lsusb.begin();
|
||||
m_usb->open();
|
||||
}
|
||||
}
|
||||
|
||||
void GScanO1003399::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
|
||||
{
|
||||
}
|
||||
|
||||
void GScanO1003399::DogEar_callback(std::function<void(int)> fun)
|
||||
{
|
||||
}
|
||||
static int aquirenum = 0;
|
||||
static int getimgnum = 0;
|
||||
int GScanO1003399::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
|
||||
{
|
||||
StopWatch sw;
|
||||
while (true)
|
||||
{
|
||||
if ((m_imagedata.Size() < 1)&&(!is_runing()))
|
||||
{
|
||||
DoEvents();
|
||||
this_thread::sleep_for(chrono::milliseconds(1));
|
||||
if (!is_runing())
|
||||
{
|
||||
if (devState == DEV_WRONG)
|
||||
return get_ErrorCode();
|
||||
return -1;
|
||||
}
|
||||
if (sw.elapsed_s() > 30.0)
|
||||
{
|
||||
devState = DEV_STOP;
|
||||
if (fu_rx.valid())
|
||||
fu_rx.wait();
|
||||
Stop_scan();
|
||||
ResetScanner();
|
||||
return AQUIRE_IMAGE_TIMEOUT;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((m_imagedata.Size() > 0))
|
||||
{
|
||||
FileTools::writelog(log_INFO, "aquire_bmpdata num =" + to_string(aquirenum++));
|
||||
bmpdata = *(m_imagedata.Take());
|
||||
UpdateScanInfo(get_imgnReaded(), countNTransfered());
|
||||
return 0;
|
||||
}
|
||||
DoEvents();
|
||||
this_thread::sleep_for(chrono::milliseconds(2));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
BOOL GScanO1003399::IsConnected()
|
||||
{
|
||||
return m_usb.get()&&m_usb->is_connected();
|
||||
}
|
||||
|
||||
std::string GScanO1003399::GetFWVersion()
|
||||
{
|
||||
std::string fw;
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_GET_FWVERSION, 0);
|
||||
fw.resize(10);
|
||||
read_data(&fw[0], fw.length(), 200);
|
||||
}
|
||||
return fw;
|
||||
}
|
||||
|
||||
std::string GScanO1003399::GetSerialNum()
|
||||
{
|
||||
std::string sn;
|
||||
if (m_usb.get() && m_usb->is_connected())
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_GET_SERIALNUM, 0);
|
||||
sn.resize(14);
|
||||
read_data(&sn[0], sn.length(), 200);
|
||||
}
|
||||
return sn;
|
||||
}
|
||||
|
||||
std::uint32_t GScanO1003399::GetMotorFPGA()
|
||||
{
|
||||
return std::uint32_t();
|
||||
}
|
||||
|
||||
std::uint32_t GScanO1003399::GetScanFPGA()
|
||||
{
|
||||
return std::uint32_t();
|
||||
}
|
||||
|
||||
bool GScanO1003399::is_scan()
|
||||
{
|
||||
//return devState==DEV_ISRUNNING;
|
||||
return is_runing() || (m_imagedata.Size() > 0);
|
||||
}
|
||||
|
||||
BOOL GScanO1003399::Get_Scanner_PaperOn()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_PAPER_READY);
|
||||
}
|
||||
|
||||
int GScanO1003399::Get_Roller_num()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GScanO1003399::config_params(GScanCap& param)
|
||||
{
|
||||
m_param = param;
|
||||
HGScanConfig cfg;
|
||||
cfg = { 0 };
|
||||
#ifdef G200
|
||||
|
||||
PaperStatus ps = { param.papertype,param.paperAlign };
|
||||
cfg.g200params.paper = SupPaperTyps.count(ps)>0 ? SupPaperTyps[ps] : 0;
|
||||
if (param.filter != 3 || param.enhance_color != 0 || param.hsvcorrect)
|
||||
cfg.g200params.color = 1;//color
|
||||
else
|
||||
{
|
||||
cfg.g200params.color = SupPixelTypes.count(param.pixtype) > 0 ? SupPixelTypes[param.pixtype] : 2;
|
||||
|
||||
}
|
||||
cfg.g200params.dpi = SupResolutions.count(param.resolution_native)>0 ? SupResolutions[param.resolution_native] : 1;
|
||||
cfg.g200params.double_feed_enbale = (unsigned int)param.hardwarecaps.en_doublefeed;
|
||||
cfg.g200params.stable_enbale = (unsigned int)param.hardwarecaps.en_stapledetect;
|
||||
cfg.g200params.screw_detect_enable = (unsigned int)param.hardwarecaps.en_skrewdetect;
|
||||
cfg.g200params.screw_detect_level = (unsigned int)cfg.g200params.screw_detect_enable ? secrewMaps[param.hardwarecaps.skrewdetectlevel] : 0;
|
||||
|
||||
cfg.g200params.enable_sizecheck = param.en_sizecheck == 1 ? 1 : 0;
|
||||
cfg.g200params.unused_one = cfg.g200params.sizeerror_errorratio = 0;
|
||||
param.resolution_dst >= 240.0f ? 1 : 0;
|
||||
|
||||
#else
|
||||
|
||||
cfg.g400params.doubleFeeded = param.hardwarecaps.en_doublefeed == 0 ? 0 : 1;
|
||||
cfg.g400params.dpi = G400_DPI::G400_D200;//gcap.resolution_dst <= 200.0f ? G400_DPI::G400_D200 : (gcap.resolution_dst <= 300.0f ? G400_DPI::G400_D300 : G400_DPI::G400_D600);
|
||||
cfg.g400params.enableLed = 1;
|
||||
if (param.filter != 3 || param.enhance_color)
|
||||
cfg.g400params.isColor = 1;
|
||||
else
|
||||
cfg.g400params.isColor = SupPixelTypes[param.pixtype];
|
||||
cfg.g400params.enableStable = 0;//gcap.hardwarecaps.en_stapledetect==0?0:1;
|
||||
cfg.g400params.isCorrect = 1;//1 »úÆ÷УÕý
|
||||
PaperStatus ps = { param.papertype,param.paperAlign };
|
||||
cfg.g400params.pageSize = SupPaperTyps[ps];
|
||||
CSize size;
|
||||
#ifdef G300
|
||||
size = Device::PaperSize().GetPaperSize(TwSS::A4, 200.0f, gcap.paperAlign);//G300 ×î´óÖ§³ÖA4·ùÃæ
|
||||
#else
|
||||
size = Device::PaperSize().GetPaperSize(param.papertype, 200.0f, param.paperAlign);
|
||||
#endif// G300
|
||||
cfg.g400params.dstHeight = (int)((size.cy + 200) / 100);
|
||||
cfg.g400params.reversed1 = cfg.g400params.reversed2 = 0;
|
||||
#endif // G200
|
||||
config_scanparam(cfg);
|
||||
config_imgprocparam({0});
|
||||
GScanCap_3399 param39{ 0 };
|
||||
param39.AutoCrop_threshold = param.AutoCrop_threshold;
|
||||
param39.autodescrew = param.autodescrew;
|
||||
param39.automaticcolor = param.automaticcolor;
|
||||
param39.automaticcolortype = param39.automaticcolortype;
|
||||
param39.brightness = param.brightness;
|
||||
param39.contrast = param.contrast;
|
||||
param39.detachnoise = param.detachnoise;
|
||||
param39.discardblank_percent = param.discardblank_percent;
|
||||
param39.en_fold = param.en_fold;
|
||||
param39.en_sizecheck = param.en_sizecheck;
|
||||
param39.enhance_color = param.enhance_color;
|
||||
param39.fillbackground = param.fillbackground;
|
||||
param39.fillhole = param.fillhole;
|
||||
param39.filter = param.filter;
|
||||
param39.gamma = param.gamma;
|
||||
param39.hardwarecaps = param.hardwarecaps;
|
||||
param39.hsvcorrect = param.hsvcorrect;
|
||||
param39.imageRotateDegree = param.imageRotateDegree;
|
||||
param39.indent = param.indent;
|
||||
param39.is_autocontrast = param.is_autocontrast;
|
||||
param39.is_autocrop = param.is_autocrop;
|
||||
param39.is_autodiscradblank_normal = param.is_autodiscradblank_normal;
|
||||
param39.is_autodiscradblank_vince = param.is_autodiscradblank_vince;
|
||||
param39.is_autotext = param.is_autotext;
|
||||
param39.is_backrotate180 = param.is_backrotate180;
|
||||
param39.is_convex = param.is_convex;
|
||||
param39.is_dogeardetection = param.is_dogeardetection;
|
||||
param39.is_duplex = param.is_duplex;
|
||||
param39.is_switchfrontback = param.is_switchfrontback;
|
||||
param39.multi_output_red = param.multi_output_red;
|
||||
param39.noise = param.noise;
|
||||
param39.paperAlign = param.paperAlign;
|
||||
param39.papertype = param.papertype;
|
||||
param39.pixtype = param.pixtype;
|
||||
param39.resolution_dst = param.resolution_dst;
|
||||
param39.resolution_native = param.resolution_native;
|
||||
param39.scannum = param.scannum;
|
||||
param39.sharpen = param.sharpen;
|
||||
param39.threshold = param.threshold;
|
||||
m_usb->write_bulk(¶m39, sizeof(param39));
|
||||
|
||||
}
|
||||
|
||||
void GScanO1003399::Scanner_StartScan(UINT16 count)
|
||||
{
|
||||
|
||||
scanflag = true;
|
||||
Set_ErrorCode(0);
|
||||
getimgnum = 0;
|
||||
aquirenum = 0;
|
||||
|
||||
reset();
|
||||
devState = DEV_ISRUNNING;
|
||||
if (scan_mode())
|
||||
{
|
||||
devState = DEV_WRONG;
|
||||
Set_ErrorCode(COUNT_MODE);
|
||||
return;
|
||||
}
|
||||
//if (!Get_Scanner_PaperOn())
|
||||
//{
|
||||
// devState = DEV_WRONG;
|
||||
// Set_ErrorCode(NO_FEED);
|
||||
// return;
|
||||
//}
|
||||
|
||||
start();
|
||||
if (!m_usbthread.get()) {
|
||||
b_usbthread = true;
|
||||
m_usbthread.reset(new thread(&GScanO1003399::usb_run, this));
|
||||
}
|
||||
}
|
||||
|
||||
void GScanO1003399::Stop_scan()
|
||||
{
|
||||
if (devState != DEV_ISRUNNING)
|
||||
return;
|
||||
stop();
|
||||
scanflag = false;
|
||||
if (fu_rx.valid())
|
||||
fu_rx.wait();
|
||||
devState == DEV_ISRUNNING ? devState = DEV_STOP : devState = DEV_WRONG;
|
||||
}
|
||||
|
||||
int GScanO1003399::notifyscan()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GScanO1003399::ResetScanner()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool GScanO1003399::Get_IsImageQueueEmpty()
|
||||
{
|
||||
return m_imagedata.Size() < 1;
|
||||
}
|
||||
|
||||
void GScanO1003399::reset()
|
||||
{
|
||||
devState = DEV_STOP;
|
||||
m_imagedata.Clear();
|
||||
}
|
||||
|
||||
void GScanO1003399::clear_hwerror()
|
||||
{
|
||||
}
|
||||
|
||||
UINT32 GScanO1003399::get_ErrorCode()
|
||||
{
|
||||
return Error_Code;
|
||||
}
|
||||
|
||||
void GScanO1003399::Set_ErrorCode(UINT32 value)
|
||||
{
|
||||
Error_Code = value;
|
||||
}
|
||||
|
||||
int GScanO1003399::get_scanned_num()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GScanO1003399::set_sleep_time(int mode)
|
||||
{
|
||||
}
|
||||
|
||||
bool GScanO1003399::set_scannercode(std::string str)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string GScanO1003399::get_scannercode()
|
||||
{
|
||||
return std::string();
|
||||
}
|
||||
|
||||
void GScanO1003399::usb_run()
|
||||
{
|
||||
unsigned char buff[64];
|
||||
while (b_usbthread)
|
||||
{
|
||||
if (!m_usb.get() || !m_usb->is_connected())
|
||||
{
|
||||
this_thread::sleep_for(chrono::milliseconds(20));
|
||||
continue;
|
||||
}
|
||||
memset(buff, 0, sizeof(buff));
|
||||
auto length = m_usb->read_int(buff, sizeof(buff));
|
||||
if (((length) == sizeof(buff)) || im_dev_count())
|
||||
{
|
||||
HGEIntInfo info = *(HGEIntInfo*)&buff;
|
||||
switch (info.From)
|
||||
{
|
||||
case IMG:
|
||||
if (is_runing())
|
||||
im_rx();
|
||||
break;
|
||||
case MtBoard:
|
||||
FileTools::writelog(log_ERROR, "Got MotorBoard error code = " + to_string(info.Code));
|
||||
break;
|
||||
case FPGA:
|
||||
FileTools::writelog(log_ERROR, "Got FPGA Error code = " + to_string(info.Code));
|
||||
break;
|
||||
case V4L2:
|
||||
FileTools::writelog(log_ERROR, "Got V4L2 Error code = " + to_string(info.Code));
|
||||
break;
|
||||
default:
|
||||
FileTools::writelog(log_ERROR, "Got Unkown error code ! From =" + to_string(info.From) + " Code = " + to_string(info.Code));
|
||||
break;
|
||||
}
|
||||
if ((codeconvter(info) != 0))
|
||||
{
|
||||
scanflag = false;
|
||||
devState = codeconvter(info) == -1 ? DEV_STOP : DEV_WRONG;
|
||||
}
|
||||
if (codeconvter(info) > 0)
|
||||
{
|
||||
Set_ErrorCode(codeconvter(info));
|
||||
stop();
|
||||
}
|
||||
this_thread::sleep_for(chrono::microseconds(10));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void GScanO1003399::start()
|
||||
{
|
||||
scanner_cmd(m_usb, SC_START);
|
||||
}
|
||||
|
||||
void GScanO1003399::stop()
|
||||
{
|
||||
scanner_cmd(m_usb, SC_STOP);
|
||||
}
|
||||
|
||||
bool GScanO1003399::is_runing()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_STATUS) & 0x01;
|
||||
}
|
||||
|
||||
int GScanO1003399::scan_mode()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_OS) & 0x01;
|
||||
}
|
||||
|
||||
int GScanO1003399::count()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_SCAN_COUNT);
|
||||
}
|
||||
|
||||
void GScanO1003399::abort_dev_tx()
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_IM_ABORT, 1); //!< to-list
|
||||
}
|
||||
|
||||
void GScanO1003399::config_scanparam(const HG_ScanConfig& cfg)
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_CONFIG_SCAN_PARAM, cfg.value);
|
||||
}
|
||||
|
||||
void GScanO1003399::config_imgprocparam(const HGImgProcParms& imgprocparams)
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_CONFIF_IMGPROCPARAM,imgprocparams.value);
|
||||
}
|
||||
|
||||
bool GScanO1003399::is_rx()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GScanO1003399::rx_cmd()
|
||||
{
|
||||
scanner_write_reg(m_usb, 8, 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GScanO1003399::is_dev_tx()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_IM_TXING);
|
||||
}
|
||||
|
||||
void GScanO1003399::im_rx()
|
||||
{
|
||||
if (!is_rx() && !is_dev_tx())
|
||||
{
|
||||
fu_rx = m_imgthread.enqueue([this] {
|
||||
do
|
||||
{
|
||||
/* code */
|
||||
auto &buffi = im_data;
|
||||
int count = front_datasize();
|
||||
buffi->resize(count);
|
||||
rx_cmd();
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024));
|
||||
pop_dev_im();
|
||||
vector<cv::Mat> mats;
|
||||
auto& buffs = G400Decode(buffi).getImageBuffs();
|
||||
UpdateScanInfo(countNReaded(), get_imgTransfered());
|
||||
imgproce(buffs);
|
||||
} while (im_dev_count());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
int GScanO1003399::read_data(void* data, int length, int timeout)
|
||||
{
|
||||
int readed = 0;
|
||||
int reading = 0;
|
||||
const int buffer_size = 2 * 1024 * 1024;
|
||||
StopWatch sw;
|
||||
while (readed < length && sw.elapsed_ms() < timeout) {
|
||||
reading = std::max(0, std::min(length - readed, buffer_size));
|
||||
reading = m_usb->read_bulk((unsigned char*)data + readed, reading);
|
||||
if (reading > 0) {
|
||||
readed += reading;
|
||||
}
|
||||
}
|
||||
return readed;
|
||||
}
|
||||
|
||||
void GScanO1003399::pop_dev_im()
|
||||
{
|
||||
scanner_write_reg(m_usb, SR_IM_POP, 1); //!< to-list
|
||||
}
|
||||
|
||||
int GScanO1003399::front_datasize()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_IM_FRONT_SIZE);
|
||||
}
|
||||
|
||||
int GScanO1003399::im_dev_count()
|
||||
{
|
||||
return scanner_read_reg(m_usb, SR_IM_COUNT); //!< to-list ;
|
||||
}
|
||||
|
||||
void GScanO1003399::imgproce(std::vector<std::shared_ptr<std::vector<char>>>& buffs)
|
||||
{
|
||||
vector<cv::Mat> mats;
|
||||
for (auto& buf : buffs) {
|
||||
cv::ImreadModes rmc;
|
||||
//int rm;
|
||||
if (m_param.filter != 3 || m_param.enhance_color || m_param.hsvcorrect) {
|
||||
rmc = cv::IMREAD_COLOR;
|
||||
//rm = 1;
|
||||
}
|
||||
else {
|
||||
rmc = m_param.pixtype == 2 ? cv::IMREAD_COLOR : cv::IMREAD_GRAYSCALE;
|
||||
//rm = scanParam.pixtype == 2 ? 1 : 6;
|
||||
}
|
||||
try
|
||||
{
|
||||
cv::Mat mat = cv::imdecode(*buf, rmc);
|
||||
if (mat.empty()) {
|
||||
FileTools::writelog(log_ERROR, "decode image data error");
|
||||
continue;
|
||||
}
|
||||
buf.reset();
|
||||
mats.push_back(mat);
|
||||
FileTools::writelog(log_INFO, "push_back image num= " + to_string(getimgnum++));
|
||||
}
|
||||
catch (const std::exception& e)
|
||||
{
|
||||
//writelog(e.what());
|
||||
FileTools::writelog(log_ERROR, e.what());
|
||||
}
|
||||
}
|
||||
buffs.clear();
|
||||
if (m_param.automaticcolor)
|
||||
{
|
||||
CImageApplyColorRecognition(m_param.automaticcolortype == 1 ? CImageApplyColorRecognition::ColorRecognitionMode::Color_Gray : CImageApplyColorRecognition::ColorRecognitionMode::Color_Mono).apply(mats,m_param.is_duplex);
|
||||
|
||||
}
|
||||
for (int i = 0; i < mats.size(); i++) {
|
||||
//if (!m_param.is_duplex && i == 1) {
|
||||
// mats[i].release();
|
||||
// break;
|
||||
//}
|
||||
if (!mats[i].empty()) {
|
||||
IMat2Bmp idata;
|
||||
if (m_param.pixtype == 1 && m_param.hsvcorrect)
|
||||
if (mats[i].channels() == 3)
|
||||
cvtColor(mats[i], mats[i], cv::COLOR_BGR2GRAY);
|
||||
idata = (m_param.pixtype == 0 || (((m_param.automaticcolortype == 0) && (m_param.automaticcolor == true)) && (mats[i].channels() == 1))) ? (IMat2Bmp)Mat2BmpBw(mats[i], m_param.resolution_dst) : Mat2Bmp(mats[i], m_param.resolution_dst);
|
||||
//if (!m_param.multi_output_red)
|
||||
// mats[i].release();
|
||||
|
||||
m_imagedata.Put(idata.getBmpDataBuffer());
|
||||
}
|
||||
}
|
||||
|
||||
if (m_param.multi_output_red) {
|
||||
for (int i = 0; i < mats.size(); i++) {
|
||||
if (!mats[i].empty()) {
|
||||
ImageMultiOutput m_mlt;
|
||||
cv::Mat ret = m_mlt.GetMultiFilterMat(mats[i], 2);
|
||||
mats[i].release();
|
||||
if (!ret.empty()) {
|
||||
if (!m_param.is_duplex && i == 1) {
|
||||
ret.release();
|
||||
break;
|
||||
}
|
||||
Mat2Bmp mb(ret, m_param.resolution_dst);
|
||||
m_imagedata.Put(mb.getBmpDataBuffer());
|
||||
ret.release();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mats.clear();
|
||||
}
|
||||
|
||||
int GScanO1003399::codeconvter(HGEIntInfo code)
|
||||
{
|
||||
if (code.From == HGType::FPGA)
|
||||
{
|
||||
switch (code.Code)
|
||||
{
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code.From == HGType::MtBoard)
|
||||
{
|
||||
switch (code.Code)
|
||||
{
|
||||
case 0x00002:
|
||||
return NO_FEED;
|
||||
case 0x00004:
|
||||
return OPEN_COVER;
|
||||
case 0x00008:
|
||||
return FEED_IN_ERROR;
|
||||
case 0x00010:
|
||||
return PAPER_JAM;
|
||||
case 0x00020:
|
||||
return DETECT_DOUBLE_FEED;
|
||||
case 0x00040:
|
||||
return DETECT_STAPLE;
|
||||
case 0x00080:
|
||||
return PAPER_SKEW;
|
||||
case 0x10000:
|
||||
return AQUIRE_IMAGE_TIMEOUT;
|
||||
case 0x20000:
|
||||
return SIZE_ERROR;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (code.From == HGType::V4L2)
|
||||
{
|
||||
switch (code.Code)
|
||||
{
|
||||
case 0:
|
||||
return V4L2_AQULRE_ERROR;
|
||||
case 1:
|
||||
return V4L2_IMAGE_EMPTY;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,85 @@
|
|||
#pragma once
|
||||
#include "stdafx.h"
|
||||
#include "IGDevice.h"
|
||||
#include "GScan.h"
|
||||
#include "CyUsbEx.h"
|
||||
#include "IConfig.h"
|
||||
#include "G400ScanConfig.h"
|
||||
#include <memory>
|
||||
#include <future>
|
||||
#include <functional>
|
||||
#include "ThreadPool.h"
|
||||
#include "StopWatch.h"
|
||||
#include "ImageMatQueue.h"
|
||||
#include "opencv2/opencv.hpp"
|
||||
|
||||
|
||||
|
||||
class GScanO1003399 :public IScanner
|
||||
{
|
||||
public:
|
||||
GScanO1003399();
|
||||
virtual ~GScanO1003399();
|
||||
virtual void open(int vid, int pid) override;
|
||||
virtual void regist_deviceevent_callback(deviceevent_callback callback, void* usrdata = 0) override;
|
||||
virtual void DogEar_callback(std::function<void(int)> fun) override;
|
||||
virtual int aquire_bmpdata(std::vector<unsigned char>& bmpdata) override;
|
||||
virtual BOOL IsConnected() override;
|
||||
virtual std::string GetFWVersion() override;
|
||||
virtual std::string GetSerialNum() override;
|
||||
virtual std::uint32_t GetMotorFPGA() override;
|
||||
virtual std::uint32_t GetScanFPGA() override;
|
||||
virtual bool is_scan() override;
|
||||
virtual BOOL Get_Scanner_PaperOn() override;
|
||||
virtual int Get_Roller_num() override;
|
||||
virtual void config_params(GScanCap& param) override;
|
||||
virtual void Scanner_StartScan(UINT16 count) override;
|
||||
virtual void Stop_scan() override;
|
||||
virtual int notifyscan() override;
|
||||
virtual void ResetScanner() override;
|
||||
virtual bool Get_IsImageQueueEmpty() override;
|
||||
virtual void reset() override;
|
||||
virtual void clear_hwerror() override;
|
||||
virtual UINT32 get_ErrorCode() override;
|
||||
virtual void Set_ErrorCode(UINT32 value) override;
|
||||
virtual int get_scanned_num() override;
|
||||
virtual void set_sleep_time(int mode) override;
|
||||
virtual bool set_scannercode(std::string str) override;
|
||||
virtual std::string get_scannercode() override;
|
||||
|
||||
private:
|
||||
void usb_run();
|
||||
void im_rx();
|
||||
void start();
|
||||
void stop();
|
||||
bool is_runing();
|
||||
int scan_mode();
|
||||
int count();
|
||||
void abort_dev_tx();
|
||||
void config_scanparam(const HG_ScanConfig& cfg);
|
||||
void config_imgprocparam(const HGImgProcParms& imgprocparams);
|
||||
bool is_rx();
|
||||
bool rx_cmd();
|
||||
bool is_dev_tx();
|
||||
int read_data(void* data, int length, int timeout);
|
||||
void pop_dev_im();
|
||||
int front_datasize();
|
||||
int im_dev_count();
|
||||
void imgproce(std::vector<std::shared_ptr<std::vector<char>>>& buffs);
|
||||
int codeconvter(HGEIntInfo code);
|
||||
|
||||
private:
|
||||
volatile int devState;
|
||||
volatile int Error_Code;
|
||||
volatile bool scanflag;
|
||||
GScanCap m_param;
|
||||
std::shared_ptr<IUsb> m_usb;
|
||||
volatile bool b_usbthread;
|
||||
std::future<void> fu_rx;
|
||||
ThreadPool m_imgthread;
|
||||
std::shared_ptr<std::thread> m_usbthread;
|
||||
std::shared_ptr<std::vector<char>> im_data;
|
||||
BlockingQueue<std::shared_ptr<std::vector<unsigned char>>> m_imagedata;
|
||||
|
||||
};
|
||||
|
|
@ -6,6 +6,8 @@
|
|||
#include "PaperSize.h"
|
||||
#define FOR_LANXUM
|
||||
|
||||
using u32 = unsigned int;
|
||||
|
||||
static std::map<PaperStatus, unsigned int> SupPaperTyps = {
|
||||
#ifdef G200
|
||||
#ifdef FOR_LANXUM
|
||||
|
@ -26,9 +28,15 @@ static std::map<PaperStatus, unsigned int> SupPaperTyps = {
|
|||
{{TwSS::USLedger,PaperAlign::Rot0},12},
|
||||
{{TwSS::USLegal,PaperAlign::Rot0},13},
|
||||
{{TwSS::None,PaperAlign::Rot0},0},
|
||||
#ifdef G1003399
|
||||
{{TwSS::USStatement,PaperAlign::Rot0},17},
|
||||
{{TwSS::MaxSize,PaperAlign::Rot0},19},
|
||||
{{TwSS::Trigeminy,PaperAlign::Rot0},17}
|
||||
#else
|
||||
{{TwSS::USStatement,PaperAlign::Rot0},16},
|
||||
{{TwSS::MaxSize,PaperAlign::Rot0},16},
|
||||
{{TwSS::Trigeminy,PaperAlign::Rot0},16}
|
||||
#endif
|
||||
#else
|
||||
{{TwSS::A3,PaperAlign::Rot0},0},
|
||||
{{TwSS::A4,PaperAlign::Rot0},1},
|
||||
|
@ -102,6 +110,108 @@ static std::map<BYTE, BYTE> secrewMaps = {
|
|||
{4,3},
|
||||
{5,4}
|
||||
};
|
||||
|
||||
|
||||
enum HGType
|
||||
{
|
||||
MtBoard = 1,
|
||||
FPGA,
|
||||
V4L2,
|
||||
IMG,
|
||||
STOPSCAN,
|
||||
};
|
||||
|
||||
struct HGEIntInfo
|
||||
{
|
||||
HGType From;
|
||||
unsigned int Code;
|
||||
};
|
||||
|
||||
#define USB_REQ_GET_FPGA_REGS 0x40
|
||||
#define USB_REQ_SET_FPGA_REGS 0x41
|
||||
#define USB_REQ_GET_MOTOR_REGS 0x42
|
||||
#define USB_REQ_SET_MOTOR_REGS 0x43
|
||||
|
||||
#define USB_REQ_GET_DEV_STATUS 0x60
|
||||
#define USB_REQ_GET_DEV_CONFIGURATION 0x61
|
||||
#define USB_REQ_SET_DEV_CONFIGURATION 0x62
|
||||
#define USB_REQ_GET_DEV_REGS 0x63
|
||||
#define USB_REQ_SET_DEV_REGS 0x64
|
||||
|
||||
enum Scanner_Reg_Defs
|
||||
{
|
||||
SR_CMD,
|
||||
SR_STATUS,
|
||||
SR_SCAN_COUNT,
|
||||
SR_OS,
|
||||
SR_SENSORS,
|
||||
SR_MOTOR,
|
||||
SR_IM_TYPE,
|
||||
SR_IM_COUNT,
|
||||
SR_IM_TX,
|
||||
SR_IM_FRONT_SIZE,
|
||||
SR_IM_CLEAR,
|
||||
SR_IM_TXING,
|
||||
SR_IM_POP,
|
||||
SR_IM_ABORT,
|
||||
SR_COUNT,
|
||||
SR_CONFIG_SCAN_PARAM,
|
||||
SR_GET_FWVERSION,
|
||||
SR_SET_FWERSION,
|
||||
SR_GET_SERIALNUM,
|
||||
SR_SET_SERIALNUM,
|
||||
SR_CONFIF_IMGPROCPARAM,
|
||||
SR_PAPER_READY,
|
||||
};
|
||||
|
||||
enum Scanner_Cmd_Defs
|
||||
{
|
||||
SC_START,
|
||||
SC_STOP,
|
||||
SC_CLEAR,
|
||||
SC_COUNT
|
||||
};
|
||||
|
||||
typedef union HG_ImgProcParms
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
u32 papertype : 5;
|
||||
u32 scanside : 3;
|
||||
u32 res : 10;
|
||||
u32 rotate : 2;
|
||||
u32 autodescrew : 1;
|
||||
u32 fillbackground : 1;
|
||||
u32 filter : 4;
|
||||
u32 enhancecolor : 2;
|
||||
u32 fillhole : 1;
|
||||
u32 reversed : 3;
|
||||
}imgprocparams;
|
||||
}HGImgProcParms;
|
||||
|
||||
|
||||
///用于CIS 自动校正参数保存
|
||||
typedef struct
|
||||
{
|
||||
u32 gainF[6];
|
||||
u32 gainB[6];
|
||||
u32 offsetsF[6];
|
||||
u32 offsetsB[6];
|
||||
u32 expF[3];
|
||||
u32 expB[3];
|
||||
u32 sp;
|
||||
}HGCISConfig;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
HGCISConfig colorCorrect;
|
||||
HGCISConfig color;
|
||||
HGCISConfig grayCorrect;
|
||||
HGCISConfig gray;
|
||||
}HGCorrectConfigs;
|
||||
|
||||
typedef union Config_Param {
|
||||
unsigned int value;
|
||||
struct {
|
||||
|
@ -121,6 +231,39 @@ typedef union Config_Param {
|
|||
};
|
||||
} ConfigParam;
|
||||
|
||||
typedef union HG_ScanConfig
|
||||
{
|
||||
unsigned int value;
|
||||
struct
|
||||
{
|
||||
unsigned int paper : 5;
|
||||
unsigned int color : 1;
|
||||
unsigned int dpi : 2;
|
||||
unsigned int double_feed_enbale : 1;
|
||||
unsigned int stable_enbale : 1;
|
||||
unsigned int screw_detect_enable : 1;
|
||||
unsigned int screw_detect_level : 3;//第十四位
|
||||
unsigned int unused_one : 6;
|
||||
unsigned int pc_correct : 1;
|
||||
unsigned int enable_sizecheck : 1;
|
||||
unsigned int enabledsp_cache : 1;
|
||||
unsigned int sizeerror_errorratio : 9;
|
||||
}g200params;
|
||||
struct
|
||||
{
|
||||
unsigned int pageSize : 5;
|
||||
unsigned int isColor : 1;
|
||||
unsigned int dpi : 2;
|
||||
unsigned int doubleFeeded : 1;
|
||||
unsigned int enableStable : 1;
|
||||
unsigned int enableLed : 1;
|
||||
unsigned int reversed1 : 6;
|
||||
unsigned int isCorrect : 1;
|
||||
unsigned int dstHeight : 8;
|
||||
unsigned int reversed2 : 6;
|
||||
}g400params;
|
||||
}HGScanConfig;
|
||||
|
||||
class IConfig
|
||||
{
|
||||
public:
|
||||
|
|
|
@ -6,7 +6,7 @@ class IUsb
|
|||
public:
|
||||
virtual ~IUsb() {}
|
||||
virtual bool open() = 0;
|
||||
virtual void set_usbhotplug_callback(usbhotplug_callback callback=NULL,void* userdata=NULL)=0;
|
||||
virtual void set_usbhotplug_callback(usbhotplug_callback callback=0,void* userdata=0)=0;
|
||||
virtual bool close() = 0;
|
||||
virtual bool is_open() = 0;
|
||||
virtual bool is_connected() = 0;
|
||||
|
|
|
@ -84,7 +84,8 @@ const std::string AUTOCROP_THRESHOLD = "AutoCrop_Threshold";
|
|||
const std::string NOISE = "Noise";
|
||||
const std::string LOWPOWERMODE = "ilowpowermode";
|
||||
|
||||
|
||||
#pragma pack(push)
|
||||
#pragma pack(4)
|
||||
/******************
|
||||
**参数保存结构体**
|
||||
*******************/
|
||||
|
@ -186,7 +187,7 @@ typedef struct Scan_Rect {
|
|||
int y;
|
||||
}ScanRect;
|
||||
|
||||
enum PaperAlign :byte {
|
||||
enum PaperAlign :uint8_t {
|
||||
Rot0 = 0,
|
||||
Rot270 = 3,
|
||||
AutoTextOrientation = 5
|
||||
|
@ -212,12 +213,12 @@ typedef enum SharpenBlur :short {
|
|||
|
||||
struct GScanCap
|
||||
{
|
||||
byte papertype; /**< the current paper source ADF or Flatbed*/
|
||||
uint8_t papertype; /**< the current paper source ADF or Flatbed*/
|
||||
PaperAlign paperAlign;
|
||||
byte en_sizecheck; /**< 尺寸检测*/
|
||||
uint8_t en_sizecheck; /**< 尺寸检测*/
|
||||
float imageRotateDegree;
|
||||
byte is_duplex; /**< True to use duplex false for simplex, ignored if flatbed*/
|
||||
byte en_fold; /**<对折*/
|
||||
uint8_t is_duplex; /**< True to use duplex false for simplex, ignored if flatbed*/
|
||||
uint8_t en_fold; /**<对折*/
|
||||
int pixtype; /**< type of pixels to transfer image as */
|
||||
int automaticcolor; /**<顔色自動識別*/
|
||||
int automaticcolortype; /**<顔色自動識別后非彩色上傳類型*/
|
||||
|
@ -228,34 +229,79 @@ struct GScanCap
|
|||
float contrast; /**< Contrast */
|
||||
float brightness; /**< Brightness */
|
||||
float threshold; /**< Threshold */
|
||||
byte is_autocontrast; /**< 自动对比度*/
|
||||
byte is_autocrop; /**< 自动裁切*/
|
||||
byte is_autodiscradblank_normal; /**< 自动丢弃空白页通用*/
|
||||
uint8_t is_autocontrast; /**< 自动对比度*/
|
||||
uint8_t is_autocrop; /**< 自动裁切*/
|
||||
uint8_t is_autodiscradblank_normal; /**< 自动丢弃空白页通用*/
|
||||
int discardblank_percent; /**<跳过空白页阀值*/
|
||||
byte is_autodiscradblank_vince;/**自动丢弃空白页发票*/
|
||||
byte is_switchfrontback; /**交换正反面*/
|
||||
byte autodescrew; /**< 自动纠偏*/
|
||||
byte multi_output_red; /*多流输出*/
|
||||
byte hsvcorrect; /**<答题卡除红*/
|
||||
byte filter; /**< 除色*/
|
||||
byte sharpen;
|
||||
byte enhance_color; /**< 颜色增强*/
|
||||
byte fillbackground; /**< 填黑框*/
|
||||
uint8_t is_autodiscradblank_vince;/**自动丢弃空白页发票*/
|
||||
uint8_t is_switchfrontback; /**交换正反面*/
|
||||
uint8_t autodescrew; /**< 自动纠偏*/
|
||||
uint8_t multi_output_red; /*多流输出*/
|
||||
uint8_t hsvcorrect; /**<答题卡除红*/
|
||||
uint8_t filter; /**< 除色*/
|
||||
uint8_t sharpen;
|
||||
uint8_t enhance_color; /**< 颜色增强*/
|
||||
uint8_t fillbackground; /**< 填黑框*/
|
||||
bool is_convex; /**< 填黑框模式,true为凸多边形填充,false为凹多边形填充,默认true*/
|
||||
int noise; /**< 除噪像素,能够消除noise宽度的背景竖条纹干扰,默认40*/
|
||||
int indent; /**< 轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认5*/
|
||||
int AutoCrop_threshold; /**< 自动裁剪二值化阈值,取值范围(0, 255),默认40*/
|
||||
unsigned short scannum; /**< 扫描张数*/
|
||||
byte is_backrotate180; /**< 背面旋转180*/
|
||||
byte is_dogeardetection; /**<折角检测*/
|
||||
uint8_t is_backrotate180; /**< 背面旋转180*/
|
||||
uint8_t is_dogeardetection; /**<折角检测*/
|
||||
HardwareCaps hardwarecaps; /**< 硬件扫描参数*/
|
||||
FillHole fillhole;
|
||||
DetachNoise detachnoise; /**< 黑白降噪*/
|
||||
byte is_autotext; /**< 自动文本方向识别*/
|
||||
uint8_t is_autotext; /**< 自动文本方向识别*/
|
||||
std::string Caption;
|
||||
std::string SavePath;
|
||||
};
|
||||
|
||||
|
||||
struct GScanCap_3399
|
||||
{
|
||||
uint8_t papertype; /**< the current paper source ADF or Flatbed*/
|
||||
PaperAlign paperAlign;
|
||||
uint8_t en_sizecheck; /**< 尺寸检测*/
|
||||
float imageRotateDegree;
|
||||
uint8_t is_duplex; /**< True to use duplex false for simplex, ignored if flatbed*/
|
||||
uint8_t en_fold; /**<对折*/
|
||||
int pixtype; /**< type of pixels to transfer image as */
|
||||
int automaticcolor; /**<顔色自動識別*/
|
||||
int automaticcolortype; /**<顔色自動識別后非彩色上傳類型*/
|
||||
//ScanRect scanrect;
|
||||
float resolution_dst; /**< horizontal resolution */
|
||||
float resolution_native;
|
||||
float gamma; /**< Gamma */
|
||||
float contrast; /**< Contrast */
|
||||
float brightness; /**< Brightness */
|
||||
float threshold; /**< Threshold */
|
||||
uint8_t is_autocontrast; /**< 自动对比度*/
|
||||
uint8_t is_autocrop; /**< 自动裁切*/
|
||||
uint8_t is_autodiscradblank_normal; /**< 自动丢弃空白页通用*/
|
||||
int discardblank_percent; /**<跳过空白页阀值*/
|
||||
uint8_t is_autodiscradblank_vince;/**自动丢弃空白页发票*/
|
||||
uint8_t is_switchfrontback; /**交换正反面*/
|
||||
uint8_t autodescrew; /**< 自动纠偏*/
|
||||
uint8_t multi_output_red; /*多流输出*/
|
||||
uint8_t hsvcorrect; /**<答题卡除红*/
|
||||
uint8_t filter; /**< 除色*/
|
||||
uint8_t sharpen;
|
||||
uint8_t enhance_color; /**< 颜色增强*/
|
||||
uint8_t fillbackground; /**< 填黑框*/
|
||||
bool is_convex; /**< 填黑框模式,true为凸多边形填充,false为凹多边形填充,默认true*/
|
||||
int noise; /**< 除噪像素,能够消除noise宽度的背景竖条纹干扰,默认40*/
|
||||
int indent; /**< 轮廓缩进,裁剪、纠偏或者黑底填充时,对探索到的纸张轮廓进行缩进indent像素,默认5*/
|
||||
int AutoCrop_threshold; /**< 自动裁剪二值化阈值,取值范围(0, 255),默认40*/
|
||||
unsigned short scannum; /**< 扫描张数*/
|
||||
uint8_t is_backrotate180; /**< 背面旋转180*/
|
||||
uint8_t is_dogeardetection; /**<折角检测*/
|
||||
HardwareCaps hardwarecaps; /**< 硬件扫描参数*/
|
||||
FillHole fillhole;
|
||||
DetachNoise detachnoise; /**< 黑白降噪*/
|
||||
uint8_t is_autotext; /**< 自动文本方向识别*/
|
||||
};
|
||||
|
||||
typedef struct Paper_Status {
|
||||
Paper_Status(unsigned int paper, unsigned int orentate) :Paper(paper), Orentate(orentate) {}
|
||||
Paper_Status():Paper(0), Orentate(0){}
|
||||
|
@ -296,6 +342,7 @@ enum G400_DPI {
|
|||
G400_D600
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
#define CAPTION_LEN 256
|
||||
#define TWAIN_IMAGE_FILE_LIST_NAME TEXT(".dat")
|
||||
|
||||
|
|
|
@ -0,0 +1,98 @@
|
|||
#ifndef THREAD_POOL_H
|
||||
#define THREAD_POOL_H
|
||||
|
||||
#include <vector>
|
||||
#include <queue>
|
||||
#include <memory>
|
||||
#include <thread>
|
||||
#include <mutex>
|
||||
#include <condition_variable>
|
||||
#include <future>
|
||||
#include <functional>
|
||||
#include <stdexcept>
|
||||
|
||||
class ThreadPool {
|
||||
public:
|
||||
ThreadPool(size_t);
|
||||
template<class F, class... Args>
|
||||
auto enqueue(F&& f, Args&&... args)
|
||||
-> std::future<typename std::result_of<F(Args...)>::type>;
|
||||
~ThreadPool();
|
||||
private:
|
||||
// need to keep track of threads so we can join them
|
||||
std::vector< std::thread > workers;
|
||||
// the task queue
|
||||
std::queue< std::function<void()> > tasks;
|
||||
|
||||
// synchronization
|
||||
std::mutex queue_mutex;
|
||||
std::condition_variable condition;
|
||||
bool stop;
|
||||
};
|
||||
|
||||
// the constructor just launches some amount of workers
|
||||
inline ThreadPool::ThreadPool(size_t threads)
|
||||
: stop(false)
|
||||
{
|
||||
for(size_t i = 0;i<threads;++i)
|
||||
workers.emplace_back(
|
||||
[this]
|
||||
{
|
||||
for(;;)
|
||||
{
|
||||
std::function<void()> task;
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(this->queue_mutex);
|
||||
this->condition.wait(lock,
|
||||
[this]{ return this->stop || !this->tasks.empty(); });
|
||||
if(this->stop && this->tasks.empty())
|
||||
return;
|
||||
task = std::move(this->tasks.front());
|
||||
this->tasks.pop();
|
||||
}
|
||||
|
||||
task();
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
// add new work item to the pool
|
||||
template<class F, class... Args>
|
||||
auto ThreadPool::enqueue(F&& f, Args&&... args)
|
||||
-> std::future<typename std::result_of<F(Args...)>::type>
|
||||
{
|
||||
using return_type = typename std::result_of<F(Args...)>::type;
|
||||
|
||||
auto task = std::make_shared< std::packaged_task<return_type()> >(
|
||||
std::bind(std::forward<F>(f), std::forward<Args>(args)...)
|
||||
);
|
||||
|
||||
std::future<return_type> res = task->get_future();
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||
|
||||
// don't allow enqueueing after stopping the pool
|
||||
if(stop)
|
||||
throw std::runtime_error("enqueue on stopped ThreadPool");
|
||||
|
||||
tasks.emplace([task](){ (*task)(); });
|
||||
}
|
||||
condition.notify_one();
|
||||
return res;
|
||||
}
|
||||
|
||||
// the destructor joins all threads
|
||||
inline ThreadPool::~ThreadPool()
|
||||
{
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(queue_mutex);
|
||||
stop = true;
|
||||
}
|
||||
condition.notify_all();
|
||||
for(std::thread &worker: workers)
|
||||
worker.join();
|
||||
}
|
||||
|
||||
#endif
|
|
@ -16,6 +16,7 @@
|
|||
#include "Device/PublicFunc.h"
|
||||
#include "Device/GScanO200.h"
|
||||
#include "Device/GScanO400.h"
|
||||
#include "Device/GScanO1003399.h"
|
||||
#include "Device/filetools.h"
|
||||
#include "Device/GScanVirtual.h"
|
||||
#include <list>
|
||||
|
@ -96,7 +97,7 @@ static constexpr const Identity srcIdent(
|
|||
#endif
|
||||
|
||||
#ifdef G200
|
||||
#ifdef ISG100
|
||||
#if defined (ISG100) || defined (G1003399)
|
||||
#ifdef LANXUM
|
||||
"G62S Series",
|
||||
#else // ISG100
|
||||
|
@ -126,7 +127,7 @@ static constexpr const Identity srcIdent(
|
|||
#endif
|
||||
|
||||
#ifdef G200
|
||||
#ifdef ISG100
|
||||
#if defined (ISG100) || defined (G1003399)
|
||||
#ifdef MAKEHUAGAO
|
||||
"HUAGOSCAN G100 TWAIN"
|
||||
#elif defined LANXUM //!LANXUM
|
||||
|
@ -345,19 +346,24 @@ void HuagaoDs::showmsg(std::string caption, std::string text, int retcode)
|
|||
if (scanner.get()) {
|
||||
int losemun = scanner->get_lose_image_num();
|
||||
int num = 0;
|
||||
bool is_duplex = m_scanparam->is_duplex;
|
||||
#ifdef G1003399
|
||||
is_duplex = false;
|
||||
#endif // G1003399
|
||||
|
||||
if ((retcode == 64 || retcode == 8 || retcode == 16) && losemun > 0)//64 ->SStop
|
||||
losemun--;
|
||||
if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince))
|
||||
{
|
||||
if (m_scanparam->is_duplex && m_scanparam->en_fold && m_scanparam->multi_output_red)
|
||||
if (is_duplex && m_scanparam->en_fold && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
else if (m_scanparam->is_duplex && m_scanparam->en_fold)
|
||||
else if (is_duplex && m_scanparam->en_fold)
|
||||
num = scanner->get_imgnReaded() - scanner->get_imgTransfered();
|
||||
else if (m_scanparam->is_duplex && m_scanparam->multi_output_red)
|
||||
else if (is_duplex && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 4 - scanner->get_imgTransfered();
|
||||
else if ((!m_scanparam->is_duplex) && m_scanparam->multi_output_red)
|
||||
else if ((!is_duplex) && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
else if (!m_scanparam->is_duplex)
|
||||
else if (!is_duplex)
|
||||
num = scanner->get_imgnReaded() - scanner->get_imgTransfered();
|
||||
else
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
|
@ -770,6 +776,7 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
showmsg("警告", msgs[(UsbSupported)202]);
|
||||
return { ReturnCode::Failure, ConditionCode::CapBadOperation };
|
||||
}
|
||||
#ifndef G1003399
|
||||
auto usblist = UsbScan_List::find_all_usb();
|
||||
if (!usblist.empty())
|
||||
{
|
||||
|
@ -790,16 +797,8 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
}
|
||||
}
|
||||
}
|
||||
FileTools::writelog(log_INFO, "open ds find device vid=" + to_string(vid) + "\tpid=" + to_string(pid));
|
||||
m_haveError = false;
|
||||
updataGscanCap();
|
||||
bmpData->resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
|
||||
BITMAPINFOHEADER& bmInfo = *((BITMAPINFOHEADER*)header());
|
||||
bmInfo.biHeight = 2000;
|
||||
bmInfo.biWidth = 2000;
|
||||
bmInfo.biBitCount = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
|
||||
m_iBitdepth = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
|
||||
|
||||
FileTools::writelog(log_INFO, "open ds find device vid=" + to_string(vid) + "\tpid=" + to_string(pid));
|
||||
if (vid == 0 || pid == 0)
|
||||
{
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
|
||||
|
@ -811,6 +810,10 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
return checkDeviceOnline();
|
||||
}
|
||||
scanner->open(vid, pid);
|
||||
#else
|
||||
scanner.reset(new GScanO1003399());
|
||||
#endif // G1003399
|
||||
|
||||
|
||||
if (!scanner->IsConnected()) {
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), CString("201"), NULL, SW_HIDE);
|
||||
|
@ -826,8 +829,6 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
scanner->regist_deviceevent_callback(DeviceEvent_callback, this);
|
||||
auto dgcall = [&](int pagenum)
|
||||
{
|
||||
CString text;
|
||||
text.Format(_T("74 %d"), pagenum);
|
||||
//ShellExecute(NULL, TEXT("open"), GetHidedlgPath(), text, NULL, SW_HIDE);
|
||||
showmsg("警告", "在" + to_string(pagenum) + "检测到折角!");
|
||||
scanner->Stop_scan();
|
||||
|
@ -837,6 +838,15 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
|||
};
|
||||
scanner->DogEar_callback(dgcall);
|
||||
}
|
||||
|
||||
m_haveError = false;
|
||||
updataGscanCap();
|
||||
bmpData->resize(sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER));
|
||||
BITMAPINFOHEADER& bmInfo = *((BITMAPINFOHEADER*)header());
|
||||
bmInfo.biHeight = 2000;
|
||||
bmInfo.biWidth = 2000;
|
||||
bmInfo.biBitCount = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
|
||||
m_iBitdepth = m_scanparam->pixtype == 2 ? 24 : (m_scanparam->pixtype == 1 ? 8 : 1);
|
||||
//MessageBox(NULL, L"2", L"", 0);
|
||||
// init caps
|
||||
// there are caps a minimal source must support
|
||||
|
@ -1916,15 +1926,20 @@ Result HuagaoDs::pendingXfersEnd(const Identity&, PendingXfers& data) {
|
|||
if (!(m_scanparam->is_autodiscradblank_normal || m_scanparam->is_autodiscradblank_vince))
|
||||
{
|
||||
int num = 0;
|
||||
if (m_scanparam->is_duplex && m_scanparam->en_fold && m_scanparam->multi_output_red)
|
||||
bool is_duplex = m_scanparam->is_duplex;
|
||||
#ifdef G1003399
|
||||
is_duplex = false;
|
||||
#endif // G1003399
|
||||
|
||||
if (is_duplex && m_scanparam->en_fold && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
else if (m_scanparam->is_duplex && m_scanparam->en_fold)
|
||||
else if (is_duplex && m_scanparam->en_fold)
|
||||
num = scanner->get_imgnReaded() - scanner->get_imgTransfered();
|
||||
else if (m_scanparam->is_duplex && m_scanparam->multi_output_red)
|
||||
else if (is_duplex && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 4 - scanner->get_imgTransfered();
|
||||
else if ((!m_scanparam->is_duplex) && m_scanparam->multi_output_red)
|
||||
else if ((!is_duplex) && m_scanparam->multi_output_red)
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
else if (!m_scanparam->is_duplex)
|
||||
else if (!is_duplex)
|
||||
num = scanner->get_imgnReaded() - scanner->get_imgTransfered();
|
||||
else
|
||||
num = scanner->get_imgnReaded() * 2 - scanner->get_imgTransfered();
|
||||
|
@ -1991,13 +2006,13 @@ Result HuagaoDs::userInterfaceEnable(const Identity&, UserInterface& ui) {
|
|||
if (!ui.showUi()) {
|
||||
// this is an exception when we want to set state explicitly, notifyXferReady can be called only in enabled state
|
||||
// with hidden UI, the usual workflow DsState::Enabled -> notifyXferReady() -> DsState::XferReady is a single step
|
||||
//#ifndef G200
|
||||
#ifndef G200
|
||||
while (!scanner->Get_Scanner_PaperOn())
|
||||
{
|
||||
if (MessageBox(NULL, L"检测到无纸,请添加纸张", L"提示", MB_YESNO | MB_SYSTEMMODAL) == IDNO)
|
||||
return seqError();
|
||||
}
|
||||
//#endif // !G200
|
||||
#endif // !G200
|
||||
|
||||
|
||||
auto ret = startScan();
|
||||
|
|
BIN
huagao/stdafx.h
BIN
huagao/stdafx.h
Binary file not shown.
Loading…
Reference in New Issue