#pragma once #include "s2t_api.h" #include #include 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)); }; 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: unsigned char* allocate(const wchar_t* file, unsigned long long size = 0, bool force_file = false); unsigned char* buffer(unsigned long long off, unsigned int* bytes); bool save(const void* data, size_t* bytes, unsigned long long off); bool save(unsigned long long off, mapping_buf* mbuf, unsigned long long src_off = 0); int read(void* buf, size_t* bytes, unsigned long long off); 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); }; class scanned_img : public IScanImg, virtual public refer { SANE_Parameters head_; mapping_buf* data_; int dpi_; SANE_Handle dev_; std::wstring file_; unsigned int header_size_; SANE_FinalImgFormat fmt_; SANE_Image_Statu status_; std::string file_header(SANE_ImageType type, float resolution, twain_xfer xfer); void do_result(bool ok, twain_xfer xfer); void swap_rgb(void); public: scanned_img(SANE_Handle dev, SANE_Parameters head, int dpi, const wchar_t* tmp_file , twain_xfer xfer = TWAIN_XFER_Native, SANE_FinalImgFormat *fmt = NULL); scanned_img(SANE_Handle dev, SANE_Parameters head, void* data, unsigned int len, int dpi, const wchar_t* 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(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)); 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)); }; template class safe_queue { typedef struct _t_and_size { size_t bytes; T t; }TNS; std::mutex lock_; std::vector 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 lock(lock_); if (bytes) *bytes = bytes_; return queue_.size(); } bool save(T v, size_t bytes) { std::lock_guard lock(lock_); TNS tns = { bytes, v }; queue_.push_back(tns); bytes_ += bytes; return true; } T take(bool remove = true, void(__stdcall* first)(T) = NULL) { std::lock_guard 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(__stdcall* tfree)(T) = NULL) { std::lock_guard lock(lock_); if (tfree) { for (auto& v : queue_) tfree(v.t); } queue_.clear(); bytes_ = 0; } }; class safe_img_queue : public safe_queue { static void __stdcall access_image(scanned_img* img); static void __stdcall 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 { std::string u2a(const wchar_t* unic, UINT cp = CP_ACP); std::wstring a2u(const char* asc, UINT cp = CP_ACP); 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); }