diff --git a/hardware/cis/FpgaComm.cpp b/hardware/cis/FpgaComm.cpp index 17d5940..9f224df 100644 --- a/hardware/cis/FpgaComm.cpp +++ b/hardware/cis/FpgaComm.cpp @@ -108,6 +108,31 @@ int FpgaComm::getFrameHeight() { return Reg(frame).height; } +int FpgaComm::get_real_height(void) +{ + unsigned int val; + unsigned int reg8 = 0; + + this->read(8, reg8); + + this->read(14, val); + int regv = val; + val &= 0x0000ffff; + + this->write(8, reg8 & 0xfffffff7); + + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + + this->read(14, val); + regv = val; + val &= 0x0000ffff; + this->read(8, reg8); + + std::this_thread::sleep_for(std::chrono::milliseconds(5)); + this->write(8, reg8 | 0x8); + + return val; +} void FpgaComm::setFrameNum(int num){ Reg(frame).num = num; diff --git a/hardware/cis/FpgaComm.h b/hardware/cis/FpgaComm.h index f923580..fb8b367 100644 --- a/hardware/cis/FpgaComm.h +++ b/hardware/cis/FpgaComm.h @@ -185,6 +185,7 @@ public: int getRegs(int addr); void setFrameHeight(int height); int getFrameHeight(); + int get_real_height(void); void setFrameNum(int num); void enableLed(bool bEnable); void enableUV(bool enable); diff --git a/hardware/hardware.cpp b/hardware/hardware.cpp index 8ef0490..305422c 100644 --- a/hardware/hardware.cpp +++ b/hardware/hardware.cpp @@ -325,7 +325,7 @@ void scanner_hw::thread_image_capture(void) { PACKIMAGE img(img_base_); safe_fifo avail_mem("v4l2-mem"); - int used_v4l2_mem = 0, times = 0; + int used_v4l2_mem = 0, times = 0, minh = 210 * dpi_ / 25.4; std::pair mbev; auto put_v4l2_mem = [&](BEFORE_DESTROY_PARAM) -> BEFORE_DESTROY_RET @@ -350,6 +350,8 @@ void scanner_hw::thread_image_capture(void) // scanning ONE turn ... while(scanning_ && motor_->wait_paper_out(3000)) { + img.height = get_image_real_height(minh); + size_t size = 0; int ind = -1; void* frame = camera_->read_frame(5 * 1000, size, ind); @@ -363,6 +365,7 @@ void scanner_hw::thread_image_capture(void) used_v4l2_mem++; img.pos.paper_ind++; img.pos.status = IMG_STATUS_OK; + printf("Image height: %d\n", img.height); img_handler_(mem, true, &img); if(img.pos.paper_ind == scan_count_ || is_scan_fatal()) @@ -412,6 +415,20 @@ void scanner_hw::thread_image_capture(void) scanning_ = false; img_handler_((dyn_mem_ptr)WORKER_STATUS_IDLE, false, 0); } +int scanner_hw::get_image_real_height(int minh) +{ + chronograph watch; + unsigned int h = 0; + + while(h < minh && watch.elapse_ms() < 500) + { + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + img_controller_->read(14, h); + } + h = img_controller_->get_real_height(); + + return h; +} bool scanner_hw::is_scan_fatal(void) { return false; @@ -579,6 +596,10 @@ int scanner_hw::open(std::function image_handler) img_base_.resolution_x = dpi_; img_base_.resolution_y = dpi_; + img_base_.width = dpi_ == 300 ? 1296 : 2592; + img_base_.width *= 6; + if(mode_ == "\345\275\251\350\211\262") + img_base_.width *= 3; img_controller_->setColorMode(mode_ == "\345\275\251\350\211\262" ? COLOR_MODE : GRAY_MODE); img_controller_->setDpi(dpi_ == 300 ? DPI_300 : DPI_600); @@ -674,7 +695,6 @@ int scanner_hw::open(std::function image_handler) // for(int i = 0; i < _countof(vals); ++i) // img_controller_->write(i, vals[i]); // } - // img_controller_->write(1, 0x0330100d); // DPI mode should be revised (only support 2 and 3) ... img_controller_->update(); return SCANNER_ERR_OK; diff --git a/hardware/hardware.h b/hardware/hardware.h index 677e742..9c1dfea 100644 --- a/hardware/hardware.h +++ b/hardware/hardware.h @@ -84,6 +84,7 @@ class scanner_hw : public sane_opt_provider void init(void); void init_version(std::string& text); void thread_image_capture(void); + int get_image_real_height(int minh); bool is_scan_fatal(void); void retrieve_v4l2_mem(safe_fifo* mem, int* used); void set_gain_value(bool front, bool gain, int sector, int val); diff --git a/imgproc/imgprc_mgr.cpp b/imgproc/imgprc_mgr.cpp index 5b167ae..38ba8c0 100644 --- a/imgproc/imgprc_mgr.cpp +++ b/imgproc/imgprc_mgr.cpp @@ -7,7 +7,7 @@ static std::string device_opt_json[] = { - "{\"is-multiout\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34817,\"ui-pos\":10,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"multiout-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"fix-id\":34818,\"ui-pos\":11,\"auth\":0,\"enabled\":false,\"size\":66,\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend\":\"is-multiout==true\"},\"mode\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend\":\"is-multiout!=true\"},\"resolution\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":200,\"default\":200,\"range\":{\"min\":100,\"max\":{\"default\":600,\"paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 || paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8 || paper==\\u4e09\\u8054\\u8bd5\\u5377\":500},\"step\":1}}}" + "{\"is-multiout\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\",\"desc\":\"\\u540c\\u65f6\\u8f93\\u51fa\\u591a\\u79cd\\u989c\\u8272\\u6a21\\u5f0f\\u7684\\u56fe\\u50cf\",\"type\":\"bool\",\"fix-id\":34817,\"ui-pos\":10,\"auth\":0,\"size\":4,\"cur\":false,\"default\":false},\"multiout-type\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u591a\\u6d41\\u8f93\\u51fa\\u7c7b\\u578b\",\"desc\":\"\\u9009\\u62e9\\u591a\\u6d41\\u8f93\\u51fa\\u7684\\u7c7b\\u578b\",\"type\":\"string\",\"fix-id\":34818,\"ui-pos\":11,\"auth\":0,\"enabled\":false,\"size\":66,\"cur\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"default\":\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"range\":[\"\\u5f69\\u8272+\\u7070\\u5ea6+\\u9ed1\\u767d\",\"\\u5f69\\u8272+\\u7070\\u5ea6\",\"\\u5f69\\u8272+\\u9ed1\\u767d\",\"\\u7070\\u5ea6+\\u9ed1\\u767d\"],\"depend\":\"is-multiout==true\"},\"mode\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u989c\\u8272\\u6a21\\u5f0f\",\"desc\":\"\\u9009\\u62e9\\u8272\\u5f69\\u6a21\\u5f0f\",\"type\":\"string\",\"fix-id\":34819,\"ui-pos\":15,\"auth\":0,\"size\":24,\"cur\":\"24\\u4f4d\\u5f69\\u8272\",\"default\":\"24\\u4f4d\\u5f69\\u8272\",\"range\":[\"24\\u4f4d\\u5f69\\u8272\",\"256\\u7ea7\\u7070\\u5ea6\",\"\\u9ed1\\u767d\",\"\\u989c\\u8272\\u81ea\\u52a8\\u8bc6\\u522b\"],\"depend\":\"is-multiout!=true\"},\"resolution\":{\"cat\":\"base\",\"group\":\"base\",\"title\":\"\\u5206\\u8fa8\\u7387\",\"desc\":\"\\u8bbe\\u7f6e\\u626b\\u63cf\\u56fe\\u50cf\\u7684\\u5206\\u8fa8\\u7387\",\"type\":\"int\",\"fix-id\":34840,\"ui-pos\":20,\"auth\":0,\"size\":4,\"cur\":200,\"default\":200,\"range\":{\"min\":100,\"max\":{\"default\":600,\"paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8\\u81ea\\u52a8\\u88c1\\u5207 || paper==\\u6700\\u5927\\u626b\\u63cf\\u5c3a\\u5bf8 || paper==\\u4e09\\u8054\\u8bd5\\u5377\":500},\"step\":1}},\"dump-img\":{\"cat\":\"base\",\"group\":\"\\u9ad8\\u7ea7\\u8bbe\\u7f6e\",\"title\":\"\\u8f93\\u51fa\\u4e2d\\u95f4\\u56fe\\u50cf\",\"desc\":\"\\u8f93\\u51fa\\u5404\\u7b97\\u6cd5\\u4e2d\\u95f4\\u7ed3\\u679c\\u56fe\\u50cf\",\"type\":\"bool\",\"ui-pos\":10,\"auth\":0,\"affect\":2,\"size\":4,\"cur\":false,\"default\":false}}" }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// @@ -103,7 +103,6 @@ void imgproc_mgr::process(RAWIMG* img) ele.ext_info = ""; ele.info = img->info; ele.img = cv::Mat(ele.info.height, ele.info.width, CV_8UC1, (void*)img->data->ptr(), img->data->get_rest()); - img->data->release(); in.push_back(ele); if(dump_img_) @@ -140,13 +139,15 @@ void imgproc_mgr::send_image(std::vector& imgs, bool clear_after_se { uint32_t size = v.img.total() * v.img.channels(); dyn_mem_ptr mem(dyn_mem::memory(size)); + printf("image bits: %p + %u\n", mem->ptr(), size); mem->put(v.img.data, size); - if(clear_after_send) - v.img.deallocate(); + // if(clear_after_send) + // v.img.deallocate(); image_packet_ptr ptr = imgproc_mgr::image_sent_packet(&v.info, mem, scan_id_, &v.ext_info[0], v.ext_info.length()); ptr->set_session_id(session_id_); + printf("sending image packet: %p + %u\n", ptr->ptr(), ptr->get_rest()); img_sender_(ptr); ptr->release(); mem->release(); @@ -157,7 +158,10 @@ int imgproc_mgr::set_value(const char* name, void* val) { int ret = SCANNER_ERR_OK; - // ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; + if(strcmp(name, SANE_FULL_NAME(DUMP_IMG)) == 0) + dump_img_ = *(bool*)val; + else + ret = SCANNER_ERR_DEVICE_NOT_SUPPORT; return ret; } diff --git a/sdk/base/data.cpp b/sdk/base/data.cpp index 292b456..470b989 100644 --- a/sdk/base/data.cpp +++ b/sdk/base/data.cpp @@ -91,6 +91,7 @@ int mem_holder::put_data(const void* data, uint32_t* size) memcpy(buf_ + wpos_, data, *size); wpos_ += *size; + notify_progress(space_, wpos_, 0); return 0; } @@ -115,6 +116,63 @@ uint8_t* mem_holder::data(void) return buf_; } + + +//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// +// image_holder +image_holder::image_holder(LPPACKIMAGE head) : mem_holder(head->info_size + head->data_size), head_(*head) +{} +image_holder::~image_holder() +{} + +void image_holder::set_info(LPPACKIMAGE head) +{ + head_ = *head; +} +LPPACKIMAGE image_holder::get_info(void) +{ + return &head_; +} +int image_holder::save_2_file(const char* root_dir, const char* alg) +{ + std::string file(root_dir); + FILE* dst = nullptr; + int err = ENOTSUP; + char buf[80] = { 0 }; + + file += PATH_SEPARATOR; + sprintf(buf, "%04d", head_.pos.paper_ind); + file += buf; + if (head_.pos.paper_side == PAPER_SIDE_FRONT) + file += "_Front"; + else if (head_.pos.paper_side == PAPER_SIDE_BACK) + file += "_Back"; + else + file += "_Comp"; + sprintf(buf, "_%x", head_.pos.split_ind); + file += buf; + if (alg && *alg) + file += std::string("_") + alg; + if (head_.format == IMG_FMT_BMP) + { + std::string bih(utils::bitmap_info_header(head_.width, head_.height, head_.bpp * head_.channels, head_.resolution_x, head_.resolution_y)), + bfh(utils::bitmap_file_header((BITMAPINFOHEADER*)&bih[0])); + file += ".bmp"; + dst = fopen(file.c_str(), "wb"); + if (dst) + { + fwrite(bfh.c_str(), 1, bfh.length(), dst); + fwrite(bih.c_str(), 1, bih.length(), dst); + fwrite(data() + head_.info_size, 1, head_.data_size, dst); + } + } + + if (dst) + fclose(dst); + + return err; +} + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // empty_holer::empty_holer(uint64_t size) : size_(size), put_(0) @@ -830,7 +888,8 @@ uint8_t* file_map::buffer(void) //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // image_packet -image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid, const void* info, size_t info_size) +image_packet::image_packet(LPPACKIMAGE head, dyn_mem_ptr img, uint32_t scanid + , const void* info, size_t info_size) : img_(img), offset_(0), info_over_(false) { LPPACK_BASE pack = nullptr; diff --git a/sdk/base/data.h b/sdk/base/data.h index 3a42a83..a87ead2 100644 --- a/sdk/base/data.h +++ b/sdk/base/data.h @@ -105,7 +105,7 @@ public: mem_holder(size_t size); protected: - ~mem_holder(); + virtual ~mem_holder(); // data_holder public: @@ -118,6 +118,22 @@ public: uint8_t* data(void); }; +class image_holder : public mem_holder +{ + PACKIMAGE head_; + +public: + image_holder(LPPACKIMAGE head); + +protected: + virtual ~image_holder(); + +public: + void set_info(LPPACKIMAGE head); + LPPACKIMAGE get_info(void); + int save_2_file(const char* root_dir, const char* alg = nullptr); +}; + class empty_holer : public data_holder { uint64_t size_; @@ -319,6 +335,7 @@ public: CLS_PTR(packet_data_base); CLS_PTR(data_holder); CLS_PTR(mem_holder); +CLS_PTR(image_holder); CLS_PTR(data_source); CLS_PTR(dyn_mem); CLS_PTR(dyn_mem_shared); diff --git a/sdk/sane/sane_ex.h b/sdk/sane/sane_ex.h index 1a91652..e5914a8 100644 --- a/sdk/sane/sane_ex.h +++ b/sdk/sane/sane_ex.h @@ -232,7 +232,7 @@ enum opt_visible_level // "visible" field #define SANE_STD_OPT_NAME_FREE_BUFFER "free-buf" // 释放由驱动返回的内存, data - (void**)&buf #define SANE_STD_OPT_NAME_PAPER_ON "paper-on" // check whether paper is on #define SANE_STD_OPT_NAME_INITIAL_BOOT_TIME "initial-boot-time" // 设备的初始开机时间 -#define SANE_STD_OPT_NAME_DUMP_IMG "dumpimg" // 是否输出算法各阶段中间图像 +#define SANE_STD_OPT_NAME_DUMP_IMG "dump-img" // 是否输出算法各阶段中间图像 #define SANE_STD_OPT_NAME_DUMP_IMG_PATH "dump-path" // 中间图像输出路径 #define SANE_STD_OPT_NAME_CIS_LENGTH "cis-len" // CIS 长度(采集图像的最大宽度) diff --git a/usb/usb_io.cpp b/usb/usb_io.cpp index 791316d..7a034d6 100644 --- a/usb/usb_io.cpp +++ b/usb/usb_io.cpp @@ -877,7 +877,7 @@ int async_usb_gadget::write_bulk(data_source_ptr data) if(data->get_session_id() != session_id_ || !online_) { utils::to_log(LOG_LEVEL_DEBUG, "Discard reply packet for the session ID(%u) is not equal current session(%u) or is offline.\n", data->get_session_id(), session_id_); - data->release(); + // data->release(); return sent_que_.size(); } diff --git a/xmake.lua b/xmake.lua index 54dd66c..6fe218d 100644 --- a/xmake.lua +++ b/xmake.lua @@ -60,8 +60,8 @@ add_packagedirs("sdk") add_defines("BUILD_AS_DEVICE") add_defines("VER_MAIN=2") add_defines("VER_FAMILY=200") -add_defines("VER_DATE=20240116") -add_defines("VER_BUILD=11") +add_defines("VER_DATE=20240117") +add_defines("VER_BUILD=12") target("conf") set_kind("phony")