mirror of http://192.168.1.51:8099/lmh188/twain3.0
调整usb readbulk超时时间 增加固件兼容性
This commit is contained in:
parent
0aa4e0e025
commit
e964c60148
|
@ -55,4 +55,10 @@
|
||||||
13.添加画质优先与速度优先模式
|
13.添加画质优先与速度优先模式
|
||||||
14.调整互斥锁,不同设备能在同一台pc上使用
|
14.调整互斥锁,不同设备能在同一台pc上使用
|
||||||
15.调整速度优先600 dpi 按照真实300dpi 缩放
|
15.调整速度优先600 dpi 按照真实300dpi 缩放
|
||||||
16.协议问题排查
|
16.协议问题排查
|
||||||
|
17.完成安卓3399适配
|
||||||
|
18.取消UI置顶
|
||||||
|
2020年8月10日
|
||||||
|
版本:3.3.5.9
|
||||||
|
1.调整usb通信,加长readbulk超时时间
|
||||||
|
2.屏蔽3288 自适应幅面功能
|
|
@ -59,6 +59,7 @@ CImageProcPage::~CImageProcPage()
|
||||||
|
|
||||||
void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool is_Crop,int dpi)
|
void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool is_Crop,int dpi)
|
||||||
{
|
{
|
||||||
|
this->colormode_index = val;
|
||||||
this->dpi = dpi;
|
this->dpi = dpi;
|
||||||
this->twss = twss;
|
this->twss = twss;
|
||||||
this->cmduplexsel = cmduplexsel;
|
this->cmduplexsel = cmduplexsel;
|
||||||
|
@ -88,6 +89,7 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool
|
||||||
GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(TRUE);
|
GetDlgItem(IDC_CHMULTIPUT)->EnableWindow(TRUE);
|
||||||
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(((CButton*)GetDlgItem(IDC_CHMULTIPUT))->GetCheck());
|
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(((CButton*)GetDlgItem(IDC_CHMULTIPUT))->GetCheck());
|
||||||
}
|
}
|
||||||
|
t_chMultiOutput->EnableWindow(TRUE);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(FALSE);
|
GetDlgItem(IDC_CKHSVCORRECT)->EnableWindow(FALSE);
|
||||||
|
@ -98,21 +100,22 @@ void CImageProcPage::ImageProcPageUpdate(int val,int twss, int cmduplexsel,bool
|
||||||
((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE);
|
((CButton*)GetDlgItem(IDC_CHMULTIPUT))->SetCheck(FALSE);
|
||||||
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
|
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
|
||||||
((CButton*)GetDlgItem(IDC_CMBMULTIOUT))->SetCheck(FALSE);
|
((CButton*)GetDlgItem(IDC_CMBMULTIOUT))->SetCheck(FALSE);
|
||||||
|
t_chMultiOutput->SetCheck(FALSE);
|
||||||
|
t_chMultiOutput->EnableWindow(FALSE);
|
||||||
}
|
}
|
||||||
if (0 == val||val==3)//彩色
|
if (0 == val||val==3)//彩色
|
||||||
{
|
{
|
||||||
m_temp->SetCurSel(0);
|
m_temp->SetCurSel(0);
|
||||||
m_temp->EnableWindow(FALSE);
|
m_temp->EnableWindow(FALSE);
|
||||||
//t_chMultiOutput->SetCheck(TRUE);
|
//t_chMultiOutput->SetCheck(TRUE);
|
||||||
t_chMultiOutput->EnableWindow(TRUE);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
m_temp->EnableWindow(TRUE);
|
m_temp->EnableWindow(TRUE);
|
||||||
t_chMultiOutput->SetCheck(FALSE);
|
|
||||||
t_chMultiOutput->EnableWindow(FALSE);
|
|
||||||
GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE);
|
GetDlgItem(IDC_CKBACKGROUNDSMOOTH)->EnableWindow(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (val == 2)
|
if (val == 2)
|
||||||
{
|
{
|
||||||
((CButton*)GetDlgItem(IDC_CHECKDETACHNOISE))->EnableWindow(true);
|
((CButton*)GetDlgItem(IDC_CHECKDETACHNOISE))->EnableWindow(true);
|
||||||
|
@ -234,8 +237,10 @@ void CImageProcPage::SetMultiOutputEnable(int pixtype, bool enable)
|
||||||
switch (pixtype)
|
switch (pixtype)
|
||||||
{
|
{
|
||||||
case 2://彩色
|
case 2://彩色
|
||||||
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->SetCheck(enable);
|
if (colormode_index == 0) {
|
||||||
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->EnableWindow(TRUE);
|
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->SetCheck(enable);
|
||||||
|
((CButton*)GetDlgItem(IDC_CKMULTIOUTPUT))->EnableWindow(TRUE);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case 0://灰度 黑白
|
case 0://灰度 黑白
|
||||||
case 1:
|
case 1:
|
||||||
|
@ -350,7 +355,10 @@ void CImageProcPage::OnBnClickedChmultiput()
|
||||||
{
|
{
|
||||||
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
|
GetDlgItem(IDC_CMBMULTIOUT)->EnableWindow(FALSE);
|
||||||
((CComboBox*)GetDlgItem(IDC_CMBMULTIOUT))->SetCurSel(0);
|
((CComboBox*)GetDlgItem(IDC_CMBMULTIOUT))->SetCurSel(0);
|
||||||
GetDlgItem(IDC_CKMULTIOUTPUT)->EnableWindow(TRUE);
|
if (colormode_index == 0)
|
||||||
|
{
|
||||||
|
GetDlgItem(IDC_CKMULTIOUTPUT)->EnableWindow(TRUE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -42,6 +42,7 @@ public:
|
||||||
int twss;
|
int twss;
|
||||||
int cmduplexsel;
|
int cmduplexsel;
|
||||||
int dpi;
|
int dpi;
|
||||||
|
int colormode_index;
|
||||||
bool is_convex;
|
bool is_convex;
|
||||||
bool is_crop;
|
bool is_crop;
|
||||||
bool is_bw;
|
bool is_bw;
|
||||||
|
|
|
@ -0,0 +1,605 @@
|
||||||
|
#include "GScan439Android.h"
|
||||||
|
#include "IUsb.h"
|
||||||
|
#include "UsbScanEx.h"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
static std::mutex mx_ctrl;
|
||||||
|
|
||||||
|
#define m_max(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
|
#define m_min(a, b) (((a) < (b)) ? (a) : (b))
|
||||||
|
|
||||||
|
static int read_reg(std::shared_ptr<IUsb>& usb, int addr)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(mx_ctrl);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
if (usb.get() && usb->is_connected()) {
|
||||||
|
int val = 0;
|
||||||
|
usb->control_msg(0xc0, USB_REQ_GET_DEV_REGS, addr, 0, 4, &val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileTools::writelog(log_ERROR, " read_reg error usb disconnect");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void write_reg(std::shared_ptr<IUsb>& usb, int addr, int val)
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lck(mx_ctrl);
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(50));
|
||||||
|
if (usb.get() && usb->is_connected())
|
||||||
|
{
|
||||||
|
usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileTools::writelog(log_ERROR, " write_reg error usb disconnect");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scanner_control(std::shared_ptr<IUsb>& usb, int cmd)
|
||||||
|
{
|
||||||
|
write_reg(usb, 0, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
GScan439Android::GScan439Android():m_readimgpool(1)
|
||||||
|
{
|
||||||
|
im_data.reset(new std::vector<char>());
|
||||||
|
m_status = -1;
|
||||||
|
m_pImages.reset(new ImageMatQueue());
|
||||||
|
}
|
||||||
|
|
||||||
|
GScan439Android::~GScan439Android()
|
||||||
|
{
|
||||||
|
if (m_usbthread.get() && m_usbthread->joinable())
|
||||||
|
{
|
||||||
|
b_usbthread = false;
|
||||||
|
m_usbthread->join();
|
||||||
|
m_usbthread.reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
imgs.ShutDown();
|
||||||
|
|
||||||
|
m_imagedata.ShutDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::open(int vid, int pid)
|
||||||
|
{
|
||||||
|
if (m_usb.get() && m_usb->is_connected())
|
||||||
|
return;
|
||||||
|
auto lsusb = UsbScan_List::find_vid_pid(vid, pid);
|
||||||
|
if (!lsusb.empty())
|
||||||
|
{
|
||||||
|
m_usb = *lsusb.begin();
|
||||||
|
m_usb->open();
|
||||||
|
if (m_usb->is_open())
|
||||||
|
m_usb->set_usbhotplug_callback(usbhotplug_callback, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::regist_deviceevent_callback(deviceevent_callback callback, void* usrdata)
|
||||||
|
{
|
||||||
|
huagods = usrdata;
|
||||||
|
dev_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::DogEar_callback(std::function<void(int)> fun)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
int GScan439Android::aquire_bmpdata(std::vector<unsigned char>& bmpdata)
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata start");
|
||||||
|
StopWatch sw;
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (m_pImages->empty()) {
|
||||||
|
DoEvents();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(10));
|
||||||
|
if (sw.elapsed_s() > 30.00)
|
||||||
|
{
|
||||||
|
if (m_usbthread.get() && m_usbthread->joinable()) {
|
||||||
|
m_status = DEV_STOP;
|
||||||
|
m_usbthread->join();
|
||||||
|
m_usbthread.reset();
|
||||||
|
}
|
||||||
|
Stop_scan();//ֹͣɨ<D6B9><C9A8>
|
||||||
|
ResetScanner();
|
||||||
|
auto rollernew = Get_Roller_num();
|
||||||
|
set_scannum(abs(rollernew - roller_num));
|
||||||
|
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata timeout");
|
||||||
|
return HARDWARE_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!is_scan()) {
|
||||||
|
auto rollernew = Get_Roller_num();
|
||||||
|
set_scannum(abs(rollernew - roller_num));
|
||||||
|
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata stop");
|
||||||
|
if (m_status == DEV_WRONG) {
|
||||||
|
return get_ErrorCode();
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (m_pImages->valid()) {
|
||||||
|
bmpdata = *(m_pImages->popBmpdata());
|
||||||
|
UpdateScanInfo(get_imgnReaded(), countNTransfered());
|
||||||
|
FileTools::writelog(log_lv::log_DEBUG, " aquire_bmpdata quit");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
DoEvents();
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(2));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL GScan439Android::IsConnected()
|
||||||
|
{
|
||||||
|
return m_usb.get() && m_usb->is_connected();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GScan439Android::GetFWVersion()
|
||||||
|
{
|
||||||
|
static std::string fw;// = "12312312";
|
||||||
|
if (m_usb.get() && m_usb->is_connected() && fw.empty())
|
||||||
|
{
|
||||||
|
write_reg(m_usb, SR_GET_FWVERSION, 0);
|
||||||
|
fw.resize(512);
|
||||||
|
m_usb->read_bulk(&fw[0], 512);
|
||||||
|
//read_data(&fw[0], fw.length(), 100);
|
||||||
|
}
|
||||||
|
return fw;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GScan439Android::GetSerialNum()
|
||||||
|
{
|
||||||
|
static std::string sn;// = "12333123123123";
|
||||||
|
if (m_usb.get() && m_usb->is_connected() && sn.empty())
|
||||||
|
{
|
||||||
|
write_reg(m_usb, SR_GET_SERIALNUM, 0);
|
||||||
|
sn.resize(512);
|
||||||
|
m_usb->read_bulk(&sn[0], 512);
|
||||||
|
//read_data(&sn[0], sn.length(), 100);
|
||||||
|
}
|
||||||
|
return sn;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GScan439Android::GetMacAdder()
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t GScan439Android::GetMotorFPGA()
|
||||||
|
{
|
||||||
|
return std::uint32_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::uint32_t GScan439Android::GetScanFPGA()
|
||||||
|
{
|
||||||
|
return std::uint32_t();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GScan439Android::is_scan()
|
||||||
|
{
|
||||||
|
return m_status == DEV_ISRUNNING || (m_imagedata.Size() > 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL GScan439Android::Get_Scanner_PaperOn()
|
||||||
|
{
|
||||||
|
return read_reg(m_usb, SR_GET_PAPERON);
|
||||||
|
}
|
||||||
|
|
||||||
|
int GScan439Android::Get_Roller_num()
|
||||||
|
{
|
||||||
|
return read_reg(m_usb, SR_GET_ROLLER_NUM);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::config_params(GScanCap& param)
|
||||||
|
{
|
||||||
|
m_param = param;
|
||||||
|
HGScanConfig cfg;
|
||||||
|
cfg.value = 0;
|
||||||
|
|
||||||
|
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 = param.resolution_dst >=300 ? 2 : 1;// SupResolutions.count(param.resolution_native) > 0 ? SupResolutions[param.resolution_native] : 1;
|
||||||
|
param.resolution_native = param.resolution_dst >= 300 ? 300 : 200;
|
||||||
|
cfg.g200params.double_feed_enbale = (unsigned int)param.hardwarecaps.en_doublefeed;
|
||||||
|
//cfg.g200params.stable_enbale = 0;
|
||||||
|
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;
|
||||||
|
|
||||||
|
write_reg(m_usb, SR_CONFIG_SCAN_PARAM, cfg.value);
|
||||||
|
m_pImages->setparam(param);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::Scanner_StartScan(UINT16 count)
|
||||||
|
{
|
||||||
|
error_index = 0;
|
||||||
|
roller_num = read_reg(m_usb, SR_GET_ROLLER_NUM);
|
||||||
|
|
||||||
|
Set_ErrorCode(0);
|
||||||
|
getimgnum = 0;
|
||||||
|
aquirenum = 0;
|
||||||
|
imagecount = 0;
|
||||||
|
reset();
|
||||||
|
m_status = DEV_ISRUNNING;
|
||||||
|
//if (read_reg(m_usb, SR_GET_SLEEP_STAUTUS) != 1)
|
||||||
|
//{
|
||||||
|
// m_status = DEV_WRONG;
|
||||||
|
// Set_ErrorCode(SLEEPING);
|
||||||
|
// scanflag = false;
|
||||||
|
// return;
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (!Get_Scanner_PaperOn())
|
||||||
|
{
|
||||||
|
m_status = DEV_WRONG;
|
||||||
|
Set_ErrorCode(NO_FEED);
|
||||||
|
scanflag = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int state = read_reg(m_usb, SR_GET_ANDROID_STATE);
|
||||||
|
if (state != 0)
|
||||||
|
{
|
||||||
|
if (state == 1) Set_ErrorCode(OPEN_COVER);
|
||||||
|
else if (state == 2) Set_ErrorCode(PAPER_JAM);
|
||||||
|
else if (state == 3) Set_ErrorCode(NO_FEED);
|
||||||
|
else Set_ErrorCode(HARDWARE_ERROR);
|
||||||
|
scanflag = false;
|
||||||
|
m_status = DEV_WRONG;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
write_reg(m_usb, 0x1000, m_param.is_duplex ? m_param.scannum /2 : m_param.scannum);
|
||||||
|
scanner_control(m_usb, SC_START);
|
||||||
|
|
||||||
|
|
||||||
|
if (!m_usbthread.get()) {
|
||||||
|
b_usbthread = true;
|
||||||
|
m_usbthread.reset(new thread(&GScan439Android::usbmainloop, this));
|
||||||
|
}
|
||||||
|
m_pImages->setscanflags(true);
|
||||||
|
m_pImages->run();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::Stop_scan()
|
||||||
|
{
|
||||||
|
scanner_control(m_usb, SC_STOP);
|
||||||
|
if ((m_status == DEV_WRONG) || (m_status == DEV_STOP))
|
||||||
|
return;
|
||||||
|
m_status = DEV_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GScan439Android::notifyscan()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::ResetScanner()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GScan439Android::Get_IsImageQueueEmpty()
|
||||||
|
{
|
||||||
|
return m_pImages->empty() && m_status == DEV_STOP;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::reset()
|
||||||
|
{
|
||||||
|
m_status = DEV_STOP;
|
||||||
|
m_pImages->clear();
|
||||||
|
//scanner_control(m_usb, SC_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::clear_hwerror()
|
||||||
|
{
|
||||||
|
//scanner_control(m_usb, SC_INIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
UINT32 GScan439Android::get_ErrorCode()
|
||||||
|
{
|
||||||
|
return Error_Code;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::Set_ErrorCode(UINT32 value)
|
||||||
|
{
|
||||||
|
Error_Code = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GScan439Android::get_scanned_num()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::set_sleep_time(int mode)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GScan439Android::set_scannercode(std::string str)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string GScan439Android::get_scannercode()
|
||||||
|
{
|
||||||
|
return std::string();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void GScan439Android::usbhotplug_callback(bool isconnect, void* userdata)
|
||||||
|
{
|
||||||
|
GScan439Android* This = (GScan439Android*)userdata;
|
||||||
|
This->usbhotplug(isconnect);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::usbhotplug(bool isleft)
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_ERROR, "enable usb callback ");
|
||||||
|
if (isleft) {
|
||||||
|
m_status = DEV_WRONG;
|
||||||
|
Error_Code = USB_DISCONNECTED;
|
||||||
|
m_pImages->setscanflags(false);
|
||||||
|
scanflag = false;
|
||||||
|
if (m_usb.get())
|
||||||
|
m_usb.reset();
|
||||||
|
if (huagods)
|
||||||
|
dev_callback(USB_DISCONNECTED, huagods);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int GScan439Android::read_data(void* data, int length, int timeout)
|
||||||
|
{
|
||||||
|
if (!m_usb.get() && !m_usb->is_connected())
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_INFO, "if (!m_usb.get() && !m_usb->is_connected())");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
timeout = std::max(1000, timeout);
|
||||||
|
|
||||||
|
int readed = 0;
|
||||||
|
int reading = 0;
|
||||||
|
const int buffer_size = 512 * 1024;
|
||||||
|
StopWatch sw;
|
||||||
|
FileTools::writelog(log_INFO, "read_data timeout =" + to_string(timeout));
|
||||||
|
while (readed < length) {
|
||||||
|
if (sw.elapsed_ms() < timeout && m_usb.get())
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
sw.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_INFO, "read usb image data time out ,time = " + std::to_string(sw.elapsed_ms()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::usbmainloop()
|
||||||
|
{
|
||||||
|
unsigned char buff[32];
|
||||||
|
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;
|
||||||
|
if (codeconvter(info) > 0 && get_ErrorCode() == 0)
|
||||||
|
{
|
||||||
|
Set_ErrorCode(codeconvter(info));
|
||||||
|
}
|
||||||
|
if (codeconvter(info) == -1)
|
||||||
|
{
|
||||||
|
m_readimgpool.enqueue([this] {
|
||||||
|
StopWatch stoptime;
|
||||||
|
while (stoptime.elapsed_s() < 3) {
|
||||||
|
if (read_reg(m_usb, SR_IM_COUNT) > 0)
|
||||||
|
{
|
||||||
|
readimg();
|
||||||
|
stoptime.reset();
|
||||||
|
}
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(200));
|
||||||
|
}
|
||||||
|
m_status = get_ErrorCode() == 0 ? DEV_STOP : DEV_WRONG;
|
||||||
|
m_pImages->setscanflags(false); });
|
||||||
|
}
|
||||||
|
switch (info.From)
|
||||||
|
{
|
||||||
|
case IMG:
|
||||||
|
m_readimgpool.enqueue([this] {
|
||||||
|
if (read_reg(m_usb, SR_IM_COUNT) > 0)
|
||||||
|
readimg();
|
||||||
|
});
|
||||||
|
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));
|
||||||
|
scanner_control(m_usb, SC_STOP);
|
||||||
|
break;
|
||||||
|
case STOPSCAN:
|
||||||
|
FileTools::writelog(log_INFO, "StopScan");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
FileTools::writelog(log_ERROR, "Got Unkown error code ! From =" + to_string(info.From) + " Code = " + to_string(info.Code));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
//this_thread::sleep_for(chrono::microseconds(10));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GScan439Android::readimg()
|
||||||
|
{
|
||||||
|
if (read_reg(m_usb, SR_IM_TXING))
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_ERROR, "Read image TXING");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (read_reg(m_usb, SR_IM_COUNT) > 0 && getStatus())
|
||||||
|
{
|
||||||
|
unsigned int len = read_reg(m_usb, SR_IM_FRONT_SIZE);
|
||||||
|
if (len > 0)
|
||||||
|
{
|
||||||
|
write_reg(m_usb, SR_IM_TX, 1);
|
||||||
|
im_data->resize(len);
|
||||||
|
static int indeximg = 0;
|
||||||
|
auto nreaded = tranxferimg(len, im_data);
|
||||||
|
if (nreaded == len)
|
||||||
|
{
|
||||||
|
m_pImages->pushMat(std::shared_ptr<IDecode>(new G400Decode(im_data)));
|
||||||
|
this_thread::sleep_for(chrono::milliseconds(10));
|
||||||
|
write_reg(m_usb, SR_IM_POP, 1);
|
||||||
|
FileTools::writelog(log_ERROR, "Enqueue image " + to_string(++indeximg) + "size " + to_string(nreaded));
|
||||||
|
UpdateScanInfo(countNReaded(), get_imgTransfered());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_ERROR, "error :read image data len error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileTools::writelog(log_ERROR, "error :Get front image data len ZERO" );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileTools::writelog(log_ERROR, "image queue empty or not scanning" );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int GScan439Android::tranxferimg(unsigned int datalen, std::shared_ptr<std::vector<char>> data)
|
||||||
|
{
|
||||||
|
unsigned int timeout = 3000;
|
||||||
|
unsigned int readed = 0;
|
||||||
|
unsigned int reading = 0;
|
||||||
|
const int buffer_size = 512 * 1024;
|
||||||
|
StopWatch sw;
|
||||||
|
while (readed < datalen)
|
||||||
|
{
|
||||||
|
if (sw.elapsed_ms() < timeout && m_usb.get())
|
||||||
|
{
|
||||||
|
reading = m_max(0, m_min(datalen - readed, buffer_size));
|
||||||
|
reading = m_usb->read_bulk((unsigned char*)data->data() + readed, reading);
|
||||||
|
if (reading > 0)
|
||||||
|
{
|
||||||
|
readed += reading;
|
||||||
|
sw.reset();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
FileTools::writelog(log_ERROR, "Read Image size zero");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FileTools::writelog(log_ERROR, "Read Image timeout" );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return readed;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int GScan439Android::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;
|
||||||
|
case 0x40000:
|
||||||
|
return PAPER_HOLE;
|
||||||
|
case 0x80000:
|
||||||
|
return MLTOP_TIMEOUT;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (code.From == HGType::V4L2)
|
||||||
|
{
|
||||||
|
switch (code.Code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return V4L2_AQULRE_ERROR;
|
||||||
|
case 1:
|
||||||
|
return V4L2_IMAGE_EMPTY;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (code.From == HGType::STOPSCAN)
|
||||||
|
{
|
||||||
|
switch (code.Code)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return -1;
|
||||||
|
case 1:
|
||||||
|
if (m_status == DEV_ISRUNNING)
|
||||||
|
m_status = DEV_STOP;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GScan439Android::getStatus()
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
int val = read_reg(m_usb, SR_STATUS) & 0x3;
|
||||||
|
bool ret = (val > 0) && (val < 4);
|
||||||
|
return ret;
|
||||||
|
}
|
|
@ -0,0 +1,76 @@
|
||||||
|
#pragma once
|
||||||
|
#include "stdafx.h"
|
||||||
|
#include "GScan.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 GScan439Android :
|
||||||
|
public IScanner
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
GScan439Android();
|
||||||
|
virtual ~GScan439Android();
|
||||||
|
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::string GetMacAdder() 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:
|
||||||
|
static void usbhotplug_callback(bool isconnect, void* userdata);
|
||||||
|
void usbhotplug(bool isleft);
|
||||||
|
int read_data(void* data, int length, int timeout);
|
||||||
|
void usbmainloop();
|
||||||
|
void readimg();
|
||||||
|
int tranxferimg(unsigned int datalen, std::shared_ptr<std::vector<char>> data);
|
||||||
|
int codeconvter(HGEIntInfo code);
|
||||||
|
bool getStatus();
|
||||||
|
private:
|
||||||
|
volatile int Error_Code;
|
||||||
|
volatile bool scanflag;
|
||||||
|
std::atomic_int imagecount;
|
||||||
|
int aquirenum = 0;
|
||||||
|
int getimgnum = 0;
|
||||||
|
GScanCap m_param;
|
||||||
|
std::shared_ptr<IUsb> m_usb;
|
||||||
|
volatile bool b_imgprothread;
|
||||||
|
volatile bool b_usbthread;
|
||||||
|
volatile int m_status;
|
||||||
|
|
||||||
|
ThreadPool m_readimgpool;
|
||||||
|
BlockingQueue<std::shared_ptr<std::vector<char>>> imgs;
|
||||||
|
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;
|
||||||
|
deviceevent_callback dev_callback;
|
||||||
|
void* huagods;
|
||||||
|
};
|
|
@ -440,7 +440,8 @@ void GScanO200::Scanner_StartScan(UINT16 count)
|
||||||
// return;
|
// return;
|
||||||
// }
|
// }
|
||||||
//#endif // !G200
|
//#endif // !G200
|
||||||
m_pImages->reset_DogEar();
|
|
||||||
|
m_pImages->reset_DogEar();
|
||||||
if (gcap.is_duplex)
|
if (gcap.is_duplex)
|
||||||
count = count == 65535 ? 65535 : count / 2;
|
count = count == 65535 ? 65535 : count / 2;
|
||||||
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
|
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
|
||||||
|
|
|
@ -371,11 +371,11 @@ void GScanO400::config_params(GScanCap& params)
|
||||||
G400ScanConfig cfg = G400ScanConfig(params);
|
G400ScanConfig cfg = G400ScanConfig(params);
|
||||||
UINT32 cfgdata = cfg.GetData();
|
UINT32 cfgdata = cfg.GetData();
|
||||||
auto fw = GetFWVersion();
|
auto fw = GetFWVersion();
|
||||||
if (atoi(fw.substr(4, 6).c_str()) >= 220117)
|
//if (atoi(fw.substr(4, 6).c_str()) >= 220117)
|
||||||
{
|
//{
|
||||||
if (params.papertype == 52 || params.papertype == 54 || params.papertype == 131 || params.papertype == 0)
|
// if (params.papertype == 52 || params.papertype == 54 || params.papertype == 131 || params.papertype == 0)
|
||||||
cfgdata = (cfgdata & 0xffffffe0) + 18;
|
// cfgdata = (cfgdata & 0xffffffe0) + 18;
|
||||||
}
|
//}
|
||||||
#ifdef G400
|
#ifdef G400
|
||||||
if (atoi(fw.substr(4, 6).c_str()) >= 220117)
|
if (atoi(fw.substr(4, 6).c_str()) >= 220117)
|
||||||
{
|
{
|
||||||
|
|
|
@ -190,6 +190,13 @@ enum Scanner_Reg_Defs
|
||||||
SR_SET_JSON,
|
SR_SET_JSON,
|
||||||
SR_GET_FILE_POS,
|
SR_GET_FILE_POS,
|
||||||
SR_SET_FILE_POS,
|
SR_SET_FILE_POS,
|
||||||
|
SR_NOTIFY_SLEEP,
|
||||||
|
SR_GET_FEEDMODE,
|
||||||
|
SR_SET_FEEDMODE,
|
||||||
|
SR_GET_AUTOMATICCONTROLFEEDMODE_ENABLE,
|
||||||
|
SR_SET_AUTOMATICCONTROLFEEDMODE_ENABLE,
|
||||||
|
SR_GET_AUTOMATICCONTROLFEEDMODE_THRESHOLD,
|
||||||
|
SR_SET_AUTOMATICCONTROLFEEDMODE_THRESHOLD,
|
||||||
SR_GET_CUO_ERROR = 0x50,
|
SR_GET_CUO_ERROR = 0x50,
|
||||||
SR_GET_DOU_ERROR,
|
SR_GET_DOU_ERROR,
|
||||||
SR_GET_JAM_ERROR,
|
SR_GET_JAM_ERROR,
|
||||||
|
@ -227,7 +234,10 @@ enum Scanner_Reg_Defs
|
||||||
SR_GET_MBVERSION_LENGHT,
|
SR_GET_MBVERSION_LENGHT,
|
||||||
SR_GET_MBVERSION,
|
SR_GET_MBVERSION,
|
||||||
SR_GET_USBVIDPID,
|
SR_GET_USBVIDPID,
|
||||||
SR_SET_USBVIDPID
|
SR_SET_USBVIDPID,
|
||||||
|
SR_SET_ANDROID_SCANCOUNT = 0x1000,
|
||||||
|
SR_GET_ANDROID_STATE = 0x1001,
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum Scanner_Cmd_Defs
|
enum Scanner_Cmd_Defs
|
||||||
|
|
|
@ -167,7 +167,7 @@ void ImageMatQueue::setparam(const GScanCap& param)
|
||||||
|
|
||||||
if (scanParam.fillhole.is_fillhole && scanParam.resolution_dst < 500) {
|
if (scanParam.fillhole.is_fillhole && scanParam.resolution_dst < 500) {
|
||||||
float ratio = scanParam.fillhole.fillholeratio / 100.0;
|
float ratio = scanParam.fillhole.fillholeratio / 100.0;
|
||||||
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyOutHole(200, ratio, 50)));
|
m_iaList.push_back(shared_ptr<CImageApply>(new CImageApplyOutHole(25, ratio, 40)));
|
||||||
} //确保能够获取正反两面图
|
} //确保能够获取正反两面图
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -359,6 +359,7 @@ struct GScanCap_3399
|
||||||
uint32_t dogeardistabce; /**< 折角检测理论顶点到实际轮廓最新距离>*/
|
uint32_t dogeardistabce; /**< 折角检测理论顶点到实际轮廓最新距离>*/
|
||||||
bool fadeback; /**< 除底色>*/
|
bool fadeback; /**< 除底色>*/
|
||||||
int fadebackrange; /**< 除底色范围>*/
|
int fadebackrange; /**< 除底色范围>*/
|
||||||
|
bool isuploadexceptionimage; /**< 是否上传双张报错后的异常图像>*/
|
||||||
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
|
uint32_t reserve[1024]; /**< 预留4096字节做协议扩展*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,8 +3,8 @@
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
#include <winioctl.h>
|
#include <winioctl.h>
|
||||||
|
|
||||||
//#ifdef ANDROIDSERIAL
|
#ifdef ANDROIDSERIAL
|
||||||
#if false
|
|
||||||
|
|
||||||
UsbScanEx::UsbScanEx(int index)
|
UsbScanEx::UsbScanEx(int index)
|
||||||
{
|
{
|
||||||
|
@ -30,9 +30,9 @@ bool UsbScanEx::open()
|
||||||
//ut.TimeoutEvent = 1;
|
//ut.TimeoutEvent = 1;
|
||||||
//ut.TimeoutRead = 1;
|
//ut.TimeoutRead = 1;
|
||||||
//ut.TimeoutWrite = 1;
|
//ut.TimeoutWrite = 1;
|
||||||
ut.TimeoutEvent = 0;
|
ut.TimeoutEvent = 1;
|
||||||
ut.TimeoutRead = 0;
|
ut.TimeoutRead = 2;
|
||||||
ut.TimeoutWrite = 0;
|
ut.TimeoutWrite = 3;
|
||||||
|
|
||||||
_stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), m_h_index);
|
_stprintf(szDevPath, TEXT("\\\\.\\Usbscan%d"), m_h_index);
|
||||||
m_h_dev = CreateFile(szDevPath,
|
m_h_dev = CreateFile(szDevPath,
|
||||||
|
@ -79,7 +79,6 @@ bool UsbScanEx::open()
|
||||||
CloseHandle(m_h_dev);
|
CloseHandle(m_h_dev);
|
||||||
m_h_dev = INVALID_HANDLE_VALUE;
|
m_h_dev = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
//FileTools::writelog(log_lv::log_INFO,"USB Open!");
|
|
||||||
return m_h_dev;
|
return m_h_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +114,6 @@ bool UsbScanEx::close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_b_is_connected = FALSE;
|
m_b_is_connected = FALSE;
|
||||||
//FileTools::writelog(log_lv::log_INFO,"USB Close!");
|
|
||||||
return b_ret;
|
return b_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -201,7 +199,7 @@ int UsbScanEx::control_msg(int rtype, int req, int value, int index, int len, vo
|
||||||
|
|
||||||
LPOVERLAPPED lp_overlap = ov + CTRL_IN_OUT;
|
LPOVERLAPPED lp_overlap = ov + CTRL_IN_OUT;
|
||||||
b_ret = DeviceIoControl(m_h_dev, IOCTL_SEND_USB_REQUEST, &irp, sizeof(irp), data, len, &dw_ret, NULL);
|
b_ret = DeviceIoControl(m_h_dev, IOCTL_SEND_USB_REQUEST, &irp, sizeof(irp), data, len, &dw_ret, NULL);
|
||||||
|
FileTools::writelog(log_ERROR, " USB control_msg ret = " + std::to_string(b_ret));
|
||||||
//if (!b_ret)
|
//if (!b_ret)
|
||||||
// b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0;
|
// b_ret = WaitForSingleObject(lp_overlap->hEvent, timeout) == WAIT_OBJECT_0;
|
||||||
|
|
||||||
|
@ -234,7 +232,8 @@ int UsbScanEx::read_int(void* data, int len)
|
||||||
return dw_ret;
|
return dw_ret;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
switch (GetLastError())
|
int error_code = GetLastError();
|
||||||
|
switch (error_code)
|
||||||
{
|
{
|
||||||
case ERROR_FILE_NOT_FOUND:
|
case ERROR_FILE_NOT_FOUND:
|
||||||
case ERROR_ACCESS_DENIED:
|
case ERROR_ACCESS_DENIED:
|
||||||
|
@ -244,7 +243,7 @@ int UsbScanEx::read_int(void* data, int len)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -393,7 +392,6 @@ bool UsbScanEx::open()
|
||||||
CloseHandle(m_h_dev);
|
CloseHandle(m_h_dev);
|
||||||
m_h_dev = INVALID_HANDLE_VALUE;
|
m_h_dev = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
//FileTools::writelog(log_lv::log_INFO,"USB Open!");
|
|
||||||
return m_h_dev;
|
return m_h_dev;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -446,7 +444,6 @@ bool UsbScanEx::close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_b_is_connected = FALSE;
|
m_b_is_connected = FALSE;
|
||||||
//FileTools::writelog(log_lv::log_INFO,"USB Close!");
|
|
||||||
return b_ret;
|
return b_ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -481,7 +478,7 @@ int UsbScanEx::read_bulk(void* data, int len)
|
||||||
#ifdef ANDROIDSERIAL
|
#ifdef ANDROIDSERIAL
|
||||||
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE);
|
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, TRUE);
|
||||||
#else
|
#else
|
||||||
WaitForSingleObject(lp_overlap->hEvent, 500);
|
WaitForSingleObject(lp_overlap->hEvent, 1000);
|
||||||
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE);
|
GetOverlappedResult(h_pipe, lp_overlap, &pdw_ret, FALSE);
|
||||||
#endif // ANDROIDSERIAL
|
#endif // ANDROIDSERIAL
|
||||||
return pdw_ret;
|
return pdw_ret;
|
||||||
|
@ -489,7 +486,6 @@ int UsbScanEx::read_bulk(void* data, int len)
|
||||||
case ERROR_FILE_NOT_FOUND:
|
case ERROR_FILE_NOT_FOUND:
|
||||||
case ERROR_ACCESS_DENIED:
|
case ERROR_ACCESS_DENIED:
|
||||||
m_b_is_connected = false;
|
m_b_is_connected = false;
|
||||||
//FileTools::writelog(log_lv::log_WARN, "errorcode =" + std::to_string(error_code));
|
|
||||||
if (hotplug_call) {
|
if (hotplug_call) {
|
||||||
hotplug_call(true, usrdata);
|
hotplug_call(true, usrdata);
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,7 @@ public:
|
||||||
{
|
{
|
||||||
log4cplus::SharedAppenderPtr rf(new log4cplus::RollingFileAppender(
|
log4cplus::SharedAppenderPtr rf(new log4cplus::RollingFileAppender(
|
||||||
path,
|
path,
|
||||||
2048 * 1024,
|
1024 * 1024 * 10,
|
||||||
5
|
5
|
||||||
));
|
));
|
||||||
rf->setName(LOG4CPLUS_TEXT("file"));
|
rf->setName(LOG4CPLUS_TEXT("file"));
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
#include "ImageApplyOutHole.h"
|
#include "ImageApplyOutHole.h"
|
||||||
#include "ImageProcess_Public.h"
|
#include "ImageProcess_Public.h"
|
||||||
|
|
||||||
|
#ifdef LOG
|
||||||
|
#include "Device/filetools.h"
|
||||||
|
#endif // LOG
|
||||||
|
|
||||||
CImageApplyOutHole::CImageApplyOutHole(void)
|
CImageApplyOutHole::CImageApplyOutHole(void)
|
||||||
: CImageApply()
|
: CImageApply()
|
||||||
, m_borderSize(600)
|
, m_borderSize(600)
|
||||||
|
@ -29,13 +33,23 @@ void CImageApplyOutHole::apply(cv::Mat& pDib, int side)
|
||||||
|
|
||||||
void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG
|
||||||
|
FileTools::write_log("imgprc.txt", "enter ImageOutHole apply");
|
||||||
|
#endif // LOG
|
||||||
|
|
||||||
if (mats.size() < 2)
|
if (mats.size() < 2)
|
||||||
{
|
{
|
||||||
|
#ifdef LOG
|
||||||
|
FileTools::write_log("imgprc.txt", "exit ImageOutHole apply");
|
||||||
|
#endif // LOG
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mats[0].empty() || mats[1].empty())
|
if (mats[0].empty() || mats[1].empty())
|
||||||
{
|
{
|
||||||
|
#ifdef LOG
|
||||||
|
FileTools::write_log("imgprc.txt", "exit ImageOutHole apply");
|
||||||
|
#endif // LOG
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,6 +77,9 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
|
std::vector<cv::Point> maxContour_front = hg::getMaxContour(contours_front, b1_front);
|
||||||
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
|
std::vector<cv::Point> maxContour_back = hg::getMaxContour(contours_back, b1_back);
|
||||||
|
|
||||||
|
if (maxContour_front.empty() || maxContour_back.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
|
cv::RotatedRect rrect_front = hg::getBoundingRect(maxContour_front); //提取正面最大轮廓的最小外接矩形
|
||||||
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
|
cv::RotatedRect rrect_back = hg::getBoundingRect(maxContour_back); //提取反面最大轮廓的最小外接矩形
|
||||||
|
|
||||||
|
@ -78,19 +95,25 @@ void CImageApplyOutHole::apply(std::vector<cv::Mat>& mats, bool isTwoSide)
|
||||||
|
|
||||||
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
|
cv::Mat roiMat_front(front_thre, roi_front); //在正面二值图像中截取重叠部分
|
||||||
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
|
cv::Mat roiMat_back(back_thre, roi_back); //在反面二值图像中截取重叠部分
|
||||||
|
//cv::imwrite("roiMat_front.jpg", roiMat_front);
|
||||||
|
//cv::imwrite("roiMat_back.jpg", roiMat_back);
|
||||||
|
|
||||||
//正反面二值图像做或运算,真正镂空区域保留0,其他地方填充为255
|
//正反面二值图像做或运算,真正镂空区域保留0,其他地方填充为255
|
||||||
cv::Mat mask;
|
cv::Mat mask;
|
||||||
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
|
cv::bitwise_or(roiMat_front, roiMat_back, mask); //或运算,正反面二值图像重叠
|
||||||
|
//cv::imwrite("mask1.jpg", mask);
|
||||||
|
|
||||||
//二值图像重叠图像颜色取反,膨胀,提取轮廓
|
//二值图像重叠图像颜色取反,膨胀,提取轮廓
|
||||||
cv::bitwise_not(mask, mask); //·´É«
|
cv::bitwise_not(mask, mask);
|
||||||
|
//cv::imwrite("mask2.jpg", mask); //·´É«
|
||||||
|
|
||||||
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));
|
element = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(10, 10));
|
||||||
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
|
cv::dilate(mask, mask, element, cv::Point(-1, -1), 1, cv::BORDER_CONSTANT, cv::Scalar(255)); //膨胀算法,增大孔洞连通区域面积
|
||||||
|
//cv::imwrite("mask3.jpg", mask);
|
||||||
|
|
||||||
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
|
//为了避免孔洞彻底贯穿纸边,人为绘制纸张轮廓,确保所有孔洞为封闭图形,不会与背景粘连
|
||||||
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(0), 15); //»æÖÆÖ½ÕžØÐαßÔµ
|
cv::polylines(mask, hg::getVertices(mask_rotatedRect), true, cv::Scalar(255), 15); //»æÖÆÖ½ÕžØÐαßÔµ
|
||||||
|
//cv::imwrite("mask4.jpg", mask);
|
||||||
|
|
||||||
std::vector<std::vector<cv::Point>> contours_mask;
|
std::vector<std::vector<cv::Point>> contours_mask;
|
||||||
std::vector<cv::Vec4i> b1_mask;
|
std::vector<cv::Vec4i> b1_mask;
|
||||||
|
@ -215,7 +238,11 @@ std::vector<std::vector<cv::Point>> CImageApplyOutHole::filterPoly(std::vector<s
|
||||||
if (m[i][2] != -1) continue;
|
if (m[i][2] != -1) continue;
|
||||||
|
|
||||||
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
|
cv::RotatedRect rrect = hg::getBoundingRect(contours[i]);
|
||||||
if (rrect.size.area() < areaThreshold) continue;
|
if (rrect.size.width < areaThreshold ||
|
||||||
|
rrect.size.height < areaThreshold ||
|
||||||
|
rrect.size.width > areaThreshold * 6 ||
|
||||||
|
rrect.size.height > areaThreshold * 6)
|
||||||
|
continue;
|
||||||
|
|
||||||
bool enabled = true;
|
bool enabled = true;
|
||||||
for (size_t j = 0, count = contours[i].size(); j < count; j++)
|
for (size_t j = 0, count = contours[i].size(); j < count; j++)
|
||||||
|
@ -293,10 +320,10 @@ uchar CImageApplyOutHole::getBackGroudChannelMean(const cv::Mat& gray, int total
|
||||||
hist_array[i] = hist.at<float>(i, 0);
|
hist_array[i] = hist.at<float>(i, 0);
|
||||||
|
|
||||||
int length = 1;
|
int length = 1;
|
||||||
const int length_max = 255 - m_threshold;
|
const int length_max = 255;
|
||||||
while (length < length_max)
|
while (length < length_max)
|
||||||
{
|
{
|
||||||
for (size_t i = m_threshold + 1; i < 256 - length; i++)
|
for (size_t i = 1; i < 256 - length; i++)
|
||||||
{
|
{
|
||||||
int count = 0;
|
int count = 0;
|
||||||
uint pixSum = 0;
|
uint pixSum = 0;
|
||||||
|
|
|
@ -6,12 +6,17 @@
|
||||||
* 生成时间:2020/11/21
|
* 生成时间:2020/11/21
|
||||||
* 最近修改时间:2020/05/12 v1.0
|
* 最近修改时间:2020/05/12 v1.0
|
||||||
* 2020/11/17 v1.1
|
* 2020/11/17 v1.1
|
||||||
* 2021/09/06 v1.2 调整默认二值化阈值,从原来的50调整为100。将填充颜色从局部颜色提取改为全局颜色提取。
|
* 2021/09/06 v1.2 调整默认二值化阈值,从原来的50调整为100。将填充颜色从局部颜色提取改为全局颜色提取。
|
||||||
* 2021/11/03 v1.3 增加逻辑,如果正反面图像尺寸差异超过10个像素,直接返回,不再进行除穿孔处理。
|
* 2021/11/03 v1.3 增加逻辑,如果正反面图像尺寸差异超过10个像素,直接返回,不再进行除穿孔处理。
|
||||||
* 2021/11/04 v1.4 增加背景抗噪机制,能够抗5像素的背景噪声。
|
* 2021/11/04 v1.4 增加背景抗噪机制,能够抗5像素的背景噪声。
|
||||||
* 2021/11/17 v1.5 调整代码格式,避免一些由于opencv版本导致的BUG。
|
* 2021/11/17 v1.5 调整代码格式,避免一些由于opencv版本导致的BUG。
|
||||||
* 2022/04/18 v1.6 修复由于图像超出边界导致的定位孔洞异常的BUG。
|
* 2022/04/18 v1.6 修复由于图像超出边界导致的定位孔洞异常的BUG。
|
||||||
* 版本号:v1.6
|
* 2022/05/04 v1.6.1 增加逻辑判断,如果出现黑图,直接返回,不对原图进行任何处理。
|
||||||
|
* 2022/07/16 v1.6.2 修复自动识别填充颜色的BUG
|
||||||
|
* 2022/07/18 v1.6.3 修复mask的一些逻辑错误
|
||||||
|
* 2022/07/18 v1.7 修复逻辑BUG,替换构造函数borderSize逻辑,由原来面积改为边长,定义穿孔范围为[borderSize, borderSize * 6]
|
||||||
|
* 2022/07/22 v1.7.1 修复自动识别填充颜色的BUG
|
||||||
|
* 版本号:v1.7.1
|
||||||
|
|
||||||
* ====================================================
|
* ====================================================
|
||||||
*/
|
*/
|
||||||
|
@ -72,4 +77,5 @@ private:
|
||||||
double m_threshold;
|
double m_threshold;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // !IMAGE_APPLY_OUT_HOLE_H
|
#endif // !IMAGE_APPLY_OUT_HOLE_H
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include "Device/GScanO400.h"
|
#include "Device/GScanO400.h"
|
||||||
#include "Device/GScanO400Android.h"
|
#include "Device/GScanO400Android.h"
|
||||||
#include "Device/GScanO1003399.h"
|
#include "Device/GScanO1003399.h"
|
||||||
|
#include "Device/GScan439Android.h"
|
||||||
#include "Device/filetools.h"
|
#include "Device/filetools.h"
|
||||||
#include "Device/GScanVirtual.h"
|
#include "Device/GScanVirtual.h"
|
||||||
#include <list>
|
#include <list>
|
||||||
|
@ -98,7 +99,7 @@ using namespace std::placeholders;
|
||||||
TWPP_ENTRY_MFC(HuagaoDs)
|
TWPP_ENTRY_MFC(HuagaoDs)
|
||||||
|
|
||||||
static constexpr const Identity srcIdent(
|
static constexpr const Identity srcIdent(
|
||||||
Version(3, 3, Language::English, Country::China, "v3.3.5.8"),
|
Version(3, 3, Language::English, Country::China, "v3.3.5.9"),
|
||||||
DataGroup::Image,
|
DataGroup::Image,
|
||||||
#ifdef MAKEHUAGAO
|
#ifdef MAKEHUAGAO
|
||||||
"HUAGO",
|
"HUAGO",
|
||||||
|
@ -202,8 +203,10 @@ static constexpr const Identity srcIdent(
|
||||||
#ifdef MAKEHUAGAO
|
#ifdef MAKEHUAGAO
|
||||||
#ifdef UV
|
#ifdef UV
|
||||||
"HUAGOSCAN G300UV TWAIN"
|
"HUAGOSCAN G300UV TWAIN"
|
||||||
|
#elif defined ANDROIDSERIAL
|
||||||
|
"HUAGOSCAN G300 Android TWAIN"// ¼æÈݾɼ«¿Î pm changed "HUAGOSCAN G300 TWAIN"
|
||||||
#else
|
#else
|
||||||
"HUAGOSCAN G300 TWAIN"// ¼æÈݾɼ«¿Î pm changed "HUAGOSCAN G300 TWAIN"
|
"HUAGOSCAN G300 Linux TWAIN"
|
||||||
#endif
|
#endif
|
||||||
#elif defined UV && defined MAKERIGHTWAY
|
#elif defined UV && defined MAKERIGHTWAY
|
||||||
"RIGHTWAYSCAN G300 TWAIN"
|
"RIGHTWAYSCAN G300 TWAIN"
|
||||||
|
@ -224,7 +227,11 @@ static constexpr const Identity srcIdent(
|
||||||
#endif
|
#endif
|
||||||
#elif defined(G400) // G200
|
#elif defined(G400) // G200
|
||||||
#ifdef MAKEHUAGAO
|
#ifdef MAKEHUAGAO
|
||||||
"HUAGOSCAN G400 TWAIN"
|
#ifdef ANDROIDSERIAL
|
||||||
|
"HUAGOSCAN G400 Android TWAIN"
|
||||||
|
#else
|
||||||
|
"HUAGOSCAN G400 Linux TWAIN"
|
||||||
|
#endif // ANDROIDSERIES
|
||||||
#elif defined HANVON
|
#elif defined HANVON
|
||||||
#ifdef ANDROIDSERIAL
|
#ifdef ANDROIDSERIAL
|
||||||
"Hanvon HW-7000 TAWIN"
|
"Hanvon HW-7000 TAWIN"
|
||||||
|
@ -333,6 +340,7 @@ static std::vector<Vid_pid> DeviceID{
|
||||||
#endif // ISG100
|
#endif // ISG100
|
||||||
#elif defined G300
|
#elif defined G300
|
||||||
{0x31c9,0x8420},
|
{0x31c9,0x8420},
|
||||||
|
{0x31c9,0x8429},
|
||||||
#elif defined G400
|
#elif defined G400
|
||||||
{0x31c9,0x8520},
|
{0x31c9,0x8520},
|
||||||
{0x31c9,0x8529},
|
{0x31c9,0x8529},
|
||||||
|
@ -396,10 +404,18 @@ static std::vector<Vid_pid> DeviceID{
|
||||||
#endif // ISG100
|
#endif // ISG100
|
||||||
#elif defined G300
|
#elif defined G300
|
||||||
{0x3072,0x0300},
|
{0x3072,0x0300},
|
||||||
{0x3072,0x0339},
|
#ifdef ANDROIDSERIAL
|
||||||
|
{0x3072,0x0302},
|
||||||
|
#else
|
||||||
|
{0x3072,0x0339},
|
||||||
|
#endif // ANDROIDSERIAL
|
||||||
#elif defined G400
|
#elif defined G400
|
||||||
{0x3072,0x0400},
|
{0x3072,0x0400},
|
||||||
{0x3072,0x0439},
|
#ifdef ANDROIDSERIAL
|
||||||
|
{0x3072,0x0402},
|
||||||
|
#else
|
||||||
|
{0x3072,0x0439},
|
||||||
|
#endif // ANDROIDSERIAL
|
||||||
#endif // ISG100
|
#endif // ISG100
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -881,6 +897,7 @@ Result HuagaoDs::capabilitySet(const Identity& origin, Capability& data) {
|
||||||
Result HuagaoDs::eventProcess(const Identity&, Event& event) {
|
Result HuagaoDs::eventProcess(const Identity&, Event& event) {
|
||||||
// Qt needs to process its events, otherwise the GUI will appear frozen
|
// Qt needs to process its events, otherwise the GUI will appear frozen
|
||||||
// this is Windows-only method, Linux and macOS behave differently
|
// this is Windows-only method, Linux and macOS behave differently
|
||||||
|
//FileTools::writelog(log_ERROR, "eventProcess " + to_string((int)event.message()));
|
||||||
if (guiTwain) {
|
if (guiTwain) {
|
||||||
// // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM
|
// // QApplication::processEvents(); - TODO: needs more investigation; results in freeze when attempting to scan using old DSM
|
||||||
// QApplication::sendPostedEvents();
|
// QApplication::sendPostedEvents();
|
||||||
|
@ -983,14 +1000,18 @@ Result HuagaoDs::identityOpenDs(const Identity&) {
|
||||||
scanner.reset(new GScanO200());
|
scanner.reset(new GScanO200());
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (pid == 0x339 || pid == 0x439 || pid == 0x7039 || pid == 0x8529)
|
if (pid == 0x339 || pid == 0x439 || pid == 0x7039 || pid == 0x8529 || pid == 0x8429)
|
||||||
scanner.reset(new GScanO1003399());
|
scanner.reset(new GScanO1003399());
|
||||||
else
|
else {
|
||||||
#ifdef ANDROIDSERIAL
|
#ifdef ANDROIDSERIAL
|
||||||
scanner.reset(new GScanO400Android());
|
if (pid == 0x402 || pid == 0x302)
|
||||||
|
scanner.reset(new GScan439Android());
|
||||||
|
else
|
||||||
|
scanner.reset(new GScanO400Android());
|
||||||
#else
|
#else
|
||||||
scanner.reset(new GScanO400());
|
scanner.reset(new GScanO400());
|
||||||
#endif
|
#endif
|
||||||
|
}
|
||||||
#endif // G400
|
#endif // G400
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2816,7 +2837,7 @@ Twpp::Result HuagaoDs::showTwainUI(Twpp::UserInterface& ui, bool bUiOnly)
|
||||||
::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect);
|
::GetWindowRect(static_cast<HWND>(ui.parent().raw()), &newRect);
|
||||||
if (newRect.top <= 0 || newRect.left <= 0)
|
if (newRect.top <= 0 || newRect.left <= 0)
|
||||||
newRect.top = newRect.left = 20;
|
newRect.top = newRect.left = 20;
|
||||||
SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE);
|
SetWindowPos(guiTwain->m_hWnd, HWND_TOP, newRect.left + 20, newRect.top + 100, 0, 0, SWP_SHOWWINDOW | SWP_NOSIZE | SWP_NOACTIVATE);
|
||||||
//SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
|
//SetWindowPos(guiTwain->m_hWnd, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOSIZE);
|
||||||
guiTwain->ShowWindow(SW_SHOWNORMAL);
|
guiTwain->ShowWindow(SW_SHOWNORMAL);
|
||||||
return success();
|
return success();
|
||||||
|
|
Binary file not shown.
BIN
huagao/stdafx.h
BIN
huagao/stdafx.h
Binary file not shown.
Loading…
Reference in New Issue