diff --git a/hgdriver/hgdev/hg_ipc.cpp b/hgdriver/hgdev/hg_ipc.cpp index c9f66b0..5eb7fac 100644 --- a/hgdriver/hgdev/hg_ipc.cpp +++ b/hgdriver/hgdev/hg_ipc.cpp @@ -346,141 +346,183 @@ int shared_memory::write(const char* data, size_t len) ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // tiny_file_map ... -#ifdef WIN32 -#define IS_VALID_MAP(map) map -#else -#define IS_VALID_MAP(map) map != -1 -#endif -tiny_file_map::tiny_file_map() : size_(0), map_(0), buf_(nullptr), file_(""), keep_f_(false) +tiny_file_map::tiny_file_map() : size_(0), map_(INVALID_HANDLE_NAME), buf_(nullptr), file_(""), keep_f_(false) + , map_off_(0), map_bytes_(0), page_size_(hg_log::get_page_size()) {} tiny_file_map::~tiny_file_map() { close(); } -int tiny_file_map::open(const char* file, unsigned int size, bool readonly) +HANDLE_NAME tiny_file_map::open_file_for_mapping(const char* file, unsigned* bytes, bool create) { - close(); + HANDLE_NAME ret = INVALID_HANDLE_NAME; - int ret = 0; #ifdef WIN32 - if (readonly) + HANDLE f = INVALID_HANDLE_VALUE; + if (create) { - HANDLE f = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (f == INVALID_HANDLE_VALUE) - ret = GetLastError(); - else + f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (f != INVALID_HANDLE_VALUE) { - size_ = GetFileSize(f, NULL); - map_ = CreateFileMappingA(f, NULL, PAGE_READONLY, 0, 0, NULL); - if (map_) + DWORD wrote = SetFilePointer(f, *bytes - 1, NULL, FILE_BEGIN); + if (wrote != *bytes - 1 || !WriteFile(f, "\0", 1, &wrote, NULL)) { - buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0); - if (!buf_) - { - ret = GetLastError(); - CloseHandle(map_); - map_ = nullptr; - size_ = 0; - } + CloseHandle(f); + f = INVALID_HANDLE_VALUE; } - else - ret = GetLastError(); - CloseHandle(f); } } else { - size_ = size; + f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + if (f != INVALID_HANDLE_VALUE) + *bytes = GetFileSize(f, NULL); + } + if (f != INVALID_HANDLE_VALUE) + { + ret = CreateFileMapping(f, NULL, PAGE_READWRITE, 0, *bytes, NULL); + CloseHandle(f); + } +#else + if (create) + { + ret = ::open(file, O_CREAT | O_RDWR); + if (ret != INVALID_HANDLE_NAME) + { + if (lseek(ret, *bytes - 1, SEEK_SET) < 0) + { + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", *bytes, errno); + ::close(ret); + remove(file); + ret = INVALID_HANDLE_NAME; + } + if (write(ret, "0", 1) < 0) + { + VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", *bytes, errno); + ::close(ret); + remove(file); + ret = INVALID_HANDLE_NAME; + } + } + } + else + { + ret = ::open(file, O_RDWR); + if (ret != INVALID_HANDLE_NAME) + { + struct stat fsize; + if (fstat(ret, &fsize) >= 0) + *bytes = fsize.st_size; + } + } +#endif + + return ret; +} +void tiny_file_map::close_handle_name(HANDLE_NAME h) +{ +#ifdef WIN32 + CloseHandle(h); +#else + ::close(h); +#endif +} +void* tiny_file_map::sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err) +{ + void* mem = nullptr; - HANDLE f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); - if (f == INVALID_HANDLE_VALUE) - ret = GetLastError(); +#ifdef WIN32 + mem = MapViewOfFile(h, access, 0, off, size); + if (err) + { + if (mem) + *err = SCANNER_ERR_OK; else { - //SYSTEM_INFO si = { 0 }; - //GetSystemInfo(&si); - //size += si.dwPageSize - 1; - //size /= si.dwPageSize; - //size *= si.dwPageSize; - DWORD wrote = SetFilePointer(f, size - 1, NULL, FILE_BEGIN); - if (wrote == size - 1) - WriteFile(f, "\0", 1, &wrote, NULL); - map_ = CreateFileMappingA(f, NULL, PAGE_READWRITE, 0, size, NULL); - if (map_) - { - buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size); - if (!buf_) - ret = GetLastError(); - } + if (GetLastError() == ERROR_NOT_ENOUGH_MEMORY) + *err = SCANNER_ERR_INSUFFICIENT_MEMORY; else - ret = GetLastError(); - CloseHandle(f); - if (ret) - { - keep_f_ = false; - close(); - } + *err = SCANNER_ERR_OUT_OF_RANGE; } } #else - if (readonly) + mem = mmap(nullptr, size, access, MAP_SHARED, h, off); + if (mem == MAP_FAILED) { - map_ = ::open(file, O_RDONLY); - if (IS_VALID_MAP(map_)) - { - struct stat fsize; - if (fstat(map_, &fsize) >= 0) - size_ = size = fsize.st_size; - } + mem = nullptr; + if (errno == ENOMEM) + *err = SCANNER_ERR_INSUFFICIENT_MEMORY; + else + *err = SCANNER_ERR_OUT_OF_RANGE; } - else - { - map_ = ::open(file, O_CREAT | O_RDWR); - if (IS_VALID_MAP(map_)) - { - if (lseek(map_, size - 1, SEEK_SET) < 0) - { - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u - 1 bytes failed: %d\n", size, errno); - ret = errno; - ::close(map_); - map_ = 0; - remove(file); - return ret; - } - if (write(map_, "0", 1) < 0) - { - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "set file size to %u bytes failed: %d\n", size, errno); - ret = errno; - ::close(map_); - map_ = 0; - remove(file); - return ret; - } - } - } - if (IS_VALID_MAP(map_)) - { - buf_ = (unsigned char*)mmap(nullptr, size, readonly ? PROT_READ : PROT_WRITE, MAP_SHARED, map_, 0); - if (buf_ == (unsigned char*)MAP_FAILED) - { - buf_ = nullptr; - ret = errno; - VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "mmap(%u) = %d\n", size, ret); - size_ = 0; - if (!readonly) - remove(file); - } - ::close(map_); - map_ = 0; - } - else - ret = errno; + else if(err) + *err = SCANNER_ERR_OK; #endif + return mem; +} +void tiny_file_map::sys_unmap_api(void* buf, size_t size) +{ +#ifdef WIN32 + UnmapViewOfFile(buf); +#else + munmap(buf, size); +#endif +} - VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", readonly ? "R" : "RW", file, ret); - if (ret == 0) +int tiny_file_map::map_to_mem(unsigned int off) +{ + int err = SCANNER_ERR_OUT_OF_RANGE; + +#ifdef WIN32 + int acc = FILE_MAP_READ | FILE_MAP_WRITE; +#else + int acc = PROT_READ | PROT_WRITE; +#endif + if (off < size_) + { + unsigned int bytes = size_ - off; + if (off >= map_off_ && off + bytes <= map_off_ + map_bytes_) + err = SCANNER_ERR_OK; + else + { + if (buf_) + tiny_file_map::sys_unmap_api(buf_, map_bytes_); + off /= page_size_; + off *= page_size_; + map_bytes_ = bytes; + map_off_ = off; + buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err); // MapViewOfFile(map_, FILE_MAP_READ | FILE_MAP_WRITE, 0, off, map_bytes_); + if (err != SCANNER_ERR_OK) + { + map_bytes_ /= page_size_; + map_bytes_ *= page_size_; + while (map_bytes_ >= page_size_ + && !(buf_ = (unsigned char*)tiny_file_map::sys_map_api(map_, acc, map_off_, map_bytes_, &err)) + && err == SCANNER_ERR_INSUFFICIENT_MEMORY) + map_bytes_ -= page_size_; + } + } + } + + return err; +} + +int tiny_file_map::open(const char* file, bool existing, unsigned int size) +{ + int ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + + close(); + map_ = tiny_file_map::open_file_for_mapping(file, &size, !existing); + if (map_ != INVALID_HANDLE_NAME) + { + ret = SCANNER_ERR_OK; + size_ = size; + } + + VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", existing ? "existing" : "new", file, ret); + if (ret == SCANNER_ERR_OK) file_ = file; return ret; @@ -489,21 +531,13 @@ void tiny_file_map::close(void) { if (buf_) { -#ifdef WIN32 - UnmapViewOfFile(buf_); -#else - munmap(buf_, size_); -#endif + tiny_file_map::sys_unmap_api(buf_, size_); buf_ = nullptr; } - if (map_) + if (map_ != INVALID_HANDLE_NAME) { -#ifdef WIN32 - CloseHandle(map_); -#else - ::close(map_); -#endif - map_ = 0; + close_handle_name(map_); + map_ = INVALID_HANDLE_NAME; } if (!keep_f_ && !file_.empty()) remove(file_.c_str()); @@ -511,14 +545,51 @@ void tiny_file_map::close(void) size_ = 0; file_ = ""; keep_f_ = false; + map_off_ = map_bytes_ = 0; } void tiny_file_map::keep_file(bool keep) { keep_f_ = keep; } -unsigned char* tiny_file_map::mapping_buffer(void) +unsigned char* tiny_file_map::mapping_buffer(unsigned int off, unsigned int* bytes) { - return buf_; + unsigned int len = bytes ? *bytes : size_; + unsigned char* buf = nullptr; + + if (off >= size_) + { + return buf; + } + if (!buf_ && map_to_mem(off) != SCANNER_ERR_OK) + { + return buf; + } + + if (off >= map_off_ && off + len <= map_off_ + map_bytes_) + { + buf = buf_ + off - map_off_; + + return buf; + } + + if (off < map_off_ || off >= map_off_ + map_bytes_) + { + if (map_to_mem(off) == SCANNER_ERR_OK) + { + buf = buf_ + off - map_off_; + if (bytes) + *bytes = map_bytes_ - (off - map_off_); + } + + return buf; + } + + // + buf = buf_ + off - map_off_; + if (bytes) + *bytes = map_bytes_ - (off - map_off_); + + return buf; } std::string tiny_file_map::file(void) { @@ -533,34 +604,8 @@ bool tiny_file_map::swap(void) { bool ret = true; - if (buf_) - { -#ifdef WIN32 - UnmapViewOfFile(buf_); -#else - munmap(buf_, size_); -#endif - buf_ = nullptr; - } - else if (IS_VALID_MAP(map_)) - { -#ifdef WIN32 - buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, size_); -#else - buf_ = (unsigned char*)mmap(nullptr, size_, PROT_READ, MAP_PRIVATE, map_, 0); - if (buf_ == (unsigned char*)MAP_FAILED) - { - buf_ == nullptr; - VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' failed: %d\n", file_.c_str(), errno); - } -#endif - ret = buf_ != nullptr; - } - else - { - VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap '%s' bug the handle is %d\n", file_.c_str(), map_); - ret = false; - } + tiny_file_map::sys_unmap_api(buf_, size_); + buf_ = nullptr; return ret; } @@ -576,11 +621,13 @@ tiny_buffer::tiny_buffer(unsigned int size { init(tmp_path, name_leading, ext, uniq_id); } -tiny_buffer::tiny_buffer(const char* src_file) +tiny_buffer::tiny_buffer(const char* src_file) : size_(0), buf_(nullptr) { - fmap_.open(src_file, 0, true); - buf_ = fmap_.mapping_buffer(); + fmap_.open(src_file); size_ = fmap_.size(); + + unsigned int len = size_; + buf_ = fmap_.mapping_buffer(0, &len); } tiny_buffer::~tiny_buffer() { @@ -602,28 +649,41 @@ void tiny_buffer::init(const char* tmp_path, const char* name_leading, const cha } catch (...) { - std::string f(tmp_path); - char buf[128] = { 0 }; + if (tmp_path && *tmp_path) + { + std::string f(tmp_path); + char buf[128] = { 0 }; - f += PATH_SEPARATOR; - f += name_leading ? name_leading : "mapf"; - sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp"); - f += buf; + f += PATH_SEPARATOR; + f += name_leading ? name_leading : "mapf"; + sprintf(buf, "_%05u.%s", uniq_id, ext ? ext : "tmp"); + f += buf; - fmap_.open(f.c_str(), size_, false); - buf_ = fmap_.mapping_buffer(); + unsigned int bytes = size_; + fmap_.open(f.c_str(), size_, false); + buf_ = fmap_.mapping_buffer(0, &bytes); + } } - -// VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Acquire memory with bytes %u = %s\n", size_, hg_log::format_ptr(buf_).c_str()); } unsigned int tiny_buffer::size(void) { return size_; } -unsigned char* tiny_buffer::data(void) +unsigned char* tiny_buffer::data(unsigned int off, unsigned int* bytes) { - return buf_; + if (off >= size_) + return nullptr; + + if (fmap_.file().empty()) + { + if (size_ - off < *bytes) + *bytes = size_ - off; + + return buf_ + off; + } + + return fmap_.mapping_buffer(off, bytes); } void tiny_buffer::keep_file(bool keep) { @@ -640,8 +700,9 @@ bool tiny_buffer::swap(void) return true; bool ret = fmap_.swap(); + unsigned int bytes = size_; - buf_ = fmap_.mapping_buffer(); + buf_ = fmap_.mapping_buffer(0, &bytes); return ret; } @@ -672,6 +733,7 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v { IMGDT imgd; bool ret = false; + unsigned int l = bytes, off = 0; imgd.header.bits = bpp; imgd.header.bytes = bytes; @@ -681,18 +743,28 @@ bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, v imgd.header.width = w; imgd.offset = 0; imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind)); - if(imgd.data->data()) + + unsigned char* buf = imgd.data->data(off, &l), + * src = (unsigned char*)data; + while(buf) { - memcpy(imgd.data->data(), data, bytes); - if (imgd.data->swap()) - { - std::lock_guard lck(lock_); - queue_.push_back(imgd); - ret = true; - } - else - imgd.data.reset(); + memcpy(buf, src, l); + off += l; + if (off >= bytes) + break; + + src += l; + l = bytes - off; + buf = imgd.data->data(off, &l); } + if (off >= bytes && imgd.data->swap()) + { + std::lock_guard lck(lock_); + queue_.push_back(imgd); + ret = true; + } + else + imgd.data.reset(); return ret; } @@ -719,24 +791,29 @@ void final_img_queue::fetch_front(void* buf, int* len, bool* over) } else { + // for third-apps, we make fake data upto len when re-map file failed here IMGDT& imgd = queue_[0]; if (imgd.offset == 0) { if (!imgd.data->swap()) { - *len = 0; - if (over) - *over = true; - VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload final image '%s' failed!\n", imgd.data->file().c_str()); - return; } } if (imgd.offset + *len >= imgd.header.bytes) *len = imgd.header.bytes - imgd.offset; - memcpy(buf, imgd.data->data() + imgd.offset, *len); + + unsigned char* src = imgd.data->data(imgd.offset, (unsigned int*)len); + if (src) + { + memcpy(buf, src, *len); + } + else + { + VLOG_MINI_2(LOG_LEVEL_FATAL, "Remap final image '%s + 0x%08x' failed!\n", imgd.data->file().c_str(), imgd.offset); + } imgd.offset += *len; if (imgd.offset >= imgd.header.bytes) { diff --git a/hgdriver/hgdev/hg_ipc.h b/hgdriver/hgdev/hg_ipc.h index fcab959..d5a0e7d 100644 --- a/hgdriver/hgdev/hg_ipc.h +++ b/hgdriver/hgdev/hg_ipc.h @@ -131,27 +131,40 @@ public: }; // buffer +#ifdef WIN32 +#define HANDLE_NAME HANDLE +#define INVALID_HANDLE_NAME NULL +#else +#define HANDLE_NAME int +#define INVALID_HANDLE_NAME -1 +#endif class tiny_file_map { unsigned int size_; -#ifdef WIN32 - HANDLE map_; -#else - int map_; -#endif + unsigned int page_size_; + HANDLE_NAME map_; unsigned char *buf_; std::string file_; bool keep_f_; + unsigned int map_off_; + unsigned int map_bytes_; + int map_to_mem(unsigned int off = 0); + public: tiny_file_map(); ~tiny_file_map(); + static HANDLE_NAME open_file_for_mapping(const char* file, unsigned* bytes, bool create); + static void close_handle_name(HANDLE_NAME h); + static void* sys_map_api(HANDLE_NAME h, int access, unsigned int off, unsigned size, int* err); + static void sys_unmap_api(void* buf, size_t size = 0); + public: - int open(const char* file, unsigned int size, bool readonly); + int open(const char* file, bool existing = true, unsigned int size = 0); void close(void); void keep_file(bool keep); - unsigned char* mapping_buffer(void); + unsigned char* mapping_buffer(unsigned int off, unsigned int* bytes); std::string file(void); unsigned int size(void); @@ -173,7 +186,7 @@ public: public: unsigned int size(void); - unsigned char* data(void); + unsigned char* data(unsigned int off, unsigned int* bytes/*[in] - need bytes, [out] - real bytes*/); void keep_file(bool keep); std::string file(void); diff --git a/hgdriver/hgdev/hg_scanner.cpp b/hgdriver/hgdev/hg_scanner.cpp index e4fe0cd..c054fc0 100644 --- a/hgdriver/hgdev/hg_scanner.cpp +++ b/hgdriver/hgdev/hg_scanner.cpp @@ -95,11 +95,17 @@ hg_scanner::hg_scanner(ScannerSerial serial { final_path_ = hg_log::ini_get("paths", "final_img"); if(final_path_.empty()) - final_path_ = hg_log::get_scanner_path() + "imgs"; + final_path_ = hg_log::local_data_path() + PATH_SEPARATOR + "imgs"; if (hg_log::create_folder(final_path_.c_str())) + { + VLOG_MINI_1(LOG_LEVEL_WARNING, "temporary image folder: %s\n", final_path_.c_str()); final_path_ += PATH_SEPARATOR; + } else + { + VLOG_MINI_1(LOG_LEVEL_WARNING, "create temporary image folder failed: %s\n", final_path_.c_str()); final_path_ = ""; + } custom_gamma_val_ = new SANE_Gamma; memset(custom_gamma_val_, 0, sizeof(SANE_Gamma)); @@ -948,7 +954,7 @@ int hg_scanner::setting_multi_out_type(void *data) int ret = SCANNER_ERR_OK; std::string str((char*)data); - + bool exact = check_range(setting_map_[HG_BASE_SETTING_INDEX_MULTI_OUT], str); int color; image_prc_param_.bits.multi_out = match_best_multi_out(str,NULL); @@ -960,7 +966,7 @@ int hg_scanner::setting_multi_out_type(void *data) color = COLOR_MODE_256_GRAY; else color = COLOR_MODE_24_BITS; - + on_color_mode_changed(color); return ret; } @@ -1694,7 +1700,7 @@ std::shared_ptr hg_scanner::aquire_memory(int size, bool from_usb) unsigned int ind = from_usb ? usb_img_index_ : final_img_index_; std::shared_ptr mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind)); - if (!mem->data()) + if (!mem->data(0, (unsigned int*)&size)) { mem.reset(); LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n"); diff --git a/hgdriver/hgdev/hg_scanner_200.cpp b/hgdriver/hgdev/hg_scanner_200.cpp index 6ee8cfa..2b3d96c 100644 --- a/hgdriver/hgdev/hg_scanner_200.cpp +++ b/hgdriver/hgdev/hg_scanner_200.cpp @@ -573,7 +573,16 @@ int hg_scanner_200::get_img_data(unsigned int bytes) if (total < block) block = total; - ret = io_->read_bulk(imagedata->data() + index, &block); + unsigned int size = block; + void* buf = imagedata->data(index, &size); + if (!buf) + { + VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_); + ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + break; + } + block = size; + ret = io_->read_bulk(buf, &block); io_->set_timeout(500); //不能删除可能会导致IO超时 if (ret != SCANNER_ERR_OK) break; diff --git a/hgdriver/hgdev/hg_scanner_239.cpp b/hgdriver/hgdev/hg_scanner_239.cpp index cc69e9a..1a13708 100644 --- a/hgdriver/hgdev/hg_scanner_239.cpp +++ b/hgdriver/hgdev/hg_scanner_239.cpp @@ -1020,16 +1020,36 @@ int hg_scanner_239::read_one_image_from_usb(void) { std::lock_guard lock(io_lock_); - ret = io_->read_bulk(buf->data(), &r); - - while (ret == SCANNER_ERR_OK) + unsigned int size = r; + void* buff = buf->data(off, &size); + if (!buff) { - off += r; - if (off >= total) - break; + VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_); + ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + } + else + { + r = size; + ret = io_->read_bulk(buff, &r); - r = total - off; - ret = io_->read_bulk(buf->data() + off, &r); + while (ret == SCANNER_ERR_OK) + { + off += r; + if (off >= total) + break; + + r = total - off; + size = r; + buff = buf->data(off, &size); + if (!buff) + { + VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", off, r, usb_img_index_); + ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + break; + } + r = size; + ret = io_->read_bulk(buff, &r); + } } } if (ret == SCANNER_ERR_OK) @@ -1179,6 +1199,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode) { dev_conf_.g200params.color = 1; } + HGSCANCONF d = dev_conf_; if (image_prc_param_.bits.rid_color != RID_COLOR_NONE @@ -1203,6 +1224,7 @@ int hg_scanner_239::on_color_mode_changed(int& color_mode) } if(color_mode == -1) ret = writedown_device_configuration(&d); + return ret; } int hg_scanner_239::on_paper_changed(int& paper) diff --git a/hgdriver/hgdev/hg_scanner_300.cpp b/hgdriver/hgdev/hg_scanner_300.cpp index 2477d5b..f20b499 100644 --- a/hgdriver/hgdev/hg_scanner_300.cpp +++ b/hgdriver/hgdev/hg_scanner_300.cpp @@ -516,7 +516,16 @@ int hg_scanner_300::get_img_data(std::shared_ptr &imagedata) if (total < block) block = total; - ret = io_->read_bulk(imagedata->data() + index,&block); + unsigned int size = block; + void* buf = imagedata->data(index, &size); + if (!buf) + { + VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_); + ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + break; + } + block = size; + ret = io_->read_bulk(buf, &block); if (ret != SCANNER_ERR_OK) { diff --git a/hgdriver/hgdev/hg_scanner_400.cpp b/hgdriver/hgdev/hg_scanner_400.cpp index 3238a34..d4d8eb5 100644 --- a/hgdriver/hgdev/hg_scanner_400.cpp +++ b/hgdriver/hgdev/hg_scanner_400.cpp @@ -516,7 +516,16 @@ int hg_scanner_400::get_img_data(std::shared_ptr &imagedata) if (total < block) block = total; - ret = io_->read_bulk(imagedata->data() + index,&block); + unsigned int size = block; + void* buf = imagedata->data(index, &size); + if (!buf) + { + VLOG_MINI_3(LOG_LEVEL_FATAL, "memory(0x%08x + %u) fatal when read USB image %d !!!\n", index, block, usb_img_index_); + ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + break; + } + block = size; + ret = io_->read_bulk(buf, &block); if (ret != SCANNER_ERR_OK) { diff --git a/hgdriver/hgdev/image_process.cpp b/hgdriver/hgdev/image_process.cpp index 8e7cf29..702a459 100644 --- a/hgdriver/hgdev/image_process.cpp +++ b/hgdriver/hgdev/image_process.cpp @@ -87,11 +87,31 @@ namespace hg_imgproc public: int load_raw_data(std::shared_ptr buff) { + int ret = SCANNER_ERR_INSUFFICIENT_MEMORY; + buffer_.reset(new std::vector(buff->size())); if (buffer_.get()) - memcpy(buffer_->data(), buff->data(), buff->size()); + { + unsigned int total = buff->size(), + off = 0, size = total; + unsigned char* mem = buff->data(off, &size); + while (mem) + { + memcpy(buffer_->data(), mem, size); + off += size; + if (off >= total) + { + ret = SCANNER_ERR_OK; + break; + } + + size = total - off; + mem = buff->data(off, &size); + } + } mats_.clear(); - return SCANNER_ERR_OK; + + return ret; } int load_file(const char* path_file) { diff --git a/hgdriver/wrapper/hg_log.cpp b/hgdriver/wrapper/hg_log.cpp index 26ee663..be88cb3 100644 --- a/hgdriver/wrapper/hg_log.cpp +++ b/hgdriver/wrapper/hg_log.cpp @@ -445,9 +445,27 @@ extern "C" { return g_scanner_path; } + unsigned int get_page_size(void) + { + unsigned int ps = 1024; +#ifdef WIN32 + SYSTEM_INFO si = { 0 }; + + GetSystemInfo(&si); + ps = si.dwPageSize; +#else + ps = sysconf(_SC_PAGESIZE); + if(ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB + ps = getpagesize(); +#endif + if (ps < 1024 || (ps & 0x0fe0000ff)) // nKB && < 16MB + ps = 1024; + + return ps; + } static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path) { - std::string me(self_path + PATH_SEPARATOR + "configs" + PATH_SEPARATOR + " scanner.conf"); + std::string me(self_path + PATH_SEPARATOR + "Cfg" + PATH_SEPARATOR + " scanner.conf"); int lv = LOG_LEVEL_ALL; hg_log_type tp = LOG_TYPE_FILE; @@ -477,31 +495,60 @@ extern "C" else if (val == "fatal") lv = LOG_LEVEL_FATAL; } + else + create_folder((self_path + PATH_SEPARATOR + "Cfg").c_str()); return lv; } + std::string local_data_path(void) + { +#ifdef WIN32 + char* tmp = getenv("TMP"); + std::string home(tmp ? tmp : ""); + + if (home.length()) + { + size_t pos = home.rfind('\\'); + if (pos++ != std::string::npos) + home.erase(pos); + } +#else + std::string home(getenv("HOME")); + + home += "/."; +#endif + +#ifdef OEM_HANWANG + home += "HwScanner"; +#elif defined(OEM_LISICHENG) + home += "LscScanner"; +#else + home += "HuaGoScan"; +#endif; + create_folder(home.c_str()); + + return home; + } int init(void) { char* file = nullptr; std::string path(""); hg_log_type type = LOG_TYPE_FILE; - int level = get_log_config(get_scanner_path(), &type, &path); + int level = get_log_config(local_data_path(), &type, &path); if (type == LOG_TYPE_FILE) { std::string name(""), - paths[] = {pe_path(&name), get_scanner_path(), simple_ini::temporary_path()}; + paths[] = { local_data_path(), pe_path(&name), get_scanner_path(), simple_ini::temporary_path()}; int ind = 0; - if (path.empty() || !create_folder(path.c_str())) - path = paths[ind++]; - else + if (!path.empty() && create_folder(path.c_str())) ind = sizeof(paths) / sizeof(paths[0]) + 2; for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind) { - path = paths[ind] + PATH_SEPARATOR + "log"; + path = paths[ind] + PATH_SEPARATOR + "Log"; if (create_folder(path.c_str())) break; } diff --git a/hgdriver/wrapper/hg_log.h b/hgdriver/wrapper/hg_log.h index d6ae189..7d123ef 100644 --- a/hgdriver/wrapper/hg_log.h +++ b/hgdriver/wrapper/hg_log.h @@ -49,6 +49,8 @@ extern "C" std::string pe_path(std::string* name = nullptr); std::string get_module_full_path(const char* module_part_name); std::string get_scanner_path(void); + std::string local_data_path(void); + unsigned int get_page_size(void); unsigned long long available_memory(void); void str_tolower(std::string& str); bool create_folder(const char* fodler);