188 lines
4.3 KiB
C++
188 lines
4.3 KiB
C++
#pragma once
|
||
#include "s2t_api.h"
|
||
#include <vector>
|
||
#include <mutex>
|
||
|
||
#include "../../sdk/hginclude/utils.h"
|
||
|
||
|
||
class image_buf
|
||
{
|
||
unsigned long long bytes_;
|
||
unsigned long long offset_;
|
||
unsigned int mapped_bytes_;
|
||
bool is_mem_;
|
||
unsigned char* buf_;
|
||
|
||
void close(void);
|
||
|
||
public:
|
||
image_buf();
|
||
~image_buf();
|
||
|
||
public:
|
||
unsigned char* allocate(const char* file, unsigned long long size = 0, bool force_file = false);
|
||
bool save(const void* data, size_t* bytes, unsigned long long off);
|
||
bool save(unsigned long long off, image_buf* src);
|
||
unsigned long long bytes(void);
|
||
unsigned long long size(void);
|
||
unsigned char* buffer(unsigned long long off, unsigned int* bytes);
|
||
int read(void* buf, size_t* bytes, unsigned long long off);
|
||
};
|
||
|
||
class scanned_img : public IScanImg, virtual public refer
|
||
{
|
||
SANE_Parameters head_;
|
||
int dpi_;
|
||
SANE_Handle dev_;
|
||
std::string file_;
|
||
unsigned int header_size_;
|
||
SANE_FinalImgFormat fmt_;
|
||
|
||
SANE_Image_Statu status_;
|
||
image_buf* data_;
|
||
size_t pal_size_ = 0;
|
||
|
||
// 部分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);
|
||
void swap_rgb(void);
|
||
|
||
public:
|
||
scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const char* tmp_file
|
||
, twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL);
|
||
|
||
void set_image_status(SANE_Image_Statu status);
|
||
|
||
protected:
|
||
~scanned_img();
|
||
|
||
// IRef
|
||
public:
|
||
COM_API_OVERRIDE(int32_t, add_ref(void));
|
||
COM_API_OVERRIDE(int32_t, 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));
|
||
COM_API_OVERRIDE(int, dpi(void));
|
||
COM_API_OVERRIDE(SANE_Frame, type(void));
|
||
COM_API_OVERRIDE(unsigned int, bytes(void));
|
||
COM_API_OVERRIDE(unsigned int, header_size(void));
|
||
COM_API_OVERRIDE(unsigned char*, data(unsigned long long off, unsigned int* bytes));
|
||
COM_API_OVERRIDE(int, read(void* buf, size_t* bytes, unsigned long long off = 0));
|
||
COM_API_OVERRIDE(const char*, file(void));
|
||
COM_API_OVERRIDE(void, keep_file(bool keep));
|
||
COM_API_OVERRIDE(void, copy_header(SANE_Parameters* head));
|
||
COM_API_OVERRIDE(int, image_status(void));
|
||
COM_API_OVERRIDE(size_t, get_bits_offset(void));
|
||
|
||
public:
|
||
void prepare_data_for_transfer(twain_xfer xfer);
|
||
};
|
||
|
||
template<class T>
|
||
class safe_queue
|
||
{
|
||
typedef struct _t_and_size
|
||
{
|
||
size_t bytes;
|
||
T t;
|
||
}TNS;
|
||
std::mutex lock_;
|
||
std::vector<TNS> queue_;
|
||
size_t bytes_;
|
||
T empty_;
|
||
|
||
public:
|
||
safe_queue() : bytes_(0)
|
||
{}
|
||
virtual ~safe_queue()
|
||
{}
|
||
|
||
public:
|
||
size_t count(size_t* bytes = NULL)
|
||
{
|
||
std::lock_guard<std::mutex> lock(lock_);
|
||
|
||
if (bytes)
|
||
*bytes = bytes_;
|
||
|
||
return queue_.size();
|
||
}
|
||
bool save(T v, size_t bytes)
|
||
{
|
||
std::lock_guard<std::mutex> lock(lock_);
|
||
TNS tns = { bytes, v };
|
||
|
||
queue_.push_back(tns);
|
||
bytes_ += bytes;
|
||
|
||
return true;
|
||
}
|
||
T take(bool remove = true, void(* first)(T) = NULL)
|
||
{
|
||
std::lock_guard<std::mutex> lock(lock_);
|
||
TNS t;
|
||
|
||
if (queue_.size())
|
||
{
|
||
t = queue_[0];
|
||
if (remove)
|
||
{
|
||
queue_.erase(queue_.begin());
|
||
bytes_ -= t.bytes;
|
||
}
|
||
if (first)
|
||
first(t.t);
|
||
}
|
||
else
|
||
t.t = empty_;
|
||
|
||
return t.t;
|
||
}
|
||
void clear(void(* tfree)(T) = NULL)
|
||
{
|
||
std::lock_guard<std::mutex> lock(lock_);
|
||
|
||
if (tfree)
|
||
{
|
||
for (auto& v : queue_)
|
||
tfree(v.t);
|
||
}
|
||
queue_.clear();
|
||
bytes_ = 0;
|
||
}
|
||
};
|
||
|
||
class safe_img_queue : public safe_queue<scanned_img*>
|
||
{
|
||
static void access_image(scanned_img* img);
|
||
static void free_image(scanned_img* img);
|
||
|
||
public:
|
||
safe_img_queue();
|
||
~safe_img_queue();
|
||
|
||
public:
|
||
bool get_header(SANE_Parameters* header, size_t* bytes = NULL, int *dpi = NULL);
|
||
void clear();
|
||
};
|
||
|
||
namespace local_trans
|
||
{
|
||
int load_lang_pak(const char* dll);
|
||
std::string lang_trans_between_hz936(const char* in, bool from_hz = true);
|
||
const char* lang_trans_between_hz936(const char* in, bool from_hz, void* param);
|
||
|
||
const char* to_default_language(const char* str, bool* ok = nullptr);
|
||
const char* from_default_language(const char* str, bool* ok = nullptr);
|
||
}
|