图片接收转储过程中的内存全部用tiny_buffer(支持文件映射方式,WIN平台还需要完善)

This commit is contained in:
gb 2022-06-01 11:04:10 +08:00
parent 33f057b5c0
commit b83a31c5e4
21 changed files with 729 additions and 436 deletions

View File

@ -111,232 +111,4 @@ public:
}
};
#include <string.h>
typedef struct _img_header
{
int width;
int height;
int bits;
int channels;
int line_bytes;
unsigned bytes;
}IMH;
typedef struct _img
{
IMH header;
unsigned offset;
bool is_file; // when this is true, then the 'data' stores the full path of the file
void* fptr;
std::shared_ptr<std::vector<unsigned char>> data;
}IMGDT;
class image_data
{
private:
image_data(const image_data& rhs);
image_data& operator =(const image_data& rhs);
mutable std::mutex _mutex;
std::condition_variable _condvar;
deque<IMGDT> _queue;
bool isShutDown;
IMGDT tRet;
public:
image_data()
: _mutex()
, _condvar()
, _queue()
, isShutDown(false)
{
}
~image_data()
{
ShutDown();
std::cout << "blocking queue release" << std::endl;
}
void Clear()
{
lock_guard<mutex> lock(_mutex);
_condvar.notify_all();
_queue.clear();
}
void ShutDown()
{
isShutDown = true;
_condvar.notify_all();
_queue.clear();
}
bool IsShutDown()
{
return isShutDown;
}
void Put(const IMGDT task)
{
lock_guard<mutex> lock(_mutex);
if (!isShutDown)
{
{
_queue.push_back(task);
}
_condvar.notify_all();
}
}
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes)
{
IMGDT img;
img.header.width = w;
img.header.height = h;
img.header.bits = bpp;
img.header.channels = channels;
img.header.line_bytes = line_bytes;
img.offset = 0;
img.header.bytes = bytes;
img.data.reset(new std::vector<unsigned char>(bytes));
if (!img.data.get())
return false;
img.is_file = false;
img.fptr = nullptr;
memcpy(img.data->data(), data, bytes);
Put(img);
return true;
}
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes, const char* file)
{
IMGDT img;
img.header.width = w;
img.header.height = h;
img.header.bits = bpp;
img.header.channels = channels;
img.header.line_bytes = line_bytes;
img.offset = 0;
img.header.bytes = bytes;
img.is_file = true;
img.fptr = nullptr;
img.data.reset(new std::vector<unsigned char>(strlen(file) * 2));
if (!img.data.get())
return false;
strcpy((char*)&img.data->data()[0], file);
FILE* dst = fopen(file, "rw+b");
if (!dst)
return false;
fwrite(data, 1, bytes, dst);
fclose(dst);
img.fptr = fopen(file, "rb"); // open and keep it
if (!img.fptr)
{
remove(file);
return false;
}
Put(img);
return true;
}
IMGDT Take()
{
unique_lock<mutex> lock(_mutex);
if (_queue.size() <= 0)
_condvar.wait(lock);
if (isShutDown || _queue.empty())
{
return tRet;
}
IMGDT front(_queue.front());
_queue.pop_front();
return front;
}
IMGDT Front()
{
unique_lock<mutex> lock(_mutex);
if (_queue.size() <= 0)
_condvar.wait(lock);
if (isShutDown || _queue.empty())
{
return tRet;
}
IMGDT front(_queue.front());
return front;
}
bool front(IMH* header)
{
unique_lock<mutex> lock(_mutex);
if (_queue.size() <= 0)
_condvar.wait(lock);
if (isShutDown || _queue.empty())
{
return false;
}
memcpy(header, &_queue.front().header, sizeof(*header));
return true;
}
size_t Size() const
{
lock_guard<mutex> lock(_mutex);
return _queue.size();
}
void fetch_front(void* buf, int* len, bool* over)
{
if (Size() == 0)
*len = 0;
else
{
lock_guard<mutex> lock(_mutex);
if (_queue.front().is_file)
{
if (_queue.front().data->size() - _queue.front().offset <= *len)
{
*len = _queue.front().data->size() - _queue.front().offset;
fread(buf, 1, *len, (FILE*)_queue.front().fptr);
fclose((FILE*)_queue.front().fptr);
remove((const char*)_queue.front().data->data());
_queue.pop_front();
if (over)
*over = true;
}
else
{
fread(buf, 1, *len, (FILE*)_queue.front().fptr);
_queue.front().offset += *len;
if (over)
*over = false;
}
}
else
{
if (_queue.front().data->size() - _queue.front().offset <= *len)
{
*len = _queue.front().data->size() - _queue.front().offset;
memcpy(buf, _queue.front().data->data() + _queue.front().offset, *len);
_queue.pop_front();
if (over)
*over = true;
}
else
{
memcpy(buf, _queue.front().data->data() + _queue.front().offset, *len);
_queue.front().offset += *len;
if (over)
*over = false;
}
}
}
}
};
#endif

View File

