huago-corrcet_tools/HuaGoCorrect/gscan3399.cpp

792 lines
17 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}
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;
}
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);
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);
}
void gscan3399::GetRatio(int type, int& ratio,int dpi)
{
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);
}
void gscan3399::Reboot(bool loader)
{
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;
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)
{
}
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();
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;
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));
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);
}
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)
{
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);
}
}
std::string gscan3399::GetSysInfo()
{
auto info = GetDeviceFile(HG_SYSINFO_PATH);
if(info.empty())
return "Unsupported";
return info;
}
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;
++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));
if (((length) == sizeof(buff)))
{
HGEIntInfo info = *(HGEIntInfo*)&buff;
switch (info.From)
{
case IMG:
get_imgdata();
break;
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 "";
}