code_device/twain/ds/scanned_img.h

188 lines
4.2 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#pragma once
#include "s2t_api.h"
#include <vector>
#include <mutex>
#include <base/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_;
int 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(int 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);
}