@ -7,6 +7,8 @@
#else
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#endif
@ -248,7 +250,7 @@ char* shared_memory::get_buf(void)
#else
int* h = (int*)&obj_;
char* buf = (char*)shmat(*h, 0, 0);
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shared memory %d buffer = %s, error = %d\n", *h, hg_log::format_ptr(buf).c_str(), errno);
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "shared memory %d tiny_buffer = %s, error = %d\n", *h, hg_log::format_ptr(buf).c_str(), errno);
#endif
return buf;
@ -340,3 +342,407 @@ int shared_memory::write(const char* data, size_t len)
len_ = len;
release_buf(buf);
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// 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()
{
close();
}
int tiny_file_map::open(const char* file, unsigned int size, bool readonly)
{
close();
int ret = 0;
#ifdef WIN32
if (readonly)
{
HANDLE f = CreateFileA(file, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
ret = GetLastError();
else
{
size_ = GetFileSize(f, NULL);
map_ = CreateFileMappingA(f, NULL, PAGE_READONLY, 0, 0, NULL);
if (map_)
{
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, 0);
if (!buf_)
{
ret = GetLastError();
CloseHandle(map_);
map_ = nullptr;
size_ = 0;
}
}
else
ret = GetLastError();
CloseHandle(f);
}
}
else
{
size_ = size;
HANDLE f = CreateFileA(file, GENERIC_READ | GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if (f == INVALID_HANDLE_VALUE)
ret = GetLastError();
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_READONLY, 0, size, NULL);
if (map_)
{
buf_ = (unsigned char*)MapViewOfFile(map_, FILE_MAP_READ, 0, 0, size);
if (!buf_)
ret = GetLastError();
}
else
ret = GetLastError();
CloseHandle(f);
if (ret)
{
keep_f_ = false;
close();
}
}
}
#else
if (readonly)
{
map_ = ::open(file, O_RDONLY);
if (IS_VALID_MAP(map_))
{
struct stat fsize;
if (fstat(map_, &fsize) >= 0)
size_ = size = fsize.st_size;
}
}
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;
#endif
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "map([%s]%s) = %d\n", readonly ? "R" : "RW", file, ret);
if (ret == 0)
file_ = file;
return ret;
}
void tiny_file_map::close(void)
{
if (buf_)
{
#ifdef WIN32
UnmapViewOfFile(buf_);
#else
munmap(buf_, size_);
#endif
buf_ = nullptr;
}
if (map_)
{
#ifdef WIN32
CloseHandle(map_);
#else
::close(map_);
#endif
map_ = 0;
}
if (!keep_f_ && !file_.empty())
remove(file_.c_str());
size_ = 0;
file_ = "";
keep_f_ = false;
}
void tiny_file_map::keep_file(bool keep)
{
keep_f_ = keep;
}
unsigned char* tiny_file_map::mapping_buffer(void)
{
return buf_;
}
std::string tiny_file_map::file(void)
{
return file_;
}
unsigned int tiny_file_map::size(void)
{
return size_;
}
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;
}
return ret;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// memory or file mapping ...
tiny_buffer::tiny_buffer(unsigned int size
, const char* tmp_path
, const char* name_leading
, const char* ext
, unsigned int uniq_id)
: size_(size), buf_(nullptr)
{
init(tmp_path, name_leading, ext, uniq_id);
}
tiny_buffer::tiny_buffer(const char* src_file)
{
fmap_.open(src_file, 0, true);
buf_ = fmap_.mapping_buffer();
size_ = fmap_.size();
}
tiny_buffer::~tiny_buffer()
{
if (buf_)
{
if (fmap_.file().empty())
delete[] buf_;
else
fmap_.close();
}
}
void tiny_buffer::init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id)
{
try
{
buf_ = new unsigned char[size_];
memset(buf_, 0, size_);
}
catch (...)
{
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;
fmap_.open(f.c_str(), size_, false);
buf_ = fmap_.mapping_buffer();
}
// 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)
{
return buf_;
}
void tiny_buffer::keep_file(bool keep)
{
fmap_.keep_file(keep);
}
std::string tiny_buffer::file(void)
{
return fmap_.file();
}
bool tiny_buffer::swap(void)
{
if (fmap_.file().empty())
return true;
bool ret = fmap_.swap();
buf_ = fmap_.mapping_buffer();
return ret;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// final_img_queue
final_img_queue::final_img_queue()
{}
final_img_queue::~final_img_queue()
{}
size_t final_img_queue::size(void)
{
std::lock_guard<std::mutex> lck(lock_);
return queue_.size();
}
void final_img_queue::clear(void)
{
std::lock_guard<std::mutex> lck(lock_);
queue_.clear();
}
bool final_img_queue::put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
, const char* tmp_path, const char* name_leading, const char* ext, int ind)
{
IMGDT imgd;
bool ret = false;
imgd.header.bits = bpp;
imgd.header.bytes = bytes;
imgd.header.channels = channels;
imgd.header.height = h;
imgd.header.line_bytes = line_bytes;
imgd.header.width = w;
imgd.offset = 0;
imgd.data.reset(new tiny_buffer(bytes, tmp_path, name_leading, ext, ind));
if(imgd.data->data())
{
memcpy(imgd.data->data(), data, bytes);
if (imgd.data->swap())
{
std::lock_guard<std::mutex> lck(lock_);
queue_.push_back(imgd);
ret = true;
}
else
imgd.data.reset();
}
return ret;
}
bool final_img_queue::front(IMH* header)
{
std::lock_guard<std::mutex> lck(lock_);
if (queue_.size() == 0)
return false;
memcpy(header, &queue_[0].header, sizeof(*header));
return true;
}
void final_img_queue::fetch_front(void* buf, int* len, bool* over)
{
std::lock_guard<std::mutex> lck(lock_);
if (queue_.size() == 0)
{
if(len)
*len = 0;
if(over)
*over = true;
}
else
{
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);
imgd.offset += *len;
if (imgd.offset >= imgd.header.bytes)
{
if (over)
*over = true;
queue_.erase(queue_.begin());
}
}
}

View File

