huago-corrcet_tools/HuaGoCorrect/gscan3399.cpp

792 lines
17 KiB
C++
Raw Permalink Normal View History

#include "stdafx.h"
#include "gscan3399.h"
#include "scn_usb.h"
#include "filetools.h"
#include <opencv2/opencv.hpp>
const std::string HG_SYSINFO_PATH = "/usr/local/huago/sysinfo.json";
using namespace cv;
static std::mutex mx_ctrl;
void DoEvents() {
MSG msg;
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
DispatchMessage(&msg);
TranslateMessage(&msg);
}
}
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);
}
gscan3399::gscan3399() :
m_imgthread(1)
{
im_data.reset(new std::vector<char>());
}
gscan3399::~gscan3399()
{
if (m_usbthread.get() && m_usbthread->joinable())
{
b_usbthread = false;
m_usbthread->join();
m_usbthread.reset();
}
if (m_usb.get())
m_usb.reset();
}
void gscan3399::open(int vid, int pid, int index)
{
if (m_usb.get() && m_usb->is_connected())
return;
auto usbs = UsbScan_List::find_vid_pid(vid, pid);
if (!usbs.empty())
{
m_usb = *usbs.begin();
VID = vid;
PID = pid;
m_usb->open();
if (m_usb->is_connected())
{
m_usb->set_usbhotplug_callback(gscan3399::usbcallback, this);
}
}
}
int gscan3399::aquire_image(std::string& image, int num)
{
StopWatch sw;
while (true)
{
if ((imgremains == 0) && (!is_runing()))
{
DoEvents();
this_thread::sleep_for(chrono::milliseconds(1));
if (!is_runing())
{
if (devState == DEV_WRONG)
return Error_Code;
return -1;
}
if (sw.elapsed_s() > 30.0)
{
devState = DEV_STOP;
Stop_scan();
ResetScanner();
return AQUIRE_IMAGE_TIMEOUT;
}
}
else
{
if ((m_imagespath.Size() > 0))
{
image = m_imagespath.Take();
imgremains--;
return 0;
}
DoEvents();
this_thread::sleep_for(chrono::milliseconds(2));
}
}
}
bool gscan3399::IsConnected()
{
return true;
}
std::string gscan3399::GetFWVersion()
{
std::string fw = "0123456789";
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;
}
void gscan3399::SetFWVersion()
{
}
std::string gscan3399::GetSerialNum()
{
std::string sr = "01234567890123";
if (m_usb.get() && m_usb->is_connected())
{
int length = scanner_read_reg(m_usb, SR_GET_SERIAL_LEN);
sr.resize(length);
scanner_write_reg(m_usb, SR_GET_SERIALNUM, 0);
read_data(&sr[0], sr.length(), 200);
}
return sr;
}
void gscan3399::SetSerialNum(std::string serial)
{
if (m_usb.get() && m_usb->is_connected())
{
scanner_write_reg(m_usb, SR_SET_SERIALNUM, serial.length());
m_usb->write_bulk(&serial[0], serial.length());
}
}
std::string gscan3399::GetIpAddr()
{
std::string version = "unkown";
if (m_usb.get() && m_usb->is_connected())
{
int length = scanner_read_reg(m_usb, SR_GET_IPADDR_LENGHT);
version.resize(length);
if (length > 0)
{
scanner_write_reg(m_usb, SR_GET_IPADDR, length);
read_data(&version[0], version.length(), 200);
}
}
return version;
}
std::string gscan3399::GetMbVersion()
{
std::string version = "unkown";
if (m_usb.get() && m_usb->is_connected())
{
int length = scanner_read_reg(m_usb, SR_GET_MBVERSION_LENGHT);
version.resize(length);
if (length > 0)
{
scanner_write_reg(m_usb, SR_GET_MBVERSION, length);
read_data(&version[0], version.length(), 200);
}
}
return version;
}
2021-08-17 01:07:55 +00:00
std::string gscan3399::GetKernelVersion()
{
std::string version = "unkown";
if (m_usb.get() && m_usb->is_connected())
{
int length = scanner_read_reg(m_usb, SR_KERNEL_VERSION_INFO_LENGTH);
version.resize(length);
if (length > 0)
{
scanner_write_reg(m_usb, SR_GET_KERNEL_VERSION, length);
read_data(&version[0], version.length(), 200);
}
}
return version;
}
2022-01-26 09:05:59 +00:00
void gscan3399::SetRatio(int tyepe, int ration,int dpi)
{
scanner_write_reg(m_usb, tyepe == 0 ? SR_SET_H_RATIO : SR_SET_V_RATIO, ration);
2022-01-27 01:50:36 +00:00
if (dpi == 1)
scanner_write_reg(m_usb, tyepe == 0 ? SR_SET_H_200_RATIO : SR_SET_V_200_RATIO, ration);
else if(dpi == 2)
scanner_write_reg(m_usb, tyepe == 0 ? SR_SET_H_300_RATIO : SR_SET_V_300_RATIO, ration);
else
scanner_write_reg(m_usb, tyepe == 0 ? SR_SET_H_600_RATIO : SR_SET_V_600_RATIO, ration);
}
2022-01-26 09:05:59 +00:00
void gscan3399::GetRatio(int type, int& ratio,int dpi)
{
2022-01-27 01:50:36 +00:00
if (dpi == 1)
ratio = scanner_read_reg(m_usb, type == 0 ? SR_GET_H_200_RATIO : SR_GET_V_200_RATIO);
else if (dpi == 2)
ratio = scanner_read_reg(m_usb, type == 0 ? SR_GET_H_300_RATIO : SR_GET_V_300_RATIO);
else
ratio = scanner_read_reg(m_usb, type == 0 ? SR_GET_H_600_RATIO : SR_GET_V_600_RATIO);
if(*((float*)&ratio) >1.2 || *((float*)&ratio) < 0.8)
ratio = scanner_read_reg(m_usb, type == 0 ? SR_GET_H_RATIO : SR_GET_V_RATIO);
}
2021-12-30 05:55:29 +00:00
void gscan3399::Reboot(bool loader)
{
2021-12-30 05:55:29 +00:00
scanner_write_reg(m_usb, SR_REBOOT, loader?1:0);
}
void gscan3399::PowerOff()
{
scanner_write_reg(m_usb, SR_POWEROFF, 0);
}
bool gscan3399::is_scan()
{
return 0;
}
bool gscan3399::Get_Scanner_PaperOn()
{
return true;
}
void gscan3399::Config_Scanner(HGScanConfig config)
{
m_config = config;
2021-08-17 01:07:55 +00:00
scanner_write_reg(m_usb, SR_CONFIG_SCAN_PARAM, config.value);
}
void gscan3399::Scanner_StartScan(UINT16 count)
{
scanner_cmd(m_usb, SC_START);
if (m_usbthread.get())
{
b_usbthread = false;
if (m_usbthread->joinable())
{
m_usbthread->join();
m_usbthread.reset();
}
}
b_usbthread = true;
m_usbthread.reset(new thread(&gscan3399::usb_run, this));
}
void gscan3399::Stop_scan()
{
scanner_cmd(m_usb, SC_STOP);
}
void gscan3399::ResetScanner()
{
}
bool gscan3399::Get_IsImageQueueEmpty()
{
return true;
}
void gscan3399::reset()
{
}
void gscan3399::run()
{
}
int gscan3399::get_decompress_pix_type()
{
return 0;
}
void gscan3399::set_decompress_pix_type(int pixtype)
{
}
2021-08-17 01:07:55 +00:00
void gscan3399::GetFlatMaxBright(bool iscolor, unsigned int& val)
{
if (m_usb.get() && m_usb->is_connected())
{
val= scanner_read_reg(m_usb, iscolor?SR_FLAT_CLR_MAX_BRIGHT:SR_FLAT_GRAY_MAX_BRIGHT);
}
}
void gscan3399::SetFlatMaxBright(bool iscolor, unsigned int val)
{
if (m_usb.get() && m_usb->is_connected())
{
scanner_write_reg(m_usb, iscolor ? SR_FLAT_CLR_MAX_BRIGHT : SR_FLAT_GRAY_MAX_BRIGHT,val);
}
}
bool gscan3399::Updata(std::string filename, std::function<void(long, long)> func)
{
std::ifstream updatefile;
updatefile.open(filename, std::ios_base::in | std::ios_base::binary);
if (!updatefile.is_open())
{
return false;
}
updatefile.seekg(0, std::ios::end);
size_t length = updatefile.tellg();
func(0, length);
updatefile.seekg(0, std::ios::beg);
scanner_write_reg(m_usb, 0x100, length);
size_t nreaded = 0;
size_t nleft = length;
int buffersize = 512 * 1024;
if (length <= buffersize)//С<><D0A1>1MB
{
char* uotstream = new char[length];
updatefile.read(uotstream, length);
m_usb->write_bulk(uotstream, length);
delete[] uotstream;
}
else
{
while (true)
{
int ntotransfer;
if (nleft < buffersize)
ntotransfer = nleft;
else
ntotransfer = buffersize;
std::vector<char> data;
data.resize(ntotransfer);
updatefile.read(data.data(), ntotransfer);
m_usb->write_bulk(data.data(), ntotransfer);
nreaded += ntotransfer;
nleft -= ntotransfer;
func(nreaded, length);
if (nreaded >= length)
break;
this_thread::sleep_for(std::chrono::milliseconds(5));
}
}
this_thread::sleep_for(std::chrono::milliseconds(200));
if (!scanner_read_reg(m_usb, 0x101))
return false;
auto now = std::chrono::steady_clock::now();
2022-05-09 07:47:56 +00:00
while (std::chrono::duration<double>(std::chrono::steady_clock::now() - now).count() < 70)
{
int status= scanner_read_reg(m_usb, 0x102);
if (status == 2)
{
scanner_read_reg(m_usb, 0x104);
return true;
}
if (status == 3)
{
scanner_read_reg(m_usb, 0x103);
return true;
}
if (status == 6)
{
return false;
}
this_thread::sleep_for(std::chrono::milliseconds(20));
}
return false;
}
void gscan3399::SetIsDuplex(bool value)
{
}
void gscan3399::ActiveteUSB()
{
}
int gscan3399::GetScanNum()
{
return scanner_read_reg(m_usb, SR_SCAN_COUNT);
}
int gscan3399::GetRollerNum()
{
uint32_t num = scanner_read_reg(m_usb, SR_GET_ROLLER_NUM);
return num;
}
void gscan3399::ClrRollerNum()
{
scanner_read_reg(m_usb, SR_CLR_ROLLER_NUM);
}
void gscan3399::ClrScanNum()
{
}
void gscan3399::SendFlatData(CorrectParam param, int index)
{
if (m_usb.get() && m_usb->is_connected())
{
scanner_write_reg(m_usb, SC_SET_CORRECT_PARAM, index);
HGCISConfig cisconfig = { 0 };
int t_index = index;
memcpy(cisconfig.expF, param.Exposures, sizeof(u32) * 3);
memcpy(cisconfig.expB, &param.Exposures[0] + 3, sizeof(u32) * 3);
memcpy(cisconfig.gainF, param.Gain, sizeof(u32) * 6);
memcpy(cisconfig.gainB, &param.Gain[0] + 6, sizeof(u32) * 6);
memcpy(cisconfig.offsetsF, param.Offset, sizeof(u32) * 6);
memcpy(cisconfig.offsetsB, &param.Offset[0] + 6, sizeof(u32) * 6);
m_usb->write_bulk(&cisconfig, sizeof(HGCISConfig));
}
}
CaptureParams gscan3399::GetFlatData()
{
CaptureParams param;
HGCorrectConfigs cisconfigs = { 0 };
scanner_write_reg(m_usb, SC_GET_CORRECT_PARAM, 0);
m_usb->read_bulk(&cisconfigs, sizeof(HGCorrectConfigs));
for (size_t i = 0; i < 2; i++)
{
memcpy(&param.correctColorExposure[0] + i * 3, i == 0 ? &cisconfigs.colorCorrect.expF[0] : &cisconfigs.colorCorrect.expB[0], sizeof(u32) * 3);
memcpy(&param.colorExposure[0] + i * 3, i == 0 ? &cisconfigs.color.expF[0] : &cisconfigs.color.expB[0], sizeof(u32) * 3);
memcpy(&param.correctGrayExposure[0] + i * 3, i == 0 ? &cisconfigs.grayCorrect.expF[0] : &cisconfigs.grayCorrect.expB[0], sizeof(u32) * 3);
memcpy(&param.grayExposure[0] + i * 3, i == 0 ? &cisconfigs.gray.expF[0] : &cisconfigs.gray.expB[0], sizeof(u32) * 3);
memcpy(&param.correctColorGain[0] + i * 6, i == 0 ? &cisconfigs.colorCorrect.gainF[0] : &cisconfigs.colorCorrect.gainB[0], sizeof(u32) * 6);
memcpy(&param.colorGain[0] + i * 6, i == 0 ? &cisconfigs.color.gainF[0] : &cisconfigs.color.gainB[0], sizeof(u32) * 6);
memcpy(&param.correctGrayGain[0] + i * 6, i == 0 ? &cisconfigs.grayCorrect.gainF[0] : &cisconfigs.grayCorrect.gainB[0], sizeof(u32) * 6);
memcpy(&param.grayGain[0] + i * 6, i == 0 ? &cisconfigs.gray.gainF[0] : &cisconfigs.gray.gainB[0], sizeof(u32) * 6);
memcpy(&param.correctColorOffset[0] + i * 6, i == 0 ? &cisconfigs.colorCorrect.offsetsF[0] : &cisconfigs.colorCorrect.offsetsB[0], sizeof(u32) * 6);
memcpy(&param.colorOffset[0] + i * 6, i == 0 ? &cisconfigs.color.offsetsF[0] : &cisconfigs.color.offsetsB[0], sizeof(u32) * 6);
memcpy(&param.correctGrayOffset[0] + i * 6, i == 0 ? &cisconfigs.grayCorrect.offsetsF[0] : &cisconfigs.grayCorrect.offsetsB[0], sizeof(u32) * 6);
memcpy(&param.grayOffset[0] + i * 6, i == 0 ? &cisconfigs.gray.offsetsF[0] : &cisconfigs.gray.offsetsB[0], sizeof(u32) * 6);
}
return param;
}
void gscan3399::StartFlat(bool iscolor)
{
int color = iscolor ? 1 : 0;
2021-08-17 01:07:55 +00:00
if (m_usbthread.get())
{
2021-08-17 01:07:55 +00:00
b_usbthread = false;
if (m_usbthread->joinable())
{
2021-08-17 01:07:55 +00:00
m_usbthread->join();
m_usbthread.reset();
}
}
2021-08-17 01:07:55 +00:00
b_usbthread = true;
m_usbthread.reset(new thread(&gscan3399::usb_run, this));
scanner_write_reg(m_usb, SC_AUTOCORRECT, color);
}
void gscan3399::DevStateChange()
{
}
int gscan3399::getMatSum()
{
return 0;
}
void gscan3399::close()
{
if (m_usb.get())
m_usb->close();
}
void gscan3399::GetExpose(int& Aside, int& Bside)
{
}
void gscan3399::SetExpose(int aside, int bside)
{
}
void gscan3399::GetSptime(int type, int& time)
{
if (type == 0)
time = scanner_read_reg(m_usb, SR_GET_GRAY_SP);
if (type == 1)
time = scanner_read_reg(m_usb, SR_GET_COLOR_SP);
}
void gscan3399::SetSptime(int type, int time)
{
if (type == 0)
scanner_write_reg(m_usb, SR_SET_GRAY_SP, time);
if (type == 1)
scanner_write_reg(m_usb, SR_SET_COLOR_SP, time);
}
void gscan3399::GetSleepTime(int& sleeptime)
{
char buf[100] = { 0 };
sleeptime = scanner_read_reg(m_usb, SR_GET_SLEEPTIME);
m_usb->read_bulk(buf,scanner_read_reg(m_usb, 0x200));
int x = 0;
}
void gscan3399::SetSleepTime(int sleeptime)
{
scanner_write_reg(m_usb, SR_SET_SLEEPTIME, sleeptime);
}
2021-08-17 01:07:55 +00:00
void gscan3399::SetFlatCallback(std::function<void(std::string)> func)
{
m_flatcallback = func;
}
void gscan3399::GetSpeedMode(int& speedmode, bool get)
{
if (m_usb.get() && m_usb->is_connected())
{
if (get)
{
speedmode= scanner_read_reg(m_usb, SR_GET_SPEEDMODE);
}
else
{
scanner_write_reg(m_usb, SR_SET_SPEEDMODE,speedmode);
}
}
}
void gscan3399::GetOrSetVIDPID(int& value, bool get)
{
2021-12-17 03:53:16 +00:00
if (m_usb.get() && m_usb->is_connected())
{
if (get)
value = scanner_read_reg(m_usb, SR_GET_USBVIDPID);
else
scanner_write_reg(m_usb, SR_SET_USBVIDPID, value);
}
}
2022-01-26 09:05:59 +00:00
std::string gscan3399::GetSysInfo()
{
auto info = GetDeviceFile(HG_SYSINFO_PATH);
if(info.empty())
return "Unsupported";
return info;
2022-01-26 09:05:59 +00:00
}
void gscan3399::usbcallback(bool isleft, void* usrdata)
{
gscan3399* This = (gscan3399*)usrdata;
This->OnUsbHotplug(isleft);
}
int gscan3399::read_data(void* data, int length, int timeout)
{
int nread = 0;
int reading = 0;
const int buffer_size = 2 * 1024 * 1024;
StopWatch sw;
while (nread < length && sw.elapsed_ms() < timeout) {
reading = std::max(0, std::min(length - nread, buffer_size));
reading = m_usb->read_bulk((unsigned char*)data + nread, reading);
if (reading > 0) {
nread += reading;
}
}
return nread;
}
void gscan3399::get_imgdata()
{
m_imgthread.enqueue([this] {
while (get_imgremains())
{
if (is_bulktransferring())
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
continue;
}
imgremains++;
auto& buffi = im_data;
int count = front_datasize();
buffi->resize(count);
bulk_starttransfer();
std::this_thread::sleep_for(std::chrono::milliseconds(1));
count = read_data(buffi->data(), count, count / (0.01 * 1024 * 1024));
popimg();
imgproce(buffi);
}
});
}
bool gscan3399::is_runing()
{
return scanner_read_reg(m_usb, SR_STATUS) & 0x03;
}
bool gscan3399::bulk_starttransfer()
{
scanner_write_reg(m_usb, SR_IM_TX, 1);
return true;
}
bool gscan3399::is_bulktransferring()
{
return scanner_read_reg(m_usb, SR_IM_TXING);
}
void gscan3399::popimg()
{
scanner_write_reg(m_usb, SR_IM_POP, 1); //!< to-list
}
int gscan3399::front_datasize()
{
return scanner_read_reg(m_usb, SR_IM_FRONT_SIZE);
}
int gscan3399::get_imgremains()
{
return scanner_read_reg(m_usb, SR_IM_COUNT); //!< to-list ;
}
void gscan3399::imgproce(std::shared_ptr<std::vector<char>>& buffs)
{
vector<cv::Mat> mats;
bool isbwimg = false;
auto rmc = m_config.g200params.color? cv::IMREAD_COLOR:cv::IMREAD_GRAYSCALE;
if (buffs->at(0) == -119 && buffs->at(1) == 0x50 && buffs->at(2) == 0x4e && buffs->at(3) == 0x47)//blackwhite
{
isbwimg = true;
rmc = cv::IMREAD_GRAYSCALE;
}
cv::Mat mat = cv::imdecode(*buffs, rmc);
time_t timp;
tm* p;
time(&timp);
p = localtime(&timp);
std::string filename = std::to_string(p->tm_hour) + "_" + std::to_string(p->tm_min) + "_" + std::to_string(p->tm_sec);
static int indeximg = 0;
2021-08-17 01:07:55 +00:00
++indeximg;
auto str = indeximg % 2 == 1 ? "F" : "B";
std::string path = csPath+"\\"+filename + str+".png";
if (!mat.empty()) {
cv::imwrite(path, mat);
m_imagespath.Put(path);
}
}
void gscan3399::OnUsbHotplug(bool isleft)
{
}
void gscan3399::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));
2021-08-17 01:07:55 +00:00
if (((length) == sizeof(buff)))
{
HGEIntInfo info = *(HGEIntInfo*)&buff;
switch (info.From)
{
case IMG:
get_imgdata();
break;
2021-08-17 01:07:55 +00:00
case AutoCorrect:
if (info.Img_Index != 0)
{
std::string s_info;
s_info.resize(info.Img_Index);
m_usb->read_bulk(&s_info[0], s_info.length());
//FileTools::write_log("D:\\info.txt", s_info);
if (m_flatcallback)
m_flatcallback(s_info);
}
if (info.Code == 4)//flat done
return;
break;
default:
break;
}
Error_Code = codeconvter(info);
if (Error_Code != 0)
{
devState = Error_Code == -1 ? DEV_STOP : DEV_WRONG;
}
this_thread::sleep_for(chrono::microseconds(2));
}
}
}
int gscan3399::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;
break;
case 1:
return V4L2_IMAGE_EMPTY;
default:
break;
}
}
if (code.From == HGType::STOPSCAN)
return -1;
return 0;
}
std::string gscan3399::GetDeviceFile(std::string path)
{
if (m_usb->is_open() && path.size() > 1)
{
scanner_write_reg(m_usb, SR_SET_JSON_PATH, path.size());
m_usb->write_bulk(&path[0], path.size());
int size = 0;
if (size = scanner_read_reg(m_usb, SR_GET_JOSN_SIZE))
{
std::string buff;
buff.resize(size);
scanner_write_reg(m_usb, SR_GET_JSON, size);
m_usb->read_bulk(&buff[0], size);
return buff;
}
return "";
}
return "";
}