twain2/hugaotwainds/gscn_drv.cpp

406 lines
8.3 KiB
C++

#include "stdafx.h"
#include "gscn_drv.h"
#include "stdio.h"
#include "turbojpeg.h"
#include <map>
#include "twainEx.h"
#include "jpeglib.h"
#include "ImageApplyDiscardBlank.h"
#include "ImageApply.h"
#include "hugaotwainds.h"
#include "filetools.h"
using namespace boost;
extern ChugaotwaindsApp theApp;
GScn_Drv::GScn_Drv():
m_bRun(false),
devState(DEV_STOP),
Error_Code(0)
{}
GScn_Drv::~GScn_Drv()
{
if (m_threadUsb.joinable())
{
m_bRun = false;
boost::this_thread::sleep_for(boost::chrono::milliseconds(300));
}
}
void GScn_Drv::open(int vid, int pid)
{
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
if (!usbs.empty()) {
m_usb = *usbs.begin();
m_usb->open();
}
}
static void DoEvents()
{
MSG msg;
if (PeekMessage(&msg
, NULL, 0, 0, PM_REMOVE))
{
DispatchMessage(&msg);
TranslateMessage(&msg);
}
}
cv::Mat GScn_Drv::popMat()
{
cv::Mat image = m_pImages.popMat();
return image;
}
int GScn_Drv::aquire_image(cv::Mat& image)
{
StopWatch sw;
while (true)
{
if (Get_IsImageQueueEmpty())
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(1));
if(sw.time_run() > 20.00)
{
if (m_threadUsb.joinable())
{
devState = DEV_STOP;
m_threadUsb.join();
}
Stop_scan();//ֹͣɨÃè
ResetScanner();
return HARDWARE_ERROR;
}
if (!is_scan())
{
if (devState==DEV_WRONG)
return get_ErrorCode();
return 0;
}
}
else
{
DoEvents();
if (m_pImages.valid())
{
image = popMat();
return 0;
}
boost::this_thread::sleep_for(boost::chrono::milliseconds(2));//¼õÉÙCPU¿ªÏú
}
}
}
void GScn_Drv::reset()
{
while (!m_pImages.empty())
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(50));
m_pImages.clear();
}
}
void GScn_Drv::pushMat(JpegBuffer& data)
{
m_pImages.pushMat(data);
}
BOOL GScn_Drv::IsConnected()
{
return m_usb.get() && m_usb->is_connected();
}
cv::Mat GScn_Drv::Get_Img_Data(int bufferSize)
{
boost::lock_guard<boost::mutex> lck(m_Locker);
cv::Mat iData(1, bufferSize,CV_8UC1);
USBCB usbcb = { GET_IMAGE,0,bufferSize };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(iData.data, bufferSize);
return iData;
}
UINT32 GScn_Drv::get_ErrorCode()
{
return Error_Code;
}
void GScn_Drv::Set_ErrorCode(UINT32 value)
{
Error_Code=value;
}
void GScn_Drv::run()
{
if (!m_threadUsb.joinable())
{
m_bRun = true;
m_threadUsb = boost::thread(&GScn_Drv::usbmain, this);
}
}
void GScn_Drv::set_decompress_pix_type(int pixtype)
{
if (pixtype==TWPT_RGB)
pixType=TJPF_BGR;
else
pixType=TJPF_GRAY;
}
void GScn_Drv::SetIsDuplex(BOOL value){
m_pImages.setduplexflag(value);
}
void GScn_Drv::setlist(std::vector<std::shared_ptr<CImageApply> >list)
{
m_pImages.setlist(list);
}
static int indexIm = 0;
static int iii = 0;
DWORD GScn_Drv::usbmain()
{
cv::Mat imgData;// = Get_Img_Data(totalNum);
cv::Mat bufferF;// = imgData.clone();
cv::Mat bufferB;// = imgData.clone();
while (m_bRun)
{
if (!m_usb->is_connected())
{
boost::this_thread::sleep_for(boost::chrono::milliseconds(200));
continue;
}
USBCB usbcb = Get_Scanner_Status();
switch (usbcb.u32_Data)
{
case HAVE_IMAGE:
{
int totalNum = usbcb.u32_Count;
DWORD transferCount = 0;
vector<Mat> mats;
imgData = Get_Img_Data(totalNum);
#ifdef G200
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);
}
}
mats.push_back(bufferB);
mats.push_back(bufferF);
#else
mats.push_back(imgData);
#endif // G200
pushMat(JpegBuffer(mats, pixType,0));
mats.clear();
imgData.release();
bufferB.release();
bufferF.release();
Pop_Image();
break;
}
case STOP_SCAN:
{
devState = DEV_STOP;
m_pImages.setscanflag(false);
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:
devState = DEV_WRONG;
Set_ErrorCode(usbcb.u32_Data);
m_pImages.setscanflag(false);
break;
case NORMAL:
break;
default:
break;
}
boost::this_thread::sleep_for(boost::chrono::milliseconds(20));
}
return 0;
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Config_Scanner(PUSBCB pUSBCB)
{
if (m_usb->is_connected())
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
DWORD transfer;
m_usb->write_bulk(pUSBCB, sizeof(USBCB));
}
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Scanner_StartScan(UINT16 count)
{
//count = 0;
if (m_usb->is_connected())
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
DWORD transfer;
USBCB usbcb = { START_COMMAND,(UINT32)count ,0 };
m_usb->write_bulk(&usbcb, sizeof(usbcb));
devState = DEV_ISRUNNING;
m_pImages.pixType=pixType;
m_pImages.setscanflag(true);
m_pImages.run();
}
}
///////////////////////////////////////////////////////////////////////////
std::string GScn_Drv::GetFWVersion()
{
if (m_usb->is_connected())
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
std::string pFWVersion = " ";
#ifndef G200
pFWVersion.resize(10);
#else
pFWVersion.reserve(8);
#endif // G200
USBCB usbcb = { GET_FW_VERSION,pFWVersion.size(),0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&pFWVersion[0], pFWVersion.size());
return pFWVersion;
}
return "";
}
///////////////////////////////////////////////////////////////////////////
std::string GScn_Drv::GetSerialNum()
{
if (m_usb->is_connected())
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
std::string pserialNum = " ";
#ifndef G200
pserialNum.resize(14);
#else
pserialNum.reserve(12);
#endif // G200
USBCB usbcb = { GET_SERIAL,pserialNum.size(),0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&pserialNum[0], pserialNum.size());
return pserialNum;
}
return "";
}
///////////////////////////////////////////////////////////////////////////
USBCB GScn_Drv::Get_Scanner_Status()
{
if (!m_usb->is_connected())
{
USBCB errorType = { NO_COMMAND ,PC_SCAN_BUSY_or_ERROR ,0 };
return errorType;
}
boost::lock_guard<boost::mutex> lck(m_imgLocker);
USBCB usbcb = { GET_DSP_STATUS ,0,0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
m_usb->read_bulk(&usbcb, sizeof(usbcb));
return usbcb;
}
///////////////////////////////////////////////////////////////////////////
bool GScn_Drv::is_scan()
{
boost::lock_guard<boost::mutex> lck(m_imgLocker);
return devState == DEV_ISRUNNING;
}
///////////////////////////////////////////////////////////////////////////
BOOL GScn_Drv::Get_Scanner_PaperOn()
{
if (!m_usb->is_connected())
{
return FALSE;
}
USBCB usbcb = { GET_PAPER_STATUS ,0,0 };
DWORD transfer;
boost::lock_guard<boost::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_connected())
{
return;
}
boost::lock_guard<boost::mutex> lck(m_imgLocker);
USBCB usbcb = { POP_IMAGE ,0,0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
///////////////////////////////////////////////////////////////////////////
void GScn_Drv::Stop_scan()
{
if (!m_usb->is_connected())
{
return;
}
boost::lock_guard<boost::mutex> lck(m_imgLocker);
USBCB usbcb = { STOP ,0,0 };
DWORD transfer;
m_usb->write_bulk(&usbcb, sizeof(usbcb));
}
void GScn_Drv::ResetScanner()
{
if (!m_usb->is_connected())
return;
boost::lock_guard<boost::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()
{
return m_pImages.empty();
}