@ -14,11 +14,14 @@
#include <semaphore.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/mman.h>
#define USB_TIMEOUT_INFINITE 0
#endif
#include <string>
#include <vector>
#include <mutex>
#include <memory>
class platform_event
@ -126,3 +129,87 @@ public:
std::string read(void);
int write(const char* data, size_t len);
};
// buffer
class tiny_file_map
{
unsigned int size_;
#ifdef WIN32
HANDLE map_;
#else
int map_;
#endif
unsigned char *buf_;
std::string file_;
bool keep_f_;
public:
tiny_file_map();
~tiny_file_map();
public:
int open(const char* file, unsigned int size, bool readonly);
void close(void);
void keep_file(bool keep);
unsigned char* mapping_buffer(void);
std::string file(void);
unsigned int size(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
};
class tiny_buffer
{
unsigned int size_;
unsigned char *buf_;
tiny_file_map fmap_;
void init(const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
public:
tiny_buffer(unsigned int size, const char* tmp_path, const char* name_leading, const char* ext, unsigned int uniq_id);
tiny_buffer(const char* src_file);
~tiny_buffer();
public:
unsigned int size(void);
unsigned char* data(void);
void keep_file(bool keep);
std::string file(void);
// mapping if unmapped; or unmapping if mapped
bool swap(void);
};
typedef struct _img_header
{
int width;
int height;
int bits;
int channels;
int line_bytes;
unsigned bytes;
}IMH;
typedef struct _img
{
IMH header;
unsigned offset;
std::shared_ptr<tiny_buffer> data;
}IMGDT;
class final_img_queue
{
mutable std::mutex lock_;
std::vector<IMGDT> queue_;
public:
final_img_queue();
~final_img_queue();
public:
size_t size(void);
void clear(void);
bool put(int w, int h, int bpp, int channels, int line_bytes, void* data, unsigned bytes
, const char* tmp_path, const char* name_leading, const char* ext, int ind);
bool front(IMH* header);
void fetch_front(void* buf, int* len, bool* over);
};

View File

@ -95,9 +95,9 @@ hg_scanner::hg_scanner(ScannerSerial serial
{
final_path_ = hg_log::ini_get("paths", "final_img");
if(final_path_.empty())
final_path_ = g_module_path + "imgs";
final_path_ = hg_log::get_scanner_path() + "imgs";
if (hg_log::create_folder(final_path_.c_str()))
final_path_ += "/";
final_path_ += PATH_SEPARATOR;
else
final_path_ = "";
@ -187,12 +187,12 @@ int hg_scanner::save_2_tempory_file(std::shared_ptr<std::vector<char>> data, std
FILE* dst = nullptr;
int ret = SCANNER_ERR_OK;
sprintf(head, "scan_%06u", index);
sprintf(head, "usb_%05u", index);
if(!path_file || path_file->empty())
file = hg_scanner::temporary_file((char*)".jpg", (char*)head);
dst = fopen(file.c_str(), "wb+");
dst = fopen(file.c_str(), "wb");
if (dst)
{
ENOSPC; EROFS; strerror(errno);
size_t wrote = fwrite(data->data(), 1, data->size(), dst);
if (wrote == data->size())
{
@ -670,8 +670,8 @@ void hg_scanner::thread_handle_image_process(void)
{
while (run_ && !user_cancel_)
{
std::shared_ptr<std::vector<char>> buffer;
if (imgs_.Size() == 0 && paths_.Size() == 0)
std::shared_ptr<tiny_buffer> tiny_buffer;
if (imgs_.Size() == 0)
{
if (wait_usb_.is_waiting())
break;
@ -680,56 +680,27 @@ void hg_scanner::thread_handle_image_process(void)
continue;
}
if (is_to_file())
{
std::string file(paths_.Take());
FILE* src = fopen(file.c_str(), "rb+");
if (src)
{
unsigned length = 0;
fseek(src, 0, SEEK_END);
length = ftell(src);
fseek(src, 0, SEEK_SET);
buffer = aquire_memory((int)length, false);
if (!buffer.get())
{
status_ = SCANNER_ERR_INSUFFICIENT_MEMORY;
break;
}
fread(buffer->data(), 1, length, src);
fclose(src);
remove(file.c_str());
}
tiny_buffer = imgs_.Take();
if(tiny_buffer->swap())
image_process(tiny_buffer);
else
{
VLOG_MINI_1(LOG_LEVEL_FATAL, "FATAL: open tempory image file '%s' failed.\n", file.c_str());
VLOG_MINI_1(LOG_LEVEL_FATAL, "Reload USB data '%s' failed!\n", tiny_buffer->file().c_str());
}
}
else
{
buffer = imgs_.Take();
}
image_process(buffer);
}
}
void hg_scanner::working_begin(void*)
{
final_img_index_ = 0;
notify_ui_working_status(STATU_DESC_SCAN_WORKING, SANE_EVENT_WORKING, SCANNER_ERR_OK);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "[%s] scanning ...\n", hg_log::current_time().c_str());
}
void hg_scanner::working_done(void*)
{
imgs_.Clear();
if(user_cancel_)
final_imgs_.Clear();
while (paths_.Size())
{
remove(paths_.Take().c_str());
}
final_imgs_.clear();
switch (status_)
{
@ -798,15 +769,13 @@ void hg_scanner::working_done(void*)
break;
}
//notify_ui_working_status(STATU_DESC_SCAN_STOPPED, SANE_EVENT_SCAN_FINISHED, status_);
if (test_1_paper_)
{
LOG_INFO(LOG_LEVEL_DEBUG_INFO, "scanning mode: finished testing ONE paper, restore to normal scanning.\n");
}
else
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "scanned %d picture(s) and finished with error %s.\n", final_img_index_, hg_scanner_err_name(status_));
VLOG_MINI_3(LOG_LEVEL_DEBUG_INFO, "[%s] scanned %d picture(s) and finished with error %s.\n", hg_log::current_time().c_str(), final_img_index_, hg_scanner_err_name(status_));
}
test_1_paper_ = false;
@ -904,7 +873,7 @@ int hg_scanner::setting_help(void* data)
#ifdef WIN32
com = "";
helpfile.insert(0, g_module_path);
helpfile.insert(0, hg_log::get_scanner_path());
FILE* src = fopen(helpfile.c_str(), "rb");
if (src)
fclose(src);
@ -1686,7 +1655,7 @@ int hg_scanner::try_third_app_handle_start(bool& handled)
while (wait_usb_result_.try_wait())
std::this_thread::sleep_for(std::chrono::milliseconds(3));
if (!wait_img_.is_waiting() || !wait_usb_.is_waiting() || final_imgs_.Size())
if (!wait_img_.is_waiting() || !wait_usb_.is_waiting() || final_imgs_.size())
ret = SCANNER_ERR_OK;
else if (final_img_index_)
{
@ -1713,41 +1682,19 @@ int hg_scanner::try_third_app_after_start(int err)
return err;
}
std::shared_ptr<std::vector<char>> hg_scanner::aquire_memory(int size, bool from_usb)
std::shared_ptr<tiny_buffer> hg_scanner::aquire_memory(int size, bool from_usb)
{
std::shared_ptr<std::vector<char>> mem;
std::string lead(from_usb ? "usb" : "imgp"), ext(from_usb ? "jpg" : "dat");
unsigned int ind = from_usb ? usb_img_index_ : final_img_index_;
std::shared_ptr<tiny_buffer> mem(new tiny_buffer(size, final_path_.c_str(), lead.c_str(), ext.c_str(), ind));
try
{
mem.reset(new std::vector<char>(size));
}
catch (...)
if (!mem->data())
{
mem.reset();
VLOG_MINI_1(LOG_LEVEL_FATAL, "Allocate memory of bytes %u failed!\n", size);
}
if (!mem.get())
{
if (from_usb && final_imgs_.Size())
{
std::this_thread::sleep_for(std::chrono::milliseconds(10));
try
{
mem.reset(new std::vector<char>(size));
}
catch (...)
{
mem.reset();
VLOG_MINI_1(LOG_LEVEL_FATAL, "Allocate memory of bytes %u failed secondary after 10 milliseconds!\n", size);
}
}
if (!mem.get())
{
LOG_INFO(LOG_LEVEL_FATAL, "Can't aquire enough memory, working must be stopped!\n");
notify_ui_working_status(STATU_DESC_SCANNER_ERR_INSUFFICIENT_MEMORY, SANE_EVENT_ERROR, SCANNER_ERR_INSUFFICIENT_MEMORY);
stop();
}
}
return mem;
}
@ -1824,30 +1771,22 @@ void hg_scanner::copy_to_sane_image_header(SANE_Parameters* header, int w, int h
header->lines = h;
header->bytes_per_line = line_bytes;
}
int hg_scanner::save_usb_data(std::shared_ptr<std::vector<char>> data)
int hg_scanner::save_usb_data(std::shared_ptr<tiny_buffer> data)
{
int ret = SCANNER_ERR_OK;
usb_img_index_++;
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "USB read one picture with %u bytes\n", data->size());
if (is_to_file())
if (!data->swap())
{
std::string file("");
ret = hg_scanner::save_2_tempory_file(data, &file, usb_img_index_);
if (ret == SCANNER_ERR_OK)
paths_.Put(file);
ret = SCANNER_ERR_OPEN_FILE_FAILED;
}
else
{
imgs_.Put(data);
#ifdef SAVE_TO_FILE
hg_scanner::save_2_tempory_file(data, NULL, usb_img_index_);
#endif
}
if (wait_img_.is_waiting())
wait_img_.notify();
}
return ret;
}
@ -1856,8 +1795,7 @@ int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf)
std::string bw("");
final_img_index_++;
//if (image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE)
if(img_conf_.pixtype == 0)
if (image_prc_param_.bits.color_mode == COLOR_MODE_BLACK_WHITE)
{
int old = head->line_bytes;
bw = bmp_821((unsigned char*)buf, head->width, head->height, &head->line_bytes, async_io_);
@ -1877,26 +1815,12 @@ int hg_scanner::save_final_image(hg_imgproc::LPIMGHEAD head, void* buf)
return ui_ev_cb_((scanner_handle)this, SANE_EVENT_IMAGE_OK, &img, &final_img_index_, NULL);
}
if (resolution_ <= 300 && final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes))
return SCANNER_ERR_OK;
else
{
// try file ...
char name[40] = { 0 };
sprintf(name, "img_%05d.dat", final_img_index_);
if (resolution_ <= 300)
{
VLOG_MINI_2(LOG_LEVEL_WARNING, "Memory(%u bytes) allocating failed when save final image, try save to file: %s\n", head->total_bytes, (final_path_ + name).c_str());
}
if(!final_path_.empty() &&
final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes
, (final_path_ + name).c_str()))
if (final_imgs_.put(head->width, head->height, head->bits, head->channels, head->line_bytes, buf, head->total_bytes
, final_path_.c_str(), "final", "dat", final_img_index_))
return SCANNER_ERR_OK;
else
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
}
int hg_scanner::is_running(void)
{
if (!scan_life_)
@ -2247,10 +2171,10 @@ int hg_scanner::get_image_info(SANE_Parameters* ii)
bzero(&imh, sizeof(imh));
bzero(ii, sizeof(*ii));
while ((!wait_img_.is_waiting() || !wait_usb_.is_waiting()) && final_imgs_.Size() <= 0)
while ((!wait_img_.is_waiting() || !wait_usb_.is_waiting()) && final_imgs_.size() <= 0)
this_thread::sleep_for(chrono::milliseconds(10));
if (final_imgs_.Size() <= 0)
if (final_imgs_.size() <= 0)
ret = SCANNER_ERR_NO_DATA;
else
{
@ -2301,7 +2225,7 @@ int hg_scanner::read_image_data(unsigned char* buf, int* len)
return SCANNER_ERR_INSUFFICIENT_MEMORY;
}
if (final_imgs_.Size() > 0)
if (final_imgs_.size() > 0)
{
int fetch = *len;
bool over = false;

View File

@ -210,7 +210,7 @@ protected:
virtual int set_setting_value(int setting_no, void* data, int len);
virtual int on_scanner_closing(bool force);
virtual void thread_handle_usb_read(void) = 0;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) = 0;
virtual void image_process(std::shared_ptr<tiny_buffer>& buff) = 0;
protected:
volatile bool run_;
@ -251,25 +251,24 @@ protected:
SCANCONF img_conf_; //此参数外部不做任何改变请在writedown_image_configuration做修改
std::string img_type_;
image_data final_imgs_; // JPG ...
final_img_queue final_imgs_; // JPG ...
unsigned int usb_img_index_;
unsigned int final_img_index_;
std::string final_path_;
BlockingQueue<std::shared_ptr<std::vector<char>>> imgs_;
BlockingQueue<std::string> paths_;
BlockingQueue<std::shared_ptr<tiny_buffer>> imgs_;
void init_settings(const char* json_setting_text);
int on_scann_error(int err); // 返回“0”忽略错误继续执行其它值则停止后续工作
int try_third_app_handle_start(bool& handled);
int try_third_app_after_start(int err);
std::shared_ptr<std::vector<char>> aquire_memory(int size, bool from_usb = true);
std::shared_ptr<tiny_buffer> aquire_memory(int size, bool from_usb = true);
// callback to ui ...
int notify_ui_working_status(const char* msg, int ev = SANE_EVENT_STATUS, int status = SCANNER_ERR_OK);
bool waiting_for_memory_enough(unsigned need_bytes);
void copy_to_sane_image_header(SANE_Parameters* header, int w, int h, int line_bytes, int channels, int bits);
int save_usb_data(std::shared_ptr<std::vector<char>> data);
int save_usb_data(std::shared_ptr<tiny_buffer> data);
int save_final_image(hg_imgproc::LPIMGHEAD head, void* buf);
enum thread_running

View File

@ -480,7 +480,7 @@ int hg_scanner_200::stop(void)
{
status_ = SCANNER_ERR_DEVICE_STOPPED;
}
final_imgs_.Clear();
final_imgs_.clear();
return status_;
}
@ -550,7 +550,7 @@ int hg_scanner_200::get_img_data(unsigned int bytes)
ret = SCANNER_ERR_OK,
index = 0,
block = total;
std::shared_ptr<std::vector<char >> imagedata(aquire_memory(total));
std::shared_ptr<tiny_buffer> imagedata(aquire_memory(total));
if (!imagedata.get())
return SCANNER_ERR_INSUFFICIENT_MEMORY;
@ -587,7 +587,7 @@ int hg_scanner_200::get_img_data(unsigned int bytes)
return ret;
}
void hg_scanner_200::image_process(std::shared_ptr<std::vector<char>>& buffer)
void hg_scanner_200::image_process(std::shared_ptr<tiny_buffer>& buffer)
{
int ret = SCANNER_ERR_OK;
hg_imgproc::IMGPRCPARAM param;

View File

@ -26,7 +26,7 @@ class hg_scanner_200 : public hg_scanner
protected:
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) override;
virtual void image_process(std::shared_ptr<tiny_buffer>& buff) override;
virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx

