分离gscn_drv对象

以便加入新的协议
This commit is contained in:
罗颖 2019-12-05 16:08:36 +08:00
parent 2c56b028c2
commit 3e478314be
12 changed files with 84 additions and 445 deletions

View File

@ -15,7 +15,7 @@ private:
mutable std::mutex _mutex;
std::condition_variable _condvar;
std::deque<T> _queue;
bool isShutDown = false;
volatile bool isShutDown = false;
T tRet;
public:

View File

@ -47,7 +47,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include "scn_config.h"
#include "gscn_drv.h"
#include "PublicFunc.h"
#include "AutoCrop.h"
#include "ImageAdjustColors.h"
@ -57,6 +56,7 @@
#include "ImageProcDiscardBlank.h"
#include "filetools.h"
#include "hugaotwainds.h"
#include "GScanO200.h"
extern ChugaotwaindsApp theApp;
#ifdef TWH_CMP_MSC
@ -92,7 +92,8 @@ using namespace std;
extern HINSTANCE g_hinstance;
#endif
GScn_Drv g_drv;
//GScn_Drv g_drv;
std::shared_ptr<IGScan> g_scan(new GScanO200());
//////////////////////////////////////////////////////////////////////////////
CScanner_FreeImage::CScanner_FreeImage() :
@ -106,7 +107,7 @@ CScanner_FreeImage::CScanner_FreeImage() :
memset(m_szSourceImagePath, 0, PATH_MAX);
resetScanner();
InitMSGMap();
g_drv.open(0x064B, 0x7823);
g_scan->open(0x064B, 0x7823);
}
//////////////////////////////////////////////////////////////////////////////
@ -151,9 +152,9 @@ bool CScanner_FreeImage::resetScanner()
m_fXResolution = 200.0;
m_fYResolution = 200.0;
if (g_drv.Get_IsImageQueueEmpty() != 0)
if (g_scan->Get_IsImageQueueEmpty() != 0)
{
g_drv.reset();
g_scan->reset();
}
return bret;
}
@ -171,8 +172,8 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
{
if (getDeviceOnline())
{
g_drv.config_params(*(getSetting()));
g_drv.Scanner_StartScan(m_wScanCount);
g_scan->config_params(*(getSetting()));
g_scan->Scanner_StartScan(m_wScanCount);
}
else
{
@ -185,12 +186,12 @@ bool CScanner_FreeImage::acquireImage(bool bscan)
#ifdef HW_VER
m_matDib.release();
UINT32 ret = g_drv.aquire_image(m_matDib);
UINT32 ret = g_scan->aquire_image(m_matDib);
if (ret != 0)
{
std::string notify = StringToUtf("提示");
MessageBox(theApp.m_pMainWnd->GetSafeHwnd(), (TCHAR*)ntcMsg[ret].c_str(), (TCHAR*)notify.c_str(), MB_SYSTEMMODAL | MB_ICONINFORMATION | MB_OK);
g_drv.Set_ErrorCode(0);//复位异常码
g_scan->Set_ErrorCode(0);//复位异常码
return false;
}
#endif
@ -345,35 +346,35 @@ short CScanner_FreeImage::getDocumentCount() const
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::isFeederLoaded() const
{
bool rtn = g_drv.Get_Scanner_PaperOn();
bool rtn = g_scan->Get_Scanner_PaperOn();
return rtn;
}
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::getDeviceOnline() const
{
return g_drv.IsConnected();
return g_scan->IsConnected();
}
//////////////////////////////////////////////////////////////////////////////
std::string CScanner_FreeImage::getSerialNum() const
{
return g_drv.GetSerialNum();
return g_scan->GetSerialNum();
}
//////////////////////////////////////////////////////////////////////////////
std::string CScanner_FreeImage::getFWVersion() const
{
return g_drv.GetFWVersion();
return g_scan->GetFWVersion();
}
///////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::StopScan()
{
bool ret = true;
g_drv.Stop_scan();
g_scan->Stop_scan();
int retry_times = 0;
while (g_drv.is_scan())
while (g_scan->is_scan())
{
if (retry_times > 10)//超过还没停止则跳出 不进行DoCloseDSRequestEvent
{
@ -389,13 +390,13 @@ bool CScanner_FreeImage::StopScan()
//////////////////////////////////////////////////////////////////////////////
bool CScanner_FreeImage::isPaperOn() //const
{
return g_drv.Get_Scanner_PaperOn();
return g_scan->Get_Scanner_PaperOn();
}
bool CScanner_FreeImage::isImageQueueEmpty()
{
bool ret;
if (!g_drv.is_scan() && g_drv.Get_IsImageQueueEmpty() && (g_drv.get_ErrorCode() == 0))
if (!g_scan->is_scan() && g_scan->Get_IsImageQueueEmpty() && (g_scan->get_ErrorCode() == 0))
ret = true;
else
ret = false;
@ -404,6 +405,6 @@ bool CScanner_FreeImage::isImageQueueEmpty()
bool CScanner_FreeImage::stillhaveImage()
{
return g_drv.Get_IsImageQueueEmpty();
return g_scan->Get_IsImageQueueEmpty();
}

View File

@ -298,12 +298,13 @@ void GDevice::recv_main()
}
}
FILE* pfile = fopen((("d:\\") + std::to_string(image_index_c)+"b.jpg").c_str(), "wb");
fwrite(bbuf, 1, b_buffer_size, pfile);
fclose(pfile);
pfile = fopen((("d:\\") + std::to_string(image_index_c) + "f.jpg").c_str(), "wb");
fwrite(fbuf, 1, f_buffer_size, pfile);
fclose(pfile);
if (image_call)
{
if ((bbuf != NULL && b_buffer_size > 0)&&(fbuf != NULL && f_buffer_size > 0))
{
image_call(bbuf, b_buffer_size, fbuf, f_buffer_size, m_imagecall_userdata);
}
}
}
}
}
@ -320,10 +321,13 @@ void GDevice::Int_main()
{
image_indexs.Put(int_buffer[1]);
}
if (((MotorStatus*)int_buffer)->motor_status == 1)
MotorStatus ms;
ms.value =int_buffer[0];
if (event_call)
{
if (event_call) {
event_call(0, m_eventcall_userdata);
//0x3fe ==>b 1111 1111 10
if (ms.value & 0x3fe) {
event_call(ms.value, m_eventcall_userdata);
}
}
}
@ -501,5 +505,5 @@ void GDevice::trigger_scan(void)
bool GDevice::DataOn()
{
return read_reg(0x02, 0x03);
return read_reg(USERDEFINE, IMAGEREGS);
}

View File

@ -2,7 +2,7 @@
#include <vector>
typedef void(*image_callback)(void*, int, int, int, void*);
typedef void(*image_callback)(void*, int, void*, int, void*);
typedef void(*event_callback)(int, void*);
enum Cam_Options {

View File

@ -18,34 +18,35 @@ ImageMatQueue::ImageMatQueue(void)
m_threadProc = NULL;
at_prced_image_remains = 0;
atm_orgin_image_remains = 0;
}
void ImageMatQueue::run()
{
if (m_threadProc)
{
bRun = false;
at_prced_image_remains = 0;
atm_orgin_image_remains = 0;
m_threadProc->join();
delete m_threadProc;
m_threadProc = NULL;
}
bRun = true;
at_prced_image_remains = 0;
atm_orgin_image_remains = 0;
m_threadProc = new thread(&ImageMatQueue::proc, this);
m_threadProc.reset(new thread(&ImageMatQueue::proc, this));
}
void ImageMatQueue::run()
{
}
ImageMatQueue::~ImageMatQueue(void)
{
m_pImages.ShutDown();
m_images.ShutDown();
if (m_threadProc)
{
bRun = false;
at_prced_image_remains = 0;
atm_orgin_image_remains = 0;
m_threadProc->join();
delete m_threadProc;
m_threadProc = NULL;
}
}
@ -144,7 +145,6 @@ void ImageMatQueue::release_img_prc_thread()
at_prced_image_remains = 0;
atm_orgin_image_remains = 0;
m_threadProc->join();
delete m_threadProc;
m_threadProc = NULL;
iscanning = false;
}
@ -158,13 +158,17 @@ bool ImageMatQueue::empty()
void ImageMatQueue::proc()
{
JpegBuffer jb;
while (bRun)
{
this_thread::sleep_for(chrono::milliseconds(5));
{
if (m_pImages.Size() != 0)//m_images.Size() == 0 &&
jb = m_pImages.Take();
// if (m_pImages.Size() != 0)//m_images.Size() == 0 &&
if(!m_pImages.IsShutDown() && !jb.empty())
{
vector<cv::Mat> mats = m_pImages.Take().getMats();
vector<cv::Mat> mats = jb.getMats();
if (scanParam.m_OutHole.EnOutHole&& mats.size() == 2)//确保能够获取正反两面图
{
ImageOutHole outhole;

View File

@ -17,6 +17,7 @@
#include "ImageChannel.h"
#include "ImageProcDiscardBlank.h"
#include "ImageRotation.h"
#include <memory>
class ImageMatQueue
{
@ -43,7 +44,7 @@ private:
BlockingQueue<JpegBuffer> m_pImages;
std::mutex m_Locker;
std::mutex m_mtxJB;
thread* m_threadProc;
std::unique_ptr<thread> m_threadProc;
volatile bool bRun;
bool can_multi_outputR;
bool isduplex;

View File

@ -80,3 +80,8 @@ int JpegBuffer::getSide()
{
return m_side;
}
bool JpegBuffer::empty()
{
return matdatas.empty();
}

View File

@ -17,6 +17,8 @@ public:
std::vector<cv::Mat> getMats();
int getMFilter();
int getSide();
bool empty();
private:
cv::Mat m_buffer;

View File

@ -9,58 +9,24 @@
#include "hugaotwainds.h"
#include "filetools.h"
#include "UsbScanEx.h"
#include "opencv2/opencv.hpp"
extern ChugaotwaindsApp theApp;
GScn_Drv::GScn_Drv() :pixType(TJPF_BGR)
{
devState = DEV_STOP;
m_h_usb_thread = NULL;
m_threadUsb = NULL;
Error_Code = 0;
}
GScn_Drv::~GScn_Drv()
{
if (m_threadUsb)
{
devState = DEV_STOP;
m_threadUsb->join();
delete m_threadUsb;
m_threadUsb = NULL;
}
}
void GScn_Drv::open(int vid, int pid)
{
//usb_scan_dev devs = Devices(vid, pid);
//if (devs._NumberOfDevs != 0)
//{
// m_usb.open(devs.dev_infos[0].index);//同时存在多个同种扫描设备时默认选取第一个vid pid匹配的设备
// GetFWVersion();
// GetSerialNum();
//}
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
if (!usbs.empty()) {
m_usb = *usbs.begin();
m_usb->open();
if (m_usb->is_open()) {
GetFWVersion();
GetSerialNum();
}
}
}
static void DoEvents()
void DoEvents()
{
MSG msg;
if (PeekMessage(&msg
, NULL, 0, 0, PM_REMOVE))
{
if (PeekMessage(&msg , NULL, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
TranslateMessage(&msg);
@ -74,313 +40,11 @@ cv::Mat GScn_Drv::popMat()
return image;
}
int GScn_Drv::aquire_image(cv::Mat& image)
{
StopWatch sw;
sw.start();
double timeout;
while (true)
{
if (Get_IsImageQueueEmpty())
{
DoEvents();
sw.stop();
timeout = sw.time_run();
if (timeout > 15.00)
{
realse_thread();//释放USB线程
m_pImages.release_img_prc_thread();//释放图像处理线程
Stop_scan();//停止扫描
ResetScanner();
return HARDWARE_ERROR;
}
if (!is_scan())
{
if (devState == DEV_WRONG)
{
return get_ErrorCode();
}
return 0;
}
}
else
{
if (m_pImages.valid())
{
image = popMat();
return 0;
}
}
}
}
void GScn_Drv::reset()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
while (!m_pImages.empty())
{
m_pImages.clear();
}
}
void GScn_Drv::pushMat(JpegBuffer& data)
{
m_pImages.pushMat(data);
}
BOOL GScn_Drv::IsConnected()
{
return m_usb->is_connected();
}
cv::Mat GScn_Drv::Get_Img_Data(int bufferSize)
{
cv::Mat iData(1, bufferSize, CV_8UC1);
USBCB usbcb = { GET_IMAGE,0,(UINT32)bufferSize };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(iData.data, bufferSize);
return iData;
}
UINT32 GScn_Drv::get_ErrorCode()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
return Error_Code;
}
void GScn_Drv::Set_ErrorCode(UINT32 value)
{
std::lock_guard<std::mutex> lck(m_imgLocker);
Error_Code = value;
}
void GScn_Drv::run()
{
if (m_threadUsb)
{
devState = DEV_STOP;
m_threadUsb->join();
delete m_threadUsb;
m_threadUsb = NULL;
}
m_threadUsb = new thread(&GScn_Drv::usbmain, this);
}
void GScn_Drv::realse_thread()
{
if (m_threadUsb)
{
devState = DEV_STOP;
m_threadUsb->join();
delete m_threadUsb;
m_threadUsb = NULL;
}
}
void GScn_Drv::setdecodepixtype(int twpixtype)
{
if (twpixtype == TWPT_RGB)
pixType = TJPF_BGR;
else
pixType = TJPF_GRAY;
}
DWORD GScn_Drv::usbmain()
{
cv::Mat imgData;
cv::Mat bufferF;
cv::Mat bufferB;
devState = DEV_ISRUNNING;
while (devState == DEV_ISRUNNING)
{
if (!m_usb->is_connected())
{
this_thread::sleep_for(chrono::milliseconds(200));
continue;
}
USBCB usbcb = Get_Scanner_Status();
switch (usbcb.u32_Data)
{
case HAVE_IMAGE:
{
int totalNum = usbcb.u32_Count;
DWORD transferCount = 0;
imgData = Get_Img_Data(totalNum);
bufferF = Mat(imgData.rows, imgData.cols, CV_8UC1);
bufferB = Mat(imgData.rows, imgData.cols, CV_8UC1);
int j = 0;
int k = 0;
for (int i = 0; i < totalNum / 1024; i++)
{
if (imgData.data[1023 + i * 1024] == 0)
{
j++;
memcpy(&(bufferB.data[(j - 1) * 1023]), &(imgData.data[(j + k - 1) * 1024]), 1023);
}
else if (imgData.data[1023 + i * 1024] == 255)
{
k++;
memcpy(&(bufferF.data[(k - 1) * 1023]), &(imgData.data[(j + k - 1) * 1024]), 1023);
}
}
vector<Mat> mats;
mats.push_back(bufferB);
mats.push_back(bufferF);
pushMat(JpegBuffer(mats, pixType, 0));
imgData.release();
bufferB.release();
bufferF.release();
Pop_Image();
break;
}
case STOP_SCAN:
{
m_pImages.SetScanningStatus(false);
devState = DEV_STOP;
break;
}
case COUNT_MODE:
case NO_FEED:
case OPEN_COVER:
case FEED_IN_ERROR:
case PAPER_JAM:
case DETECT_DOUBLE_FEED:
case DETECT_STAPLE:
case PAPER_SKEW:
case HARDWARE_ERROR:
case PC_SCAN_BUSY_or_ERROR:
m_pImages.SetScanningStatus(false);
Set_ErrorCode(usbcb.u32_Data);
devState = DEV_WRONG;
break;
case NORMAL:
break;
default:
break;
}
this_thread::sleep_for(chrono::milliseconds(20));
}
m_h_usb_thread = NULL;
return 0;
}
void GScn_Drv::config_params(SFreeImage & params)
{
if (m_usb->is_connected())
{
hgConfigClass cfg(params);
UINT32 cfgdata = cfg.GetData();
USBCB usbcb = { CONFIGURED_DATA,cfgdata,0 };
m_usb->write_bulk(&usbcb, sizeof(USBCB));
setdecodepixtype(params.m_HardWareParams.PixType);
m_pImages.setparam(params);
}
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Scanner_StartScan(UINT16 count)
{
if (m_usb->is_connected())
{
std::lock_guard<std::mutex> lck(m_imgLocker);
DWORD transfer;
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
run();
m_pImages.SetScanningStatus(true);
m_pImages.run();
}
}
///////////////////////////////////////////////////////////////////////////
std::string GScn_Drv::GetFWVersion()
{
XdPrint("GetFWVersion \n");
if (m_usb->is_connected())
{
std::lock_guard<std::mutex> lck(m_imgLocker);
if (fwVersion.empty())
{
fwVersion = " ";
USBCB usbcb = { GET_FW_VERSION,8,0 };
m_usb->write_bulk( &usbcb, sizeof(usbcb));
m_usb->read_bulk(&fwVersion[0], 8);
}
return fwVersion;
}
return "";
}
///////////////////////////////////////////////////////////////////////////
std::string GScn_Drv::GetSerialNum()
{
if (m_usb->is_connected())
{
std::lock_guard<std::mutex> lck(m_imgLocker);
if (SerialNum.empty())
{
SerialNum = " ";
USBCB usbcb = { GET_SERIAL,12,0 };
m_usb->write_bulk( &usbcb, sizeof(usbcb));
m_usb->read_bulk(&SerialNum[0], 12);
}
return SerialNum;
}
return "";
}
///////////////////////////////////////////////////////////////////////////
USBCB GScn_Drv::Get_Scanner_Status()
{
if (!m_usb->is_connected())
{
USBCB errorType = { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 };
return errorType;
}
USBCB usbcb = { GET_DSP_STATUS ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
return usbcb;
}
///////////////////////////////////////////////////////////////////////////
bool GScn_Drv::is_scan()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
return devState == DEV_ISRUNNING;
}
///////////////////////////////////////////////////////////////////////////
BOOL GScn_Drv::Get_Scanner_PaperOn()
{
XdPrint("Get_Scanner_PaperOn \n");
if (!m_usb->is_open())
{
return FALSE;
}
USBCB usbcb = { GET_PAPER_STATUS ,0,0 };
std::lock_guard<std::mutex> lck(m_imgLocker);
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk( &usbcb, sizeof(usbcb));
return usbcb.u32_Data != 0;
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Pop_Image()
{
if (!m_usb->is_open())
{
return;
}
USBCB usbcb = { POP_IMAGE ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScn_Drv::trim(std::string &s)
{
int index = 0;
@ -392,33 +56,3 @@ void GScn_Drv::trim(std::string &s)
}
}
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Stop_scan()
{
if (!m_usb->is_connected())
{
return;
}
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { STOP ,0,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScn_Drv::ResetScanner()
{
if (!m_usb->is_connected())
return;
std::lock_guard<std::mutex> lck(m_imgLocker);
USBCB usbcb = { INIT_HARDWARE_SYS ,0,0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
///////////////////////////////////////////////////////////////////////////
bool GScn_Drv::Get_IsImageQueueEmpty()
{
std::lock_guard<std::mutex> lck(m_imgLocker);
return m_pImages.empty();
}

View File

@ -5,8 +5,6 @@
#include <queue>
#include <Windows.h>
#include "MutexEx.h"
#include "opencv2/core/core.hpp"
#include <opencv2\highgui\highgui.hpp>
#include "jpeglib.h"
#include <time.h>
#include <mutex>
@ -15,7 +13,6 @@
#include "PublicFunc.h"
#include "scn_config.h"
using namespace cv;
enum tagDevState
{
@ -32,8 +29,7 @@ enum tagEventIndex
EVENT_NUM
};
class
DiscardBlank;
class DiscardBlank;
class CImageApply;
class IGScan
@ -63,45 +59,20 @@ public:
class IUsb;
class GScn_Drv : IGScan
class GScn_Drv
{
public:
GScn_Drv();
virtual ~GScn_Drv();
void open(int vid, int pid);
int aquire_image(cv::Mat& image);
protected:
volatile UINT32 Error_Code;
BOOL IsConnected();
std::string GetFWVersion();
std::string GetSerialNum();
bool is_scan();
USBCB Get_Scanner_Status();
BOOL Get_Scanner_PaperOn();
void config_params(SFreeImage& params);
void Scanner_StartScan(UINT16 count);
void Stop_scan();
void ResetScanner();
bool Get_IsImageQueueEmpty();
void reset();
void setdecodepixtype(int twpixtype);
UINT32 get_ErrorCode();
void Set_ErrorCode(UINT32 value);
private:
cv::Mat popMat();
void pushMat(JpegBuffer& data);
cv::Mat Get_Img_Data(int buffersize);
void run();
void realse_thread();
DWORD usbmain();
void Pop_Image();
void trim(std::string &s);
// cscn_usb m_usb;
std::shared_ptr<IUsb> m_usb;
HANDLE m_h_usb_thread;
DWORD m_dw_ctrl_thread_id;
volatile int devState;
ImageMatQueue m_pImages;
@ -110,5 +81,6 @@ private:
std::string fwVersion;
std::string SerialNum;
int pixType;
thread* m_threadUsb;
};
};
void DoEvents();

View File

@ -229,6 +229,8 @@
<ClCompile Include="FeederPaper.cpp" />
<ClCompile Include="GDevice.cpp" />
<ClCompile Include="GDeviceLists.cpp" />
<ClCompile Include="GScan200.cpp" />
<ClCompile Include="GScanO200.cpp" />
<ClCompile Include="gscn_drv.cpp" />
<ClCompile Include="hugaotwainds.cpp" />
<ClCompile Include="ImageAdjustColors.cpp" />
@ -299,6 +301,8 @@
<ClInclude Include="filetools.h" />
<ClInclude Include="GDevice.h" />
<ClInclude Include="GDeviceLists.h" />
<ClInclude Include="GScan200.h" />
<ClInclude Include="GScanO200.h" />
<ClInclude Include="gscn_drv.h" />
<ClInclude Include="hugaotwainds.h" />
<ClInclude Include="IGDevice.h" />

View File

@ -195,6 +195,12 @@
<ClCompile Include="UsbScanEx.cpp">
<Filter>代码文件</Filter>
</ClCompile>
<ClCompile Include="GScan200.cpp">
<Filter>代码文件</Filter>
</ClCompile>
<ClCompile Include="GScanO200.cpp">
<Filter>代码文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<None Include="hugaotwainds.def">
@ -409,6 +415,12 @@
<ClInclude Include="UsbScanEx.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="GScan200.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="GScanO200.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="hugaotwainds.rc">