2022-06-15 03:04:40 +00:00
|
|
|
|
#pragma once
|
|
|
|
|
#include "s2t_api.h"
|
2022-06-18 00:54:01 +00:00
|
|
|
|
#include <vector>
|
|
|
|
|
#include <mutex>
|
2022-06-15 03:04:40 +00:00
|
|
|
|
|
|
|
|
|
class refer : public IRef
|
|
|
|
|
{
|
|
|
|
|
volatile long ref_;
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
refer();
|
|
|
|
|
virtual ~refer();
|
|
|
|
|
|
|
|
|
|
// IRef
|
|
|
|
|
public:
|
|
|
|
|
COM_API_OVERRIDE(long, add_ref(void));
|
|
|
|
|
COM_API_OVERRIDE(long, release(void));
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-16 08:04:58 +00:00
|
|
|
|
class mapping_buf
|
|
|
|
|
{
|
|
|
|
|
unsigned long long bytes_;
|
|
|
|
|
unsigned long long offset_;
|
|
|
|
|
unsigned int page_size_;
|
|
|
|
|
unsigned int map_unit_;
|
|
|
|
|
unsigned int mapped_bytes_;
|
|
|
|
|
HANDLE map_;
|
|
|
|
|
bool is_mem_;
|
|
|
|
|
unsigned char* buf_;
|
|
|
|
|
std::string file_;
|
|
|
|
|
bool rmv_file_;
|
|
|
|
|
|
|
|
|
|
void init_map(const char* file, unsigned long long size);
|
|
|
|
|
void close(void);
|
|
|
|
|
void map(void);
|
|
|
|
|
void set_buffer(unsigned char*& buf, unsigned long long off, unsigned int* bytes);
|
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
mapping_buf();
|
|
|
|
|
~mapping_buf();
|
|
|
|
|
|
|
|
|
|
public:
|
2022-06-29 08:13:05 +00:00
|
|
|
|
unsigned char* allocate(const wchar_t* file, unsigned long long size = 0, bool force_file = false);
|
2022-06-16 08:04:58 +00:00
|
|
|
|
unsigned char* buffer(unsigned long long off, unsigned int* bytes);
|
|
|
|
|
bool save(const void* data, size_t* bytes, unsigned long long off);
|
2022-06-29 08:13:05 +00:00
|
|
|
|
bool save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off = 0);
|
2022-06-17 03:50:18 +00:00
|
|
|
|
int read(void* buf, size_t* bytes, unsigned long long off);
|
2022-06-16 08:04:58 +00:00
|
|
|
|
void unmap();
|
|
|
|
|
void set_remove_file_when_destroyed(bool rmv);
|
|
|
|
|
const char* file(void);
|
|
|
|
|
unsigned long long bytes(void);
|
|
|
|
|
unsigned long long offset(void);
|
|
|
|
|
unsigned int mapped_bytes(void);
|
|
|
|
|
};
|
2022-06-15 03:04:40 +00:00
|
|
|
|
class scanned_img : public IScanImg, virtual public refer
|
|
|
|
|
{
|
|
|
|
|
SANE_Parameters head_;
|
2022-06-16 08:04:58 +00:00
|
|
|
|
mapping_buf* data_;
|
|
|
|
|
int dpi_;
|
2022-06-29 08:13:05 +00:00
|
|
|
|
SANE_Handle dev_;
|
|
|
|
|
std::wstring file_;
|
2022-06-17 03:50:18 +00:00
|
|
|
|
unsigned int header_size_;
|
|
|
|
|
SANE_FinalImgFormat fmt_;
|
2023-07-03 04:23:44 +00:00
|
|
|
|
size_t pal_size_;
|
2022-06-15 03:04:40 +00:00
|
|
|
|
|
2022-09-20 10:14:27 +00:00
|
|
|
|
SANE_Image_Statu status_;
|
|
|
|
|
|
2023-08-04 09:38:26 +00:00
|
|
|
|
// 部分APP不会通过XferMech来设置传输模式,原来预先准备数据的方法不适合该场合
|
|
|
|
|
// 为适应该场景,增加prepare_data_for_transfer接口,在真实读取数据之前调用,以准备恰当的数据
|
|
|
|
|
bool data_done_ = false;
|
|
|
|
|
|
|
|
|
|
std::string file_header(SANE_ImageType type, float resolution);
|
|
|
|
|
void do_result(twain_xfer xfer);
|
2022-06-18 00:54:01 +00:00
|
|
|
|
void swap_rgb(void);
|
2022-06-15 03:04:40 +00:00
|
|
|
|
|
|
|
|
|
public:
|
2022-06-29 08:13:05 +00:00
|
|
|
|
scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* tmp_file
|
2022-06-18 00:54:01 +00:00
|
|
|
|
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
2022-06-15 03:04:40 +00:00
|
|
|
|
|
2022-09-20 10:14:27 +00:00
|
|
|
|
void set_image_status(SANE_Image_Statu status);
|
2022-06-15 03:04:40 +00:00
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
~scanned_img();
|
|
|
|
|
|
|
|
|
|
// IRef
|
|
|
|
|
public:
|
|
|
|
|
COM_API_OVERRIDE(long, add_ref(void));
|
|
|
|
|
COM_API_OVERRIDE(long, release(void));
|
|
|
|
|
|
|
|
|
|
// IScanImg
|
|
|
|
|
public:
|
|
|
|
|
COM_API_OVERRIDE(int, width(void));
|
|
|
|
|
COM_API_OVERRIDE(int, line_bytes(void));
|
|
|
|
|
COM_API_OVERRIDE(int, height(void));
|
|
|
|
|
COM_API_OVERRIDE(int, depth(void));
|
|
|
|
|
COM_API_OVERRIDE(int, channel(void));
|
2022-11-06 08:49:30 +00:00
|
|
|
|
COM_API_OVERRIDE(int, dpi(void));
|
2022-06-15 03:04:40 +00:00
|
|
|
|
COM_API_OVERRIDE(SANE_Frame, type(void));
|
|
|
|
|
COM_API_OVERRIDE(unsigned int, bytes(void));
|
2022-06-17 03:50:18 +00:00
|
|
|
|
COM_API_OVERRIDE(unsigned int, header_size(void));
|
2022-06-16 08:04:58 +00:00
|
|
|
|
COM_API_OVERRIDE(unsigned char*, data(unsigned long long off, unsigned int* bytes));
|
2022-06-17 03:50:18 +00:00
|
|
|
|
COM_API_OVERRIDE(int, read(void* buf, size_t* bytes, unsigned long long off = 0));
|
2022-06-16 08:04:58 +00:00
|
|
|
|
COM_API_OVERRIDE(const char*, file(void));
|
|
|
|
|
COM_API_OVERRIDE(void, keep_file(bool keep));
|
2022-06-15 03:04:40 +00:00
|
|
|
|
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
|
2022-09-20 10:14:27 +00:00
|
|
|
|
COM_API_OVERRIDE(int, image_status(void));
|
2023-07-03 04:23:44 +00:00
|
|
|
|
COM_API_OVERRIDE(size_t, get_bits_offset(void));
|
2023-08-04 09:38:26 +00:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
void prepare_data_for_transfer(twain_xfer xfer);
|
2022-06-15 03:04:40 +00:00
|
|
|
|
};
|
|
|
|
|
|
2022-07-02 09:27:21 +00:00
|
|
|
|
template<class T>
|
|
|
|
|
class safe_queue
|
2022-06-18 00:54:01 +00:00
|
|
|
|
{
|
2022-11-25 06:20:06 +00:00
|
|
|
|
typedef struct _t_and_size
|
|
|
|
|
{
|
|
|
|
|
size_t bytes;
|
|
|
|
|
T t;
|
|
|
|
|
}TNS;
|
|
|
|
|
std::mutex lock_;
|
|
|
|
|
std::vector<TNS> queue_;
|
|
|
|
|
size_t bytes_;
|
2022-11-25 06:36:19 +00:00
|
|
|
|
T empty_;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
|
|
|
|
|
public:
|
2022-11-25 06:20:06 +00:00
|
|
|
|
safe_queue() : bytes_(0)
|
2022-07-02 09:27:21 +00:00
|
|
|
|
{}
|
|
|
|
|
virtual ~safe_queue()
|
|
|
|
|
{}
|
|
|
|
|
|
|
|
|
|
public:
|
2022-11-25 06:20:06 +00:00
|
|
|
|
size_t count(size_t* bytes = NULL)
|
2022-07-02 09:27:21 +00:00
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(lock_);
|
|
|
|
|
|
2022-11-25 06:20:06 +00:00
|
|
|
|
if (bytes)
|
|
|
|
|
*bytes = bytes_;
|
|
|
|
|
|
2022-07-02 09:27:21 +00:00
|
|
|
|
return queue_.size();
|
|
|
|
|
}
|
2022-11-25 06:20:06 +00:00
|
|
|
|
bool save(T v, size_t bytes)
|
2022-07-02 09:27:21 +00:00
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(lock_);
|
2022-11-25 06:20:06 +00:00
|
|
|
|
TNS tns = { bytes, v };
|
2022-07-02 09:27:21 +00:00
|
|
|
|
|
2022-11-25 06:20:06 +00:00
|
|
|
|
queue_.push_back(tns);
|
|
|
|
|
bytes_ += bytes;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
T take(bool remove = true, void(__stdcall* first)(T) = NULL)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(lock_);
|
2022-11-25 06:23:20 +00:00
|
|
|
|
TNS t;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
|
|
|
|
|
if (queue_.size())
|
|
|
|
|
{
|
|
|
|
|
t = queue_[0];
|
2022-11-25 06:20:06 +00:00
|
|
|
|
if (remove)
|
|
|
|
|
{
|
2022-07-02 09:27:21 +00:00
|
|
|
|
queue_.erase(queue_.begin());
|
2022-11-25 06:20:06 +00:00
|
|
|
|
bytes_ -= t.bytes;
|
|
|
|
|
}
|
2022-07-02 09:27:21 +00:00
|
|
|
|
if (first)
|
2022-11-25 06:20:06 +00:00
|
|
|
|
first(t.t);
|
2022-07-02 09:27:21 +00:00
|
|
|
|
}
|
2022-11-25 06:36:19 +00:00
|
|
|
|
else
|
|
|
|
|
t.t = empty_;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
|
2022-11-25 06:20:06 +00:00
|
|
|
|
return t.t;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
void clear(void(__stdcall* tfree)(T) = NULL)
|
|
|
|
|
{
|
|
|
|
|
std::lock_guard<std::mutex> lock(lock_);
|
|
|
|
|
|
|
|
|
|
if (tfree)
|
|
|
|
|
{
|
|
|
|
|
for (auto& v : queue_)
|
2022-11-25 06:20:06 +00:00
|
|
|
|
tfree(v.t);
|
2022-07-02 09:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
queue_.clear();
|
2022-11-25 06:20:06 +00:00
|
|
|
|
bytes_ = 0;
|
2022-07-02 09:27:21 +00:00
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
class safe_img_queue : public safe_queue<scanned_img*>
|
|
|
|
|
{
|
|
|
|
|
static void __stdcall access_image(scanned_img* img);
|
|
|
|
|
static void __stdcall free_image(scanned_img* img);
|
2022-06-18 00:54:01 +00:00
|
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
safe_img_queue();
|
|
|
|
|
~safe_img_queue();
|
|
|
|
|
|
|
|
|
|
public:
|
2022-11-06 08:49:30 +00:00
|
|
|
|
bool get_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL);
|
2022-06-18 00:54:01 +00:00
|
|
|
|
void clear();
|
|
|
|
|
};
|
|
|
|
|
|
2022-06-16 08:04:58 +00:00
|
|
|
|
namespace local_trans
|
|
|
|
|
{
|
|
|
|
|
std::string u2a(const wchar_t* unic, UINT cp = CP_ACP);
|
|
|
|
|
std::wstring a2u(const char* asc, UINT cp = CP_ACP);
|
2023-02-07 08:55:51 +00:00
|
|
|
|
|
|
|
|
|
std::wstring lang_trans_between_hz936(const wchar_t* in, bool from_hz = true);
|
|
|
|
|
const char* __stdcall lang_trans_between_hz936(const char* in, bool from_hz, void* param);
|
2022-06-16 08:04:58 +00:00
|
|
|
|
}
|