View File

@ -620,7 +620,7 @@ void hg_scanner_239::init_version(void)
else
is_kernelsnap_211209_ = false;
}
void hg_scanner_239::image_process(std::shared_ptr<std::vector<char>>& buff)
void hg_scanner_239::image_process(std::shared_ptr<tiny_buffer>& buff)
{
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Process image with %u bytes content ...\n", buff->size());
@ -1000,7 +1000,7 @@ int hg_scanner_239::read_one_image_from_usb(void)
ret = status_;
else
{
std::shared_ptr<std::vector<char>> buf(aquire_memory(total));
std::shared_ptr<tiny_buffer> buf(aquire_memory(total));
if (!buf.get())
return SCANNER_ERR_INSUFFICIENT_MEMORY;
@ -1701,17 +1701,13 @@ int hg_scanner_239::stop(void)
user_cancel_ = true;
ret = write_command(SC_STOP);
io_->set_timeout(500);
final_imgs_.Clear();
final_imgs_.clear();
return status_;
}
int hg_scanner_239::reset(void)
{
final_imgs_.Clear();
while (paths_.Size() > 0)
remove(paths_.Take().c_str());
final_imgs_.clear();
discard_all_images();
return status_;

View File

@ -72,7 +72,7 @@ protected:
virtual void on_device_reconnected(void) override;
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) override;
virtual void image_process(std::shared_ptr<tiny_buffer>& buff) override;
public:
hg_scanner_239(const char* dev_name, int pid,usb_io* io);

View File

@ -322,7 +322,7 @@ void hg_scanner_300::thread_handle_usb_read(void)
if (ret == SCANNER_ERR_OK && usb.u32_Count > 0)
{
int totalNum = usb.u32_Count;
std::shared_ptr<std::vector<char >> imagedata(aquire_memory(totalNum));
std::shared_ptr<tiny_buffer> imagedata(aquire_memory(totalNum));
if (!imagedata.get())
{
@ -425,7 +425,7 @@ int hg_scanner_300::stop(void)
{
status_ = SCANNER_ERR_DEVICE_STOPPED;
}
final_imgs_.Clear();
final_imgs_.clear();
return status_;
}
@ -491,7 +491,7 @@ int hg_scanner_300::get_scanner_status(USBCB &usb)
scanner_err code = settingsdsp_300::device_status_to_hg_err(usb.u32_Data);
return code ;
}
int hg_scanner_300::get_img_data(std::shared_ptr<std::vector<char>> &imagedata)
int hg_scanner_300::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
{
int total = imagedata->size(),
ret = SCANNER_ERR_OK,
@ -535,7 +535,7 @@ int hg_scanner_300::get_img_data(std::shared_ptr<std::vector<char>> &imagedata)
return ret;
}
void hg_scanner_300::image_process(std::shared_ptr<std::vector<char>>& buffer)
void hg_scanner_300::image_process(std::shared_ptr<tiny_buffer>& buffer)
{
int ret = SCANNER_ERR_OK;
hg_imgproc::IMGPRCPARAM param;

View File

@ -25,7 +25,7 @@ class hg_scanner_300 : public hg_scanner
protected:
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) override;
virtual void image_process(std::shared_ptr<tiny_buffer>& buff) override;
virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx
@ -55,7 +55,7 @@ private:
int readusb(USBCB &usb);
int pop_image(void);
int get_scanner_status(USBCB &usb);
int get_img_data(std::shared_ptr<std::vector<char>> &imagedata);
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
int writedown_device_configuration(bool type =false,HGSCANCONF_G400 *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(HGSCANCONF_G400 *d = NULL);

View File

@ -319,7 +319,7 @@ void hg_scanner_400::thread_handle_usb_read(void)
if (ret == SCANNER_ERR_OK && usb.u32_Count > 0)
{
int totalNum = usb.u32_Count;
std::shared_ptr<std::vector<char >> imagedata(aquire_memory(totalNum));
std::shared_ptr<tiny_buffer> imagedata(aquire_memory(totalNum));
if (!imagedata.get())
{
@ -424,7 +424,7 @@ int hg_scanner_400::stop(void)
VLOG_MINI_1(LOG_LEVEL_WARNING, "stop device:(%s)\n", hg_scanner_err_name(status_));
}
notify_ui_working_status("取消扫描", SANE_EVENT_STATUS, status_);
final_imgs_.Clear();
final_imgs_.clear();
return status_;
}
@ -489,7 +489,7 @@ int hg_scanner_400::get_scanner_status(USBCB &usb)
scanner_err code = settingsdsp_400::device_status_to_hg_err(usb.u32_Data);
return code ;
}
int hg_scanner_400::get_img_data(std::shared_ptr<std::vector<char>> &imagedata)
int hg_scanner_400::get_img_data(std::shared_ptr<tiny_buffer> &imagedata)
{
int total = imagedata->size(),
ret = SCANNER_ERR_OK,
@ -533,7 +533,7 @@ int hg_scanner_400::get_img_data(std::shared_ptr<std::vector<char>> &imagedata)
return ret;
}
void hg_scanner_400::image_process(std::shared_ptr<std::vector<char>>& buffer)
void hg_scanner_400::image_process(std::shared_ptr<tiny_buffer>& buffer)
{
int ret = SCANNER_ERR_OK;
hg_imgproc::IMGPRCPARAM param;

View File

@ -25,7 +25,7 @@ class hg_scanner_400 : public hg_scanner
protected:
virtual int on_scanner_closing(bool force) override;
virtual void thread_handle_usb_read(void) override;
virtual void image_process(std::shared_ptr<std::vector<char>>& buff) override;
virtual void image_process(std::shared_ptr<tiny_buffer>& buff) override;
virtual int on_color_mode_changed(int& color_mode); // COLOR_MODE_xxx
@ -54,7 +54,7 @@ private:
int readusb(USBCB &usb);
int pop_image(void);
int get_scanner_status(USBCB &usb);
int get_img_data(std::shared_ptr<std::vector<char>> &imagedata);
int get_img_data(std::shared_ptr<tiny_buffer> &imagedata);
int writedown_device_configuration(bool type =false,HGSCANCONF_G400 *d = NULL);
void writedown_image_configuration(void);
void printf_devconfig(HGSCANCONF_G400 *d = NULL);

View File

@ -27,6 +27,7 @@ extern "C"
#include "ocr/hanwangOCRdetect.h"
}
#endif
#include "hg_ipc.h"
using namespace std;
#define GET_BYTE(a) ((a) & 0x0ff)
@ -84,9 +85,11 @@ namespace hg_imgproc
// load data
public:
int load_raw_data(std::shared_ptr<std::vector<char>> buff)
int load_raw_data(std::shared_ptr<tiny_buffer> buff)
{
buffer_.reset(new std::vector<char >(*buff));
buffer_.reset(new std::vector<char>(buff->size()));
if (buffer_.get())
memcpy(buffer_->data(), buff->data(), buff->size());
mats_.clear();
return SCANNER_ERR_OK;
}
@ -843,7 +846,7 @@ namespace hg_imgproc
return (HIMGPRC)obj;
}
int load_buffer(HIMGPRC himg, std::shared_ptr<std::vector<char>> buff)
int load_buffer(HIMGPRC himg, std::shared_ptr<tiny_buffer> buff)
{
return ((imgproc*)himg)->load_raw_data(buff);
}

