409 lines
8.6 KiB
C++
409 lines
8.6 KiB
C++
#include "stdafx.h"
|
||
#include "gscn_drv.h"
|
||
#include "stdio.h"
|
||
#include "turbojpeg.h"
|
||
#include "PublicFunc.h"
|
||
#include <map>
|
||
#include "twainEx.h"
|
||
#include "jpeglib.h"
|
||
#include "ImageProcDiscardBlank.h"
|
||
#include "ImageApply.h"
|
||
|
||
GScn_Drv::GScn_Drv()
|
||
: m_discard(new CImageProcDiscardBlank()),canUseDiscardBlank(false)
|
||
{
|
||
//run();
|
||
m_bRun = false;
|
||
devState = DEV_STOP;
|
||
isDuplex=TRUE;
|
||
m_h_usb_thread=NULL;
|
||
}
|
||
|
||
GScn_Drv::~GScn_Drv()
|
||
{
|
||
if (m_threadUsb.joinable())
|
||
{
|
||
//XdPrint("out 1");
|
||
m_bRun = false;
|
||
//m_threadUsb.join();
|
||
}
|
||
}
|
||
|
||
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);
|
||
}
|
||
}
|
||
|
||
static void DoEvents()
|
||
{
|
||
MSG msg;
|
||
if (PeekMessage(&msg
|
||
, NULL, 0, 0, PM_REMOVE))
|
||
{
|
||
DispatchMessage(&msg);
|
||
|
||
TranslateMessage(&msg);
|
||
}
|
||
}
|
||
|
||
cv::Mat GScn_Drv::popMat()
|
||
{
|
||
boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
cv::Mat image = m_pImages.popMat();
|
||
return image;
|
||
}
|
||
|
||
twainImage GScn_Drv::PopTwainImage()
|
||
{
|
||
//boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
//cv::Mat image = m_pImages.front().getMat(pixType);
|
||
//int side=m_pImages.front().getSide();
|
||
//twainImage img(image,side);
|
||
//m_pImages.pop();
|
||
return cv::Mat();
|
||
}
|
||
|
||
int GScn_Drv::aquire_image(cv::Mat& image)
|
||
{
|
||
while (true)
|
||
{
|
||
if (Get_IsImageQueueEmpty())
|
||
{
|
||
//Sleep(100);
|
||
DoEvents();
|
||
if (!is_scan())
|
||
break;
|
||
}
|
||
else
|
||
{
|
||
if (m_pImages.valid())
|
||
{
|
||
image = popMat();
|
||
return 0;
|
||
}
|
||
}
|
||
}
|
||
return -1;
|
||
}
|
||
|
||
void GScn_Drv::reset()
|
||
{
|
||
boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
while (!m_pImages.empty())
|
||
{
|
||
m_pImages.clear();
|
||
}
|
||
}
|
||
|
||
void GScn_Drv::pushMat(JpegBuffer& data)
|
||
{
|
||
//boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
m_pImages.pushMat(data);
|
||
}
|
||
|
||
BOOL GScn_Drv::IsConnected()
|
||
{
|
||
return 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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
m_usb.Read_Data(iData.data, bufferSize, 600, &transfer);
|
||
return iData;
|
||
}
|
||
|
||
void GScn_Drv::run()
|
||
{
|
||
if (!m_threadUsb.joinable())
|
||
{
|
||
m_bRun = true;
|
||
m_threadUsb = boost::thread(&GScn_Drv::usbmain, this);
|
||
}
|
||
}
|
||
|
||
INT GScn_Drv::get_decompress_pix_type()
|
||
{
|
||
return pixType;
|
||
}
|
||
|
||
void GScn_Drv::set_decompress_pix_type(int pixtype)
|
||
{
|
||
if (pixtype==TWPT_RGB)
|
||
{
|
||
pixType=TJPF_BGR;
|
||
}
|
||
else
|
||
{
|
||
pixType=TJPF_GRAY;
|
||
}
|
||
}
|
||
|
||
void GScn_Drv::enableDiscardBlank(bool bVal)
|
||
{
|
||
canUseDiscardBlank=bVal;
|
||
}
|
||
|
||
void GScn_Drv::SetIsDuplex(BOOL value)
|
||
{
|
||
isDuplex=value;
|
||
}
|
||
|
||
void GScn_Drv::SetRotate(int rotateType)
|
||
{
|
||
m_rotate=rotateType;
|
||
}
|
||
|
||
void GScn_Drv::SetBackRotate(bool enBackRoate)
|
||
{
|
||
backRotate=enBackRoate;
|
||
}
|
||
|
||
void GScn_Drv::setlist(std::vector<std::shared_ptr<CImageApply> >list)
|
||
{
|
||
m_pImages.setlist(list);
|
||
}
|
||
|
||
DWORD GScn_Drv::usbmain()
|
||
{
|
||
while (m_bRun)
|
||
{
|
||
if (!m_usb.is_connected())
|
||
{
|
||
Sleep(200);
|
||
continue;
|
||
}
|
||
USBCB usbcb = Get_Scanner_Status();
|
||
switch (usbcb.u32_Data)
|
||
{
|
||
case HAVE_IMAGE:
|
||
{
|
||
int totalNum = usbcb.u32_Count;
|
||
DWORD transferCount = 0;
|
||
|
||
cv::Mat imgData = Get_Img_Data(totalNum);
|
||
cv::Mat bufferF = imgData.clone();
|
||
cv::Mat bufferB = imgData.clone();
|
||
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);
|
||
}
|
||
}
|
||
|
||
pushMat(JpegBuffer(bufferB,pixType,0,0));
|
||
//XdPrint("Enter Front\n");
|
||
if (isDuplex)
|
||
{
|
||
pushMat(JpegBuffer(bufferF,pixType,1,0));
|
||
//XdPrint("Enter Back\n");
|
||
}
|
||
Pop_Image();
|
||
break;
|
||
}
|
||
case STOP_SCAN:
|
||
{
|
||
devState = DEV_STOP;
|
||
break;
|
||
}
|
||
case COUNT_MODE:
|
||
MessageBox(NULL, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˳<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģʽ<EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case NO_FEED:
|
||
MessageBox(NULL, "<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD>ţ<EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONEXCLAMATION);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case OPEN_COVER:
|
||
MessageBox(NULL, "ɨ<EFBFBD><EFBFBD><EFBFBD>ǿ<EFBFBD><EFBFBD>ǣ<EFBFBD>", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case FEED_IN_ERROR:
|
||
MessageBox(NULL, "ʰֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case PAPER_JAM:
|
||
MessageBox(NULL, "<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case DETECT_DOUBLE_FEED:
|
||
MessageBox(NULL, "˫<EFBFBD>ţ<EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case DETECT_STAPLE:
|
||
MessageBox(NULL, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>룡", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case PAPER_SKEW:
|
||
MessageBox(NULL, "ֽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case HARDWARE_ERROR:
|
||
MessageBox(NULL, "Ӳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case PC_SCAN_BUSY_or_ERROR:
|
||
MessageBox(NULL, "PC<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "<EFBFBD><EFBFBD>ʾ", MB_OK | MB_ICONERROR);
|
||
devState = DEV_WRONG;
|
||
break;
|
||
case NORMAL:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
Sleep(5);
|
||
}
|
||
m_h_usb_thread = NULL;
|
||
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.bulk_out(0x00, pUSBCB, sizeof(USBCB), &transfer);
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
devState = DEV_ISRUNNING;
|
||
m_pImages.pixType=pixType;
|
||
m_pImages.run();
|
||
}
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
std::string GScn_Drv::GetFWVersion()
|
||
{
|
||
if (m_usb.is_connected())
|
||
{
|
||
boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
std::string pFWVersion = " ";
|
||
USBCB usbcb = { GET_FW_VERSION,8,0 };
|
||
DWORD transfer;
|
||
m_usb.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
m_usb.Read_Data(&pFWVersion[0], 8, 100, &transfer);
|
||
return pFWVersion;
|
||
}
|
||
return "";
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
std::string GScn_Drv::GetSerialNum()
|
||
{
|
||
if (m_usb.is_connected())
|
||
{
|
||
boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
std::string pserialNum = " ";
|
||
USBCB usbcb = { GET_SERIAL,12,0 };
|
||
DWORD transfer;
|
||
m_usb.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
m_usb.Read_Data(&pserialNum[0], 12, 100, &transfer);
|
||
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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
m_usb.Read_Data(&usbcb, sizeof(usbcb), 100, &transfer);
|
||
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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
m_usb.bulk_in(0x00, &usbcb, sizeof(usbcb), 200, &transfer);
|
||
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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
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.bulk_out(0x00, &usbcb, sizeof(usbcb), &transfer);
|
||
}
|
||
|
||
///////////////////////////////////////////////////////////////////////////
|
||
bool GScn_Drv::Get_IsImageQueueEmpty()
|
||
{
|
||
boost::lock_guard<boost::mutex> lck(m_imgLocker);
|
||
return m_pImages.empty();
|
||
}
|