#include "stdafx.h" #include "gscan3399.h" #include "scn_usb.h" #include "filetools.h" #include 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& usb, int addr) { int val = 0; std::lock_guard 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& usb, int addr, int val) { std::lock_guard lck(mx_ctrl); usb->control_msg(0x40, USB_REQ_SET_DEV_REGS, addr, 0, 4, &val); } static void scanner_cmd(std::shared_ptr& usb, int cmd) { scanner_write_reg(usb, 0, cmd); } gscan3399::gscan3399() : m_imgthread(1) { im_data.reset(new std::vector()); } 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 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)//ะกำฺ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 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(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, ¶m.Exposures[0] + 3, sizeof(u32) * 3); memcpy(cisconfig.gainF, param.Gain, sizeof(u32) * 6); memcpy(cisconfig.gainB, ¶m.Gain[0] + 6, sizeof(u32) * 6); memcpy(cisconfig.offsetsF, param.Offset, sizeof(u32) * 6); memcpy(cisconfig.offsetsB, ¶m.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(¶m.correctColorExposure[0] + i * 3, i == 0 ? &cisconfigs.colorCorrect.expF[0] : &cisconfigs.colorCorrect.expB[0], sizeof(u32) * 3); memcpy(¶m.colorExposure[0] + i * 3, i == 0 ? &cisconfigs.color.expF[0] : &cisconfigs.color.expB[0], sizeof(u32) * 3); memcpy(¶m.correctGrayExposure[0] + i * 3, i == 0 ? &cisconfigs.grayCorrect.expF[0] : &cisconfigs.grayCorrect.expB[0], sizeof(u32) * 3); memcpy(¶m.grayExposure[0] + i * 3, i == 0 ? &cisconfigs.gray.expF[0] : &cisconfigs.gray.expB[0], sizeof(u32) * 3); memcpy(¶m.correctColorGain[0] + i * 6, i == 0 ? &cisconfigs.colorCorrect.gainF[0] : &cisconfigs.colorCorrect.gainB[0], sizeof(u32) * 6); memcpy(¶m.colorGain[0] + i * 6, i == 0 ? &cisconfigs.color.gainF[0] : &cisconfigs.color.gainB[0], sizeof(u32) * 6); memcpy(¶m.correctGrayGain[0] + i * 6, i == 0 ? &cisconfigs.grayCorrect.gainF[0] : &cisconfigs.grayCorrect.gainB[0], sizeof(u32) * 6); memcpy(¶m.grayGain[0] + i * 6, i == 0 ? &cisconfigs.gray.gainF[0] : &cisconfigs.gray.gainB[0], sizeof(u32) * 6); memcpy(¶m.correctColorOffset[0] + i * 6, i == 0 ? &cisconfigs.colorCorrect.offsetsF[0] : &cisconfigs.colorCorrect.offsetsB[0], sizeof(u32) * 6); memcpy(¶m.colorOffset[0] + i * 6, i == 0 ? &cisconfigs.color.offsetsF[0] : &cisconfigs.color.offsetsB[0], sizeof(u32) * 6); memcpy(¶m.correctGrayOffset[0] + i * 6, i == 0 ? &cisconfigs.grayCorrect.offsetsF[0] : &cisconfigs.grayCorrect.offsetsB[0], sizeof(u32) * 6); memcpy(¶m.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 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>& buffs) { vector 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 ""; }