View File

@ -8,7 +8,8 @@
#include "common_setting.h"
#include <memory>
#include <vector>
//#include "common_setting.h"
class tiny_buffer;
namespace hg_imgproc
{
typedef struct _img_data
@ -159,7 +160,7 @@ namespace hg_imgproc
HIMGPRC init(LPSCANCONF parameter,LPIMGPRCPARAM param,int pid);
int load_buffer(HIMGPRC himg,std::shared_ptr<std::vector<char>> buff);
int load_buffer(HIMGPRC himg,std::shared_ptr<tiny_buffer> buff);
int load_file(HIMGPRC himg, const char* path_file);
//图像数据转换

View File

@ -652,7 +652,7 @@ bool usb_io::claim_interterface(usb_manager::USBSIMPLEX* spl)
return true;
}
VLOG_MINI_2(LOG_LEVEL_FATAL, " first libusb_claim_interface(%d) = %s\n", spl->iface, libusb_error_name(ret));
VLOG_MINI_2(LOG_LEVEL_FATAL, "libusb_claim_interface(%d) = %s, now try some actions ...\n", spl->iface, libusb_error_name(ret));
ret = libusb_kernel_driver_active(handle_, spl->iface);
if (ret == 1)
@ -668,12 +668,16 @@ bool usb_io::claim_interterface(usb_manager::USBSIMPLEX* spl)
return false;
}
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_clear_halt(%x) ...\n", spl->port);
libusb_clear_halt(handle_, spl->port);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_release_interface(%u) ...\n", spl->iface);
libusb_release_interface(handle_, spl->iface);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_set_configuration(%u) ...\n", spl->iconf);
libusb_set_configuration(handle_, spl->iconf);
else
{
VLOG_MINI_2(LOG_LEVEL_FATAL, " libusb_kernel_driver_active(%d) = %d\n", spl->iface, ret);
}
ret = libusb_clear_halt(handle_, spl->port);
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_clear_halt(%x) = %s\n", spl->port, libusb_error_name(ret));
ret = libusb_release_interface(handle_, spl->iface);
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_release_interface(%u) = %s\n", spl->iface, libusb_error_name(ret));
ret = libusb_set_configuration(handle_, spl->iconf);
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, " libusb_set_configuration(%u) = %s\n", spl->iconf, libusb_error_name(ret));
//ret = libusb_reset_device(handle_);
//VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, " libusb_reset_device = %s\n", libusb_error_name(ret));
//if (ret == LIBUSB_ERROR_NOT_FOUND)
@ -689,6 +693,7 @@ bool usb_io::claim_interterface(usb_manager::USBSIMPLEX* spl)
if (ret == LIBUSB_SUCCESS)
{
spl->claimed = true;
VLOG_MINI_2(LOG_LEVEL_FATAL, "second libusb_claim_interface(%d) = %s\n", spl->iface, libusb_error_name(ret));
return true;
}

