#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_; 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); 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(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)); }; template class safe_queue { std::mutex lock_; std::vector queue_; public: safe_queue() {} virtual ~safe_queue() {} public: size_t count(void) { std::lock_guard lock(lock_); return queue_.size(); } bool save(T v) { std::lock_guard lock(lock_); queue_.push_back(v); return true; } T take(bool remove = true, void(__stdcall* first)(T) = NULL) { std::lock_guard lock(lock_); T t = 0; if (queue_.size()) { t = queue_[0]; if(remove) queue_.erase(queue_.begin()); if (first) first(t); } return t; } void clear(void(__stdcall* tfree)(T) = NULL) { std::lock_guard lock(lock_); if (tfree) { for (auto& v : queue_) tfree(v); } queue_.clear(); } }; 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); 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); }