View File

@ -34,6 +34,9 @@
#define _INTSIZEOF(n) ((sizeof(n) + sizeof(long) - 1) & ~(sizeof(long) - 1))
#endif
extern std::string g_scanner_path; // Ending with '\\'
class log_cls
{
typedef void(*log_to)(const char*, void*);
@ -75,6 +78,7 @@ protected:
}
public:
static std::string g_time_tag;
static log_cls* instance(void)
{
if (!log_cls::inst_)
@ -112,6 +116,9 @@ public:
{
unsigned char bom[] = { 0x0ef, 0x0bb, 0x0bf };
fwrite(bom, sizeof(bom), 1, file_);
std::string now(g_time_tag + hg_log::current_time() + g_time_tag + " started.\n");
fwrite(now.c_str(), 1, now.length(), file_);
ret = 0;
}
}
@ -141,6 +148,7 @@ public:
}
};
log_cls* log_cls::inst_ = NULL;
std::string log_cls::g_time_tag = "=====";
#ifdef EXPORT_AS_C
extern "C"
@ -433,10 +441,13 @@ extern "C"
return ff.found;
}
std::string get_scanner_path(void)
{
return g_scanner_path;
}
static int get_log_config(const std::string& self_path, hg_log_type* type, std::string* path)
{
std::string me(self_path + "/configs/scanner.conf");
std::string me(self_path + PATH_SEPARATOR + "configs" + PATH_SEPARATOR + " scanner.conf");
int lv = LOG_LEVEL_ALL;
hg_log_type tp = LOG_TYPE_FILE;
@ -473,35 +484,39 @@ extern "C"
int init(void)
{
char* file = nullptr;
std::string me(g_module_path), path("");
std::string path("");
hg_log_type type = LOG_TYPE_FILE;
int level = get_log_config(me, &type, &path);
int level = get_log_config(get_scanner_path(), &type, &path);
if (type == LOG_TYPE_FILE)
{
if (path.empty())
path = me;
path += "/log";
if (!create_folder(path.c_str()))
std::string name(""),
paths[] = {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
ind = sizeof(paths) / sizeof(paths[0]) + 2;
for (; ind < sizeof(paths) / sizeof(paths[0]); ++ind)
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Create log-folder '%s' failed(%d), now try temporary directory\n", path.c_str(), errno);
path = simple_ini::temporary_path() + "/log";
if (!create_folder(path.c_str()))
path = paths[ind] + PATH_SEPARATOR + "log";
if (create_folder(path.c_str()))
break;
}
if(ind == sizeof(paths) / sizeof(paths[0]))
{
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "create temporary directory '%s' failed(%d), log to console\n", path.c_str(), errno);
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Try PE, scanner and temporary path failed(%d), log to console\n", errno);
type = LOG_TYPE_CONSOLE;
}
}
if (type == LOG_TYPE_FILE)
{
std::string name("");
pe_path(&name);
if (name.empty())
path += "/scanner.log";
path += std::string(PATH_SEPARATOR) + "scanner.log";
else
path += "/" + name + ".log";
path += PATH_SEPARATOR + name + ".log";
file = &path[0];
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Log to file: '%s'\n", path.c_str());
}
@ -510,6 +525,11 @@ extern "C"
return log_cls::instance()->set_log_type(type, file);
}
void unint(void)
{
std::string now(log_cls::g_time_tag + hg_log::current_time() + log_cls::g_time_tag + " exited.\n");
log(now.c_str());
}
void log(int level, const char* info)
{
if (lcb_)

View File

@ -10,6 +10,9 @@
#ifdef WIN32
#define bzero(a, l) memset(a, 0, l)
#define PATH_SEPARATOR "\\"
#else
#define PATH_SEPARATOR "/"
#endif
#ifdef OEM_HANWANG
@ -43,6 +46,7 @@ extern "C"
std::string u2utf8(const wchar_t* u);
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);
unsigned long long available_memory(void);
void str_tolower(std::string& str);
bool create_folder(const char* fodler);
@ -54,6 +58,7 @@ extern "C"
//
// Return: 0 - success, or -1 in LOG_TYPE_FILE and log_file cannot be created
int init(void);
void unint(void);
void log(int level, const char* info);
bool is_log_level_enabled(int level);

View File

@ -3,6 +3,12 @@
#include "../hgdev/scanner_manager.h"
#include <iostream>
#ifdef WIN32
#include <fileapi.h>
#else
#include <sys/vfs.h>
#include <string.h>
#endif
#ifndef VERSION_MAJOR
#define VERSION_MAJOR 1
@ -16,8 +22,9 @@
| (((unsigned long long)(b) & 0x0ffff) << 32) \
| (((unsigned long long)(c) & 0x0ffff) << 16) \
| (((unsigned long long)(d) & 0x0ffff) << 0))
#define GET_BUILD_VER VERSION_BUILD - 100000
std::string g_module_path = "";
std::string g_scanner_path = "";
static std::string g_sane_name = "";
static std::string g_sane_ver = "";
@ -25,16 +32,30 @@ extern "C"
{
scanner_err hg_scanner_initialize(sane_callback callback, void* reserve)
{
#ifndef WIN32
size_t pos = 0;
g_module_path = hg_log::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str());
pos = g_module_path.rfind('/');
std::string name(""),
pe(hg_log::pe_path(&name)),
path("\\"),
scanner(g_scanner_path),
sane(hg_log::get_module_full_path((g_sane_name + ".so").c_str()));
#ifdef WIN32
size_t pos = g_scanner_path.rfind('\\');
if (pos++ != std::string::npos)
g_module_path.erase(pos);
g_scanner_path.erase(pos);
#else
size_t pos = 0;
g_scanner_path = hg_log::get_module_full_path((std::string(GET_BACKEND_NAME) + ".so").c_str());
scanner = g_scanner_path;
path = "/";
pos = g_scanner_path.rfind('/');
if (pos++ != std::string::npos)
g_scanner_path.erase(pos);
#endif
hg_log::init();
VLOG_MINI_5(LOG_LEVEL_DEBUG_INFO, "Module device: [%u.%u.%u.%u] - %s\n", VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER, scanner.c_str());
VLOG_MINI_2(LOG_LEVEL_DEBUG_INFO, "Module sane : [%s] - %s\n", g_sane_ver.c_str(), sane.c_str());
VLOG_MINI_1(LOG_LEVEL_DEBUG_INFO, "Module exe : %s\n", (pe + path + name).c_str());
hg_scanner_mgr::set_version(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, VERSION_BUILD - 100000);
hg_scanner_mgr::set_version(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER);
hg_scanner_mgr::instance(callback);
return SCANNER_ERR_OK;
@ -42,11 +63,12 @@ extern "C"
void hg_scanner_uninitialize(void)
{
hg_scanner_mgr::clear();
hg_log::unint();
}
unsigned long long hg_scanner_get_version(void)
{
return MAKE_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, VERSION_BUILD - 100000);
return MAKE_VERSION(VERSION_MAJOR, VERSION_MINOR, VERSION_YEAR, GET_BUILD_VER);
}
scanner_err hg_scanner_enum(ScannerInfo* scanner_list, long* count, bool local_only)
@ -256,6 +278,54 @@ extern "C"
return buf;
}
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block)
{
int ret = SCANNER_ERR_OK;
#ifdef WIN32
ULARGE_INTEGER av = { 0 },
all = { 0 };
if (GetDiskFreeSpaceExA(path, &av, &all, NULL))
{
if (total)
*total = all.QuadPart;
if (avail)
*avail = av.QuadPart;
if (block)
{
DWORD sec = 0,
clu = 0;
std::string root(path);
size_t pos = root.find(":\\");
if (pos != std::string::npos)
root.erase(pos + 2);
if (GetDiskFreeSpaceA(root.c_str(), &clu, &sec, NULL, NULL))
{
*block = clu * sec;
}
}
}
else
ret = GetLastError();
#else
struct statfs fs = { 0 };
ret = statfs(path, &fs);
if (ret == 0)
{
VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, " Total: %lld, Free: %lld, Avail: %lld, block size: %lld\n",
fs.f_blocks, fs.f_bfree, fs.f_bavail, fs.f_bsize);
if (total)
*total = fs.f_blocks * fs.f_bsize;
if (avail)
*avail = fs.f_bavail * fs.f_bsize;
if (block)
*block = fs.f_bsize;
}
#endif
return ret;
}
}
@ -265,15 +335,15 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
if (g_module_path.empty())
if (g_scanner_path.empty())
{
char path[MAX_PATH] = { 0 };
GetModuleFileNameA(inst, path, _countof(path) - 1);
if (strrchr(path, '\\'))
// if (strrchr(path, '\\'))
{
strrchr(path, '\\')[1] = 0;
g_module_path = path;
// strrchr(path, '\\')[1] = 0;
g_scanner_path = path;
}
}
}

View File

@ -33,6 +33,8 @@
#define iconv_t void*
#endif
static std::string g_sane_path = "";
namespace local_utility
{
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -275,12 +277,6 @@ namespace local_utility
{
if (version_code)
*version_code = SANE_VERSION_CODE(SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD); // leading-char '1' is used for avoid compiler considering '0118' as an octal number :)
unsigned long long v = hg_scanner_get_version();
unsigned short* w = (unsigned short*)&v;
VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "scanner version: %u.%u.%u.%u\n", w[3], w[2], w[1], w[0]);
VLOG_MINI_4(LOG_LEVEL_DEBUG_INFO, "%s version: %u.%u.%u\n", GET_BACKEND_NAME, SANE_CURRENT_MAJOR, SANE_CURRENT_MINOR, VERSION_BUILD);
}
void stop_work(void)
{
@ -310,10 +306,10 @@ hg_sane_middleware::hg_sane_middleware(void) : opt_0_(nullptr), std_opt_(nullptr
char path[512] = { 0 };
size_t pos = 0;
g_module_path = get_file_path((std::string(GET_BACKEND_NAME) + ".so").c_str(), path);
pos = g_module_path.rfind('/');
g_sane_path = get_file_path((std::string(GET_BACKEND_NAME) + ".so").c_str(), path);
pos = g_sane_path.rfind('/');
if (pos++ != std::string::npos)
g_module_path.erase(pos);
g_sane_path.erase(pos);
#endif
}
hg_sane_middleware::~hg_sane_middleware()
@ -1962,13 +1958,11 @@ extern "C" { // avoid compiler exporting name in C++ style !!!
#ifdef WIN32
std::string g_module_path = "";
BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
{
if (reason == DLL_PROCESS_ATTACH)
{
if (g_module_path.empty())
if (g_sane_path.empty())
{
char path[MAX_PATH] = { 0 };
@ -1976,7 +1970,7 @@ BOOL WINAPI DllMain(HINSTANCE inst, DWORD reason, LPVOID reserved)
if (strrchr(path, '\\'))
{
strrchr(path, '\\')[1] = 0;
g_module_path = path;
g_sane_path = path;
}
}
}

View File

@ -131,8 +131,6 @@
#define MAKE_STR(str) _TO_STR(str)
#define GET_BACKEND_NAME MAKE_STR(BACKEND_NAME)
#include <string>
extern std::string g_module_path; // Ending with '\\'
typedef struct _device
{
@ -433,6 +431,19 @@ extern "C"{
// Return: 返回buf
char* get_file_path(const char* name, char* buf);
// Function: 获取磁盘空间
//
// Parameters: path - 全路径
//
// total - 总空间大小(字节)
//
// avail - 可用空间大小(字节)
//
// block - 磁盘单元(块/簇)大小(字节)
//
// Return: 0 - 成功;其它为失败代码
int get_disk_space(const char* path, unsigned long long* total, unsigned long long* avail, unsigned long long* block);
#ifdef __cplusplus
}
#endif